libpgf 6.14.12
PGF - Progressive Graphics File
Loading...
Searching...
No Matches
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
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
232UINT32 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
252void 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.
319void 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
435void CDecoder::Skip(UINT64 offset) THROW_ {
436 m_stream->SetPos(FSFromCurrent, offset);
437}
438
448void CDecoder::DequantizeValue(CSubband* band, UINT32 bandPos, int quantParam) THROW_ {
449 ASSERT(m_currentBlock);
450
451 if (m_currentBlock->IsCompletelyRead()) {
452 // all data of current macro block has been read --> prepare next macro block
453 DecodeTileBuffer();
454 }
455
456 band->SetData(bandPos, m_currentBlock->m_value[m_currentBlock->m_valuePos] << quantParam);
457 m_currentBlock->m_valuePos++;
458}
459
461// Read next group of blocks from stream and decodes them into macro blocks
462// It might throw an IOException.
463void 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.
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.
579void 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>
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
735UINT32 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.
798UINT32 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>
901UINT32 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
1004void 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
UINT32 AlignWordPos(UINT32 pos)
Definition: BitStream.h:260
bool GetBit(UINT32 *stream, UINT32 pos)
Definition: BitStream.h:65
UINT32 GetValueBlock(UINT32 *stream, UINT32 pos, UINT32 k)
Definition: BitStream.h:128
UINT32 SeekBitRange(UINT32 *stream, UINT32 pos, UINT32 len)
Definition: BitStream.h:206
#define CodeBufferBitLen
max number of bits in m_codeBuffer
Definition: Decoder.cpp:58
#define MaxCodeLen
max length of RL encoded block
Definition: Decoder.cpp:59
PGF decoder class.
#define WordWidthLog
ld of WordWidth
Definition: PGFplatform.h:74
#define __VAL(x)
Definition: PGFplatform.h:604
#define WordBytes
sizeof(UINT32)
Definition: PGFplatform.h:76
#define WordWidth
WordBytes*8.
Definition: PGFplatform.h:73
#define ImageModeIndexedColor
Definition: PGFplatform.h:100
#define MaxBitPlanesLog
number of bits to code the maximum number of bit planes (in 32 or 16 bit mode)
Definition: PGFtypes.h:86
#define PGFROI
supports Regions Of Interest
Definition: PGFtypes.h:64
#define InterBlockSize
side length of a coefficient block in a HL or LH subband
Definition: PGFtypes.h:80
#define HeaderSize
Definition: PGFtypes.h:231
#define ColorTableSize
Definition: PGFtypes.h:232
#define LinBlockSize
side length of a coefficient block in a HH or LL subband
Definition: PGFtypes.h:79
#define PGFMagic
PGF identification.
Definition: PGFtypes.h:55
#define MagicVersionSize
Definition: PGFtypes.h:229
@ HL
Definition: PGFtypes.h:92
@ LH
Definition: PGFtypes.h:92
#define BufferSize
must be a multiple of WordWidth
Definition: PGFtypes.h:77
#define Version6
new HeaderSize: 32 bits instead of 16 bits
Definition: PGFtypes.h:66
#define RLblockSizeLen
block size length (< 16): ld(BufferSize) < RLblockSizeLen <= 2*ld(BufferSize)
Definition: PGFtypes.h:78
INT32 DataT
Definition: PGFtypes.h:219
#define MaxBitPlanes
maximum number of bit planes of m_value: 32 minus sign bit
Definition: PGFtypes.h:82
A macro block is a decoding unit of fixed size (uncoded)
Definition: Decoder.h:51
ROIBlockHeader m_header
block header
Definition: Decoder.h:77
UINT32 m_valuePos
current position in m_value
Definition: Decoder.h:80
UINT32 ComposeBitplane(UINT32 bufferSize, DataT planeMask, UINT32 *sigBits, UINT32 *refBits, UINT32 *signBits)
Definition: Decoder.cpp:735
DataT m_value[BufferSize]
output buffer of values with index m_valuePos
Definition: Decoder.h:78
UINT32 ComposeBitplaneRLD(UINT32 bufferSize, DataT planeMask, UINT32 sigPos, UINT32 *refBits)
Definition: Decoder.cpp:798
UINT32 m_codeBuffer[CodeBufferLen]
input buffer for encoded bitstream
Definition: Decoder.h:79
bool m_sigFlagVector[BufferSize+1]
Definition: Decoder.h:89
int m_macroBlockLen
array length
Definition: Decoder.h:211
int m_currentBlockIndex
index of current macro block
Definition: Decoder.h:210
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
void DecodeInterleaved(CWaveletTransform *wtChannel, int level, int quantParam) THROW_
Definition: Decoder.cpp:319
void ReadMacroBlock(CMacroBlock *block) THROW_
throws IOException
Definition: Decoder.cpp:521
void DecodeBuffer() THROW_
Definition: Decoder.cpp:480
CMacroBlock ** m_macroBlocks
array of macroblocks
Definition: Decoder.h:209
UINT32 ReadEncodedData(UINT8 *target, UINT32 len) const THROW_
Definition: Decoder.cpp:232
CMacroBlock * m_currentBlock
current macro block (used by main thread)
Definition: Decoder.h:213
void Partition(CSubband *band, int quantParam, int width, int height, int startPos, int pitch) THROW_
Definition: Decoder.cpp:252
void Skip(UINT64 offset) THROW_
Definition: Decoder.cpp:435
~CDecoder()
Destructor.
Definition: Decoder.cpp:217
CDecoder(CPGFStream *stream, PGFPreHeader &preHeader, PGFHeader &header, PGFPostHeader &postHeader, UINT32 *&levelLength, UINT64 &userDataPos, bool useOMP, bool skipUserData) THROW_
Definition: Decoder.cpp:73
void DequantizeValue(CSubband *band, UINT32 bandPos, int quantParam) THROW_
Definition: Decoder.cpp:448
Abstract stream base class.
Definition: PGFstream.h:39
virtual void SetPos(short posMode, INT64 posOff)=0
virtual void Read(int *count, void *buffer)=0
Wavelet channel class.
Definition: Subband.h:42
bool AllocMemory()
Definition: Subband.cpp:77
int GetWidth() const
Definition: Subband.h:127
int GetHeight() const
Definition: Subband.h:122
PGF wavelet transform.
PGF exception.
Definition: PGFtypes.h:180
OSError error
operating system error code
Definition: PGFtypes.h:187
PGF header.
Definition: PGFtypes.h:123
Optional PGF post-header.
Definition: PGFtypes.h:141
PGF pre-header.
Definition: PGFtypes.h:114
UINT16 bufferSize
number of uncoded UINT32 values in a block
Definition: PGFtypes.h:167
Block header used with ROI coding scheme
Definition: PGFtypes.h:151
struct ROIBlockHeader::RBH rbh
ROI block header.
UINT16 val
Definition: PGFtypes.h:160