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 ()
void EncodeTileBuffer () THROW_
void SetROI ()

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
bool m_roi
 true: ensures region of interest (ROI) encoding

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:
stream A PGF stream
preHeader A already filled in PGF pre-header
header An 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
useOMP If true, then the encoder will use multi-threading based on openMP

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

Parameters:
stream A PGF stream
preHeader A already filled in PGF pre-header
header An 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
useOMP If true, then the encoder will use multi-threading based on openMP

Definition at line 70 of file Encoder.cpp.

00071 : m_stream(stream)
00072 , m_bufferStartPos(0)
00073 , m_currLevelIndex(0)
00074 , m_nLevels(header.nLevels)
00075 , m_favorSpeed(false)
00076 , m_forceWriting(false)
00077 #ifdef __PGFROISUPPORT__
00078 , m_roi(false)
00079 #endif
00080 {
00081         ASSERT(m_stream);
00082 
00083         int count;
00084         m_lastMacroBlock = 0;
00085         m_levelLength = NULL;
00086 
00087         // set number of threads
00088 #ifdef LIBPGF_USE_OPENMP
00089         m_macroBlockLen = omp_get_num_procs();
00090 #else
00091         m_macroBlockLen = 1;
00092 #endif
00093         
00094         if (useOMP && m_macroBlockLen > 1) {
00095 #ifdef LIBPGF_USE_OPENMP
00096                 omp_set_num_threads(m_macroBlockLen);
00097 #endif
00098                 // create macro block array
00099                 m_macroBlocks = new(std::nothrow) CMacroBlock*[m_macroBlockLen];
00100                 if (!m_macroBlocks) ReturnWithError(InsufficientMemory);
00101                 for (int i=0; i < m_macroBlockLen; i++) m_macroBlocks[i] = new CMacroBlock(this);
00102                 m_currentBlock = m_macroBlocks[m_lastMacroBlock++];
00103         } else {
00104                 m_macroBlocks = 0;
00105                 m_macroBlockLen = 1;
00106                 m_currentBlock = new CMacroBlock(this);
00107         }
00108 
00109         // save file position
00110         m_startPosition = m_stream->GetPos();
00111 
00112         // write preHeader
00113         preHeader.hSize = __VAL(preHeader.hSize);
00114         count = PreHeaderSize;
00115         m_stream->Write(&count, &preHeader);
00116 
00117         // write file header
00118         header.height = __VAL(header.height);
00119         header.width = __VAL(header.width);
00120         count = HeaderSize;
00121         m_stream->Write(&count, &header);
00122 
00123         // write postHeader
00124         if (header.mode == ImageModeIndexedColor) {
00125                 // write color table
00126                 count = ColorTableSize;
00127                 m_stream->Write(&count, (void *)postHeader.clut);
00128         }
00129         // save user data file position
00130         userDataPos = m_stream->GetPos();
00131         if (postHeader.userDataLen) {
00132                 if (postHeader.userData) {
00133                         // write user data
00134                         count = postHeader.userDataLen;
00135                         m_stream->Write(&count, postHeader.userData);
00136                 } else {
00137                         m_stream->SetPos(FSFromCurrent, count);
00138                 }
00139         }
00140 
00141         // save level length file position
00142         m_levelLengthPos = m_stream->GetPos();
00143 }

CEncoder::~CEncoder (  ) 

Destructor

Definition at line 147 of file Encoder.cpp.

00147                     {   
00148         if (m_macroBlocks) {
00149                 for (int i=0; i < m_macroBlockLen; i++) delete m_macroBlocks[i];
00150                 delete[] m_macroBlocks;
00151         } else {
00152                 delete m_currentBlock;
00153         }
00154 }


Member Function Documentation

INT64 CEncoder::ComputeBufferLength (  )  const [inline]

Compute stream length of encoded buffer.

Returns:
encoded buffer length

Definition at line 179 of file Encoder.h.

00179 { return m_stream->GetPos() - m_bufferStartPos; }

INT64 CEncoder::ComputeHeaderLength (  )  const [inline]

Compute stream length of header.

Returns:
header length

Definition at line 174 of file Encoder.h.

00174 { return m_levelLengthPos - m_startPosition; }

INT64 CEncoder::ComputeOffset (  )  const [inline]

Compute file offset between real and expected levelLength position.

Returns:
file offset

Definition at line 184 of file Encoder.h.

00184 { return m_stream->GetPos() - m_levelLengthPos; }

void CEncoder::EncodeBuffer ( ROIBlockHeader  h  )  [private]

Definition at line 341 of file Encoder.cpp.

