CEncoder - Man Page
PGF encoder.
Synopsis
#include <Encoder.h>
Classes
class CMacroBlock
A macro block is an encoding unit of fixed size (uncoded)
Public Member Functions
CEncoder (CPGFStream *stream, PGFPreHeader preHeader, PGFHeader header, const PGFPostHeader &postHeader, UINT64 &userDataPos, bool useOMP)
~CEncoder ()
Destructor.
void FavorSpeedOverSize ()
Encoder favors speed over compression size.
void Flush ()
void UpdatePostHeaderSize (PGFPreHeader preHeader)
UINT32 WriteLevelLength (UINT32 *&levelLength)
UINT32 UpdateLevelLength ()
void Partition (CSubband *band, int width, int height, int startPos, int pitch)
void SetEncodedLevel (int currentLevel)
void WriteValue (CSubband *band, int bandPos)
INT64 ComputeHeaderLength () const
INT64 ComputeBufferLength () const
INT64 ComputeOffset () const
void SetStreamPosToStart ()
Resets stream position to beginning of PGF pre-header.
void SetBufferStartPos ()
Save current stream position as beginning of current level.
Private Member Functions
void EncodeBuffer (ROIBlockHeader h)
void WriteMacroBlock (CMacroBlock *block)
Private Attributes
CPGFStream * m_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
CMacroBlock * m_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
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.
71 : m_stream(stream) 72 , m_bufferStartPos(0) 73 , m_currLevelIndex(0) 74 , m_nLevels(header.nLevels) 75 , m_favorSpeed(false) 76 , m_forceWriting(false) 77 #ifdef __PGFROISUPPORT__ 78 , m_roi(false) 79 #endif 80 { 81 ASSERT(m_stream); 82 83 int count; 84 m_lastMacroBlock = 0; 85 m_levelLength = nullptr; 86 87 // set number of threads 88 #ifdef LIBPGF_USE_OPENMP 89 m_macroBlockLen = omp_get_num_procs(); 90 #else 91 m_macroBlockLen = 1; 92 #endif 93 94 if (useOMP && m_macroBlockLen > 1) { 95 #ifdef LIBPGF_USE_OPENMP 96 omp_set_num_threads(m_macroBlockLen); 97 #endif 98 // create macro block array 99 m_macroBlocks = new(std::nothrow) CMacroBlock*[m_macroBlockLen]; 100 if (!m_macroBlocks) ReturnWithError(InsufficientMemory); 101 for (int i=0; i < m_macroBlockLen; i++) m_macroBlocks[i] = new CMacroBlock(this); 102 m_currentBlock = m_macroBlocks[m_lastMacroBlock++]; 103 } else { 104 m_macroBlocks = 0; 105 m_macroBlockLen = 1; 106 m_currentBlock = new CMacroBlock(this); 107 } 108 109 // save file position 110 m_startPosition = m_stream->GetPos(); 111 112 // write preHeader 113 preHeader.hSize = __VAL(preHeader.hSize); 114 count = PreHeaderSize; 115 m_stream->Write(&count, &preHeader); 116 117 // write file header 118 header.height = __VAL(header.height); 119 header.width = __VAL(header.width); 120 count = HeaderSize; 121 m_stream->Write(&count, &header); 122 123 // write postHeader 124 if (header.mode == ImageModeIndexedColor) { 125 // write color table 126 count = ColorTableSize; 127 m_stream->Write(&count, (void *)postHeader.clut); 128 } 129 // save user data file position 130 userDataPos = m_stream->GetPos(); 131 if (postHeader.userDataLen) { 132 if (postHeader.userData) { 133 // write user data 134 count = postHeader.userDataLen; 135 m_stream->Write(&count, postHeader.userData); 136 } else { 137 m_stream->SetPos(FSFromCurrent, count); 138 } 139 } 140 141 // save level length file position 142 m_levelLengthPos = m_stream->GetPos(); 143 }
CEncoder::~CEncoder ()
Destructor.
Definition at line 147 of file Encoder.cpp.
147 { 148 if (m_macroBlocks) { 149 for (int i=0; i < m_macroBlockLen; i++) delete m_macroBlocks[i]; 150 delete[] m_macroBlocks; 151 } else { 152 delete m_currentBlock; 153 } 154 }
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.
179 { 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.
174 { 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.
184 { return m_stream->GetPos() - m_levelLengthPos; }
void CEncoder::EncodeBuffer (ROIBlockHeader h) [private]
Definition at line 341 of file Encoder.cpp.
341 { 342 ASSERT(m_currentBlock); 343 #ifdef __PGFROISUPPORT__ 344 ASSERT(m_roi && h.rbh.bufferSize <= BufferSize || h.rbh.bufferSize == BufferSize); 345 #else 346 ASSERT(h.rbh.bufferSize == BufferSize); 347 #endif 348 m_currentBlock->m_header = h; 349 350 // macro block management 351 if (m_macroBlockLen == 1) { 352 m_currentBlock->BitplaneEncode(); 353 WriteMacroBlock(m_currentBlock); 354 } else { 355 // save last level index 356 int lastLevelIndex = m_currentBlock->m_lastLevelIndex; 357 358 if (m_forceWriting || m_lastMacroBlock == m_macroBlockLen) { 359 // encode macro blocks 360 /* 361 volatile OSError error = NoError; 362 #ifdef LIBPGF_USE_OPENMP 363 #pragma omp parallel for ordered default(shared) 364 #endif 365 for (int i=0; i < m_lastMacroBlock; i++) { 366 if (error == NoError) { 367 m_macroBlocks[i]->BitplaneEncode(); 368 #ifdef LIBPGF_USE_OPENMP 369 #pragma omp ordered 370 #endif 371 { 372 try { 373 WriteMacroBlock(m_macroBlocks[i]); 374 } catch (IOException& e) { 375 error = e.error; 376 } 377 delete m_macroBlocks[i]; m_macroBlocks[i] = 0; 378 } 379 } 380 } 381 if (error != NoError) ReturnWithError(error); 382 */ 383 #ifdef LIBPGF_USE_OPENMP 384 #pragma omp parallel for default(shared) //no declared exceptions in next block 385 #endif 386 for (int i=0; i < m_lastMacroBlock; i++) { 387 m_macroBlocks[i]->BitplaneEncode(); 388 } 389 for (int i=0; i < m_lastMacroBlock; i++) { 390 WriteMacroBlock(m_macroBlocks[i]); 391 } 392 393 // prepare for next round 394 m_forceWriting = false; 395 m_lastMacroBlock = 0; 396 } 397 // re-initialize macro block 398 m_currentBlock = m_macroBlocks[m_lastMacroBlock++]; 399 m_currentBlock->Init(lastLevelIndex); 400 } 401 }
void CEncoder::FavorSpeedOverSize () [inline]
Encoder favors speed over compression size.
Definition at line 121 of file Encoder.h.
121 { 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.
310 { 311 if (m_currentBlock->m_valuePos > 0) { 312 // pad buffer with zeros 313 memset(&(m_currentBlock->m_value[m_currentBlock->m_valuePos]), 0, (BufferSize - m_currentBlock->m_valuePos)*DataTSize); 314 m_currentBlock->m_valuePos = BufferSize; 315 316 // encode buffer 317 m_forceWriting = true; // makes sure that the following EncodeBuffer is really written into the stream 318 EncodeBuffer(ROIBlockHeader(m_currentBlock->m_valuePos, true)); 319 } 320 }
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.
246 { 247 ASSERT(band); 248 249 const div_t hh = div(height, LinBlockSize); 250 const div_t ww = div(width, LinBlockSize); 251 const int ws = pitch - LinBlockSize; 252 const int wr = pitch - ww.rem; 253 int pos, base = startPos, base2; 254 255 // main height 256 for (int i=0; i < hh.quot; i++) { 257 // main width 258 base2 = base; 259 for (int j=0; j < ww.quot; j++) { 260 pos = base2; 261 for (int y=0; y < LinBlockSize; y++) { 262 for (int x=0; x < LinBlockSize; x++) { 263 WriteValue(band, pos); 264 pos++; 265 } 266 pos += ws; 267 } 268 base2 += LinBlockSize; 269 } 270 // rest of width 271 pos = base2; 272 for (int y=0; y < LinBlockSize; y++) { 273 for (int x=0; x < ww.rem; x++) { 274 WriteValue(band, pos); 275 pos++; 276 } 277 pos += wr; 278 base += pitch; 279 } 280 } 281 // main width 282 base2 = base; 283 for (int j=0; j < ww.quot; j++) { 284 // rest of height 285 pos = base2; 286 for (int y=0; y < hh.rem; y++) { 287 for (int x=0; x < LinBlockSize; x++) { 288 WriteValue(band, pos); 289 pos++; 290 } 291 pos += ws; 292 } 293 base2 += LinBlockSize; 294 } 295 // rest of height 296 pos = base2; 297 for (int y=0; y < hh.rem; y++) { 298 // rest of width 299 for (int x=0; x < ww.rem; x++) { 300 WriteValue(band, pos); 301 pos++; 302 } 303 pos += wr; 304 } 305 }
void CEncoder::SetBufferStartPos () [inline]
Save current stream position as beginning of current level.
Definition at line 192 of file Encoder.h.
192 { m_bufferStartPos = m_stream->GetPos(); }
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.
162 { ASSERT(currentLevel >= 0); m_currentBlock->m_lastLevelIndex = m_nLevels - currentLevel - 1; m_forceWriting = true; }
void CEncoder::SetStreamPosToStart () [inline]
Resets stream position to beginning of PGF pre-header.
Definition at line 188 of file Encoder.h.
188 { ASSERT(m_stream); m_stream->SetPos(FSFromStart, m_startPosition); }
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.
202 { 203 UINT64 curPos = m_stream->GetPos(); // end of image 204 205 // set file pos to levelLength 206 m_stream->SetPos(FSFromStart, m_levelLengthPos); 207 208 if (m_levelLength) { 209 #ifdef PGF_USE_BIG_ENDIAN 210 UINT32 levelLength; 211 int count = WordBytes; 212 213 for (int i=0; i < m_currLevelIndex; i++) { 214 levelLength = __VAL(UINT32(m_levelLength[i])); 215 m_stream->Write(&count, &levelLength); 216 } 217 #else 218 int count = m_currLevelIndex*WordBytes; 219 220 m_stream->Write(&count, m_levelLength); 221 #endif //PGF_USE_BIG_ENDIAN 222 } else { 223 int count = m_currLevelIndex*WordBytes; 224 m_stream->SetPos(FSFromCurrent, count); 225 } 226 227 // begin of image 228 UINT32 retValue = UINT32(curPos - m_stream->GetPos()); 229 230 // restore file position 231 m_stream->SetPos(FSFromStart, curPos); 232 233 return retValue; 234 }
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.
160 { 161 UINT64 curPos = m_stream->GetPos(); // end of user data 162 int count = PreHeaderSize; 163 164 // write preHeader 165 SetStreamPosToStart(); 166 preHeader.hSize = __VAL(preHeader.hSize); 167 m_stream->Write(&count, &preHeader); 168 169 m_stream->SetPos(FSFromStart, curPos); 170 }
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.
177 { 178 // renew levelLength 179 delete[] levelLength; 180 levelLength = new(std::nothrow) UINT32[m_nLevels]; 181 if (!levelLength) ReturnWithError(InsufficientMemory); 182 for (UINT8 l = 0; l < m_nLevels; l++) levelLength[l] = 0; 183 m_levelLength = levelLength; 184 185 // save level length file position 186 m_levelLengthPos = m_stream->GetPos(); 187 188 // write dummy levelLength 189 int count = m_nLevels*WordBytes; 190 m_stream->Write(&count, m_levelLength); 191 192 // save current file position 193 SetBufferStartPos(); 194 195 return count; 196 }
void CEncoder::WriteMacroBlock (CMacroBlock * block) [private]
Definition at line 406 of file Encoder.cpp.
406 { 407 ASSERT(block); 408 #ifdef __PGFROISUPPORT__ 409 ROIBlockHeader h = block->m_header; 410 #endif 411 UINT16 wordLen = UINT16(NumberOfWords(block->m_codePos)); ASSERT(wordLen <= CodeBufferLen); 412 int count = sizeof(UINT16); 413 414 #ifdef TRACE 415 //UINT32 filePos = (UINT32)m_stream->GetPos(); 416 //printf("EncodeBuffer: %d\n", filePos); 417 #endif 418 419 #ifdef PGF_USE_BIG_ENDIAN 420 // write wordLen 421 UINT16 wl = __VAL(wordLen); 422 m_stream->Write(&count, &wl); ASSERT(count == sizeof(UINT16)); 423 424 #ifdef __PGFROISUPPORT__ 425 // write ROIBlockHeader 426 if (m_roi) { 427 count = sizeof(ROIBlockHeader); 428 h.val = __VAL(h.val); 429 m_stream->Write(&count, &h.val); ASSERT(count == sizeof(ROIBlockHeader)); 430 } 431 #endif // __PGFROISUPPORT__ 432 433 // convert data 434 for (int i=0; i < wordLen; i++) { 435 block->m_codeBuffer[i] = __VAL(block->m_codeBuffer[i]); 436 } 437 #else 438 // write wordLen 439 m_stream->Write(&count, &wordLen); ASSERT(count == sizeof(UINT16)); 440 441 #ifdef __PGFROISUPPORT__ 442 // write ROIBlockHeader 443 if (m_roi) { 444 count = sizeof(ROIBlockHeader); 445 m_stream->Write(&count, &h.val); ASSERT(count == sizeof(ROIBlockHeader)); 446 } 447 #endif // __PGFROISUPPORT__ 448 #endif // PGF_USE_BIG_ENDIAN 449 450 // write encoded data into stream 451 count = wordLen*WordBytes; 452 m_stream->Write(&count, block->m_codeBuffer); 453 454 // store levelLength 455 if (m_levelLength) { 456 // store level length 457 // EncodeBuffer has been called after m_lastLevelIndex has been updated 458 ASSERT(m_currLevelIndex < m_nLevels); 459 m_levelLength[m_currLevelIndex] += (UINT32)ComputeBufferLength(); 460 m_currLevelIndex = block->m_lastLevelIndex + 1; 461 462 } 463 464 // prepare for next buffer 465 SetBufferStartPos(); 466 467 // reset values 468 block->m_valuePos = 0; 469 block->m_maxAbsValue = 0; 470 }
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.
326 { 327 if (m_currentBlock->m_valuePos == BufferSize) { 328 EncodeBuffer(ROIBlockHeader(BufferSize, false)); 329 } 330 DataT val = m_currentBlock->m_value[m_currentBlock->m_valuePos++] = band->GetData(bandPos); 331 UINT32 v = abs(val); 332 if (v > m_currentBlock->m_maxAbsValue) m_currentBlock->m_maxAbsValue = v; 333 }
Member Data Documentation
UINT64 CEncoder::m_bufferStartPos [private]
stream position of encoded buffer
Definition at line 216 of file Encoder.h.
CMacroBlock* CEncoder::m_currentBlock [private]
current macro block (used by main thread)
Definition at line 221 of file Encoder.h.
int CEncoder::m_currLevelIndex [private]
counts where (=index) to save next value
Definition at line 224 of file Encoder.h.
bool CEncoder::m_favorSpeed [private]
favor speed over size
Definition at line 226 of file Encoder.h.
bool CEncoder::m_forceWriting [private]
all macro blocks have to be written into the stream
Definition at line 227 of file Encoder.h.
int CEncoder::m_lastMacroBlock [private]
array index of the last created macro block
Definition at line 220 of file Encoder.h.
UINT32* CEncoder::m_levelLength [private]
temporary saves the level index
Definition at line 223 of file Encoder.h.
UINT64 CEncoder::m_levelLengthPos [private]
stream position of Metadata
Definition at line 215 of file Encoder.h.
int CEncoder::m_macroBlockLen [private]
array length
Definition at line 219 of file Encoder.h.
CMacroBlock** CEncoder::m_macroBlocks [private]
array of macroblocks
Definition at line 218 of file Encoder.h.
UINT8 CEncoder::m_nLevels [private]
number of levels
Definition at line 225 of file Encoder.h.
UINT64 CEncoder::m_startPosition [private]
stream position of PGF start (PreHeader)
Definition at line 214 of file Encoder.h.
CPGFStream* CEncoder::m_stream [private]
output PMF stream
Definition at line 213 of file Encoder.h.
Author
Generated automatically by Doxygen for libpgf from the source code.