- Tumbleweed 7.21.7-1.16
- Leap-15.6
| CDecoder(3) | Library Functions Manual | CDecoder(3) |
NAME¶
CDecoder - PGF decoder.
SYNOPSIS¶
#include <Decoder.h>
Classes¶
class CMacroBlock
A macro block is a decoding unit of fixed size (uncoded)
Public Member Functions¶
CDecoder (CPGFStream *stream, PGFPreHeader
&preHeader, PGFHeader &header, PGFPostHeader
&postHeader, UINT32 *&levelLength, UINT64 &userDataPos, bool
useOMP, UINT32 userDataPolicy)
~CDecoder ()
Destructor. void Partition (CSubband *band, int quantParam, int
width, int height, int startPos, int pitch)
void DecodeInterleaved (CWaveletTransform *wtChannel, int level,
int quantParam)
UINT32 GetEncodedHeaderLength () const
void SetStreamPosToStart ()
Resets stream position to beginning of PGF pre-header. void
SetStreamPosToData ()
Resets stream position to beginning of data block. void Skip (UINT64
offset)
void DequantizeValue (CSubband *band, UINT32 bandPos, int
quantParam)
UINT32 ReadEncodedData (UINT8 *target, UINT32 len) const
void DecodeBuffer ()
CPGFStream * GetStream ()
void GetNextMacroBlock ()
Private Member Functions¶
void ReadMacroBlock (CMacroBlock *block)
throws IOException
Private Attributes¶
CPGFStream * m_stream
input PGF stream UINT64 m_startPos
stream position at the beginning of the PGF pre-header UINT64
m_streamSizeEstimation
estimation of stream size UINT32 m_encodedHeaderLength
stream offset from startPos to the beginning of the data part (highest level)
CMacroBlock ** m_macroBlocks
array of macroblocks int m_currentBlockIndex
index of current macro block int m_macroBlockLen
array length int m_macroBlocksAvailable
number of decoded macro blocks (including currently used macro block)
CMacroBlock * m_currentBlock
current macro block (used by main thread)
Detailed Description¶
PGF decoder.
PGF decoder class.
Author
Definition at line 46 of file Decoder.h.
Constructor & Destructor Documentation¶
CDecoder::CDecoder (CPGFStream * stream, PGFPreHeader & preHeader, PGFHeader & header, PGFPostHeader & postHeader, UINT32 *& levelLength, UINT64 & userDataPos, bool useOMP, UINT32 userDataPolicy)¶
Constructor: Read pre-header, header, and levelLength at current stream position. It might throw an IOException.
Parameters
preHeader [out] A PGF pre-header
header [out] A PGF header
postHeader [out] A PGF post-header
levelLength The location of the levelLength array. The array is allocated in this method. The caller has to delete this array.
userDataPos The stream position of the user data (metadata)
useOMP If true, then the decoder will use multi-threading based on openMP
userDataPolicy Policy of user data (meta-data) handling while reading PGF headers.
Constructor Read pre-header, header, and levelLength It might throw an IOException.
Parameters
preHeader [out] A PGF pre-header
header [out] A PGF header
postHeader [out] A PGF post-header
levelLength The location of the levelLength array. The array is allocated in this method. The caller has to delete this array.
userDataPos The stream position of the user data (metadata)
useOMP If true, then the decoder will use multi-threading based on openMP
userDataPolicy Policy of user data (meta-data) handling while reading PGF headers.
Definition at line 73 of file Decoder.cpp.
76 : m_stream(stream)
77 , m_startPos(0)
78 , m_streamSizeEstimation(0)
79 , m_encodedHeaderLength(0)
80 , m_currentBlockIndex(0)
81 , m_macroBlocksAvailable(0)
82 #ifdef __PGFROISUPPORT__
83 , m_roi(false)
84 #endif
85 {
86 ASSERT(m_stream);
87
88 int count, expected;
89
90 // store current stream position
91 m_startPos = m_stream->GetPos();
92
93 // read magic and version
94 count = expected = MagicVersionSize;
95 m_stream->Read(&count, &preHeader);
96 if (count != expected) ReturnWithError(MissingData);
97
98 // read header size
99 if (preHeader.version & Version6) {
100 // 32 bit header size since version 6
101 count = expected = 4;
102 } else {
103 count = expected = 2;
104 }
105 m_stream->Read(&count, ((UINT8*)&preHeader) + MagicVersionSize);
106 if (count != expected) ReturnWithError(MissingData);
107
108 // make sure the values are correct read
109 preHeader.hSize = __VAL(preHeader.hSize);
110
111 // check magic number
112 if (memcmp(preHeader.magic, PGFMagic, 3) != 0) {
113 // error condition: wrong Magic number
114 ReturnWithError(FormatCannotRead);
115 }
116
117 // read file header
118 count = expected = (preHeader.hSize < HeaderSize) ? preHeader.hSize : HeaderSize;
119 m_stream->Read(&count, &header);
120 if (count != expected) ReturnWithError(MissingData);
121
122 // make sure the values are correct read
123 header.height = __VAL(UINT32(header.height));
124 header.width = __VAL(UINT32(header.width));
125
126 // be ready to read all versions including version 0
127 if (preHeader.version > 0) {
128 #ifndef __PGFROISUPPORT__
129 // check ROI usage
130 if (preHeader.version & PGFROI) ReturnWithError(FormatCannotRead);
131 #endif
132
133 UINT32 size = preHeader.hSize;
134
135 if (size > HeaderSize) {
136 size -= HeaderSize;
137 count = 0;
138
139 // read post-header
140 if (header.mode == ImageModeIndexedColor) {
141 if (size < ColorTableSize) ReturnWithError(FormatCannotRead);
142 // read color table
143 count = expected = ColorTableSize;
144 m_stream->Read(&count, postHeader.clut);
145 if (count != expected) ReturnWithError(MissingData);
146 }
147
148 if (size > (UINT32)count) {
149 size -= count;
150
151 // read/skip user data
152 UserdataPolicy policy = (UserdataPolicy)((userDataPolicy <= MaxUserDataSize) ? UP_CachePrefix : 0xFFFFFFFF - userDataPolicy);
153 userDataPos = m_stream->GetPos();
154 postHeader.userDataLen = size;
155
156 if (policy == UP_Skip) {
157 postHeader.cachedUserDataLen = 0;
158 postHeader.userData = nullptr;
159 Skip(size);
160 } else {
161 postHeader.cachedUserDataLen = (policy == UP_CachePrefix) ? __min(size, userDataPolicy) : size;
162
163 // create user data memory block
164 postHeader.userData = new(std::nothrow) UINT8[postHeader.cachedUserDataLen];
165 if (!postHeader.userData) ReturnWithError(InsufficientMemory);
166
167 // read user data
168 count = expected = postHeader.cachedUserDataLen;
169 m_stream->Read(&count, postHeader.userData);
170 if (count != expected) ReturnWithError(MissingData);
171
172 // skip remaining user data
173 if (postHeader.cachedUserDataLen < size) Skip(size - postHeader.cachedUserDataLen);
174 }
175 }
176 }
177
178 // create levelLength
179 levelLength = new(std::nothrow) UINT32[header.nLevels];
180 if (!levelLength) ReturnWithError(InsufficientMemory);
181
182 // read levelLength
183 count = expected = header.nLevels*WordBytes;
184 m_stream->Read(&count, levelLength);
185 if (count != expected) ReturnWithError(MissingData);
186
187 #ifdef PGF_USE_BIG_ENDIAN
188 // make sure the values are correct read
189 for (int i=0; i < header.nLevels; i++) {
190 levelLength[i] = __VAL(levelLength[i]);
191 }
192 #endif
193
194 // compute the total size in bytes; keep attention: level length information is optional
195 for (int i=0; i < header.nLevels; i++) {
196 m_streamSizeEstimation += levelLength[i];
197 }
198
199 }
200
201 // store current stream position
202 m_encodedHeaderLength = UINT32(m_stream->GetPos() - m_startPos);
203
204 // set number of threads
205 #ifdef LIBPGF_USE_OPENMP
206 m_macroBlockLen = omp_get_num_procs();
207 #else
208 m_macroBlockLen = 1;
209 #endif
210
211 if (useOMP && m_macroBlockLen > 1) {
212 #ifdef LIBPGF_USE_OPENMP
213 omp_set_num_threads(m_macroBlockLen);
214 #endif
215
216 // create macro block array
217 m_macroBlocks = new(std::nothrow) CMacroBlock*[m_macroBlockLen];
218 if (!m_macroBlocks) ReturnWithError(InsufficientMemory);
219 for (int i = 0; i < m_macroBlockLen; i++) m_macroBlocks[i] = new CMacroBlock();
220 m_currentBlock = m_macroBlocks[m_currentBlockIndex];
221 } else {
222 m_macroBlocks = 0;
223 m_macroBlockLen = 1; // there is only one macro block
224 m_currentBlock = new(std::nothrow) CMacroBlock();
225 if (!m_currentBlock) ReturnWithError(InsufficientMemory);
226 }
227 }
CDecoder::~CDecoder ()¶
Destructor.
Definition at line 231 of file Decoder.cpp.
231 {
232 if (m_macroBlocks) {
233 for (int i=0; i < m_macroBlockLen; i++) delete m_macroBlocks[i];
234 delete[] m_macroBlocks;
235 } else {
236 delete m_currentBlock;
237 }
238 }
Member Function Documentation¶
void CDecoder::DecodeBuffer ()¶
Reads next block(s) from stream and decodes them It might throw an IOException.
Definition at line 494 of file Decoder.cpp.
494 {
495 ASSERT(m_macroBlocksAvailable <= 0);
496
497 // macro block management
498 if (m_macroBlockLen == 1) {
499 ASSERT(m_currentBlock);
500 ReadMacroBlock(m_currentBlock);
501 m_currentBlock->BitplaneDecode();
502 m_macroBlocksAvailable = 1;
503 } else {
504 m_macroBlocksAvailable = 0;
505 for (int i=0; i < m_macroBlockLen; i++) {
506 // read sequentially several blocks
507 try {
508 ReadMacroBlock(m_macroBlocks[i]);
509 m_macroBlocksAvailable++;
510 } catch(IOException& ex) {
511 if (ex.error == MissingData || ex.error == FormatCannotRead) {
512 break; // no further data available or the data isn't valid PGF data (might occur in streaming or PPPExt)
513 } else {
514 throw;
515 }
516 }
517 }
518 #ifdef LIBPGF_USE_OPENMP
519 // decode in parallel
520 #pragma omp parallel for default(shared) //no declared exceptions in next block
521 #endif
522 for (int i=0; i < m_macroBlocksAvailable; i++) {
523 m_macroBlocks[i]->BitplaneDecode();
524 }
525
526 // prepare current macro block
527 m_currentBlockIndex = 0;
528 m_currentBlock = m_macroBlocks[m_currentBlockIndex];
529 }
530 }
void CDecoder::DecodeInterleaved (CWaveletTransform * wtChannel, int level, int quantParam)¶
Deccoding and dequantization of HL and LH subband (interleaved) using partitioning scheme. Partitioning scheme: The plane is partitioned in squares of side length InterBlockSize. It might throw an IOException.
Parameters
level Wavelet transform level
quantParam Dequantization value
Definition at line 333 of file Decoder.cpp.
333 {
334 CSubband* hlBand = wtChannel->GetSubband(level, HL);
335 CSubband* lhBand = wtChannel->GetSubband(level, LH);
336 const div_t lhH = div(lhBand->GetHeight(), InterBlockSize);
337 const div_t hlW = div(hlBand->GetWidth(), InterBlockSize);
338 const int hlws = hlBand->GetWidth() - InterBlockSize;
339 const int hlwr = hlBand->GetWidth() - hlW.rem;
340 const int lhws = lhBand->GetWidth() - InterBlockSize;
341 const int lhwr = lhBand->GetWidth() - hlW.rem;
342 int hlPos, lhPos;
343 int hlBase = 0, lhBase = 0, hlBase2, lhBase2;
344
345 ASSERT(lhBand->GetWidth() >= hlBand->GetWidth());
346 ASSERT(hlBand->GetHeight() >= lhBand->GetHeight());
347
348 if (!hlBand->AllocMemory()) ReturnWithError(InsufficientMemory);
349 if (!lhBand->AllocMemory()) ReturnWithError(InsufficientMemory);
350
351 // correct quantParam with normalization factor
352 quantParam -= level;
353 if (quantParam < 0) quantParam = 0;
354
355 // main height
356 for (int i=0; i < lhH.quot; i++) {
357 // main width
358 hlBase2 = hlBase;
359 lhBase2 = lhBase;
360 for (int j=0; j < hlW.quot; j++) {
361 hlPos = hlBase2;
362 lhPos = lhBase2;
363 for (int y=0; y < InterBlockSize; y++) {
364 for (int x=0; x < InterBlockSize; x++) {
365 DequantizeValue(hlBand, hlPos, quantParam);
366 DequantizeValue(lhBand, lhPos, quantParam);
367 hlPos++;
368 lhPos++;
369 }
370 hlPos += hlws;
371 lhPos += lhws;
372 }
373 hlBase2 += InterBlockSize;
374 lhBase2 += InterBlockSize;
375 }
376 // rest of width
377 hlPos = hlBase2;
378 lhPos = lhBase2;
379 for (int y=0; y < InterBlockSize; y++) {
380 for (int x=0; x < hlW.rem; x++) {
381 DequantizeValue(hlBand, hlPos, quantParam);
382 DequantizeValue(lhBand, lhPos, quantParam);
383 hlPos++;
384 lhPos++;
385 }
386 // width difference between HL and LH
387 if (lhBand->GetWidth() > hlBand->GetWidth()) {
388 DequantizeValue(lhBand, lhPos, quantParam);
389 }
390 hlPos += hlwr;
391 lhPos += lhwr;
392 hlBase += hlBand->GetWidth();
393 lhBase += lhBand->GetWidth();
394 }
395 }
396 // main width
397 hlBase2 = hlBase;
398 lhBase2 = lhBase;
399 for (int j=0; j < hlW.quot; j++) {
400 // rest of height
401 hlPos = hlBase2;
402 lhPos = lhBase2;
403 for (int y=0; y < lhH.rem; y++) {
404 for (int x=0; x < InterBlockSize; x++) {
405 DequantizeValue(hlBand, hlPos, quantParam);
406 DequantizeValue(lhBand, lhPos, quantParam);
407 hlPos++;
408 lhPos++;
409 }
410 hlPos += hlws;
411 lhPos += lhws;
412 }
413 hlBase2 += InterBlockSize;
414 lhBase2 += InterBlockSize;
415 }
416 // rest of height
417 hlPos = hlBase2;
418 lhPos = lhBase2;
419 for (int y=0; y < lhH.rem; y++) {
420 // rest of width
421 for (int x=0; x < hlW.rem; x++) {
422 DequantizeValue(hlBand, hlPos, quantParam);
423 DequantizeValue(lhBand, lhPos, quantParam);
424 hlPos++;
425 lhPos++;
426 }
427 // width difference between HL and LH
428 if (lhBand->GetWidth() > hlBand->GetWidth()) {
429 DequantizeValue(lhBand, lhPos, quantParam);
430 }
431 hlPos += hlwr;
432 lhPos += lhwr;
433 hlBase += hlBand->GetWidth();
434 }
435 // height difference between HL and LH
436 if (hlBand->GetHeight() > lhBand->GetHeight()) {
437 // total width
438 hlPos = hlBase;
439 for (int j=0; j < hlBand->GetWidth(); j++) {
440 DequantizeValue(hlBand, hlPos, quantParam);
441 hlPos++;
442 }
443 }
444 }
void CDecoder::DequantizeValue (CSubband * band, UINT32 bandPos, int quantParam)¶
Dequantization of a single value at given position in subband. It might throw an IOException.
Parameters
bandPos A valid position in subband band
quantParam The quantization parameter
Dequantization of a single value at given position in subband. If encoded data is available, then stores dequantized band value into buffer m_value at position m_valuePos. Otherwise reads encoded data block and decodes it. It might throw an IOException.
Parameters
bandPos A valid position in subband band
quantParam The quantization parameter
Definition at line 462 of file Decoder.cpp.
462 {
463 ASSERT(m_currentBlock);
464
465 if (m_currentBlock->IsCompletelyRead()) {
466 // all data of current macro block has been read --> prepare next macro block
467 GetNextMacroBlock();
468 }
469
470 band->SetData(bandPos, m_currentBlock->m_value[m_currentBlock->m_valuePos] << quantParam);
471 m_currentBlock->m_valuePos++;
472 }
UINT32 CDecoder::GetEncodedHeaderLength () const [inline]¶
Returns the length of all encoded headers in bytes.
Returns
Definition at line 136 of file Decoder.h.
136 { return m_encodedHeaderLength; }
void CDecoder::GetNextMacroBlock ()¶
Gets next macro block It might throw an IOException.
Definition at line 477 of file Decoder.cpp.
477 {
478 // current block has been read --> prepare next current block
479 m_macroBlocksAvailable--;
480
481 if (m_macroBlocksAvailable > 0) {
482 m_currentBlock = m_macroBlocks[++m_currentBlockIndex];
483 } else {
484 DecodeBuffer();
485 }
486 ASSERT(m_currentBlock);
487 }
CPGFStream * CDecoder::GetStream () [inline]¶
Returns
Definition at line 174 of file Decoder.h.
174 { return m_stream; }
void CDecoder::Partition (CSubband * band, int quantParam, int width, int height, int startPos, int pitch)¶
Unpartitions a rectangular region of a given subband. Partitioning scheme: The plane is partitioned in squares of side length LinBlockSize. Read wavelet coefficients from the output buffer of a macro block. It might throw an IOException.
Parameters
quantParam Dequantization value
width The width of the rectangle
height The height of the rectangle
startPos The relative subband position of the top left corner of the rectangular region
pitch The number of bytes in row of the subband
Definition at line 266 of file Decoder.cpp.
266 {
267 ASSERT(band);
268
269 const div_t ww = div(width, LinBlockSize);
270 const div_t hh = div(height, LinBlockSize);
271 const int ws = pitch - LinBlockSize;
272 const int wr = pitch - ww.rem;
273 int pos, base = startPos, base2;
274
275 // main height
276 for (int i=0; i < hh.quot; i++) {
277 // main width
278 base2 = base;
279 for (int j=0; j < ww.quot; j++) {
280 pos = base2;
281 for (int y=0; y < LinBlockSize; y++) {
282 for (int x=0; x < LinBlockSize; x++) {
283 DequantizeValue(band, pos, quantParam);
284 pos++;
285 }
286 pos += ws;
287 }
288 base2 += LinBlockSize;
289 }
290 // rest of width
291 pos = base2;
292 for (int y=0; y < LinBlockSize; y++) {
293 for (int x=0; x < ww.rem; x++) {
294 DequantizeValue(band, pos, quantParam);
295 pos++;
296 }
297 pos += wr;
298 base += pitch;
299 }
300 }
301 // main width
302 base2 = base;
303 for (int j=0; j < ww.quot; j++) {
304 // rest of height
305 pos = base2;
306 for (int y=0; y < hh.rem; y++) {
307 for (int x=0; x < LinBlockSize; x++) {
308 DequantizeValue(band, pos, quantParam);
309 pos++;
310 }
311 pos += ws;
312 }
313 base2 += LinBlockSize;
314 }
315 // rest of height
316 pos = base2;
317 for (int y=0; y < hh.rem; y++) {
318 // rest of width
319 for (int x=0; x < ww.rem; x++) {
320 DequantizeValue(band, pos, quantParam);
321 pos++;
322 }
323 pos += wr;
324 }
325 }
UINT32 CDecoder::ReadEncodedData (UINT8 * target, UINT32 len) const¶
Copies data from the open stream to a target buffer. It might throw an IOException.
Parameters
len The number of bytes to read
Returns
Definition at line 246 of file Decoder.cpp.
246 {
247 ASSERT(m_stream);
248
249 int count = len;
250 m_stream->Read(&count, target);
251
252 return count;
253 }
void CDecoder::ReadMacroBlock (CMacroBlock * block) [private]¶
throws IOException
Definition at line 535 of file Decoder.cpp.
535 {
536 ASSERT(block);
537
538 UINT16 wordLen;
539 ROIBlockHeader h(BufferSize);
540 int count, expected;
541
542 #ifdef TRACE
543 //UINT32 filePos = (UINT32)m_stream->GetPos();
544 //printf("DecodeBuffer: %d\n", filePos);
545 #endif
546
547 // read wordLen
548 count = expected = sizeof(UINT16);
549 m_stream->Read(&count, &wordLen);
550 if (count != expected) ReturnWithError(MissingData);
551 wordLen = __VAL(wordLen); // convert wordLen
552 if (wordLen > BufferSize) ReturnWithError(FormatCannotRead);
553
554 #ifdef __PGFROISUPPORT__
555 // read ROIBlockHeader
556 if (m_roi) {
557 count = expected = sizeof(ROIBlockHeader);
558 m_stream->Read(&count, &h.val);
559 if (count != expected) ReturnWithError(MissingData);
560 h.val = __VAL(h.val); // convert ROIBlockHeader
561 }
562 #endif
563 // save header
564 block->m_header = h;
565
566 // read data
567 count = expected = wordLen*WordBytes;
568 m_stream->Read(&count, block->m_codeBuffer);
569 if (count != expected) ReturnWithError(MissingData);
570
571 #ifdef PGF_USE_BIG_ENDIAN
572 // convert data
573 count /= WordBytes;
574 for (int i=0; i < count; i++) {
575 block->m_codeBuffer[i] = __VAL(block->m_codeBuffer[i]);
576 }
577 #endif
578
579 #ifdef __PGFROISUPPORT__
580 ASSERT(m_roi && h.rbh.bufferSize <= BufferSize || h.rbh.bufferSize == BufferSize);
581 #else
582 ASSERT(h.rbh.bufferSize == BufferSize);
583 #endif
584 }
void CDecoder::SetStreamPosToData () [inline]¶
Resets stream position to beginning of data block.
Definition at line 144 of file Decoder.h.
144 { ASSERT(m_stream); m_stream->SetPos(FSFromStart, m_startPos + m_encodedHeaderLength); }
void CDecoder::SetStreamPosToStart () [inline]¶
Resets stream position to beginning of PGF pre-header.
Definition at line 140 of file Decoder.h.
140 { ASSERT(m_stream); m_stream->SetPos(FSFromStart, m_startPos); }
void CDecoder::Skip (UINT64 offset)¶
Skips a given number of bytes in the open stream. It might throw an IOException.
Definition at line 449 of file Decoder.cpp.
449 {
450 m_stream->SetPos(FSFromCurrent, offset);
451 }
Member Data Documentation¶
CMacroBlock* CDecoder::m_currentBlock [private]¶
current macro block (used by main thread)
Definition at line 209 of file Decoder.h.
int CDecoder::m_currentBlockIndex [private]¶
index of current macro block
Definition at line 206 of file Decoder.h.
UINT32 CDecoder::m_encodedHeaderLength [private]¶
stream offset from startPos to the beginning of the data part (highest level)
Definition at line 203 of file Decoder.h.
int CDecoder::m_macroBlockLen [private]¶
array length
Definition at line 207 of file Decoder.h.
CMacroBlock** CDecoder::m_macroBlocks [private]¶
array of macroblocks
Definition at line 205 of file Decoder.h.
int CDecoder::m_macroBlocksAvailable [private]¶
number of decoded macro blocks (including currently used macro block)
Definition at line 208 of file Decoder.h.
UINT64 CDecoder::m_startPos [private]¶
stream position at the beginning of the PGF pre-header
Definition at line 201 of file Decoder.h.
CPGFStream* CDecoder::m_stream [private]¶
input PGF stream
Definition at line 200 of file Decoder.h.
UINT64 CDecoder::m_streamSizeEstimation [private]¶
estimation of stream size
Definition at line 202 of file Decoder.h.
Author¶
Generated automatically by Doxygen for libpgf from the source code.
| Version 7.21.2 | libpgf |