00341                                                    {
00342         ASSERT(m_currentBlock);
00343 #ifdef __PGFROISUPPORT__
00344         ASSERT(m_roi && h.rbh.bufferSize <= BufferSize || h.rbh.bufferSize == BufferSize);
00345 #else
00346         ASSERT(h.rbh.bufferSize == BufferSize);
00347 #endif
00348         m_currentBlock->m_header = h;
00349 
00350         // macro block management
00351         if (m_macroBlockLen == 1) {
00352                 m_currentBlock->BitplaneEncode();
00353                 WriteMacroBlock(m_currentBlock);
00354         } else {
00355                 // save last level index
00356                 int lastLevelIndex = m_currentBlock->m_lastLevelIndex;
00357 
00358                 if (m_forceWriting || m_lastMacroBlock == m_macroBlockLen) {
00359                         // encode macro blocks
00360                         /*
00361                         volatile OSError error = NoError;
00362                         #ifdef LIBPGF_USE_OPENMP
00363                         #pragma omp parallel for ordered default(shared)
00364                         #endif
00365                         for (int i=0; i < m_lastMacroBlock; i++) {
00366                                 if (error == NoError) {
00367                                         m_macroBlocks[i]->BitplaneEncode();
00368                                         #ifdef LIBPGF_USE_OPENMP
00369                                         #pragma omp ordered
00370                                         #endif
00371                                         {
00372                                                 try {
00373                                                         WriteMacroBlock(m_macroBlocks[i]);
00374                                                 } catch (IOException& e) {
00375                                                         error = e.error;
00376                                                 }
00377                                                 delete m_macroBlocks[i]; m_macroBlocks[i] = 0;
00378                                         }
00379                                 }
00380                         }
00381                         if (error != NoError) ReturnWithError(error);
00382                         */
00383 #ifdef LIBPGF_USE_OPENMP
00384                         #pragma omp parallel for default(shared) //no declared exceptions in next block
00385 #endif
00386                         for (int i=0; i < m_lastMacroBlock; i++) {
00387                                 m_macroBlocks[i]->BitplaneEncode();
00388                         }
00389                         for (int i=0; i < m_lastMacroBlock; i++) {
00390                                 WriteMacroBlock(m_macroBlocks[i]);
00391                         }
00392                         
00393                         // prepare for next round
00394                         m_forceWriting = false;
00395                         m_lastMacroBlock = 0;
00396                 }
00397                 // re-initialize macro block
00398                 m_currentBlock = m_macroBlocks[m_lastMacroBlock++];
00399                 m_currentBlock->Init(lastLevelIndex);
00400         }
00401 }

void CEncoder::EncodeTileBuffer (  )  [inline]

Encodes tile buffer and writes it into stream It might throw an IOException.

Definition at line 194 of file Encoder.h.

void CEncoder::FavorSpeedOverSize (  )  [inline]

Encoder favors speed over compression size

Definition at line 121 of file Encoder.h.

00121 { m_favorSpeed = true; }

void CEncoder::Flush (  ) 

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

Definition at line 310 of file Encoder.cpp.

00310                             {
00311         if (m_currentBlock->m_valuePos > 0) {
00312                 // pad buffer with zeros
00313                 memset(&(m_currentBlock->m_value[m_currentBlock->m_valuePos]), 0, (BufferSize - m_currentBlock->m_valuePos)*DataTSize);
00314                 m_currentBlock->m_valuePos = BufferSize;
00315 
00316                 // encode buffer
00317                 m_forceWriting = true;  // makes sure that the following EncodeBuffer is really written into the stream
00318                 EncodeBuffer(ROIBlockHeader(m_currentBlock->m_valuePos, true));
00319         }
00320 }

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:
band A subband
width The width of the rectangle
height The height of the rectangle
startPos The absolute subband position of the top left corner of the rectangular region
pitch The number of bytes in row of the subband

Definition at line 246 of file Encoder.cpp.

00246                                                                                               {
00247         ASSERT(band);
00248 
00249         const div_t hh = div(height, LinBlockSize);
00250         const div_t ww = div(width, LinBlockSize);
00251         const int ws = pitch - LinBlockSize;
00252         const int wr = pitch - ww.rem;
00253         int pos, base = startPos, base2;
00254 
00255         // main height
00256         for (int i=0; i < hh.quot; i++) {
00257                 // main width
00258                 base2 = base;
00259                 for (int j=0; j < ww.quot; j++) {
00260                         pos = base2;
00261                         for (int y=0; y < LinBlockSize; y++) {
00262                                 for (int x=0; x < LinBlockSize; x++) {
00263                                         WriteValue(band, pos);
00264                                         pos++;
00265                                 }
00266                                 pos += ws;
00267                         }
00268                         base2 += LinBlockSize;
00269                 }
00270                 // rest of width
00271                 pos = base2;
00272                 for (int y=0; y < LinBlockSize; y++) {
00273                         for (int x=0; x < ww.rem; x++) {
00274                                 WriteValue(band, pos);
00275                                 pos++;
00276                         }
00277                         pos += wr;
00278                         base += pitch;
00279                 }
00280         }
00281         // main width 
00282         base2 = base;
00283         for (int j=0; j < ww.quot; j++) {
00284                 // rest of height
00285                 pos = base2;
00286                 for (int y=0; y < hh.rem; y++) {
00287                         for (int x=0; x < LinBlockSize; x++) {
00288                                 WriteValue(band, pos);
00289                                 pos++;
00290                         }
00291                         pos += ws;
00292                 }
00293                 base2 += LinBlockSize;
00294         }
00295         // rest of height
00296         pos = base2;
00297         for (int y=0; y < hh.rem; y++) {
00298                 // rest of width
00299                 for (int x=0; x < ww.rem; x++) {
00300                         WriteValue(band, pos);
00301                         pos++;
00302                 }
00303                 pos += wr;
00304         }
00305 }

