libpgf  7.15.32
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, UINT32 userDataPolicy)
76 : m_stream(stream)
77 , m_startPos(0)
78 , m_streamSizeEstimation(0)
79 , m_encodedHeaderLength(0)
80 , m_currentBlockIndex(0)
81 , m_macroBlocksAvailable(0)
82 #ifdef __PGFROISUPPORT__
83 , m_roi(false)
84 #endif
85 {
86  ASSERT(m_stream);
87 
88  int count, expected;
89 
90  // store current stream position
91  m_startPos = m_stream->GetPos();
92 
93  // read magic and version
94  count = expected = MagicVersionSize;
95  m_stream->Read(&count, &preHeader);
96  if (count != expected) ReturnWithError(MissingData);
97 
98  // read header size
99  if (preHeader.version & Version6) {
100  // 32 bit header size since version 6
101  count = expected = 4;
102  } else {
103  count = expected = 2;
104  }
105  m_stream->Read(&count, ((UINT8*)&preHeader) + MagicVersionSize);
106  if (count != expected) ReturnWithError(MissingData);
107 
108  // make sure the values are correct read
109  preHeader.hSize = __VAL(preHeader.hSize);
110 
111  // check magic number
112  if (memcmp(preHeader.magic, PGFMagic, 3) != 0) {
113  // error condition: wrong Magic number
114  ReturnWithError(FormatCannotRead);
115  }
116 
117  // read file header
118  count = expected = (preHeader.hSize < HeaderSize) ? preHeader.hSize : HeaderSize;
119  m_stream->Read(&count, &header);
120  if (count != expected) ReturnWithError(MissingData);
121 
122  // make sure the values are correct read
123  header.height = __VAL(UINT32(header.height));
124  header.width = __VAL(UINT32(header.width));
125 
126  // be ready to read all versions including version 0
127  if (preHeader.version > 0) {
128 #ifndef __PGFROISUPPORT__
129  // check ROI usage
130  if (preHeader.version & PGFROI) ReturnWithError(FormatCannotRead);
131 #endif
132 
133  UINT32 size = preHeader.hSize;
134 
135  if (size > HeaderSize) {
136  size -= HeaderSize;
137  count = 0;
138 
139  // read post-header
140  if (header.mode == ImageModeIndexedColor) {
141  if (size < ColorTableSize) ReturnWithError(FormatCannotRead);
142  // read color table
143  count = expected = ColorTableSize;
144  m_stream->Read(&count, postHeader.clut);
145  if (count != expected) ReturnWithError(MissingData);
146  }
147 
148  if (size > (UINT32)count) {
149  size -= count;
150 
151  // read/skip user data
152  UserdataPolicy policy = (UserdataPolicy)((userDataPolicy <= MaxUserDataSize) ? UP_CachePrefix : 0xFFFFFFFF - userDataPolicy);
153  userDataPos = m_stream->GetPos();
154  postHeader.userDataLen = size;
155 
156  if (policy == UP_Skip) {
157  postHeader.cachedUserDataLen = 0;
158  postHeader.userData = nullptr;
159  Skip(size);
160  } else {
161  postHeader.cachedUserDataLen = (policy == UP_CachePrefix) ? __min(size, userDataPolicy) : size;
162 
163  // create user data memory block
164  postHeader.userData = new(std::nothrow) UINT8[postHeader.cachedUserDataLen];
165  if (!postHeader.userData) ReturnWithError(InsufficientMemory);
166 
167  // read user data
168  count = expected = postHeader.cachedUserDataLen;
169  m_stream->Read(&count, postHeader.userData);
170  if (count != expected) ReturnWithError(MissingData);
171 
172  // skip remaining user data
173  if (postHeader.cachedUserDataLen < size) Skip(size - postHeader.cachedUserDataLen);
174  }
175  }
176  }
177 
178  // create levelLength
179  levelLength = new(std::nothrow) UINT32[header.nLevels];
180  if (!levelLength) ReturnWithError(InsufficientMemory);
181 
182  // read levelLength
183  count = expected = header.nLevels*WordBytes;
184  m_stream->Read(&count, levelLength);
185  if (count != expected) ReturnWithError(MissingData);
186 
187 #ifdef PGF_USE_BIG_ENDIAN
188  // make sure the values are correct read
189  for (int i=0; i < header.nLevels; i++) {
190  levelLength[i] = __VAL(levelLength[i]);
191  }
192 #endif
193 
194  // compute the total size in bytes; keep attention: level length information is optional
195  for (int i=0; i < header.nLevels; i++) {
196  m_streamSizeEstimation += levelLength[i];
197  }
198 
199  }
200 
201  // store current stream position
202  m_encodedHeaderLength = UINT32(m_stream->GetPos() - m_startPos);
203 
204  // set number of threads
205 #ifdef LIBPGF_USE_OPENMP
206  m_macroBlockLen = omp_get_num_procs();
207 #else
208  m_macroBlockLen = 1;
209 #endif
210 
211  if (useOMP && m_macroBlockLen > 1) {
212 #ifdef LIBPGF_USE_OPENMP
213  omp_set_num_threads(m_macroBlockLen);
214 #endif
215 
216  // create macro block array
217  m_macroBlocks = new(std::nothrow) CMacroBlock*[m_macroBlockLen];
218  if (!m_macroBlocks) ReturnWithError(InsufficientMemory);
219  for (int i = 0; i < m_macroBlockLen; i++) m_macroBlocks[i] = new CMacroBlock();
220  m_currentBlock = m_macroBlocks[m_currentBlockIndex];
221  } else {
222  m_macroBlocks = 0;
223  m_macroBlockLen = 1; // there is only one macro block
224  m_currentBlock = new(std::nothrow) CMacroBlock();
225  if (!m_currentBlock) ReturnWithError(InsufficientMemory);
226  }
227 }
228 
230 // Destructor
232  if (m_macroBlocks) {
233  for (int i=0; i < m_macroBlockLen; i++) delete m_macroBlocks[i];
234  delete[] m_macroBlocks;
235  } else {
236  delete m_currentBlock;
237  }
238 }
239 
246 UINT32 CDecoder::ReadEncodedData(UINT8* target, UINT32 len) const {
247  ASSERT(m_stream);
248 
249  int count = len;
250  m_stream->Read(&count, target);
251 
252  return count;
253 }
254 
266 void CDecoder::Partition(CSubband* band, int quantParam, int width, int height, int startPos, int pitch) {
267  ASSERT(band);
268 
269  const div_t ww = div(width, LinBlockSize);
270  const div_t hh = div(height, LinBlockSize);
271  const int ws = pitch - LinBlockSize;
272  const int wr = pitch - ww.rem;
273  int pos, base = startPos, base2;
274 
275  // main height
276  for (int i=0; i < hh.quot; i++) {
277  // main width
278  base2 = base;
279  for (int j=0; j < ww.quot; j++) {
280  pos = base2;
281  for (int y=0; y < LinBlockSize; y++) {
282  for (int x=0; x < LinBlockSize; x++) {
283  DequantizeValue(band, pos, quantParam);
284  pos++;
285  }
286  pos += ws;
287  }
288  base2 += LinBlockSize;
289  }
290  // rest of width
291  pos = base2;
292  for (int y=0; y < LinBlockSize; y++) {
293  for (int x=0; x < ww.rem; x++) {
294  DequantizeValue(band, pos, quantParam);
295  pos++;
296  }
297  pos += wr;
298  base += pitch;
299  }
300  }
301  // main width
302  base2 = base;
303  for (int j=0; j < ww.quot; j++) {
304  // rest of height
305  pos = base2;
306  for (int y=0; y < hh.rem; y++) {
307  for (int x=0; x < LinBlockSize; x++) {
308  DequantizeValue(band, pos, quantParam);
309  pos++;
310  }
311  pos += ws;
312  }
313  base2 += LinBlockSize;
314  }
315  // rest of height
316  pos = base2;
317  for (int y=0; y < hh.rem; y++) {
318  // rest of width
319  for (int x=0; x < ww.rem; x++) {
320  DequantizeValue(band, pos, quantParam);
321  pos++;
322  }
323  pos += wr;
324  }
325 }
326 
328 // Decodes and dequantizes HL, and LH band of one level
329 // LH and HH are interleaved in the codestream and must be split
330 // Deccoding and dequantization of HL and LH Band (interleaved) using partitioning scheme
331 // partitions the plane in squares of side length InterBlockSize
332 // It might throw an IOException.
333 void CDecoder::DecodeInterleaved(CWaveletTransform* wtChannel, int level, int quantParam) {
334  CSubband* hlBand = wtChannel->GetSubband(level, HL);
335  CSubband* lhBand = wtChannel->GetSubband(level, LH);
336  const div_t lhH = div(lhBand->GetHeight(), InterBlockSize);
337  const div_t hlW = div(hlBand->GetWidth(), InterBlockSize);
338  const int hlws = hlBand->GetWidth() - InterBlockSize;
339  const int hlwr = hlBand->GetWidth() - hlW.rem;
340  const int lhws = lhBand->GetWidth() - InterBlockSize;
341  const int lhwr = lhBand->GetWidth() - hlW.rem;
342  int hlPos, lhPos;
343  int hlBase = 0, lhBase = 0, hlBase2, lhBase2;
344 
345  ASSERT(lhBand->GetWidth() >= hlBand->GetWidth());
346  ASSERT(hlBand->GetHeight() >= lhBand->GetHeight());
347 
348  if (!hlBand->AllocMemory()) ReturnWithError(InsufficientMemory);
349  if (!lhBand->AllocMemory()) ReturnWithError(InsufficientMemory);
350 
351  // correct quantParam with normalization factor
352  quantParam -= level;
353  if (quantParam < 0) quantParam = 0;
354 
355  // main height
356  for (int i=0; i < lhH.quot; i++) {
357  // main width
358  hlBase2 = hlBase;
359  lhBase2 = lhBase;
360  for (int j=0; j < hlW.quot; j++) {
361  hlPos = hlBase2;
362  lhPos = lhBase2;
363  for (int y=0; y < InterBlockSize; y++) {
364  for (int x=0; x < InterBlockSize; x++) {
365  DequantizeValue(hlBand, hlPos, quantParam);
366  DequantizeValue(lhBand, lhPos, quantParam);
367  hlPos++;
368  lhPos++;
369  }
370  hlPos += hlws;
371  lhPos += lhws;
372  }
373  hlBase2 += InterBlockSize;
374  lhBase2 += InterBlockSize;
375  }
376  // rest of width
377  hlPos = hlBase2;
378  lhPos = lhBase2;
379  for (int y=0; y < InterBlockSize; y++) {
380  for (int x=0; x < hlW.rem; x++) {
381  DequantizeValue(hlBand, hlPos, quantParam);
382  DequantizeValue(lhBand, lhPos, quantParam);
383  hlPos++;
384  lhPos++;
385  }
386  // width difference between HL and LH
387  if (lhBand->GetWidth() > hlBand->GetWidth()) {
388  DequantizeValue(lhBand, lhPos, quantParam);
389  }
390  hlPos += hlwr;
391  lhPos += lhwr;
392  hlBase += hlBand->GetWidth();
393  lhBase += lhBand->GetWidth();
394  }
395  }
396  // main width
397  hlBase2 = hlBase;
398  lhBase2 = lhBase;
399  for (int j=0; j < hlW.quot; j++) {
400  // rest of height
401  hlPos = hlBase2;
402  lhPos = lhBase2;
403  for (int y=0; y < lhH.rem; y++) {
404  for (int x=0; x < InterBlockSize; x++) {
405  DequantizeValue(hlBand, hlPos, quantParam);
406  DequantizeValue(lhBand, lhPos, quantParam);
407  hlPos++;
408  lhPos++;
409  }
410  hlPos += hlws;
411  lhPos += lhws;
412  }
413  hlBase2 += InterBlockSize;
414  lhBase2 += InterBlockSize;
415  }
416  // rest of height
417  hlPos = hlBase2;
418  lhPos = lhBase2;
419  for (int y=0; y < lhH.rem; y++) {
420  // rest of width
421  for (int x=0; x < hlW.rem; x++) {
422  DequantizeValue(hlBand, hlPos, quantParam);
423  DequantizeValue(lhBand, lhPos, quantParam);
424  hlPos++;
425  lhPos++;
426  }
427  // width difference between HL and LH
428  if (lhBand->GetWidth() > hlBand->GetWidth()) {
429  DequantizeValue(lhBand, lhPos, quantParam);
430  }
431  hlPos += hlwr;
432  lhPos += lhwr;
433  hlBase += hlBand->GetWidth();
434  }
435  // height difference between HL and LH
436  if (hlBand->GetHeight() > lhBand->GetHeight()) {
437  // total width
438  hlPos = hlBase;
439  for (int j=0; j < hlBand->GetWidth(); j++) {
440  DequantizeValue(hlBand, hlPos, quantParam);
441  hlPos++;
442  }
443  }
444 }
445 
449 void CDecoder::Skip(UINT64 offset) {
450  m_stream->SetPos(FSFromCurrent, offset);
451 }
452 
462 void CDecoder::DequantizeValue(CSubband* band, UINT32 bandPos, int quantParam) {
463  ASSERT(m_currentBlock);
464 
466  // all data of current macro block has been read --> prepare next macro block
468  }
469 
470  band->SetData(bandPos, m_currentBlock->m_value[m_currentBlock->m_valuePos] << quantParam);
472 }
473 
475 // Gets next macro block
476 // It might throw an IOException.
478  // current block has been read --> prepare next current block
480 
481  if (m_macroBlocksAvailable > 0) {
483  } else {
484  DecodeBuffer();
485  }
486  ASSERT(m_currentBlock);
487 }
488 
490 // Reads next block(s) from stream and decodes them
491 // Decoding scheme: <wordLen>(16 bits) [ ROI ] data
492 // ROI ::= <bufferSize>(15 bits) <eofTile>(1 bit)
493 // It might throw an IOException.
495  ASSERT(m_macroBlocksAvailable <= 0);
496 
497  // macro block management
498  if (m_macroBlockLen == 1) {
499  ASSERT(m_currentBlock);
503  } else {
505  for (int i=0; i < m_macroBlockLen; i++) {
506  // read sequentially several blocks
507  try {
510  } catch(IOException& ex) {
511  if (ex.error == MissingData || ex.error == FormatCannotRead) {
512  break; // no further data available or the data isn't valid PGF data (might occur in streaming or PPPExt)
513  } else {
514  throw;
515  }
516  }
517  }
518 #ifdef LIBPGF_USE_OPENMP
519  // decode in parallel
520  #pragma omp parallel for default(shared) //no declared exceptions in next block
521 #endif
522  for (int i=0; i < m_macroBlocksAvailable; i++) {
524  }
525 
526  // prepare current macro block
529  }
530 }
531 
533 // Reads next block from stream and stores it in the given macro block
534 // It might throw an IOException.
536  ASSERT(block);
537 
538  UINT16 wordLen;
540  int count, expected;
541 
542 #ifdef TRACE
543  //UINT32 filePos = (UINT32)m_stream->GetPos();
544  //printf("DecodeBuffer: %d\n", filePos);
545 #endif
546 
547  // read wordLen
548  count = expected = sizeof(UINT16);
549  m_stream->Read(&count, &wordLen);
550  if (count != expected) ReturnWithError(MissingData);
551  wordLen = __VAL(wordLen); // convert wordLen
552  if (wordLen > BufferSize) ReturnWithError(FormatCannotRead);
553 
554 #ifdef __PGFROISUPPORT__
555  // read ROIBlockHeader
556  if (m_roi) {
557  count = expected = sizeof(ROIBlockHeader);
558  m_stream->Read(&count, &h.val);
559  if (count != expected) ReturnWithError(MissingData);
560  h.val = __VAL(h.val); // convert ROIBlockHeader
561  }
562 #endif
563  // save header
564  block->m_header = h;
565 
566  // read data
567  count = expected = wordLen*WordBytes;
568  m_stream->Read(&count, block->m_codeBuffer);
569  if (count != expected) ReturnWithError(MissingData);
570 
571 #ifdef PGF_USE_BIG_ENDIAN
572  // convert data
573  count /= WordBytes;
574  for (int i=0; i < count; i++) {
575  block->m_codeBuffer[i] = __VAL(block->m_codeBuffer[i]);
576  }
577 #endif
578 
579 #ifdef __PGFROISUPPORT__
580  ASSERT(m_roi && h.rbh.bufferSize <= BufferSize || h.rbh.bufferSize == BufferSize);
581 #else
582  ASSERT(h.rbh.bufferSize == BufferSize);
583 #endif
584 }
585 
586 #ifdef __PGFROISUPPORT__
587 // Resets stream position to next tile.
589 // Used with ROI encoding scheme only.
590 // Reads several next blocks from stream but doesn't decode them into macro blocks
591 // Encoding scheme: <wordLen>(16 bits) ROI data
592 // ROI ::= <bufferSize>(15 bits) <eofTile>(1 bit)
593 // It might throw an IOException.
594 void CDecoder::SkipTileBuffer() {
595  ASSERT(m_roi);
596 
597  // current macro block belongs to the last tile, so go to the next macro block
600 
601  // check if pre-decoded data is available
602  while (m_macroBlocksAvailable > 0 && !m_macroBlocks[m_currentBlockIndex]->m_header.rbh.tileEnd) {
605  }
606  if (m_macroBlocksAvailable > 0) {
607  // set new current macro block
610  return;
611  }
612 
613  ASSERT(m_macroBlocksAvailable <= 0);
615  UINT16 wordLen;
616  ROIBlockHeader h(0);
617  int count, expected;
618 
619  // skips all blocks until tile end
620  do {
621  // read wordLen
622  count = expected = sizeof(wordLen);
623  m_stream->Read(&count, &wordLen);
624  if (count != expected) ReturnWithError(MissingData);
625  wordLen = __VAL(wordLen); // convert wordLen
626  if (wordLen > BufferSize) ReturnWithError(FormatCannotRead);
627 
628  // read ROIBlockHeader
629  count = expected = sizeof(ROIBlockHeader);
630  m_stream->Read(&count, &h.val);
631  if (count != expected) ReturnWithError(MissingData);
632  h.val = __VAL(h.val); // convert ROIBlockHeader
633 
634  // skip data
635  m_stream->SetPos(FSFromCurrent, wordLen*WordBytes);
636  } while (!h.rbh.tileEnd);
637 }
638 #endif
639 
641 // Decodes macro block into buffer of given size using bit plane coding.
642 // A buffer contains bufferLen UINT32 values, thus, bufferSize bits per bit plane.
643 // Following coding scheme is used:
644 // Buffer ::= <nPlanes>(5 bits) foreach(plane i): Plane[i]
645 // Plane[i] ::= [ Sig1 | Sig2 ] [DWORD alignment] refBits
646 // Sig1 ::= 1 <codeLen>(15 bits) codedSigAndSignBits
647 // Sig2 ::= 0 <sigLen>(15 bits) [Sign1 | Sign2 ] [DWORD alignment] sigBits
648 // Sign1 ::= 1 <codeLen>(15 bits) codedSignBits
649 // Sign2 ::= 0 <signLen>(15 bits) [DWORD alignment] signBits
651  UINT32 bufferSize = m_header.rbh.bufferSize; ASSERT(bufferSize <= BufferSize);
652 
653  // clear significance vector
654  for (UINT32 k=0; k < bufferSize; k++) {
655  m_sigFlagVector[k] = false;
656  }
657  m_sigFlagVector[bufferSize] = true; // sentinel
658 
659  // clear output buffer
660  for (UINT32 k=0; k < BufferSize; k++) {
661  m_value[k] = 0;
662  }
663 
664  // read number of bit planes
665  // <nPlanes>
666  UINT32 nPlanes = GetValueBlock(m_codeBuffer, 0, MaxBitPlanesLog);
667  UINT32 codePos = MaxBitPlanesLog;
668 
669  // loop through all bit planes
670  if (nPlanes == 0) nPlanes = MaxBitPlanes + 1;
671  ASSERT(0 < nPlanes && nPlanes <= MaxBitPlanes + 1);
672  DataT planeMask = 1 << (nPlanes - 1);
673 
674  for (int plane = nPlanes - 1; plane >= 0; plane--) {
675  UINT32 sigLen = 0;
676 
677  // read RL code
678  if (GetBit(m_codeBuffer, codePos)) {
679  // RL coding of sigBits is used
680  // <1><codeLen><codedSigAndSignBits>_<refBits>
681  codePos++;
682 
683  // read codeLen
684  UINT32 codeLen = GetValueBlock(m_codeBuffer, codePos, RLblockSizeLen); ASSERT(codeLen <= MaxCodeLen);
685 
686  // position of encoded sigBits and signBits
687  UINT32 sigPos = codePos + RLblockSizeLen; ASSERT(sigPos < CodeBufferBitLen);
688 
689  // refinement bits
690  codePos = AlignWordPos(sigPos + codeLen); ASSERT(codePos < CodeBufferBitLen);
691 
692  // run-length decode significant bits and signs from m_codeBuffer and
693  // read refinement bits from m_codeBuffer and compose bit plane
694  sigLen = ComposeBitplaneRLD(bufferSize, planeMask, sigPos, &m_codeBuffer[codePos >> WordWidthLog]);
695 
696  } else {
697  // no RL coding is used for sigBits and signBits together
698  // <0><sigLen>
699  codePos++;
700 
701  // read sigLen
702  sigLen = GetValueBlock(m_codeBuffer, codePos, RLblockSizeLen); ASSERT(sigLen <= MaxCodeLen);
703  codePos += RLblockSizeLen; ASSERT(codePos < CodeBufferBitLen);
704 
705  // read RL code for signBits
706  if (GetBit(m_codeBuffer, codePos)) {
707  // RL coding is used just for signBits
708  // <1><codeLen><codedSignBits>_<sigBits>_<refBits>
709  codePos++;
710 
711  // read codeLen
712  UINT32 codeLen = GetValueBlock(m_codeBuffer, codePos, RLblockSizeLen); ASSERT(codeLen <= MaxCodeLen);
713 
714  // sign bits
715  UINT32 signPos = codePos + RLblockSizeLen; ASSERT(signPos < CodeBufferBitLen);
716 
717  // significant bits
718  UINT32 sigPos = AlignWordPos(signPos + codeLen); ASSERT(sigPos < CodeBufferBitLen);
719 
720  // refinement bits
721  codePos = AlignWordPos(sigPos + sigLen); ASSERT(codePos < CodeBufferBitLen);
722 
723  // read significant and refinement bitset from m_codeBuffer
724  sigLen = ComposeBitplaneRLD(bufferSize, planeMask, &m_codeBuffer[sigPos >> WordWidthLog], &m_codeBuffer[codePos >> WordWidthLog], signPos);
725 
726  } else {
727  // RL coding of signBits was not efficient and therefore not used
728  // <0><signLen>_<signBits>_<sigBits>_<refBits>
729  codePos++;
730 
731  // read signLen
732  UINT32 signLen = GetValueBlock(m_codeBuffer, codePos, RLblockSizeLen); ASSERT(signLen <= MaxCodeLen);
733 
734  // sign bits
735  UINT32 signPos = AlignWordPos(codePos + RLblockSizeLen); ASSERT(signPos < CodeBufferBitLen);
736 
737  // significant bits
738  UINT32 sigPos = AlignWordPos(signPos + signLen); ASSERT(sigPos < CodeBufferBitLen);
739 
740  // refinement bits
741  codePos = AlignWordPos(sigPos + sigLen); ASSERT(codePos < CodeBufferBitLen);
742 
743  // read significant and refinement bitset from m_codeBuffer
744  sigLen = ComposeBitplane(bufferSize, planeMask, &m_codeBuffer[sigPos >> WordWidthLog], &m_codeBuffer[codePos >> WordWidthLog], &m_codeBuffer[signPos >> WordWidthLog]);
745  }
746  }
747 
748  // start of next chunk
749  codePos = AlignWordPos(codePos + bufferSize - sigLen); ASSERT(codePos < CodeBufferBitLen);
750 
751  // next plane
752  planeMask >>= 1;
753  }
754 
755  m_valuePos = 0;
756 }
757 
759 // Reconstructs bitplane from significant bitset and refinement bitset
760 // returns length [bits] of sigBits
761 // input: sigBits, refBits, signBits
762 // output: m_value
763 UINT32 CDecoder::CMacroBlock::ComposeBitplane(UINT32 bufferSize, DataT planeMask, UINT32* sigBits, UINT32* refBits, UINT32* signBits) {
764  ASSERT(sigBits);
765  ASSERT(refBits);
766  ASSERT(signBits);
767 
768  UINT32 valPos = 0, signPos = 0, refPos = 0, sigPos = 0;
769 
770  while (valPos < bufferSize) {
771  // search next 1 in m_sigFlagVector using searching with sentinel
772  UINT32 sigEnd = valPos;
773  while(!m_sigFlagVector[sigEnd]) { sigEnd++; }
774  sigEnd -= valPos;
775  sigEnd += sigPos;
776 
777  // search 1's in sigBits[sigPos..sigEnd)
778  // these 1's are significant bits
779  while (sigPos < sigEnd) {
780  // search 0's
781  UINT32 zerocnt = SeekBitRange(sigBits, sigPos, sigEnd - sigPos);
782  sigPos += zerocnt;
783  valPos += zerocnt;
784  if (sigPos < sigEnd) {
785  // write bit to m_value
786  SetBitAtPos(valPos, planeMask);
787 
788  // copy sign bit
789  SetSign(valPos, GetBit(signBits, signPos++));
790 
791  // update significance flag vector
792  m_sigFlagVector[valPos++] = true;
793  sigPos++;
794  }
795  }
796  // refinement bit
797  if (valPos < bufferSize) {
798  // write one refinement bit
799  if (GetBit(refBits, refPos)) {
800  SetBitAtPos(valPos, planeMask);
801  }
802  refPos++;
803  valPos++;
804  }
805  }
806  ASSERT(sigPos <= bufferSize);
807  ASSERT(refPos <= bufferSize);
808  ASSERT(signPos <= bufferSize);
809  ASSERT(valPos == bufferSize);
810 
811  return sigPos;
812 }
813 
815 // Reconstructs bitplane from significant bitset and refinement bitset
816 // returns length [bits] of decoded significant bits
817 // input: RL encoded sigBits and signBits in m_codeBuffer, refBits
818 // output: m_value
819 // RLE:
820 // - Decode run of 2^k zeros by a single 0.
821 // - Decode run of count 0's followed by a 1 with codeword: 1<count>x
822 // - x is 0: if a positive sign has been stored, otherwise 1
823 // - Read each bit from m_codeBuffer[codePos] and increment codePos.
824 UINT32 CDecoder::CMacroBlock::ComposeBitplaneRLD(UINT32 bufferSize, DataT planeMask, UINT32 codePos, UINT32* refBits) {
825  ASSERT(refBits);
826 
827  UINT32 valPos = 0, refPos = 0;
828  UINT32 sigPos = 0, sigEnd;
829  UINT32 k = 3;
830  UINT32 runlen = 1 << k; // = 2^k
831  UINT32 count = 0, rest = 0;
832  bool set1 = false;
833 
834  while (valPos < bufferSize) {
835  // search next 1 in m_sigFlagVector using searching with sentinel
836  sigEnd = valPos;
837  while(!m_sigFlagVector[sigEnd]) { sigEnd++; }
838  sigEnd -= valPos;
839  sigEnd += sigPos;
840 
841  while (sigPos < sigEnd) {
842  if (rest || set1) {
843  // rest of last run
844  sigPos += rest;
845  valPos += rest;
846  rest = 0;
847  } else {
848  // decode significant bits
849  if (GetBit(m_codeBuffer, codePos++)) {
850  // extract counter and generate zero run of length count
851  if (k > 0) {
852  // extract counter
853  count = GetValueBlock(m_codeBuffer, codePos, k);
854  codePos += k;
855  if (count > 0) {
856  sigPos += count;
857  valPos += count;
858  }
859 
860  // adapt k (half run-length interval)
861  k--;
862  runlen >>= 1;
863  }
864 
865  set1 = true;
866 
867  } else {
868  // generate zero run of length 2^k
869  sigPos += runlen;
870  valPos += runlen;
871 
872  // adapt k (double run-length interval)
873  if (k < WordWidth) {
874  k++;
875  runlen <<= 1;
876  }
877  }
878  }
879 
880  if (sigPos < sigEnd) {
881  if (set1) {
882  set1 = false;
883 
884  // write 1 bit
885  SetBitAtPos(valPos, planeMask);
886 
887  // set sign bit
888  SetSign(valPos, GetBit(m_codeBuffer, codePos++));
889 
890  // update significance flag vector
891  m_sigFlagVector[valPos++] = true;
892  sigPos++;
893  }
894  } else {
895  rest = sigPos - sigEnd;
896  sigPos = sigEnd;
897  valPos -= rest;
898  }
899 
900  }
901 
902  // refinement bit
903  if (valPos < bufferSize) {
904  // write one refinement bit
905  if (GetBit(refBits, refPos)) {
906  SetBitAtPos(valPos, planeMask);
907  }
908  refPos++;
909  valPos++;
910  }
911  }
912  ASSERT(sigPos <= bufferSize);
913  ASSERT(refPos <= bufferSize);
914  ASSERT(valPos == bufferSize);
915 
916  return sigPos;
917 }
918 
920 // Reconstructs bitplane from significant bitset, refinement bitset, and RL encoded sign bits
921 // returns length [bits] of sigBits
922 // input: sigBits, refBits, RL encoded signBits
923 // output: m_value
924 // RLE:
925 // decode run of 2^k 1's by a single 1
926 // decode run of count 1's followed by a 0 with codeword: 0<count>
927 UINT32 CDecoder::CMacroBlock::ComposeBitplaneRLD(UINT32 bufferSize, DataT planeMask, UINT32* sigBits, UINT32* refBits, UINT32 signPos) {
928  ASSERT(sigBits);
929  ASSERT(refBits);
930 
931  UINT32 valPos = 0, refPos = 0;
932  UINT32 sigPos = 0, sigEnd;
933  UINT32 zerocnt, count = 0;
934  UINT32 k = 0;
935  UINT32 runlen = 1 << k; // = 2^k
936  bool signBit = false;
937  bool zeroAfterRun = false;
938 
939  while (valPos < bufferSize) {
940  // search next 1 in m_sigFlagVector using searching with sentinel
941  sigEnd = valPos;
942  while(!m_sigFlagVector[sigEnd]) { sigEnd++; }
943  sigEnd -= valPos;
944  sigEnd += sigPos;
945 
946  // search 1's in sigBits[sigPos..sigEnd)
947  // these 1's are significant bits
948  while (sigPos < sigEnd) {
949  // search 0's
950  zerocnt = SeekBitRange(sigBits, sigPos, sigEnd - sigPos);
951  sigPos += zerocnt;
952  valPos += zerocnt;
953  if (sigPos < sigEnd) {
954  // write bit to m_value
955  SetBitAtPos(valPos, planeMask);
956 
957  // check sign bit
958  if (count == 0) {
959  // all 1's have been set
960  if (zeroAfterRun) {
961  // finish the run with a 0
962  signBit = false;
963  zeroAfterRun = false;
964  } else {
965  // decode next sign bit
966  if (GetBit(m_codeBuffer, signPos++)) {
967  // generate 1's run of length 2^k
968  count = runlen - 1;
969  signBit = true;
970 
971  // adapt k (double run-length interval)
972  if (k < WordWidth) {
973  k++;
974  runlen <<= 1;
975  }
976  } else {
977  // extract counter and generate 1's run of length count
978  if (k > 0) {
979  // extract counter
980  count = GetValueBlock(m_codeBuffer, signPos, k);
981  signPos += k;
982 
983  // adapt k (half run-length interval)
984  k--;
985  runlen >>= 1;
986  }
987  if (count > 0) {
988  count--;
989  signBit = true;
990  zeroAfterRun = true;
991  } else {
992  signBit = false;
993  }
994  }
995  }
996  } else {
997  ASSERT(count > 0);
998  ASSERT(signBit);
999  count--;
1000  }
1001 
1002  // copy sign bit
1003  SetSign(valPos, signBit);
1004 
1005  // update significance flag vector
1006  m_sigFlagVector[valPos++] = true;
1007  sigPos++;
1008  }
1009  }
1010 
1011  // refinement bit
1012  if (valPos < bufferSize) {
1013  // write one refinement bit
1014  if (GetBit(refBits, refPos)) {
1015  SetBitAtPos(valPos, planeMask);
1016  }
1017  refPos++;
1018  valPos++;
1019  }
1020  }
1021  ASSERT(sigPos <= bufferSize);
1022  ASSERT(refPos <= bufferSize);
1023  ASSERT(valPos == bufferSize);
1024 
1025  return sigPos;
1026 }
1027 
1029 #ifdef TRACE
1030 void CDecoder::DumpBuffer() {
1031  //printf("\nDump\n");
1032  //for (int i=0; i < BufferSize; i++) {
1033  // printf("%d", m_value[i]);
1034  //}
1035 }
1036 #endif //TRACE
bool GetBit(UINT32 *stream, UINT32 pos)
Definition: BitStream.h:79
#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:195
UINT8 version
PGF version.
Definition: PGFtypes.h:115
UINT32 ComposeBitplane(UINT32 bufferSize, DataT planeMask, UINT32 *sigBits, UINT32 *refBits, UINT32 *signBits)
Definition: Decoder.cpp:763
UINT8 mode
image mode according to Adobe&#39;s image modes
Definition: PGFtypes.h:158
#define MaxCodeLen
max length of RL encoded block
Definition: Decoder.cpp:59
UINT32 AlignWordPos(UINT32 pos)
Definition: BitStream.h:328
CMacroBlock ** m_macroBlocks
array of macroblocks
Definition: Decoder.h:205
Abstract stream base class.
Definition: PGFstream.h:39
UINT32 width
image width in pixels
Definition: PGFtypes.h:152
#define LinBlockSize
side length of a coefficient block in a HH or LL subband
Definition: PGFtypes.h:86
#define ColorTableSize
Definition: PGFtypes.h:275
INT32 DataT
Definition: PGFtypes.h:262
#define __VAL(x)
Definition: PGFplatform.h:601
UINT32 userDataLen
user data size in bytes (not part of file header)
Definition: PGFtypes.h:171
UINT16 tileEnd
1: last part of a tile
Definition: PGFtypes.h:196
UINT8 * userData
user data of size userDataLen (optional part of file header)
Definition: PGFtypes.h:170
bool AllocMemory()
Definition: Subband.cpp:77
UINT32 m_valuePos
current position in m_value
Definition: Decoder.h:79
void DecodeInterleaved(CWaveletTransform *wtChannel, int level, int quantParam)
Definition: Decoder.cpp:333
#define BufferSize
must be a multiple of WordWidth, BufferSize <= UINT16_MAX
Definition: PGFtypes.h:84
#define HeaderSize
Definition: PGFtypes.h:274
~CDecoder()
Destructor.
Definition: Decoder.cpp:231
virtual void SetPos(short posMode, INT64 posOff)=0
PGF pre-header.
Definition: PGFtypes.h:123
UINT8 nLevels
number of FWT transforms
Definition: PGFtypes.h:154
#define RLblockSizeLen
block size length (< 16): ld(BufferSize) < RLblockSizeLen <= 2*ld(BufferSize)
Definition: PGFtypes.h:85
Wavelet channel class.
Definition: Subband.h:42
void DecodeBuffer()
Definition: Decoder.cpp:494
int m_macroBlockLen
array length
Definition: Decoder.h:207
void Partition(CSubband *band, int quantParam, int width, int height, int startPos, int pitch)
Definition: Decoder.cpp:266
PGF wavelet transform.
DataT m_value[BufferSize]
output buffer of values with index m_valuePos
Definition: Decoder.h:77
#define PGFMagic
PGF identification.
Definition: PGFtypes.h:61
Block header used with ROI coding scheme.
Definition: PGFtypes.h:179
int GetHeight() const
Definition: Subband.h:123
PGF header.
Definition: PGFtypes.h:150
#define WordWidthLog
ld of WordWidth
Definition: PGFplatform.h:74
#define Version6
hSize in PGFPreHeader uses 32 bits instead of 16 bits
Definition: PGFtypes.h:72
UINT32 cachedUserDataLen
cached user data size in bytes (not part of file header)
Definition: PGFtypes.h:172
int m_currentBlockIndex
index of current macro block
Definition: Decoder.h:206
UINT32 SeekBitRange(UINT32 *stream, UINT32 pos, UINT32 len)
Definition: BitStream.h:220
#define MaxBitPlanesLog
number of bits to code the maximum number of bit planes (in 32 or 16 bit mode)
Definition: PGFtypes.h:93
CMacroBlock * m_currentBlock
current macro block (used by main thread)
Definition: Decoder.h:209
#define __PGFROISUPPORT__
Definition: PGFplatform.h:60
Definition: PGFtypes.h:99
#define WordBytes
sizeof(UINT32)
Definition: PGFplatform.h:76
PGF decoder class.
bool IsCompletelyRead() const
Definition: Decoder.h:68
Definition: PGFtypes.h:99
CSubband * GetSubband(int level, Orientation orientation)
A macro block is a decoding unit of fixed size (uncoded)
Definition: Decoder.h:51
Optional PGF post-header.
Definition: PGFtypes.h:168
#define __min(x, y)
Definition: PGFplatform.h:91
CPGFStream * m_stream
input PGF stream
Definition: Decoder.h:200
void Skip(UINT64 offset)
Definition: Decoder.cpp:449
int m_macroBlocksAvailable
number of decoded macro blocks (including currently used macro block)
Definition: Decoder.h:208
void GetNextMacroBlock()
Definition: Decoder.cpp:477
#define PGFROI
supports Regions Of Interest
Definition: PGFtypes.h:70
UserdataPolicy
Definition: PGFtypes.h:101
UINT16 val
Definition: PGFtypes.h:188
UINT32 GetValueBlock(UINT32 *stream, UINT32 pos, UINT32 k)
Definition: BitStream.h:142
#define MaxBitPlanes
maximum number of bit planes of m_value: 32 minus sign bit
Definition: PGFtypes.h:89
#define InterBlockSize
side length of a coefficient block in a HL or LH subband
Definition: PGFtypes.h:87
UINT32 ReadEncodedData(UINT8 *target, UINT32 len) const
Definition: Decoder.cpp:246
OSError error
operating system error code
Definition: PGFtypes.h:215
#define MagicVersionSize
Definition: PGFtypes.h:272
void ReadMacroBlock(CMacroBlock *block)
throws IOException
Definition: Decoder.cpp:535
CDecoder(CPGFStream *stream, PGFPreHeader &preHeader, PGFHeader &header, PGFPostHeader &postHeader, UINT32 *&levelLength, UINT64 &userDataPos, bool useOMP, UINT32 userDataPolicy)
Definition: Decoder.cpp:73
UINT32 ComposeBitplaneRLD(UINT32 bufferSize, DataT planeMask, UINT32 sigPos, UINT32 *refBits)
Definition: Decoder.cpp:824
int GetWidth() const
Definition: Subband.h:128
#define MaxUserDataSize
Definition: PGFtypes.h:277
void DequantizeValue(CSubband *band, UINT32 bandPos, int quantParam)
Definition: Decoder.cpp:462
PGF exception.
Definition: PGFtypes.h:208
UINT32 height
image height in pixels
Definition: PGFtypes.h:153
RGBQUAD clut[ColorTableLen]
color table for indexed color images (optional part of file header)
Definition: PGFtypes.h:169
ROIBlockHeader m_header
block header
Definition: Decoder.h:76
void SetData(UINT32 pos, DataT v)
Definition: Subband.h:102
#define CodeBufferBitLen
max number of bits in m_codeBuffer
Definition: Decoder.cpp:58
bool m_sigFlagVector[BufferSize+1]
Definition: Decoder.h:88
#define WordWidth
WordBytes*8.
Definition: PGFplatform.h:73
UINT32 m_codeBuffer[CodeBufferLen]
input buffer for encoded bitstream
Definition: Decoder.h:78