libpgf  6.12.24
PGF - Progressive Graphics File
 All Classes Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
CEncoder Class Reference

PGF encoder. More...

#include <Encoder.h>

List of all members.

Classes

class  CMacroBlock
 A macro block is an encoding unit of fixed size (uncoded) More...

Public Member Functions

 CEncoder (CPGFStream *stream, PGFPreHeader preHeader, PGFHeader header, const PGFPostHeader &postHeader, UINT64 &userDataPos, bool useOMP) THROW_
 ~CEncoder ()
void FavorSpeedOverSize ()
void Flush () THROW_
void UpdatePostHeaderSize (PGFPreHeader preHeader) THROW_
UINT32 WriteLevelLength (UINT32 *&levelLength) THROW_
UINT32 UpdateLevelLength () THROW_
void Partition (CSubband *band, int width, int height, int startPos, int pitch) THROW_
void SetEncodedLevel (int currentLevel)
void WriteValue (CSubband *band, int bandPos) THROW_
INT64 ComputeHeaderLength () const
INT64 ComputeBufferLength () const
INT64 ComputeOffset () const
void SetBufferStartPos ()

Private Member Functions

void EncodeBuffer (ROIBlockHeader h) THROW_
void WriteMacroBlock (CMacroBlock *block) THROW_

Private Attributes

CPGFStreamm_stream
 output PMF stream
UINT64 m_startPosition
 stream position of PGF start (PreHeader)
UINT64 m_levelLengthPos
 stream position of Metadata
UINT64 m_bufferStartPos
 stream position of encoded buffer
CMacroBlock ** m_macroBlocks
 array of macroblocks
int m_macroBlockLen
 array length
int m_lastMacroBlock
 array index of the last created macro block
CMacroBlockm_currentBlock
 current macro block (used by main thread)
UINT32 * m_levelLength
 temporary saves the level index
int m_currLevelIndex
 counts where (=index) to save next value
UINT8 m_nLevels
 number of levels
bool m_favorSpeed
 favor speed over size
bool m_forceWriting
 all macro blocks have to be written into the stream

Detailed Description

PGF encoder.

PGF encoder class.

Author:
C. Stamm

Definition at line 46 of file Encoder.h.


Constructor & Destructor Documentation

CEncoder::CEncoder ( CPGFStream stream,
PGFPreHeader  preHeader,
PGFHeader  header,
const PGFPostHeader postHeader,
UINT64 &  userDataPos,
bool  useOMP 
)

Write pre-header, header, post-Header, and levelLength. It might throw an IOException.

Parameters:
streamA PGF stream
preHeaderA already filled in PGF pre-header
headerAn already filled in PGF header
postHeader[in] An already filled in PGF post-header (containing color table, user data, ...)
userDataPos[out] File position of user data
useOMPIf true, then the encoder will use multi-threading based on openMP

Write pre-header, header, postHeader, and levelLength. It might throw an IOException.

Parameters:
streamA PGF stream
preHeaderA already filled in PGF pre-header
headerAn already filled in PGF header
postHeader[in] An already filled in PGF post-header (containing color table, user data, ...)
userDataPos[out] File position of user data
useOMPIf true, then the encoder will use multi-threading based on openMP

Definition at line 70 of file Encoder.cpp.

