libpgf  6.14.12
PGF - Progressive Graphics File
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  // 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 }
214 
216 // Destructor
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 }
225 
232 UINT32 CDecoder::ReadEncodedData(UINT8* target, UINT32 len) const THROW_ {
233  ASSERT(m_stream);
234 
235  int count = len;
236  m_stream->Read(&count, target);
237 
238  return count;
239 }
240 
252 void CDecoder::Partition(CSubband* band, int quantParam, int width, int height, int startPos, int pitch) THROW_ {
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 }
312 
314 // Decode and dequantize HL, and LH band of one level
315 // LH and HH are interleaved in the codestream and must be split
316 // Deccoding and dequantization of HL and LH Band (interleaved) using partitioning scheme
317 // partitions the plane in squares of side length InterBlockSize
318 // It might throw an IOException.
319 void CDecoder::DecodeInterleaved(CWaveletTransform* wtChannel, int level, int quantParam) THROW_ {
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 }
431 
435 void CDecoder::Skip(UINT64 offset) THROW_ {
436  m_stream->SetPos(FSFromCurrent, offset);
437 }
438 
448 void CDecoder::DequantizeValue(CSubband* band, UINT32 bandPos, int quantParam) THROW_ {
449  ASSERT(m_currentBlock);
450 
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);
458 }
459 
461 // Read next group of blocks from stream and decodes them into macro blocks
462 // It might throw an IOException.
463 void CDecoder::DecodeTileBuffer() THROW_ {
464  // current block has been read --> prepare next current block
466 
467  if (m_macroBlocksAvailable > 0) {
469  } else {
470  DecodeBuffer();
471  }
472  ASSERT(m_currentBlock);
473 }
474 
476 // Read next block from stream and decode into macro block
477 // Decoding scheme: <wordLen>(16 bits) [ ROI ] data
478 // ROI ::= <bufferSize>(15 bits) <eofTile>(1 bit)
479 // It might throw an IOException.
480 void CDecoder::DecodeBuffer() THROW_ {
481  ASSERT(m_macroBlocksAvailable <= 0);
482 
483  // macro block management
484  if (m_macroBlockLen == 1) {
485  ASSERT(m_currentBlock);
489  } else {
491  for (int i=0; i < m_macroBlockLen; i++) {
492  // read sequentially several blocks
493  try {
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++) {
510  }
511 
512  // prepare current macro block
515  }
516 }
517 
519 // Read next block from stream and store it in the given block
520 // It might throw an IOException.
522  ASSERT(block);
523 
524  UINT16 wordLen;
526  int count, expected;
527 
528 #ifdef TRACE
529  //UINT32 filePos = (UINT32)m_stream->GetPos();
530  //printf("DecodeBuffer: %d\n", 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 }
573 
575 // Read next block from stream but don't decode into macro block
576 // Encoding scheme: <wordLen>(16 bits) [ ROI ] data
577 // ROI ::= <bufferSize>(15 bits) <eofTile>(1 bit)
578 // It might throw an IOException.
579 void CDecoder::SkipTileBuffer() THROW_ {
580  // current block is not used
582 
583  // check if pre-decoded data is available
584  if (m_macroBlocksAvailable > 0) {
586  return;
587  }
588 
589  UINT16 wordLen;
590  int count, expected;
591 
592  // read wordLen
593  count = expected = sizeof(wordLen);
594  m_stream->Read(&count, &wordLen);
595  if (count != expected) ReturnWithError(MissingData);
596  wordLen = __VAL(wordLen);
597  ASSERT(wordLen <= BufferSize);
598 
599 #ifdef __PGFROISUPPORT__
600  if (m_roi) {
601  // skip ROIBlockHeader
602  m_stream->SetPos(FSFromCurrent, sizeof(ROIBlockHeader));
603  }
604 #endif
605 
606  // skip data
607  m_stream->SetPos(FSFromCurrent, wordLen*WordBytes);
608 }
609 
611 // Decode block into buffer of given size using bit plane coding.
612 // A buffer contains bufferLen UINT32 values, thus, bufferSize bits per bit plane.
613 // Following coding scheme is used:
614 // Buffer ::= <nPlanes>(5 bits) foreach(plane i): Plane[i]
615 // Plane[i] ::= [ Sig1 | Sig2 ] [DWORD alignment] refBits
616 // Sig1 ::= 1 <codeLen>(15 bits) codedSigAndSignBits
617 // Sig2 ::= 0 <sigLen>(15 bits) [Sign1 | Sign2 ] [DWORD alignment] sigBits
618 // Sign1 ::= 1 <codeLen>(15 bits) codedSignBits
619 // Sign2 ::= 0 <signLen>(15 bits) [DWORD alignment] signBits
621  UINT32 bufferSize = m_header.rbh.bufferSize; ASSERT(bufferSize <= BufferSize);
622 
623  UINT32 nPlanes;
624  UINT32 codePos = 0, codeLen, sigLen, sigPos, signLen, signPos;
625  DataT planeMask;
626 
627  // clear significance vector
628  for (UINT32 k=0; k < bufferSize; k++) {
629  m_sigFlagVector[k] = false;
630  }
631  m_sigFlagVector[bufferSize] = true; // sentinel
632 
633  // clear output buffer
634  for (UINT32 k=0; k < BufferSize; k++) {
635  m_value[k] = 0;
636  }
637 
638  // read number of bit planes
639  // <nPlanes>
640  nPlanes = GetValueBlock(m_codeBuffer, 0, MaxBitPlanesLog);
641  codePos += MaxBitPlanesLog;
642 
643  // loop through all bit planes
644  if (nPlanes == 0) nPlanes = MaxBitPlanes + 1;
645  ASSERT(0 < nPlanes && nPlanes <= MaxBitPlanes + 1);
646  planeMask = 1 << (nPlanes - 1);
647 
648  for (int plane = nPlanes - 1; plane >= 0; plane--) {
649  // read RL code
650  if (GetBit(m_codeBuffer, codePos)) {
651  // RL coding of sigBits is used
652  // <1><codeLen><codedSigAndSignBits>_<refBits>
653  codePos++;
654 
655  // read codeLen
656  codeLen = GetValueBlock(m_codeBuffer, codePos, RLblockSizeLen); ASSERT(codeLen <= MaxCodeLen);
657 
658  // position of encoded sigBits and signBits
659  sigPos = codePos + RLblockSizeLen; ASSERT(sigPos < CodeBufferBitLen);
660 
661  // refinement bits
662  codePos = AlignWordPos(sigPos + codeLen); ASSERT(codePos < CodeBufferBitLen);
663 
664  // run-length decode significant bits and signs from m_codeBuffer and
665  // read refinement bits from m_codeBuffer and compose bit plane
666  sigLen = ComposeBitplaneRLD(bufferSize, planeMask, sigPos, &m_codeBuffer[codePos >> WordWidthLog]);
667 
668  } else {
669  // no RL coding is used for sigBits and signBits together
670  // <0><sigLen>
671  codePos++;
672 
673  // read sigLen
674  sigLen = GetValueBlock(m_codeBuffer, codePos, RLblockSizeLen); ASSERT(sigLen <= MaxCodeLen);
675  codePos += RLblockSizeLen; ASSERT(codePos < CodeBufferBitLen);
676 
677  // read RL code for signBits
678  if (GetBit(m_codeBuffer, codePos)) {
679  // RL coding is used just for signBits
680  // <1><codeLen><codedSignBits>_<sigBits>_<refBits>
681  codePos++;
682 
683  // read codeLen
684  codeLen = GetValueBlock(m_codeBuffer, codePos, RLblockSizeLen); ASSERT(codeLen <= MaxCodeLen);
685 
686  // sign bits
687  signPos = codePos + RLblockSizeLen; ASSERT(signPos < CodeBufferBitLen);
688 
689  // significant bits
690  sigPos = AlignWordPos(signPos + codeLen); ASSERT(sigPos < CodeBufferBitLen);
691 
692  // refinement bits
693  codePos = AlignWordPos(sigPos + sigLen); ASSERT(codePos < CodeBufferBitLen);
694 
695  // read significant and refinement bitset from m_codeBuffer
696  sigLen = ComposeBitplaneRLD(bufferSize, planeMask, &m_codeBuffer[sigPos >> WordWidthLog], &m_codeBuffer[codePos >> WordWidthLog], signPos);
697 
698  } else {
699  // RL coding of signBits was not efficient and therefore not used
700  // <0><signLen>_<signBits>_<sigBits>_<refBits>
701  codePos++;
702 
703  // read signLen
704  signLen = GetValueBlock(m_codeBuffer, codePos, RLblockSizeLen); ASSERT(signLen <= MaxCodeLen);
705 
706  // sign bits
707  signPos = AlignWordPos(codePos + RLblockSizeLen); ASSERT(signPos < CodeBufferBitLen);
708 
709  // significant bits
710  sigPos = AlignWordPos(signPos + signLen); ASSERT(sigPos < CodeBufferBitLen);
711 
712  // refinement bits
713  codePos = AlignWordPos(sigPos + sigLen); ASSERT(codePos < CodeBufferBitLen);
714 
715  // read significant and refinement bitset from m_codeBuffer
716  sigLen = ComposeBitplane(bufferSize, planeMask, &m_codeBuffer[sigPos >> WordWidthLog], &m_codeBuffer[codePos >> WordWidthLog], &m_codeBuffer[signPos >> WordWidthLog]);
717  }
718  }
719 
720  // start of next chunk
721  codePos = AlignWordPos(codePos + bufferSize - sigLen); ASSERT(codePos < CodeBufferBitLen);
722 
723  // next plane
724  planeMask >>= 1;
725  }
726 
727  m_valuePos = 0;
728 }
729 
731 // Reconstruct bitplane from significant bitset and refinement bitset
732 // returns length [bits] of sigBits
733 // input: sigBits, refBits, signBits
734 // output: m_value
735 UINT32 CDecoder::CMacroBlock::ComposeBitplane(UINT32 bufferSize, DataT planeMask, UINT32* sigBits, UINT32* refBits, UINT32* signBits) {
736  ASSERT(sigBits);
737  ASSERT(refBits);
738  ASSERT(signBits);
739 
740  UINT32 valPos = 0, signPos = 0, refPos = 0;
741  UINT32 sigPos = 0, sigEnd;
742  UINT32 zerocnt;
743 
744  while (valPos < bufferSize) {
745  // search next 1 in m_sigFlagVector using searching with sentinel
746  sigEnd = valPos;
747  while(!m_sigFlagVector[sigEnd]) { sigEnd++; }
748  sigEnd -= valPos;
749  sigEnd += sigPos;
750 
751  // search 1's in sigBits[sigPos..sigEnd)
752  // these 1's are significant bits
753  while (sigPos < sigEnd) {
754  // search 0's
755  zerocnt = SeekBitRange(sigBits, sigPos, sigEnd - sigPos);
756  sigPos += zerocnt;
757  valPos += zerocnt;
758  if (sigPos < sigEnd) {
759  // write bit to m_value
760  SetBitAtPos(valPos, planeMask);
761 
762  // copy sign bit
763  SetSign(valPos, GetBit(signBits, signPos++));
764 
765  // update significance flag vector
766  m_sigFlagVector[valPos++] = true;
767  sigPos++;
768  }
769  }
770  // refinement bit
771  if (valPos < bufferSize) {
772  // write one refinement bit
773  if (GetBit(refBits, refPos)) {
774  SetBitAtPos(valPos, planeMask);
775  }
776  refPos++;
777  valPos++;
778  }
779  }
780  ASSERT(sigPos <= bufferSize);
781  ASSERT(refPos <= bufferSize);
782  ASSERT(signPos <= bufferSize);
783  ASSERT(valPos == bufferSize);
784 
785  return sigPos;
786 }
787 
789 // Reconstruct bitplane from significant bitset and refinement bitset
790 // returns length [bits] of decoded significant bits
791 // input: RL encoded sigBits and signBits in m_codeBuffer, refBits
792 // output: m_value
793 // RLE:
794 // - Decode run of 2^k zeros by a single 0.
795 // - Decode run of count 0's followed by a 1 with codeword: 1<count>x
796 // - x is 0: if a positive sign has been stored, otherwise 1
797 // - Read each bit from m_codeBuffer[codePos] and increment codePos.
798 UINT32 CDecoder::CMacroBlock::ComposeBitplaneRLD(UINT32 bufferSize, DataT planeMask, UINT32 codePos, UINT32* refBits) {
799  ASSERT(refBits);
800 
801  UINT32 valPos = 0, refPos = 0;
802  UINT32 sigPos = 0, sigEnd;
803  UINT32 k = 3;
804  UINT32 runlen = 1 << k; // = 2^k
805  UINT32 count = 0, rest = 0;
806  bool set1 = false;
807 
808  while (valPos < bufferSize) {
809  // search next 1 in m_sigFlagVector using searching with sentinel
810  sigEnd = valPos;
811  while(!m_sigFlagVector[sigEnd]) { sigEnd++; }
812  sigEnd -= valPos;
813  sigEnd += sigPos;
814 
815  while (sigPos < sigEnd) {
816  if (rest || set1) {
817  // rest of last run
818  sigPos += rest;
819  valPos += rest;
820  rest = 0;
821  } else {
822  // decode significant bits
823  if (GetBit(m_codeBuffer, codePos++)) {
824  // extract counter and generate zero run of length count
825  if (k > 0) {
826  // extract counter
827  count = GetValueBlock(m_codeBuffer, codePos, k);
828  codePos += k;
829  if (count > 0) {
830  sigPos += count;
831  valPos += count;
832  }
833 
834  // adapt k (half run-length interval)
835  k--;
836  runlen >>= 1;
837  }
838 
839  set1 = true;
840 
841  } else {
842  // generate zero run of length 2^k
843  sigPos += runlen;
844  valPos += runlen;
845 
846  // adapt k (double run-length interval)
847  if (k < WordWidth) {
848  k++;
849  runlen <<= 1;
850  }
851  }
852  }
853 
854  if (sigPos < sigEnd) {
855  if (set1) {
856  set1 = false;
857 
858  // write 1 bit
859  SetBitAtPos(valPos, planeMask);
860 
861  // set sign bit
862  SetSign(valPos, GetBit(m_codeBuffer, codePos++));
863 
864  // update significance flag vector
865  m_sigFlagVector[valPos++] = true;
866  sigPos++;
867  }
868  } else {
869  rest = sigPos - sigEnd;
870  sigPos = sigEnd;
871  valPos -= rest;
872  }
873 
874  }
875 
876  // refinement bit
877  if (valPos < bufferSize) {
878  // write one refinement bit
879  if (GetBit(refBits, refPos)) {
880  SetBitAtPos(valPos, planeMask);
881  }
882  refPos++;
883  valPos++;
884  }
885  }
886  ASSERT(sigPos <= bufferSize);
887  ASSERT(refPos <= bufferSize);
888  ASSERT(valPos == bufferSize);
889 
890  return sigPos;
891 }
892 
894 // Reconstruct bitplane from significant bitset, refinement bitset, and RL encoded sign bits
895 // returns length [bits] of sigBits
896 // input: sigBits, refBits, RL encoded signBits
897 // output: m_value
898 // RLE:
899 // decode run of 2^k 1's by a single 1
900 // decode run of count 1's followed by a 0 with codeword: 0<count>
901 UINT32 CDecoder::CMacroBlock::ComposeBitplaneRLD(UINT32 bufferSize, DataT planeMask, UINT32* sigBits, UINT32* refBits, UINT32 signPos) {
902  ASSERT(sigBits);
903  ASSERT(refBits);
904 
905  UINT32 valPos = 0, refPos = 0;
906  UINT32 sigPos = 0, sigEnd;
907  UINT32 zerocnt, count = 0;
908  UINT32 k = 0;
909  UINT32 runlen = 1 << k; // = 2^k
910  bool signBit = false;
911  bool zeroAfterRun = false;
912 
913  while (valPos < bufferSize) {
914  // search next 1 in m_sigFlagVector using searching with sentinel
915  sigEnd = valPos;
916  while(!m_sigFlagVector[sigEnd]) { sigEnd++; }
917  sigEnd -= valPos;
918  sigEnd += sigPos;
919 
920  // search 1's in sigBits[sigPos..sigEnd)
921  // these 1's are significant bits
922  while (sigPos < sigEnd) {
923  // search 0's
924  zerocnt = SeekBitRange(sigBits, sigPos, sigEnd - sigPos);
925  sigPos += zerocnt;
926  valPos += zerocnt;
927  if (sigPos < sigEnd) {
928  // write bit to m_value
929  SetBitAtPos(valPos, planeMask);
930 
931  // check sign bit
932  if (count == 0) {
933  // all 1's have been set
934  if (zeroAfterRun) {
935  // finish the run with a 0
936  signBit = false;
937  zeroAfterRun = false;
938  } else {
939  // decode next sign bit
940  if (GetBit(m_codeBuffer, signPos++)) {
941  // generate 1's run of length 2^k
942  count = runlen - 1;
943  signBit = true;
944 
945  // adapt k (double run-length interval)
946  if (k < WordWidth) {
947  k++;
948  runlen <<= 1;
949  }
950  } else {
951  // extract counter and generate 1's run of length count
952  if (k > 0) {
953  // extract counter
954  count = GetValueBlock(m_codeBuffer, signPos, k);
955  signPos += k;
956 
957  // adapt k (half run-length interval)
958  k--;
959  runlen >>= 1;
960  }
961  if (count > 0) {
962  count--;
963  signBit = true;
964  zeroAfterRun = true;
965  } else {
966  signBit = false;
967  }
968  }
969  }
970  } else {
971  ASSERT(count > 0);
972  ASSERT(signBit);
973  count--;
974  }
975 
976  // copy sign bit
977  SetSign(valPos, signBit);
978 
979  // update significance flag vector
980  m_sigFlagVector[valPos++] = true;
981  sigPos++;
982  }
983  }
984 
985  // refinement bit
986  if (valPos < bufferSize) {
987  // write one refinement bit
988  if (GetBit(refBits, refPos)) {
989  SetBitAtPos(valPos, planeMask);
990  }
991  refPos++;
992  valPos++;
993  }
994  }
995  ASSERT(sigPos <= bufferSize);
996  ASSERT(refPos <= bufferSize);
997  ASSERT(valPos == bufferSize);
998 
999  return sigPos;
1000 }
1001 
1003 #ifdef TRACE
1004 void CDecoder::DumpBuffer() {
1005  //printf("\nDump\n");
1006  //for (int i=0; i < BufferSize; i++) {
1007  // printf("%d", m_value[i]);
1008  //}
1009 }
1010 #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:735
#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:209
Abstract stream base class.
Definition: PGFstream.h:39
void DecodeInterleaved(CWaveletTransform *wtChannel, int level, int quantParam) THROW_
Definition: Decoder.cpp:319
#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:232
#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:80
void ReadMacroBlock(CMacroBlock *block) THROW_
throws IOException
Definition: Decoder.cpp:521
#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:252
#define HeaderSize
Definition: PGFtypes.h:231
~CDecoder()
Destructor.
Definition: Decoder.cpp:217
virtual void SetPos(short posMode, INT64 posOff)=0
PGF pre-header.
Definition: PGFtypes.h:114
#define RLblockSizeLen
block size length (< 16): ld(BufferSize) < RLblockSizeLen <= 2*ld(BufferSize)
Definition: PGFtypes.h:78
Wavelet channel class.
Definition: Subband.h:42
int m_macroBlockLen
array length
Definition: Decoder.h:211
PGF wavelet transform.
DataT m_value[BufferSize]
output buffer of values with index m_valuePos
Definition: Decoder.h:78
void DequantizeValue(CSubband *band, UINT32 bandPos, int quantParam) THROW_
Definition: Decoder.cpp:448
#define PGFMagic
PGF identification.
Definition: PGFtypes.h:55
Block header used with ROI coding scheme.
Definition: PGFtypes.h:151
int GetHeight() const
Definition: Subband.h:122
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:210
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:213
Definition: PGFtypes.h:92
#define WordBytes
sizeof(UINT32)
Definition: PGFplatform.h:76
PGF decoder class.
bool IsCompletelyRead() const
Definition: Decoder.h:69
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:204
int m_macroBlocksAvailable
number of decoded macro blocks (including currently used macro block)
Definition: Decoder.h:212
#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:480
UINT32 ComposeBitplaneRLD(UINT32 bufferSize, DataT planeMask, UINT32 sigPos, UINT32 *refBits)
Definition: Decoder.cpp:798
int GetWidth() const
Definition: Subband.h:127
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:435
PGF exception.
Definition: PGFtypes.h:180
#define CodeBufferBitLen
max number of bits in m_codeBuffer
Definition: Decoder.cpp:58
#define WordWidth
WordBytes*8.
Definition: PGFplatform.h:73