void CEncoder::SetBufferStartPos (  )  [inline]

Save current stream position as beginning of current level.

Definition at line 188 of file Encoder.h.

void CEncoder::SetEncodedLevel ( int  currentLevel  )  [inline]

Informs the encoder about the encoded level.

Parameters:
currentLevel encoded level [0, nLevels)

Definition at line 162 of file Encoder.h.

00162 { ASSERT(currentLevel >= 0); m_currentBlock->m_lastLevelIndex = m_nLevels - currentLevel - 1; m_forceWriting = true; }

void CEncoder::SetROI (  )  [inline]

Enables region of interest (ROI) status.

Definition at line 198 of file Encoder.h.

00198 { m_roi = true; }

UINT32 CEncoder::UpdateLevelLength (  ) 

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

Returns:
Written image bytes.

Definition at line 202 of file Encoder.cpp.

00202                                           {
00203         UINT64 curPos = m_stream->GetPos(); // end of image
00204 
00205         // set file pos to levelLength
00206         m_stream->SetPos(FSFromStart, m_levelLengthPos);
00207 
00208         if (m_levelLength) {
00209         #ifdef PGF_USE_BIG_ENDIAN 
00210                 UINT32 levelLength;
00211                 int count = WordBytes;
00212                 
00213                 for (int i=0; i < m_currLevelIndex; i++) {
00214                         levelLength = __VAL(UINT32(m_levelLength[i]));
00215                         m_stream->Write(&count, &levelLength);
00216                 }
00217         #else
00218                 int count = m_currLevelIndex*WordBytes;
00219                 
00220                 m_stream->Write(&count, m_levelLength);
00221         #endif //PGF_USE_BIG_ENDIAN 
00222         } else {
00223                 int count = m_currLevelIndex*WordBytes;
00224                 m_stream->SetPos(FSFromCurrent, count);
00225         }
00226 
00227         // begin of image
00228         UINT32 retValue = UINT32(curPos - m_stream->GetPos());
00229                 
00230         // restore file position
00231         m_stream->SetPos(FSFromStart, curPos);
00232 
00233         return retValue;
00234 }

void CEncoder::UpdatePostHeaderSize ( PGFPreHeader  preHeader  ) 

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

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

Definition at line 160 of file Encoder.cpp.

00160                                                                  {
00161         UINT64 curPos = m_stream->GetPos(); // end of user data
00162         int count = PreHeaderSize;
00163 
00164         // write preHeader
00165         m_stream->SetPos(FSFromStart, m_startPosition);
00166         preHeader.hSize = __VAL(preHeader.hSize);
00167         m_stream->Write(&count, &preHeader);
00168 
00169         m_stream->SetPos(FSFromStart, curPos);
00170 }

UINT32 CEncoder::WriteLevelLength ( UINT32 *&  levelLength  ) 

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

Parameters:
levelLength A 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 177 of file Encoder.cpp.

00177                                                              {
00178         // renew levelLength
00179         delete[] levelLength;
00180         levelLength = new(std::nothrow) UINT32[m_nLevels];
00181         if (!levelLength) ReturnWithError(InsufficientMemory);
00182         for (UINT8 l = 0; l < m_nLevels; l++) levelLength[l] = 0;
00183         m_levelLength = levelLength;
00184 
00185         // save level length file position
00186         m_levelLengthPos = m_stream->GetPos();
00187 
00188         // write dummy levelLength
00189         int count = m_nLevels*WordBytes;
00190         m_stream->Write(&count, m_levelLength);
00191 
00192         // save current file position
00193         SetBufferStartPos();
00194 
00195         return count;
00196 }

void CEncoder::WriteMacroBlock ( CMacroBlock block  )  [private]

Definition at line 406 of file Encoder.cpp.

00406                                                         {
00407         ASSERT(block);
00408 #ifdef __PGFROISUPPORT__
00409         ROIBlockHeader h = block->m_header;
00410 #endif
00411         UINT16 wordLen = UINT16(NumberOfWords(block->m_codePos)); ASSERT(wordLen <= CodeBufferLen);
00412         int count = sizeof(UINT16);
00413         
00414 #ifdef TRACE
00415         //UINT32 filePos = (UINT32)m_stream->GetPos();
00416         //printf("EncodeBuffer: %d\n", filePos);
00417 #endif
00418 
00419 #ifdef PGF_USE_BIG_ENDIAN 
00420         // write wordLen
00421         UINT16 wl = __VAL(wordLen);
00422         m_stream->Write(&count, &wl); ASSERT(count == sizeof(UINT16));
00423 
00424 #ifdef __PGFROISUPPORT__
00425         // write ROIBlockHeader
00426         if (m_roi) {
00427                 h.val = __VAL(h.val);
00428                 m_stream->Write(&count, &h.val); ASSERT(count == sizeof(UINT16));
00429         }
00430 #endif // __PGFROISUPPORT__
00431 
00432         // convert data
00433         for (int i=0; i < wordLen; i++) {
00434                 block->m_codeBuffer[i] = __VAL(block->m_codeBuffer[i]);
00435         }
00436 #else
00437         // write wordLen
00438         m_stream->Write(&count, &wordLen); ASSERT(count == sizeof(UINT16));
00439 
00440 #ifdef __PGFROISUPPORT__
00441         // write ROIBlockHeader
00442         if (m_roi) {
00443                 m_stream->Write(&count, &h.val); ASSERT(count == sizeof(UINT16));
00444         }
00445 #endif // __PGFROISUPPORT__
00446 #endif // PGF_USE_BIG_ENDIAN
00447 
00448         // write encoded data into stream
00449         count = wordLen*WordBytes;
00450         m_stream->Write(&count, block->m_codeBuffer);
00451 
00452         // store levelLength
00453         if (m_levelLength) {
00454                 // store level length
00455                 // EncodeBuffer has been called after m_lastLevelIndex has been updated
00456                 ASSERT(m_currLevelIndex < m_nLevels);
00457                 m_levelLength[m_currLevelIndex] += (UINT32)ComputeBufferLength();
00458                 m_currLevelIndex = block->m_lastLevelIndex + 1;
00459 
00460         }
00461 
00462         // prepare for next buffer
00463         SetBufferStartPos();
00464 
00465         // reset values
00466         block->m_valuePos = 0;
00467         block->m_maxAbsValue = 0;
00468 }

void CEncoder::WriteValue ( CSubband band,
int  bandPos 
)

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

Parameters:
band A subband
bandPos A valid position in subband band

Definition at line 326 of file Encoder.cpp.

00326                                                             {
00327         if (m_currentBlock->m_valuePos == BufferSize) {
00328                 EncodeBuffer(ROIBlockHeader(BufferSize, false));
00329         }
00330         DataT val = m_currentBlock->m_value[m_currentBlock->m_valuePos++] = band->GetData(bandPos);
00331         UINT32 v = abs(val);
00332         if (v > m_currentBlock->m_maxAbsValue) m_currentBlock->m_maxAbsValue = v;
00333 }


Member Data Documentation

UINT64 CEncoder::m_bufferStartPos [private]

stream position of encoded buffer

Definition at line 212 of file Encoder.h.

current macro block (used by main thread)

Definition at line 217 of file Encoder.h.

counts where (=index) to save next value

Definition at line 220 of file Encoder.h.

bool CEncoder::m_favorSpeed [private]

favor speed over size

Definition at line 222 of file Encoder.h.

bool CEncoder::m_forceWriting [private]

all macro blocks have to be written into the stream

Definition at line 223 of file Encoder.h.

array index of the last created macro block

Definition at line 216 of file Encoder.h.

UINT32* CEncoder::m_levelLength [private]

temporary saves the level index

Definition at line 219 of file Encoder.h.

UINT64 CEncoder::m_levelLengthPos [private]

stream position of Metadata

Definition at line 211 of file Encoder.h.

array length

Definition at line 215 of file Encoder.h.

array of macroblocks

Definition at line 214 of file Encoder.h.

UINT8 CEncoder::m_nLevels [private]

number of levels

Definition at line 221 of file Encoder.h.

bool CEncoder::m_roi [private]

true: ensures region of interest (ROI) encoding

Definition at line 225 of file Encoder.h.

UINT64 CEncoder::m_startPosition [private]

stream position of PGF start (PreHeader)

Definition at line 210 of file Encoder.h.

output PMF stream

Definition at line 209 of file Encoder.h.


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

Generated on 18 Feb 2019 for libpgf by  doxygen 1.6.1