: m_stream(stream)
, m_nLevels(header.nLevels)
, m_favorSpeed(false)
#ifdef __PGFROISUPPORT__
, m_roi(false)
#endif
{
ASSERT(m_stream);
int count;
// set number of threads
#ifdef LIBPGF_USE_OPENMP
m_macroBlockLen = omp_get_num_procs();
#else
#endif
if (useOMP && m_macroBlockLen > 1) {
#ifdef LIBPGF_USE_OPENMP
omp_set_num_threads(m_macroBlockLen);
#endif
// create macro block array
m_macroBlocks = new(std::nothrow) CMacroBlock*[m_macroBlockLen];
if (!m_macroBlocks) ReturnWithError(InsufficientMemory);
for (int i=0; i < m_macroBlockLen; i++) m_macroBlocks[i] = new CMacroBlock(this);
} else {
m_macroBlockLen = 1;
m_currentBlock = new CMacroBlock(this);
}
// save file position
// write preHeader
preHeader.hSize = __VAL(preHeader.hSize);
count = PreHeaderSize;
m_stream->Write(&count, &preHeader);
// write file header
header.height = __VAL(header.height);
header.width = __VAL(header.width);
count = HeaderSize;
m_stream->Write(&count, &header);
// write postHeader
if (header.mode == ImageModeIndexedColor) {
// write color table
count = ColorTableSize;
m_stream->Write(&count, (void *)postHeader.clut);
}
// save user data file position
userDataPos = m_stream->GetPos();
if (postHeader.userDataLen) {
if (postHeader.userData) {
// write user data
count = postHeader.userDataLen;
m_stream->Write(&count, postHeader.userData);
} else {
m_stream->SetPos(FSFromCurrent, count);
}
}
// save level length file position
}
CEncoder::~CEncoder ( )

Destructor

Definition at line 146 of file Encoder.cpp.

{
delete[] m_macroBlocks;
}

Member Function Documentation

INT64 CEncoder::ComputeBufferLength ( ) const
inline

Compute stream length of encoded buffer.

Returns:
encoded buffer length

Definition at line 175 of file Encoder.h.

INT64 CEncoder::ComputeHeaderLength ( ) const
inline

Compute stream length of header.

Returns:
header length

Definition at line 170 of file Encoder.h.

INT64 CEncoder::ComputeOffset ( ) const
inline

Compute file offset between real and expected levelLength position.

Returns:
file offset

Definition at line 180 of file Encoder.h.

void CEncoder::EncodeBuffer ( ROIBlockHeader  h)
private

Definition at line 336 of file Encoder.cpp.

{
ASSERT(m_currentBlock);
#ifdef __PGFROISUPPORT__
ASSERT(m_roi && h.rbh.bufferSize <= BufferSize || h.rbh.bufferSize == BufferSize);
#else
ASSERT(h.rbh.bufferSize == BufferSize);
#endif
// macro block management
if (m_macroBlockLen == 1) {
} else {
// save last level index
int lastLevelIndex = m_currentBlock->m_lastLevelIndex;
// encode macro blocks
/*
volatile OSError error = NoError;
#pragma omp parallel for ordered default(shared)
for (int i=0; i < m_lastMacroBlock; i++) {
if (error == NoError) {
m_macroBlocks[i]->BitplaneEncode();
#pragma omp ordered
{
try {
WriteMacroBlock(m_macroBlocks[i]);
} catch (IOException& e) {
error = e.error;
}
delete m_macroBlocks[i]; m_macroBlocks[i] = 0;
}
}
}
if (error != NoError) ReturnWithError(error);
*/
#pragma omp parallel for default(shared) //no declared exceptions in next block
for (int i=0; i < m_lastMacroBlock; i++) {
}
for (int i=0; i < m_lastMacroBlock; i++) {
}
// prepare for next round
m_forceWriting = false;
m_lastMacroBlock = 0;
}
// re-initialize macro block
m_currentBlock = m_macroBlocks[m_lastMacroBlock++];
m_currentBlock->Init(lastLevelIndex);
}
}
void CEncoder::FavorSpeedOverSize ( )
inline

Encoder favors speed over compression size

Definition at line 117 of file Encoder.h.

{ m_favorSpeed = true; }
void CEncoder::Flush ( )

Pad buffer with zeros and encode buffer. It might throw an IOException.

Definition at line 305 of file Encoder.cpp.

{
// pad buffer with zeros
// encode buffer
m_forceWriting = true; // makes sure that the following EncodeBuffer is really written into the stream
}
}
void CEncoder::Partition ( CSubband band,
int  width,
int  height,
int  startPos,
int  pitch 
)

Partitions a rectangular region of a given subband. Partitioning scheme: The plane is partitioned in squares of side length LinBlockSize. Write wavelet coefficients from subband into the input buffer of a macro block. It might throw an IOException.

Parameters:
bandA subband
widthThe width of the rectangle
heightThe height of the rectangle
startPosThe absolute subband position of the top left corner of the rectangular region
pitchThe number of bytes in row of the subband

