CDecoder man page

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, bool skipUserData) THROW_

~CDecoder ()
Destructor.
void Partition (CSubband *band, int quantParam, int width, int height, int startPos, int pitch) THROW_

void DecodeInterleaved (CWaveletTransform *wtChannel, int level, int quantParam) THROW_

UINT32 GetEncodedHeaderLength () const

void SetStreamPosToStart () THROW_
Reset stream position to beginning of PGF pre-header.
void SetStreamPosToData () THROW_
Reset stream position to beginning of data block.
void Skip (UINT64 offset) THROW_

void DequantizeValue (CSubband *band, UINT32 bandPos, int quantParam) THROW_

UINT32 ReadEncodedData (UINT8 *target, UINT32 len) const THROW_

void DecodeBuffer () THROW_

CPGFStream * GetStream ()

bool MacroBlocksAvailable () const

Private Member Functions

void ReadMacroBlock (CMacroBlock *block) THROW_
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:

C. Stamm, R. Spuler

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, bool skipUserData)

Constructor: Read pre-header, header, and levelLength at current stream position. It might throw an IOException.

Parameters:

stream A PGF stream
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
skipUserData If true, then user data is not read. In case of available user data, the file position is still returned in userDataPos.

Constructor Read pre-header, header, and levelLength It might throw an IOException.

Parameters:

stream A PGF stream
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
skipUserData If true, then user data is not read. In case of available user data, the file position is still returned in userDataPos.

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                 int size = preHeader.hSize - HeaderSize;
134 
135                 if (size > 0) {
136                         // read post-header
137                         if (header.mode == ImageModeIndexedColor) {
138                                 if (size < ColorTableSize) ReturnWithError(FormatCannotRead);
139                                 // read color table
140                                 count = expected = ColorTableSize;
141                                 m_stream->Read(&count, postHeader.clut);
142                                 if (count != expected) ReturnWithError(MissingData);
143                                 size -= count;
144                         }
145 
146                         if (size > 0) {
147                                 userDataPos = m_stream->GetPos();
148                                 postHeader.userDataLen = size;
149                                 if (skipUserData) {
150                                         Skip(size);
151                                 } else {
152                                         // create user data memory block
153                                         postHeader.userData = new(std::nothrow) UINT8[postHeader.userDataLen];
154                                         if (!postHeader.userData) ReturnWithError(InsufficientMemory);
155 
156                                         // read user data
157                                         count = expected = postHeader.userDataLen;
158                                         m_stream->Read(&count, postHeader.userData);
159                                         if (count != expected) ReturnWithError(MissingData);
160                                 }
161                         }
162                 }
163 
164                 // create levelLength
165                 levelLength = new(std::nothrow) UINT32[header.nLevels];
166                 if (!levelLength) ReturnWithError(InsufficientMemory);
167 
168                 // read levelLength
169                 count = expected = header.nLevels*WordBytes;
170                 m_stream->Read(&count, levelLength);
171                 if (count != expected) ReturnWithError(MissingData);
172 
173 #ifdef PGF_USE_BIG_ENDIAN 
174                 // make sure the values are correct read
175                 for (int i=0; i < header.nLevels; i++) {
176                         levelLength[i] = __VAL(levelLength[i]);
177                 }
178 #endif
179 
180                 // compute the total size in bytes; keep attention: level length information is optional
181                 for (int i=0; i < header.nLevels; i++) {
182                         m_streamSizeEstimation += levelLength[i];
183                 }
184                 
185         }
186 
187         // store current stream position
188         m_encodedHeaderLength = UINT32(m_stream->GetPos() - m_startPos);
189 
190         // set number of threads
191 #ifdef LIBPGF_USE_OPENMP 
192         m_macroBlockLen = omp_get_num_procs();
193 #else
194         m_macroBlockLen = 1;
195 #endif
196 
197         if (useOMP && m_macroBlockLen > 1) {
198 #ifdef LIBPGF_USE_OPENMP
199                 omp_set_num_threads(m_macroBlockLen);
200 #endif
201 
202                 // create macro block array
203                 m_macroBlocks = new(std::nothrow) CMacroBlock*[m_macroBlockLen];
204                 if (!m_macroBlocks) ReturnWithError(InsufficientMemory);
205                 for (int i = 0; i < m_macroBlockLen; i++) m_macroBlocks[i] = new CMacroBlock();
206                 m_currentBlock = m_macroBlocks[m_currentBlockIndex];
207         } else {
208                 m_macroBlocks = 0;
209                 m_macroBlockLen = 1; // there is only one macro block
210                 m_currentBlock = new(std::nothrow) CMacroBlock();
211                 if (!m_currentBlock) ReturnWithError(InsufficientMemory);
212         }
213 }

CDecoder::~CDecoder ()

Destructor.

