libpgf  6.13.45
PGF - Progressive Graphics File
 All Classes Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
Decoder.cpp
Go to the documentation of this file.
1 /*
2  * The Progressive Graphics File; http://www.libpgf.org
3  *
4  * $Date: 2006-06-04 22:05:59 +0200 (So, 04 Jun 2006) $
5  * $Revision: 229 $
6  *
7  * This file Copyright (C) 2006 xeraina GmbH, Switzerland
8  *
9  * This program is free software; you can redistribute it and/or
10  * modify it under the terms of the GNU LESSER GENERAL PUBLIC LICENSE
11  * as published by the Free Software Foundation; either version 2.1
12  * of the License, or (at your option) any later version.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program; if not, write to the Free Software
21  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
22  */
23 
28 
29 #include "Decoder.h"
30 #ifdef TRACE
31  #include <stdio.h>
32 #endif
33 
35 // PGF: file structure
36 //
37 // PGFPreHeader PGFHeader PGFPostHeader LevelLengths Level_n-1 Level_n-2 ... Level_0
38 // PGFPostHeader ::= [ColorTable] [UserData]
39 // LevelLengths ::= UINT32[nLevels]
40 
42 // Decoding scheme
43 // input: binary file
44 // output: wavelet coefficients stored in subbands
45 //
46 // file (for each buffer: packedLength (16 bit), packed bits)
47 // |
48 // m_codeBuffer (for each plane: RLcodeLength (16 bit), RLcoded sigBits + m_sign, refBits)
49 // | | |
50 // m_sign sigBits refBits [BufferLen, BufferLen, BufferLen]
51 // | | |
52 // m_value [BufferSize]
53 // |
54 // subband
55 //
56 
57 // Constants
58 #define CodeBufferBitLen (CodeBufferLen*WordWidth)
59 #define MaxCodeLen ((1 << RLblockSizeLen) - 1)
60 
61 CDecoder::CDecoder(CPGFStream* stream, PGFPreHeader& preHeader, PGFHeader& header,
74  PGFPostHeader& postHeader, UINT32*& levelLength, UINT64& userDataPos,
75  bool useOMP, bool skipUserData) THROW_
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  // set number of threads
91 #ifdef LIBPGF_USE_OPENMP
92  m_macroBlockLen = omp_get_num_procs();
93 #else
94  m_macroBlockLen = 1;
95 #endif
96 
97  if (useOMP && m_macroBlockLen > 1) {
98 #ifdef LIBPGF_USE_OPENMP
99  omp_set_num_threads(m_macroBlockLen);
100 #endif
101 
102  // create macro block array
103  m_macroBlocks = new(std::nothrow) CMacroBlock*[m_macroBlockLen];
104  if (!m_macroBlocks) ReturnWithError(InsufficientMemory);
105  for (int i=0; i < m_macroBlockLen; i++) m_macroBlocks[i] = new CMacroBlock(this);
106  m_currentBlock = m_macroBlocks[m_currentBlockIndex];
107  } else {
108  m_macroBlocks = 0;
109  m_macroBlockLen = 1; // there is only one macro block
110  m_currentBlock = new CMacroBlock(this);
111  }
112 
113  // store current stream position
114  m_startPos = m_stream->GetPos();
115 
116  // read magic and version
117  count = expected = MagicVersionSize;
118  m_stream->Read(&count, &preHeader);
119  if (count != expected) ReturnWithError(MissingData);
120 
121  // read header size
122  if (preHeader.version & Version6) {
123  // 32 bit header size since version 6
124  count = expected = 4;
125  } else {
126  count = expected = 2;
127  }
128  m_stream->Read(&count, ((UINT8*)&preHeader) + MagicVersionSize);
129  if (count != expected) ReturnWithError(MissingData);
130 
131  // make sure the values are correct read
132  preHeader.hSize = __VAL(preHeader.hSize);
133 
134  // check magic number
135  if (memcmp(preHeader.magic, PGFMagic, 3) != 0) {
136  // error condition: wrong Magic number
137  ReturnWithError(FormatCannotRead);
138  }
139 
140  // read file header
141  count = expected = (preHeader.hSize < HeaderSize) ? preHeader.hSize : HeaderSize;
142  m_stream->Read(&count, &header);
143  if (count != expected) ReturnWithError(MissingData);
144 
145  // make sure the values are correct read
146  header.height = __VAL(UINT32(header.height));
147  header.width = __VAL(UINT32(header.width));
148 
149  // be ready to read all versions including version 0
150  if (preHeader.version > 0) {
151 #ifndef __PGFROISUPPORT__
152  // check ROI usage
153  if (preHeader.version & PGFROI) ReturnWithError(FormatCannotRead);
154 #endif
155 
156  int size = preHeader.hSize - HeaderSize;
157 
158  if (size > 0) {
159  // read post-header
160  if (header.mode == ImageModeIndexedColor) {
161  ASSERT((size_t)size >= ColorTableSize);
162  // read color table
163  count = expected = ColorTableSize;
164  m_stream->Read(&count, postHeader.clut);
165  if (count != expected) ReturnWithError(MissingData);
166  size -= count;
167  }
168 
169  if (size > 0) {
170  userDataPos = m_stream->GetPos();
171  postHeader.userDataLen = size;
172  if (skipUserData) {
173  Skip(size);
174  } else {
175  // create user data memory block
176  postHeader.userData = new(std::nothrow) UINT8[postHeader.userDataLen];
177  if (!postHeader.userData) ReturnWithError(InsufficientMemory);
178 
179  // read user data
180  count = expected = postHeader.userDataLen;
181  m_stream->Read(&count, postHeader.userData);
182  if (count != expected) ReturnWithError(MissingData);
183  }
184  }
185  }
186 
187  // create levelLength
188  levelLength = new(std::nothrow) UINT32[header.nLevels];
189  if (!levelLength) ReturnWithError(InsufficientMemory);
190 
191  // read levelLength
192  count = expected = header.nLevels*WordBytes;
193  m_stream->Read(&count, levelLength);
194  if (count != expected) ReturnWithError(MissingData);
195 
196 #ifdef PGF_USE_BIG_ENDIAN
197  // make sure the values are correct read
198  for (int i=0; i < header.nLevels; i++) {
199  levelLength[i] = __VAL(levelLength[i]);
200  }
201 #endif
202 
203  // compute the total size in bytes; keep attention: level length information is optional
204  for (int i=0; i < header.nLevels; i++) {
205  m_streamSizeEstimation += levelLength[i];
206  }
207 
208  }
209 
210  // store current stream position
211  m_encodedHeaderLength = UINT32(m_stream->GetPos() - m_startPos);
212 }
213 
215 // Destructor
217  if (m_macroBlocks) {
218  for (int i=0; i < m_macroBlockLen; i++) delete m_macroBlocks[i];
219  delete[] m_macroBlocks;
220  } else {
221  delete m_currentBlock;
222  }
223 }
224 
231 UINT32 CDecoder::ReadEncodedData(UINT8* target, UINT32 len) const THROW_ {
232  ASSERT(m_stream);
233 
234  int count = len;
235  m_stream->Read(&count, target);
236 
237  return count;
238 }
239 
251 void CDecoder::Partition(CSubband* band, int quantParam, int width, int height, int startPos, int pitch) THROW_ {
252  ASSERT(band);
253 
254  const div_t ww = div(width, LinBlockSize);
255  const div_t hh = div(height, LinBlockSize);
256  const int ws = pitch - LinBlockSize;
257  const int wr = pitch - ww.rem;
258  int pos, base = startPos, base2;
259 
260  // main height
261  for (int i=0; i < hh.quot; i++) {
262  // main width
263  base2 = base;
264  for (int j=0; j < ww.quot; j++) {
265  pos = base2;
266  for (int y=0; y < LinBlockSize; y++) {
267  for (int x=0; x < LinBlockSize; x++) {
268  DequantizeValue(band, pos, quantParam);
269  pos++;
270  }
271  pos += ws;
272  }
273  base2 += LinBlockSize;
274  }
275  // rest of width
276  pos = base2;
277  for (int y=0; y < LinBlockSize; y++) {
278  for (int x=0; x < ww.rem; x++) {
279  DequantizeValue(band, pos, quantParam);
280  pos++;
281  }
282  pos += wr;
283  base += pitch;
284  }
285  }
286  // main width
287  base2 = base;
288  for (int j=0; j < ww.quot; j++) {
289  // rest of height
290  pos = base2;
291  for (int y=0; y < hh.rem; y++) {
292  for (int x=0; x < LinBlockSize; x++) {
293  DequantizeValue(band, pos, quantParam);
294  pos++;
295  }
296  pos += ws;
297  }
298  base2 += LinBlockSize;
299  }
300  // rest of height
301  pos = base2;
302  for (int y=0; y < hh.rem; y++) {
303  // rest of width
304  for (int x=0; x < ww.rem; x++) {
305  DequantizeValue(band, pos, quantParam);
306  pos++;
307  }
308  pos += wr;
309  }
310 }
311 
313 // Decode and dequantize HL, and LH band of one level
314 // LH and HH are interleaved in the codestream and must be split
315 // Deccoding and dequantization of HL and LH Band (interleaved) using partitioning scheme
316 // partitions the plane in squares of side length InterBlockSize
317 // It might throw an IOException.
318 void CDecoder::DecodeInterleaved(CWaveletTransform* wtChannel, int level, int quantParam) THROW_ {
319  CSubband* hlBand = wtChannel->GetSubband(level, HL);
320  CSubband* lhBand = wtChannel->GetSubband(level, LH);
321  const div_t lhH = div(lhBand->GetHeight(), InterBlockSize);
322  const div_t hlW = div(hlBand->GetWidth(), InterBlockSize);
323  const int hlws = hlBand->GetWidth() - InterBlockSize;
324  const int hlwr = hlBand->GetWidth() - hlW.rem;
325  const int lhws = lhBand->GetWidth() - InterBlockSize;
326  const int lhwr = lhBand->GetWidth() - hlW.rem;
327  int hlPos, lhPos;
328  int hlBase = 0, lhBase = 0, hlBase2, lhBase2;
329 
330  ASSERT(lhBand->GetWidth() >= hlBand->GetWidth());
331  ASSERT(hlBand->GetHeight() >= lhBand->GetHeight());
332 
333  if (!hlBand->AllocMemory()) ReturnWithError(InsufficientMemory);
334  if (!lhBand->AllocMemory()) ReturnWithError(InsufficientMemory);
335 
336  // correct quantParam with normalization factor
337  quantParam -= level;
338  if (quantParam < 0) quantParam = 0;
339 
340  // main height
341  for (int i=0; i < lhH.quot; i++) {
342  // main width
343  hlBase2 = hlBase;
344  lhBase2 = lhBase;
345  for (int j=0; j < hlW.quot; j++) {
346  hlPos = hlBase2;
347  lhPos = lhBase2;
348  for (int y=0; y < InterBlockSize; y++) {
349  for (int x=0; x < InterBlockSize; x++) {
350  DequantizeValue(hlBand, hlPos, quantParam);
351  DequantizeValue(lhBand, lhPos, quantParam);
352  hlPos++;
353  lhPos++;
354  }
355  hlPos += hlws;
356  lhPos += lhws;
357  }
358  hlBase2 += InterBlockSize;
359  lhBase2 += InterBlockSize;
360  }
361  // rest of width
362  hlPos = hlBase2;
363  lhPos = lhBase2;
364  for (int y=0; y < InterBlockSize; y++) {
365  for (int x=0; x < hlW.rem; x++) {
366  DequantizeValue(hlBand, hlPos, quantParam);
367  DequantizeValue(lhBand, lhPos, quantParam);
368  hlPos++;
369  lhPos++;
370  }
371  // width difference between HL and LH
372  if (lhBand->GetWidth() > hlBand->GetWidth()) {
373  DequantizeValue(lhBand, lhPos, quantParam);
374  }
375  hlPos += hlwr;
376  lhPos += lhwr;
377  hlBase += hlBand->GetWidth();
378  lhBase += lhBand->GetWidth();
379  }
380  }
381  // main width
382  hlBase2 = hlBase;
383  lhBase2 = lhBase;
384  for (int j=0; j < hlW.quot; j++) {
385  // rest of height
386  hlPos = hlBase2;
387  lhPos = lhBase2;
388  for (int y=0; y < lhH.rem; y++) {
389  for (int x=0; x < InterBlockSize; x++) {
390  DequantizeValue(hlBand, hlPos, quantParam);
391  DequantizeValue(lhBand, lhPos, quantParam);
392  hlPos++;
393  lhPos++;
394  }
395  hlPos += hlws;
396  lhPos += lhws;
397  }
398  hlBase2 += InterBlockSize;
399  lhBase2 += InterBlockSize;
400  }
401  // rest of height
402  hlPos = hlBase2;
403  lhPos = lhBase2;
404  for (int y=0; y < lhH.rem; y++) {
405  // rest of width
406  for (int x=0; x < hlW.rem; x++) {
407  DequantizeValue(hlBand, hlPos, quantParam);
408  DequantizeValue(lhBand, lhPos, quantParam);
409  hlPos++;
410  lhPos++;
411  }
412  // width difference between HL and LH
413  if (lhBand->GetWidth() > hlBand->GetWidth()) {
414  DequantizeValue(lhBand, lhPos, quantParam);
415  }
416  hlPos += hlwr;
417  lhPos += lhwr;
418  hlBase += hlBand->GetWidth();
419  }
420  // height difference between HL and LH
421  if (hlBand->GetHeight() > lhBand->GetHeight()) {
422  // total width
423  hlPos = hlBase;
424  for (int j=0; j < hlBand->GetWidth(); j++) {
425  DequantizeValue(hlBand, hlPos, quantParam);
426  hlPos++;
427  }
428  }
429 }
430 
434 void CDecoder::Skip(UINT64 offset) THROW_ {
435  m_stream->SetPos(FSFromCurrent, offset);
436 }
437 
447 void CDecoder::DequantizeValue(CSubband* band, UINT32 bandPos, int quantParam) THROW_ {
448  ASSERT(m_currentBlock);
449 
450  if (m_currentBlock->IsCompletelyRead()) {
451  // all data of current macro block has been read --> prepare next macro block
452  DecodeTileBuffer();
453  }
454 
455  band->SetData(bandPos, m_currentBlock->m_value[m_currentBlock->m_valuePos] << quantParam);
456  m_currentBlock->m_valuePos++;
457 }
458 
460 // Read next group of blocks from stream and decodes them into macro blocks
461 // It might throw an IOException.
462 void CDecoder::DecodeTileBuffer() THROW_ {
463  // current block has been read --> prepare next current block
465 
466  if (m_macroBlocksAvailable > 0) {
468  } else {
469  DecodeBuffer();
470  }
471  ASSERT(m_currentBlock);
472 }
473 
475 // Read next block from stream and decode into macro block
476 // Decoding scheme: <wordLen>(16 bits) [ ROI ] data
477 // ROI ::= <bufferSize>(15 bits) <eofTile>(1 bit)
478 // It might throw an IOException.
479 void CDecoder::DecodeBuffer() THROW_ {
480  ASSERT(m_macroBlocksAvailable <= 0);
481 
482  // macro block management
483  if (m_macroBlockLen == 1) {
484  ASSERT(m_currentBlock);
488  } else {
490  for (int i=0; i < m_macroBlockLen; i++) {
491  // read sequentially several blocks
492  try {
495  } catch(IOException& ex) {
496  if (ex.error == MissingData) {
497  break; // no further data available
498  } else {
499  throw;
500  }
501  }
502  }
503 #ifdef LIBPGF_USE_OPENMP
504  // decode in parallel
505  #pragma omp parallel for default(shared) //no declared exceptions in next block
506 #endif
507  for (int i=0; i < m_macroBlocksAvailable; i++) {
509  }
510 
511  // prepare current macro block
514  }
515 }
516 
518 // Read next block from stream and store it in the given block
519 // It might throw an IOException.
521  ASSERT(block);
522 
523  UINT16 wordLen;
525  int count, expected;
526 
527 #ifdef TRACE
528  //UINT32 filePos = (UINT32)m_stream->GetPos();
529  //printf("DecodeBuffer: %d\n", filePos);
530 #endif
531 
532  // read wordLen
533  count = expected = sizeof(UINT16);
534  m_stream->Read(&count, &wordLen);
535  if (count != expected) ReturnWithError(MissingData);
536  wordLen = __VAL(wordLen);
537  if (wordLen > BufferSize)
538  ReturnWithError(FormatCannotRead);
539 
540 #ifdef __PGFROISUPPORT__
541  // read ROIBlockHeader
542  if (m_roi) {
543  m_stream->Read(&count, &h.val);
544  if (count != expected) ReturnWithError(MissingData);
545 
546  // convert ROIBlockHeader
547  h.val = __VAL(h.val);
548  }
549 #endif
550  // save header
551  block->m_header = h;
552 
553  // read data
554  count = expected = wordLen*WordBytes;
555  m_stream->Read(&count, block->m_codeBuffer);
556  if (count != expected) ReturnWithError(MissingData);
557 
558 #ifdef PGF_USE_BIG_ENDIAN
559  // convert data
560  count /= WordBytes;
561  for (int i=0; i < count; i++) {
562  block->m_codeBuffer[i] = __VAL(block->m_codeBuffer[i]);
563  }
564 #endif
565 
566 #ifdef __PGFROISUPPORT__
567  ASSERT(m_roi && h.rbh.bufferSize <= BufferSize || h.rbh.bufferSize == BufferSize);
568 #else
569  ASSERT(h.rbh.bufferSize == BufferSize);
570 #endif
571 }
572 
574 // Read next block from stream but don't decode into macro block
575 // Encoding scheme: <wordLen>(16 bits) [ ROI ] data
576 // ROI ::= <bufferSize>(15 bits) <eofTile>(1 bit)
577 // It might throw an IOException.
578 void CDecoder::SkipTileBuffer() THROW_ {
579  // current block is not used
581 
582  // check if pre-decoded data is available
583  if (m_macroBlocksAvailable > 0) {
585  return;
586  }
587 
588  UINT16 wordLen;
589  int count, expected;
590 
591  // read wordLen
592  count = expected = sizeof(wordLen);
593  m_stream->Read(&count, &wordLen);
594  if (count != expected) ReturnWithError(MissingData);
595  wordLen = __VAL(wordLen);
596  ASSERT(wordLen <= BufferSize);
597 
598 #ifdef __PGFROISUPPORT__
599  if (m_roi) {
600  // skip ROIBlockHeader
601  m_stream->SetPos(FSFromCurrent, sizeof(ROIBlockHeader));
602  }
603 #endif
604 
605  // skip data
606  m_stream->SetPos(FSFromCurrent, wordLen*WordBytes);
607 }
608 
610 // Decode block into buffer of given size using bit plane coding.
611 // A buffer contains bufferLen UINT32 values, thus, bufferSize bits per bit plane.
612 // Following coding scheme is used:
613 // Buffer ::= <nPlanes>(5 bits) foreach(plane i): Plane[i]
614 // Plane[i] ::= [ Sig1 | Sig2 ] [DWORD alignment] refBits
615 // Sig1 ::= 1 <codeLen>(15 bits) codedSigAndSignBits
616 // Sig2 ::= 0 <sigLen>(15 bits) [Sign1 | Sign2 ] [DWORD alignment] sigBits
617 // Sign1 ::= 1 <codeLen>(15 bits) codedSignBits
618 // Sign2 ::= 0 <signLen>(15 bits) [DWORD alignment] signBits
620  UINT32 bufferSize = m_header.rbh.bufferSize; ASSERT(bufferSize <= BufferSize);
621 
622  UINT32 nPlanes;
623  UINT32 codePos = 0, codeLen, sigLen, sigPos, signLen, signPos;
624  DataT planeMask;
625 
626  // clear significance vector
627  for (UINT32 k=0; k < bufferSize; k++) {
628  m_sigFlagVector[k] = false;
629  }
630  m_sigFlagVector[bufferSize] = true; // sentinel
631 
632  // clear output buffer
633  for (UINT32 k=0; k < BufferSize; k++) {
634  m_value[k] = 0;
635  }
636 
637  // read number of bit planes
638  // <nPlanes>
640  codePos += MaxBitPlanesLog;
641 
642  // loop through all bit planes
643  if (nPlanes == 0) nPlanes = MaxBitPlanes + 1;
644  ASSERT(0 < nPlanes && nPlanes <= MaxBitPlanes + 1);
645  planeMask = 1 << (nPlanes - 1);
646 
647  for (int plane = nPlanes - 1; plane >= 0; plane--) {
648  // read RL code
649  if (GetBit(m_codeBuffer, codePos)) {
650  // RL coding of sigBits is used
651  // <1><codeLen><codedSigAndSignBits>_<refBits>
652  codePos++;
653 
654  // read codeLen
655  codeLen = GetValueBlock(m_codeBuffer, codePos, RLblockSizeLen); ASSERT(codeLen <= MaxCodeLen);
656 
657  // position of encoded sigBits and signBits
658  sigPos = codePos + RLblockSizeLen; ASSERT(sigPos < CodeBufferBitLen);
659 
660  // refinement bits
661  codePos = AlignWordPos(sigPos + codeLen); ASSERT(codePos < CodeBufferBitLen);
662 
663  // run-length decode significant bits and signs from m_codeBuffer and
664  // read refinement bits from m_codeBuffer and compose bit plane
665  sigLen = ComposeBitplaneRLD(bufferSize, planeMask, sigPos, &m_codeBuffer[codePos >> WordWidthLog]);
666 
667  } else {
668  // no RL coding is used for sigBits and signBits together
669  // <0><sigLen>
670  codePos++;
671 
672  // read sigLen
673  sigLen = GetValueBlock(m_codeBuffer, codePos, RLblockSizeLen); ASSERT(sigLen <= MaxCodeLen);
674  codePos += RLblockSizeLen; ASSERT(codePos < CodeBufferBitLen);
675 
676  // read RL code for signBits
677  if (GetBit(m_codeBuffer, codePos)) {
678  // RL coding is used just for signBits
679  // <1><codeLen><codedSignBits>_<sigBits>_<refBits>
680  codePos++;
681 
682  // read codeLen
683  codeLen = GetValueBlock(m_codeBuffer, codePos, RLblockSizeLen); ASSERT(codeLen <= MaxCodeLen);
684 
685  // sign bits
686  signPos = codePos + RLblockSizeLen; ASSERT(signPos < CodeBufferBitLen);
687 
688  // significant bits
689  sigPos = AlignWordPos(signPos + codeLen); ASSERT(sigPos < CodeBufferBitLen);
690 
691  // refinement bits
692  codePos = AlignWordPos(sigPos + sigLen); ASSERT(codePos < CodeBufferBitLen);
693 
694  // read significant and refinement bitset from m_codeBuffer
695  sigLen = ComposeBitplaneRLD(bufferSize, planeMask, &m_codeBuffer[sigPos >> WordWidthLog], &m_codeBuffer[codePos >> WordWidthLog], signPos);
696 
697  } else {
698  // RL coding of signBits was not efficient and therefore not used
699  // <0><signLen>_<signBits>_<sigBits>_<refBits>
700  codePos++;
701 
702  // read signLen
703  signLen = GetValueBlock(m_codeBuffer, codePos, RLblockSizeLen); ASSERT(signLen <= MaxCodeLen);
704 
705  // sign bits
706  signPos = AlignWordPos(codePos + RLblockSizeLen); ASSERT(signPos < CodeBufferBitLen);
707 
708  // significant bits
709  sigPos = AlignWordPos(signPos + signLen); ASSERT(sigPos < CodeBufferBitLen);
710 
711  // refinement bits
712  codePos = AlignWordPos(sigPos + sigLen); ASSERT(codePos < CodeBufferBitLen);
713 
714  // read significant and refinement bitset from m_codeBuffer
715  sigLen = ComposeBitplane(bufferSize, planeMask, &m_codeBuffer[sigPos >> WordWidthLog], &m_codeBuffer[codePos >> WordWidthLog], &m_codeBuffer[signPos >> WordWidthLog]);
716  }
717  }
718 
719  // start of next chunk
720  codePos = AlignWordPos(codePos + bufferSize - sigLen); ASSERT(codePos < CodeBufferBitLen);
721 
722  // next plane
723  planeMask >>= 1;
724  }
725 
726  m_valuePos = 0;
727 }
728 
730 // Reconstruct bitplane from significant bitset and refinement bitset
731 // returns length [bits] of sigBits
732 // input: sigBits, refBits, signBits
733 // output: m_value
734 UINT32 CDecoder::CMacroBlock::ComposeBitplane(UINT32 bufferSize, DataT planeMask, UINT32* sigBits, UINT32* refBits, UINT32* signBits) {
735  ASSERT(sigBits);
736  ASSERT(refBits);
737  ASSERT(signBits);
738 
739  UINT32 valPos = 0, signPos = 0, refPos = 0;
740  UINT32 sigPos = 0, sigEnd;
741  UINT32 zerocnt;
742 
743  while (valPos < bufferSize) {
744  // search next 1 in m_sigFlagVector using searching with sentinel
745  sigEnd = valPos;
746  while(!m_sigFlagVector[sigEnd]) { sigEnd++; }
747  sigEnd -= valPos;
748  sigEnd += sigPos;
749 
750  // search 1's in sigBits[sigPos..sigEnd)
751  // these 1's are significant bits
752  while (sigPos < sigEnd) {
753  // search 0's
754  zerocnt = SeekBitRange(sigBits, sigPos, sigEnd - sigPos);
755  sigPos += zerocnt;
756  valPos += zerocnt;
757  if (sigPos < sigEnd) {
758  // write bit to m_value
759  SetBitAtPos(valPos, planeMask);
760 
761  // copy sign bit
762  SetSign(valPos, GetBit(signBits, signPos++));
763 
764  // update significance flag vector
765  m_sigFlagVector[valPos++] = true;
766  sigPos++;
767  }
768  }
769  // refinement bit
770  if (valPos < bufferSize) {
771  // write one refinement bit
772  if (GetBit(refBits, refPos)) {
773  SetBitAtPos(valPos, planeMask);
774  }
775  refPos++;
776  valPos++;
777  }
778  }
779  ASSERT(sigPos <= bufferSize);
780  ASSERT(refPos <= bufferSize);
781  ASSERT(signPos <= bufferSize);
782  ASSERT(valPos == bufferSize);
783 
784  return sigPos;
785 }
786 
788 // Reconstruct bitplane from significant bitset and refinement bitset
789 // returns length [bits] of decoded significant bits
790 // input: RL encoded sigBits and signBits in m_codeBuffer, refBits
791 // output: m_value
792 // RLE:
793 // - Decode run of 2^k zeros by a single 0.
794 // - Decode run of count 0's followed by a 1 with codeword: 1<count>x
795 // - x is 0: if a positive sign has been stored, otherwise 1
796 // - Read each bit from m_codeBuffer[codePos] and increment codePos.
797 UINT32 CDecoder::CMacroBlock::ComposeBitplaneRLD(UINT32 bufferSize, DataT planeMask, UINT32 codePos, UINT32* refBits) {
798  ASSERT(refBits);
799 
800  UINT32 valPos = 0, refPos = 0;
801  UINT32 sigPos = 0, sigEnd;
802  UINT32 k = 3;
803  UINT32 runlen = 1 << k; // = 2^k
804  UINT32 count = 0, rest = 0;
805  bool set1 = false;
806 
807  while (valPos < bufferSize) {
808  // search next 1 in m_sigFlagVector using searching with sentinel
809  sigEnd = valPos;
810  while(!m_sigFlagVector[sigEnd]) { sigEnd++; }
811  sigEnd -= valPos;
812  sigEnd += sigPos;
813 
814  while (sigPos < sigEnd) {
815  if (rest || set1) {
816  // rest of last run
817  sigPos += rest;
818  valPos += rest;
819  rest = 0;
820  } else {
821  // decode significant bits
822  if (GetBit(m_codeBuffer, codePos++)) {
823  // extract counter and generate zero run of length count
824  if (k > 0) {
825  // extract counter
826  count = GetValueBlock(m_codeBuffer, codePos, k);
827  codePos += k;
828  if (count > 0) {
829  sigPos += count;
830  valPos += count;
831  }
832 
833  // adapt k (half run-length interval)
834  k--;
835  runlen >>= 1;
836  }
837 
838  set1 = true;
839 
840  } else {
841  // generate zero run of length 2^k
842  sigPos += runlen;
843  valPos += runlen;
844 
845  // adapt k (double run-length interval)
846  if (k < WordWidth) {
847  k++;
848  runlen <<= 1;
849  }
850  }
851  }
852 
853  if (sigPos < sigEnd) {
854  if (set1) {
855  set1 = false;
856 
857  // write 1 bit
858  SetBitAtPos(valPos, planeMask);
859 
860  // set sign bit
861  SetSign(valPos, GetBit(m_codeBuffer, codePos++));
862 
863  // update significance flag vector
864  m_sigFlagVector[valPos++] = true;
865  sigPos++;
866  }
867  } else {
868  rest = sigPos - sigEnd;
869  sigPos = sigEnd;
870  valPos -= rest;
871  }
872 
873  }
874 
875  // refinement bit
876  if (valPos < bufferSize) {
877  // write one refinement bit
878  if (GetBit(refBits, refPos)) {
879  SetBitAtPos(valPos, planeMask);
880  }
881  refPos++;
882  valPos++;
883  }
884  }
885  ASSERT(sigPos <= bufferSize);
886  ASSERT(refPos <= bufferSize);
887  ASSERT(valPos == bufferSize);
888 
889  return sigPos;
890 }
891 
893 // Reconstruct bitplane from significant bitset, refinement bitset, and RL encoded sign bits
894 // returns length [bits] of sigBits
895 // input: sigBits, refBits, RL encoded signBits
896 // output: m_value
897 // RLE:
898 // decode run of 2^k 1's by a single 1
899 // decode run of count 1's followed by a 0 with codeword: 0<count>
900 UINT32 CDecoder::CMacroBlock::ComposeBitplaneRLD(UINT32 bufferSize, DataT planeMask, UINT32* sigBits, UINT32* refBits, UINT32 signPos) {
901  ASSERT(sigBits);
902  ASSERT(refBits);
903 
904  UINT32 valPos = 0, refPos = 0;
905  UINT32 sigPos = 0, sigEnd;
906  UINT32 zerocnt, count = 0;
907  UINT32 k = 0;
908  UINT32 runlen = 1 << k; // = 2^k
909  bool signBit = false;
910  bool zeroAfterRun = false;
911 
912  while (valPos < bufferSize) {
913  // search next 1 in m_sigFlagVector using searching with sentinel
914  sigEnd = valPos;
915  while(!m_sigFlagVector[sigEnd]) { sigEnd++; }
916  sigEnd -= valPos;
917  sigEnd += sigPos;
918 
919  // search 1's in sigBits[sigPos..sigEnd)
920  // these 1's are significant bits
921  while (sigPos < sigEnd) {
922  // search 0's
923  zerocnt = SeekBitRange(sigBits, sigPos, sigEnd - sigPos);
924  sigPos += zerocnt;
925  valPos += zerocnt;
926  if (sigPos < sigEnd) {
927  // write bit to m_value
928  SetBitAtPos(valPos, planeMask);
929 
930  // check sign bit
931  if (count == 0) {
932  // all 1's have been set
933  if (zeroAfterRun) {
934  // finish the run with a 0
935  signBit = false;
936  zeroAfterRun = false;
937  } else {
938  // decode next sign bit
939  if (GetBit(m_codeBuffer, signPos++)) {
940  // generate 1's run of length 2^k
941  count = runlen - 1;
942  signBit = true;
943 
944  // adapt k (double run-length interval)
945  if (k < WordWidth) {
946  k++;
947  runlen <<= 1;
948  }
949  } else {
950  // extract counter and generate 1's run of length count
951  if (k > 0) {
952  // extract counter
953  count = GetValueBlock(m_codeBuffer, signPos, k);
954  signPos += k;
955 
956  // adapt k (half run-length interval)
957  k--;
958  runlen >>= 1;
959  }
960  if (count > 0) {
961  count--;
962  signBit = true;
963  zeroAfterRun = true;
964  } else {
965  signBit = false;
966  }
967  }
968  }
969  } else {
970  ASSERT(count > 0);
971  ASSERT(signBit);
972  count--;
973  }
974 
975  // copy sign bit
976  SetSign(valPos, signBit);
977 
978  // update significance flag vector
979  m_sigFlagVector[valPos++] = true;
980  sigPos++;
981  }
982  }
983 
984  // refinement bit
985  if (valPos < bufferSize) {
986  // write one refinement bit
987  if (GetBit(refBits, refPos)) {
988  SetBitAtPos(valPos, planeMask);
989  }
990  refPos++;
991  valPos++;
992  }
993  }
994  ASSERT(sigPos <= bufferSize);
995  ASSERT(refPos <= bufferSize);
996  ASSERT(valPos == bufferSize);
997 
998  return sigPos;
999 }
1000 
1002 #ifdef TRACE
1003 void CDecoder::DumpBuffer() {
1004  //printf("\nDump\n");
1005  //for (int i=0; i < BufferSize; i++) {
1006  // printf("%d", m_value[i]);
1007  //}
1008 }
1009 #endif //TRACE
bool GetBit(UINT32 *stream, UINT32 pos)
Definition: BitStream.h:65
#define ImageModeIndexedColor
Definition: PGFplatform.h:100
struct ROIBlockHeader::RBH rbh
ROI block header.
virtual void Read(int *count, void *buffer)=0
UINT16 bufferSize
number of uncoded UINT32 values in a block
Definition: PGFtypes.h:167
UINT32 ComposeBitplane(UINT32 bufferSize, DataT planeMask, UINT32 *sigBits, UINT32 *refBits, UINT32 *signBits)
Definition: Decoder.cpp:734
#define MaxCodeLen
max length of RL encoded block
Definition: Decoder.cpp:59
UINT32 AlignWordPos(UINT32 pos)
Definition: BitStream.h:260
CMacroBlock ** m_macroBlocks
array of macroblocks
Definition: Decoder.h:212
Abstract stream base class.
Definition: PGFstream.h:39
void DecodeInterleaved(CWaveletTransform *wtChannel, int level, int quantParam) THROW_
Definition: Decoder.cpp:318
int GetHeight() const
Definition: Subband.h:122
#define LinBlockSize
side length of a coefficient block in a HH or LL subband
Definition: PGFtypes.h:79
UINT32 ReadEncodedData(UINT8 *target, UINT32 len) const THROW_
Definition: Decoder.cpp:231
#define ColorTableSize
Definition: PGFtypes.h:232
INT32 DataT
Definition: PGFtypes.h:219
#define __VAL(x)
Definition: PGFplatform.h:604
bool AllocMemory()
Definition: Subband.cpp:77
UINT32 m_valuePos
current position in m_value
Definition: Decoder.h:82
void ReadMacroBlock(CMacroBlock *block) THROW_
throws IOException
Definition: Decoder.cpp:520
#define BufferSize
must be a multiple of WordWidth
Definition: PGFtypes.h:77
void Partition(CSubband *band, int quantParam, int width, int height, int startPos, int pitch) THROW_
Definition: Decoder.cpp:251
#define HeaderSize
Definition: PGFtypes.h:231
~CDecoder()
Destructor.
Definition: Decoder.cpp:216
virtual void SetPos(short posMode, INT64 posOff)=0
PGF pre-header.
Definition: PGFtypes.h:114
#define RLblockSizeLen
block size length (&lt; 16): ld(BufferSize) &lt; RLblockSizeLen &lt;= 2*ld(BufferSize)
Definition: PGFtypes.h:78
Wavelet channel class.
Definition: Subband.h:42
int m_macroBlockLen
array length
Definition: Decoder.h:214
PGF wavelet transform.
DataT m_value[BufferSize]
output buffer of values with index m_valuePos
Definition: Decoder.h:80
void DequantizeValue(CSubband *band, UINT32 bandPos, int quantParam) THROW_
Definition: Decoder.cpp:447
#define PGFMagic
PGF identification.
Definition: PGFtypes.h:55
Block header used with ROI coding scheme.
Definition: PGFtypes.h:151
PGF header.
Definition: PGFtypes.h:123
#define WordWidthLog
ld of WordWidth
Definition: PGFplatform.h:74
#define Version6
new HeaderSize: 32 bits instead of 16 bits
Definition: PGFtypes.h:66
int m_currentBlockIndex
index of current macro block
Definition: Decoder.h:213
UINT32 SeekBitRange(UINT32 *stream, UINT32 pos, UINT32 len)
Definition: BitStream.h:206
#define MaxBitPlanesLog
number of bits to code the maximum number of bit planes (in 32 or 16 bit mode)
Definition: PGFtypes.h:86
CMacroBlock * m_currentBlock
current macro block (used by main thread)
Definition: Decoder.h:216
Definition: PGFtypes.h:92
#define WordBytes
sizeof(UINT32)
Definition: PGFplatform.h:76
PGF decoder class.
Definition: PGFtypes.h:92
A macro block is a decoding unit of fixed size (uncoded)
Definition: Decoder.h:51
Optional PGF post-header.
Definition: PGFtypes.h:141
CPGFStream * m_stream
input PGF stream
Definition: Decoder.h:207
int m_macroBlocksAvailable
number of decoded macro blocks (including currently used macro block)
Definition: Decoder.h:215
int GetWidth() const
Definition: Subband.h:127
#define PGFROI
supports Regions Of Interest
Definition: PGFtypes.h:64
UINT16 val
Definition: PGFtypes.h:160
UINT32 GetValueBlock(UINT32 *stream, UINT32 pos, UINT32 k)
Definition: BitStream.h:128
#define MaxBitPlanes
maximum number of bit planes of m_value: 32 minus sign bit
Definition: PGFtypes.h:82
#define InterBlockSize
side length of a coefficient block in a HL or LH subband
Definition: PGFtypes.h:80
OSError error
operating system error code
Definition: PGFtypes.h:187
#define MagicVersionSize
Definition: PGFtypes.h:229
void DecodeBuffer() THROW_
Definition: Decoder.cpp:479
UINT32 ComposeBitplaneRLD(UINT32 bufferSize, DataT planeMask, UINT32 sigPos, UINT32 *refBits)
Definition: Decoder.cpp:797
CDecoder(CPGFStream *stream, PGFPreHeader &preHeader, PGFHeader &header, PGFPostHeader &postHeader, UINT32 *&levelLength, UINT64 &userDataPos, bool useOMP, bool skipUserData) THROW_
Definition: Decoder.cpp:73
void Skip(UINT64 offset) THROW_
Definition: Decoder.cpp:434
PGF exception.
Definition: PGFtypes.h:180
ROIBlockHeader m_header
block header
Definition: Decoder.h:79
#define CodeBufferBitLen
max number of bits in m_codeBuffer
Definition: Decoder.cpp:58
bool m_sigFlagVector[BufferSize+1]
Definition: Decoder.h:92
#define WordWidth
WordBytes*8.
Definition: PGFplatform.h:73
UINT32 m_codeBuffer[CodeBufferLen]
input buffer for encoded bitstream
Definition: Decoder.h:81