Definition at line 241 of file Encoder.cpp.

{
ASSERT(band);
const div_t hh = div(height, LinBlockSize);
const div_t ww = div(width, LinBlockSize);
const int ws = pitch - LinBlockSize;
const int wr = pitch - ww.rem;
int pos, base = startPos, base2;
// main height
for (int i=0; i < hh.quot; i++) {
// main width
base2 = base;
for (int j=0; j < ww.quot; j++) {
pos = base2;
for (int y=0; y < LinBlockSize; y++) {
for (int x=0; x < LinBlockSize; x++) {
WriteValue(band, pos);
pos++;
}
pos += ws;
}
base2 += LinBlockSize;
}
// rest of width
pos = base2;
for (int y=0; y < LinBlockSize; y++) {
for (int x=0; x < ww.rem; x++) {
WriteValue(band, pos);
pos++;
}
pos += wr;
base += pitch;
}
}
// main width
base2 = base;
for (int j=0; j < ww.quot; j++) {
// rest of height
pos = base2;
for (int y=0; y < hh.rem; y++) {
for (int x=0; x < LinBlockSize; x++) {
WriteValue(band, pos);
pos++;
}
pos += ws;
}
base2 += LinBlockSize;
}
// rest of height
pos = base2;
for (int y=0; y < hh.rem; y++) {
// rest of width
for (int x=0; x < ww.rem; x++) {
WriteValue(band, pos);
pos++;
}
pos += wr;
}
}
void CEncoder::SetBufferStartPos ( )
inline

Save current stream position as beginning of current level.

Definition at line 184 of file Encoder.h.

void CEncoder::SetEncodedLevel ( int  currentLevel)
inline

Informs the encoder about the encoded level.

Parameters:
currentLevelencoded level [0, nLevels)

Definition at line 158 of file Encoder.h.

{ ASSERT(currentLevel >= 0); m_currentBlock->m_lastLevelIndex = m_nLevels - currentLevel - 1; m_forceWriting = true; }
UINT32 CEncoder::UpdateLevelLength ( )

Write new levelLength into stream. It might throw an IOException.

Returns:
Written image bytes.

Definition at line 197 of file Encoder.cpp.

{
UINT64 curPos = m_stream->GetPos(); // end of image
// set file pos to levelLength
#ifdef PGF_USE_BIG_ENDIAN
UINT32 levelLength;
int count = WordBytes;
for (int i=0; i < m_currLevelIndex; i++) {
levelLength = __VAL(UINT32(m_levelLength[i]));
m_stream->Write(&count, &levelLength);
}
#else
int count = m_currLevelIndex*WordBytes;
#endif //PGF_USE_BIG_ENDIAN
} else {
int count = m_currLevelIndex*WordBytes;
m_stream->SetPos(FSFromCurrent, count);
}
// begin of image
UINT32 retValue = UINT32(curPos - m_stream->GetPos());
// restore file position
m_stream->SetPos(FSFromStart, curPos);
return retValue;
}
void CEncoder::UpdatePostHeaderSize ( PGFPreHeader  preHeader)

Increase post-header size and write new size into stream.

Parameters:
preHeaderAn already filled in PGF pre-header It might throw an IOException.

Definition at line 155 of file Encoder.cpp.

{
UINT64 curPos = m_stream->GetPos(); // end of user data
int count = PreHeaderSize;
// write preHeader
preHeader.hSize = __VAL(preHeader.hSize);
m_stream->Write(&count, &preHeader);
m_stream->SetPos(FSFromStart, curPos);
}
UINT32 CEncoder::WriteLevelLength ( UINT32 *&  levelLength)

Create level length data structure and write a place holder into stream. It might throw an IOException.

Parameters:
levelLengthA reference to an integer array, large enough to save the relative file positions of all PGF levels
Returns:
number of bytes written into stream

Definition at line 172 of file Encoder.cpp.