Definition at line 217 of file Decoder.cpp.

217                     {
218         if (m_macroBlocks) {
219                 for (int i=0; i < m_macroBlockLen; i++) delete m_macroBlocks[i];
220                 delete[] m_macroBlocks;
221         } else {
222                 delete m_currentBlock;
223         }
224 }

Member Function Documentation

void CDecoder::DecodeBuffer ()

Reads stream and decodes tile buffer It might throw an IOException.

Definition at line 480 of file Decoder.cpp.

480                                    {
481         ASSERT(m_macroBlocksAvailable <= 0);
482 
483         // macro block management
484         if (m_macroBlockLen == 1) {
485                 ASSERT(m_currentBlock);
486                 ReadMacroBlock(m_currentBlock);
487                 m_currentBlock->BitplaneDecode();
488                 m_macroBlocksAvailable = 1;
489         } else {
490                 m_macroBlocksAvailable = 0;
491                 for (int i=0; i < m_macroBlockLen; i++) {
492                         // read sequentially several blocks
493                         try {
494                                 ReadMacroBlock(m_macroBlocks[i]);
495                                 m_macroBlocksAvailable++;
496                         } catch(IOException& ex) {
497                                 if (ex.error == MissingData) {
498                                         break; // no further data available
499                                 } else {
500                                         throw;
501                                 }
502                         }
503                 }
504 #ifdef LIBPGF_USE_OPENMP
505                 // decode in parallel
506                 #pragma omp parallel for default(shared) //no declared exceptions in next block
507 #endif
508                 for (int i=0; i < m_macroBlocksAvailable; i++) {
509                         m_macroBlocks[i]->BitplaneDecode();
510                 }
511                 
512                 // prepare current macro block
513                 m_currentBlockIndex = 0;
514                 m_currentBlock = m_macroBlocks[m_currentBlockIndex];
515         }
516 }

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:

wtChannel A wavelet transform channel containing the HL and HL band
level Wavelet transform level
quantParam Dequantization value

Definition at line 319 of file Decoder.cpp.

319                                                                                                {
320         CSubband* hlBand = wtChannel->GetSubband(level, HL);
321         CSubband* lhBand = wtChannel->GetSubband(level, LH);
322         const div_t lhH = div(lhBand->GetHeight(), InterBlockSize);
323         const div_t hlW = div(hlBand->GetWidth(), InterBlockSize);
324         const int hlws = hlBand->GetWidth() - InterBlockSize;
325         const int hlwr = hlBand->GetWidth() - hlW.rem;
326         const int lhws = lhBand->GetWidth() - InterBlockSize;
327         const int lhwr = lhBand->GetWidth() - hlW.rem;
328         int hlPos, lhPos;
329         int hlBase = 0, lhBase = 0, hlBase2, lhBase2;
330 
331         ASSERT(lhBand->GetWidth() >= hlBand->GetWidth());
332         ASSERT(hlBand->GetHeight() >= lhBand->GetHeight());
333 
334         if (!hlBand->AllocMemory()) ReturnWithError(InsufficientMemory);
335         if (!lhBand->AllocMemory()) ReturnWithError(InsufficientMemory);
336 
337         // correct quantParam with normalization factor
338         quantParam -= level;
339         if (quantParam < 0) quantParam = 0;
340 
341         // main height
342         for (int i=0; i < lhH.quot; i++) {
343                 // main width
344                 hlBase2 = hlBase;
345                 lhBase2 = lhBase;
346                 for (int j=0; j < hlW.quot; j++) {
347                         hlPos = hlBase2;
348                         lhPos = lhBase2;
349                         for (int y=0; y < InterBlockSize; y++) {
350                                 for (int x=0; x < InterBlockSize; x++) {
351                                         DequantizeValue(hlBand, hlPos, quantParam);
352                                         DequantizeValue(lhBand, lhPos, quantParam);
353                                         hlPos++;
354                                         lhPos++;
355                                 }
356                                 hlPos += hlws;
357                                 lhPos += lhws;
358                         }
359                         hlBase2 += InterBlockSize;
360                         lhBase2 += InterBlockSize;
361                 }
362                 // rest of width
363                 hlPos = hlBase2;
364                 lhPos = lhBase2;
365                 for (int y=0; y < InterBlockSize; y++) {
366                         for (int x=0; x < hlW.rem; x++) {
367                                 DequantizeValue(hlBand, hlPos, quantParam);
368                                 DequantizeValue(lhBand, lhPos, quantParam);
369                                 hlPos++;
370                                 lhPos++;
371                         }
372                         // width difference between HL and LH
373                         if (lhBand->GetWidth() > hlBand->GetWidth()) {
374                                 DequantizeValue(lhBand, lhPos, quantParam);
375                         }
376                         hlPos += hlwr;
377                         lhPos += lhwr;
378                         hlBase += hlBand->GetWidth();
379                         lhBase += lhBand->GetWidth();
380                 }
381         }
382         // main width 
383         hlBase2 = hlBase;
384         lhBase2 = lhBase;
385         for (int j=0; j < hlW.quot; j++) {
386                 // rest of height
387                 hlPos = hlBase2;
388                 lhPos = lhBase2;
389                 for (int y=0; y < lhH.rem; y++) {
390                         for (int x=0; x < InterBlockSize; x++) {
391                                 DequantizeValue(hlBand, hlPos, quantParam);
392                                 DequantizeValue(lhBand, lhPos, quantParam);
393                                 hlPos++;
394                                 lhPos++;
395                         }
396                         hlPos += hlws;
397                         lhPos += lhws;
398                 }
399                 hlBase2 += InterBlockSize;
400                 lhBase2 += InterBlockSize;
401         }
402         // rest of height
403         hlPos = hlBase2;
404         lhPos = lhBase2;
405         for (int y=0; y < lhH.rem; y++) {
406                 // rest of width
407                 for (int x=0; x < hlW.rem; x++) {
408                         DequantizeValue(hlBand, hlPos, quantParam);
409                         DequantizeValue(lhBand, lhPos, quantParam);
410                         hlPos++;
411                         lhPos++;
412                 }
413                 // width difference between HL and LH
414                 if (lhBand->GetWidth() > hlBand->GetWidth()) {
415                         DequantizeValue(lhBand, lhPos, quantParam);
416                 }
417                 hlPos += hlwr;
418                 lhPos += lhwr;
419                 hlBase += hlBand->GetWidth();
420         }
421         // height difference between HL and LH
422         if (hlBand->GetHeight() > lhBand->GetHeight()) {
423                 // total width
424                 hlPos = hlBase;
425                 for (int j=0; j < hlBand->GetWidth(); j++) {
426                         DequantizeValue(hlBand, hlPos, quantParam);
427                         hlPos++;
428                 }
429         }
430 }

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:

band A subband
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:

band A subband
bandPos A valid position in subband band
quantParam The quantization parameter

Definition at line 448 of file Decoder.cpp.

448                                                                                     {
449         ASSERT(m_currentBlock);
450 
451         if (m_currentBlock->IsCompletelyRead()) {
452                 // all data of current macro block has been read --> prepare next macro block
453                 DecodeTileBuffer();
454         }
455         
456         band->SetData(bandPos, m_currentBlock->m_value[m_currentBlock->m_valuePos] << quantParam);
457         m_currentBlock->m_valuePos++;
458 }

UINT32 CDecoder::GetEncodedHeaderLength () const [inline]

Return the length of all encoded headers in bytes.

Returns:

The length of all encoded headers in bytes

Definition at line 137 of file Decoder.h.

137 { return m_encodedHeaderLength; }

CPGFStream* CDecoder::GetStream () [inline]

Returns:

Stream

Definition at line 175 of file Decoder.h.

175 { return m_stream; }

bool CDecoder::MacroBlocksAvailable () const [inline]

Returns:

True if decoded macro blocks are available for processing

Definition at line 179 of file Decoder.h.

179 { return m_macroBlocksAvailable > 1; }

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:

band A subband
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 252 of file Decoder.cpp.

252                                                                                                               {
253         ASSERT(band);
254 
255         const div_t ww = div(width, LinBlockSize);
256         const div_t hh = div(height, LinBlockSize);
257         const int ws = pitch - LinBlockSize;
258         const int wr = pitch - ww.rem;
259         int pos, base = startPos, base2;
260 
261         // main height
262         for (int i=0; i < hh.quot; i++) {
263                 // main width
264                 base2 = base;
265                 for (int j=0; j < ww.quot; j++) {
266                         pos = base2;
267                         for (int y=0; y < LinBlockSize; y++) {
268                                 for (int x=0; x < LinBlockSize; x++) {
269                                         DequantizeValue(band, pos, quantParam);
270                                         pos++;
271                                 }
272                                 pos += ws;
273                         }
274                         base2 += LinBlockSize;
275                 }
276                 // rest of width
277                 pos = base2;
278                 for (int y=0; y < LinBlockSize; y++) {
279                         for (int x=0; x < ww.rem; x++) {
280                                 DequantizeValue(band, pos, quantParam);
281                                 pos++;
282                         }
283                         pos += wr;
284                         base += pitch;
285                 }
286         }
287         // main width 
288         base2 = base;
289         for (int j=0; j < ww.quot; j++) {
290                 // rest of height
291                 pos = base2;
292                 for (int y=0; y < hh.rem; y++) {
293                         for (int x=0; x < LinBlockSize; x++) {
294                                 DequantizeValue(band, pos, quantParam);
295                                 pos++;
296                         }
297                         pos += ws;
298                 }
299                 base2 += LinBlockSize;
300         }
301         // rest of height
302         pos = base2;
303         for (int y=0; y < hh.rem; y++) {
304                 // rest of width
305                 for (int x=0; x < ww.rem; x++) {
306                         DequantizeValue(band, pos, quantParam);
307                         pos++;
308                 }
309                 pos += wr;
310         }
311 }

UINT32 CDecoder::ReadEncodedData (UINT8 * target, UINT32 len) const

Copies data from the open stream to a target buffer. It might throw an IOException.

Parameters:

target The target buffer
len The number of bytes to read

Returns:

The number of bytes copied to the target buffer

Definition at line 232 of file Decoder.cpp.

232                                                                        {
233         ASSERT(m_stream);
234 
235         int count = len;
236         m_stream->Read(&count, target);
237 
238         return count;
239 }

void CDecoder::ReadMacroBlock (CMacroBlock * block) [private]

throws IOException

Definition at line 521 of file Decoder.cpp.

521                                                        {
522         ASSERT(block);
523 
524         UINT16 wordLen;
525         ROIBlockHeader h(BufferSize);
526         int count, expected;
527 
528 #ifdef TRACE
529         //UINT32 filePos = (UINT32)m_stream->GetPos();
530         //printf("DecodeBuffer: %d0, filePos);
531 #endif
532 
533         // read wordLen
534         count = expected = sizeof(UINT16);
535         m_stream->Read(&count, &wordLen); 
536         if (count != expected) ReturnWithError(MissingData);
537         wordLen = __VAL(wordLen);
538         if (wordLen > BufferSize) 
539                 ReturnWithError(FormatCannotRead);
540 
541 #ifdef __PGFROISUPPORT__
542         // read ROIBlockHeader
543         if (m_roi) {
544                 m_stream->Read(&count, &h.val); 
545                 if (count != expected) ReturnWithError(MissingData);
546                 
547                 // convert ROIBlockHeader
548                 h.val = __VAL(h.val);
549         }
550 #endif
551         // save header
552         block->m_header = h;
553 
554         // read data
555         count = expected = wordLen*WordBytes;
556         m_stream->Read(&count, block->m_codeBuffer);
557         if (count != expected) ReturnWithError(MissingData);
558 
559 #ifdef PGF_USE_BIG_ENDIAN 
560         // convert data
561         count /= WordBytes;
562         for (int i=0; i < count; i++) {
563                 block->m_codeBuffer[i] = __VAL(block->m_codeBuffer[i]);
564         }
565 #endif
566 
567 #ifdef __PGFROISUPPORT__
568         ASSERT(m_roi && h.rbh.bufferSize <= BufferSize || h.rbh.bufferSize == BufferSize);
569 #else
570         ASSERT(h.rbh.bufferSize == BufferSize);
571 #endif
572 }

void CDecoder::SetStreamPosToData () [inline]

Reset stream position to beginning of data block.

Definition at line 145 of file Decoder.h.

145 { ASSERT(m_stream); m_stream->SetPos(FSFromStart, m_startPos + m_encodedHeaderLength); }

void CDecoder::SetStreamPosToStart () [inline]

Reset stream position to beginning of PGF pre-header.

Definition at line 141 of file Decoder.h.

141 { ASSERT(m_stream); m_stream->SetPos(FSFromStart, m_startPos); }

void CDecoder::Skip (UINT64 offset)

Skip a given number of bytes in the open stream. It might throw an IOException.

Definition at line 435 of file Decoder.cpp.

435                                         {
436         m_stream->SetPos(FSFromCurrent, offset);
437 }

Member Data Documentation

CMacroBlock* CDecoder::m_currentBlock [private]

current macro block (used by main thread)

Definition at line 213 of file Decoder.h.

int CDecoder::m_currentBlockIndex [private]

index of current macro block

Definition at line 210 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 207 of file Decoder.h.

int CDecoder::m_macroBlockLen [private]

array length

Definition at line 211 of file Decoder.h.

CMacroBlock** CDecoder::m_macroBlocks [private]

array of macroblocks

Definition at line 209 of file Decoder.h.

int CDecoder::m_macroBlocksAvailable [private]

number of decoded macro blocks (including currently used macro block)

Definition at line 212 of file Decoder.h.

UINT64 CDecoder::m_startPos [private]

stream position at the beginning of the PGF pre-header

Definition at line 205 of file Decoder.h.

CPGFStream* CDecoder::m_stream [private]

input PGF stream

Definition at line 204 of file Decoder.h.

UINT64 CDecoder::m_streamSizeEstimation [private]

estimation of stream size

Definition at line 206 of file Decoder.h.

Author

Generated automatically by Doxygen for libpgf from the source code.

Info

Thu Feb 4 2016 Version 6.14.12 libpgf