{
// renew levelLength
delete[] levelLength;
levelLength = new(std::nothrow) UINT32[m_nLevels];
if (!levelLength) ReturnWithError(InsufficientMemory);
for (UINT8 l = 0; l < m_nLevels; l++) levelLength[l] = 0;
m_levelLength = levelLength;
// save level length file position
// write dummy levelLength
int count = m_nLevels*WordBytes;
// save current file position
return count;
}
void CEncoder::WriteMacroBlock ( CMacroBlock block)
private

Definition at line 395 of file Encoder.cpp.

{
ASSERT(block);
ROIBlockHeader h = block->m_header;
UINT16 wordLen = UINT16(NumberOfWords(block->m_codePos)); ASSERT(wordLen <= CodeBufferLen);
int count = sizeof(UINT16);
#ifdef TRACE
//UINT32 filePos = (UINT32)m_stream->GetPos();
//printf("EncodeBuffer: %d\n", filePos);
#endif
#ifdef PGF_USE_BIG_ENDIAN
// write wordLen
UINT16 wl = __VAL(wordLen);
m_stream->Write(&count, &wl); ASSERT(count == sizeof(UINT16));
#ifdef __PGFROISUPPORT__
// write ROIBlockHeader
if (m_roi) {
h.val = __VAL(h.val);
m_stream->Write(&count, &h.val); ASSERT(count == sizeof(UINT16));
}
#endif // __PGFROISUPPORT__
// convert data
for (int i=0; i < wordLen; i++) {
block->m_codeBuffer[i] = __VAL(block->m_codeBuffer[i]);
}
#else
// write wordLen
m_stream->Write(&count, &wordLen); ASSERT(count == sizeof(UINT16));
#ifdef __PGFROISUPPORT__
// write ROIBlockHeader
if (m_roi) {
m_stream->Write(&count, &h.val); ASSERT(count == sizeof(UINT16));
}
#endif // __PGFROISUPPORT__
#endif // PGF_USE_BIG_ENDIAN
// write encoded data into stream
count = wordLen*WordBytes;
m_stream->Write(&count, block->m_codeBuffer);
// store levelLength
// store level length
// EncodeBuffer has been called after m_lastLevelIndex has been updated
m_currLevelIndex = block->m_lastLevelIndex + 1;
}
// prepare for next buffer
// reset values
block->m_valuePos = 0;
block->m_maxAbsValue = 0;
}
void CEncoder::WriteValue ( CSubband band,
int  bandPos 
)

Write a single value into subband at given position. It might throw an IOException.

Parameters:
bandA subband
bandPosA valid position in subband band

Definition at line 321 of file Encoder.cpp.


Member Data Documentation

UINT64 CEncoder::m_bufferStartPos
private

stream position of encoded buffer

Definition at line 208 of file Encoder.h.

CMacroBlock* CEncoder::m_currentBlock
private

current macro block (used by main thread)

Definition at line 213 of file Encoder.h.

int CEncoder::m_currLevelIndex
private

counts where (=index) to save next value

Definition at line 216 of file Encoder.h.

bool CEncoder::m_favorSpeed
private

favor speed over size

Definition at line 218 of file Encoder.h.

bool CEncoder::m_forceWriting
private

all macro blocks have to be written into the stream

Definition at line 219 of file Encoder.h.

int CEncoder::m_lastMacroBlock
private

array index of the last created macro block

Definition at line 212 of file Encoder.h.

UINT32* CEncoder::m_levelLength
private

temporary saves the level index

Definition at line 215 of file Encoder.h.

UINT64 CEncoder::m_levelLengthPos
private

stream position of Metadata

Definition at line 207 of file Encoder.h.

int CEncoder::m_macroBlockLen
private

array length

Definition at line 211 of file Encoder.h.

CMacroBlock** CEncoder::m_macroBlocks
private

array of macroblocks

Definition at line 210 of file Encoder.h.

UINT8 CEncoder::m_nLevels
private

number of levels

Definition at line 217 of file Encoder.h.

UINT64 CEncoder::m_startPosition
private

stream position of PGF start (PreHeader)

Definition at line 206 of file Encoder.h.

CPGFStream* CEncoder::m_stream
private

output PMF stream

Definition at line 205 of file Encoder.h.


The documentation for this class was generated from the following files: