libpgf 7.21.2
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, 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)
83, m_roi(false)
84#endif
85{
86 ASSERT(m_stream);
87
88 int count, expected;
89
90 // store current stream position
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
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();
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
246UINT32 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
266void 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.
333void 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
449void CDecoder::Skip(UINT64 offset) {
450 m_stream->SetPos(FSFromCurrent, offset);
451}
452
462void 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__
588// 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.
594void 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
763UINT32 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.
824UINT32 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>
927UINT32 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
1030void 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
UINT32 AlignWordPos(UINT32 pos)
Definition BitStream.h:328
bool GetBit(UINT32 *stream, UINT32 pos)
Definition BitStream.h:79
UINT32 GetValueBlock(UINT32 *stream, UINT32 pos, UINT32 k)
Definition BitStream.h:142
UINT32 SeekBitRange(UINT32 *stream, UINT32 pos, UINT32 len)
Definition BitStream.h:220
#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 __PGFROISUPPORT__
Definition PGFplatform.h:60
#define __VAL(x)
#define WordBytes
sizeof(UINT32)
Definition PGFplatform.h:76
#define WordWidth
WordBytes*8.
Definition PGFplatform.h:73
#define __min(x, y)
Definition PGFplatform.h:91
#define ImageModeIndexedColor
#define MaxBitPlanesLog
number of bits to code the maximum number of bit planes (in 32 or 16 bit mode)
Definition PGFtypes.h:93
#define PGFROI
supports Regions Of Interest
Definition PGFtypes.h:70
UserdataPolicy
Definition PGFtypes.h:101
@ UP_CachePrefix
Definition PGFtypes.h:101
@ UP_Skip
Definition PGFtypes.h:101
#define InterBlockSize
side length of a coefficient block in a HL or LH subband
Definition PGFtypes.h:87
#define HeaderSize
Definition PGFtypes.h:281
#define ColorTableSize
Definition PGFtypes.h:282
#define MaxUserDataSize
Definition PGFtypes.h:284
#define LinBlockSize
side length of a coefficient block in a HH or LL subband
Definition PGFtypes.h:86
#define PGFMagic
PGF identification.
Definition PGFtypes.h:61
#define MagicVersionSize
Definition PGFtypes.h:279
@ HL
Definition PGFtypes.h:99
@ LH
Definition PGFtypes.h:99
#define BufferSize
must be a multiple of WordWidth, BufferSize <= UINT16_MAX
Definition PGFtypes.h:84
#define Version6
hSize in PGFPreHeader uses 32 bits instead of 16 bits
Definition PGFtypes.h:72
#define RLblockSizeLen
block size length (< 16): ld(BufferSize) < RLblockSizeLen <= 2*ld(BufferSize)
Definition PGFtypes.h:85
INT32 DataT
Definition PGFtypes.h:269
#define MaxBitPlanes
maximum number of bit planes of m_value: 32 minus sign bit
Definition PGFtypes.h:89
A macro block is a decoding unit of fixed size (uncoded)
Definition Decoder.h:51
bool IsCompletelyRead() const
Definition Decoder.h:68
ROIBlockHeader m_header
block header
Definition Decoder.h:76
UINT32 m_valuePos
current position in m_value
Definition Decoder.h:79
UINT32 ComposeBitplane(UINT32 bufferSize, DataT planeMask, UINT32 *sigBits, UINT32 *refBits, UINT32 *signBits)
Definition Decoder.cpp:763
DataT m_value[BufferSize]
output buffer of values with index m_valuePos
Definition Decoder.h:77
UINT32 ComposeBitplaneRLD(UINT32 bufferSize, DataT planeMask, UINT32 sigPos, UINT32 *refBits)
Definition Decoder.cpp:824
UINT32 m_codeBuffer[CodeBufferLen]
input buffer for encoded bitstream
Definition Decoder.h:78
bool m_sigFlagVector[BufferSize+1]
Definition Decoder.h:88
int m_macroBlockLen
array length
Definition Decoder.h:207
int m_currentBlockIndex
index of current macro block
Definition Decoder.h:206
UINT32 ReadEncodedData(UINT8 *target, UINT32 len) const
Definition Decoder.cpp:246
CPGFStream * m_stream
input PGF stream
Definition Decoder.h:200
int m_macroBlocksAvailable
number of decoded macro blocks (including currently used macro block)
Definition Decoder.h:208
void ReadMacroBlock(CMacroBlock *block)
throws IOException
Definition Decoder.cpp:535
UINT64 m_startPos
stream position at the beginning of the PGF pre-header
Definition Decoder.h:201
void Partition(CSubband *band, int quantParam, int width, int height, int startPos, int pitch)
Definition Decoder.cpp:266
UINT64 m_streamSizeEstimation
estimation of stream size
Definition Decoder.h:202
void DecodeInterleaved(CWaveletTransform *wtChannel, int level, int quantParam)
Definition Decoder.cpp:333
void DecodeBuffer()
Definition Decoder.cpp:494
CMacroBlock ** m_macroBlocks
array of macroblocks
Definition Decoder.h:205
CMacroBlock * m_currentBlock
current macro block (used by main thread)
Definition Decoder.h:209
UINT32 m_encodedHeaderLength
stream offset from startPos to the beginning of the data part (highest level)
Definition Decoder.h:203
~CDecoder()
Destructor.
Definition Decoder.cpp:231
void Skip(UINT64 offset)
Definition Decoder.cpp:449
CDecoder(CPGFStream *stream, PGFPreHeader &preHeader, PGFHeader &header, PGFPostHeader &postHeader, UINT32 *&levelLength, UINT64 &userDataPos, bool useOMP, UINT32 userDataPolicy)
Definition Decoder.cpp:73
void DequantizeValue(CSubband *band, UINT32 bandPos, int quantParam)
Definition Decoder.cpp:462
void GetNextMacroBlock()
Definition Decoder.cpp:477
Abstract stream base class.
Definition PGFstream.h:39
virtual void SetPos(short posMode, INT64 posOff)=0
virtual UINT64 GetPos() const =0
virtual void Read(int *count, void *buffer)=0
Wavelet channel class.
Definition Subband.h:42
void SetData(UINT32 pos, DataT v)
Definition Subband.h:102
bool AllocMemory()
Definition Subband.cpp:77
int GetWidth() const
Definition Subband.h:128
int GetHeight() const
Definition Subband.h:123
PGF wavelet transform.
CSubband * GetSubband(int level, Orientation orientation)
PGF exception.
Definition PGFtypes.h:210
OSError error
operating system error code
Definition PGFtypes.h:211
PGF header.
Definition PGFtypes.h:151
UINT8 mode
image mode according to Adobe's image modes
Definition PGFtypes.h:159
UINT32 height
image height in pixels
Definition PGFtypes.h:154
UINT32 width
image width in pixels
Definition PGFtypes.h:153
UINT8 nLevels
number of FWT transforms
Definition PGFtypes.h:155
char magic[3]
PGF identification = "PGF".
Definition PGFtypes.h:114
UINT8 version
PGF version.
Definition PGFtypes.h:115
Optional PGF post-header.
Definition PGFtypes.h:169
UINT32 userDataLen
user data size in bytes (not part of file header)
Definition PGFtypes.h:172
UINT32 cachedUserDataLen
cached user data size in bytes (not part of file header)
Definition PGFtypes.h:173
RGBQUAD clut[ColorTableLen]
color table for indexed color images (optional part of file header)
Definition PGFtypes.h:170
UINT8 * userData
user data of size userDataLen (optional part of file header)
Definition PGFtypes.h:171
PGF pre-header.
Definition PGFtypes.h:123
UINT32 hSize
total size of PGFHeader, [ColorTable], and [UserData] in bytes (since Version 6: 4 Bytes)
Definition PGFtypes.h:124
UINT16 tileEnd
1: last part of a tile
Definition PGFtypes.h:189
UINT16 bufferSize
number of uncoded UINT32 values in a block
Definition PGFtypes.h:188
Block header used with ROI coding scheme
Definition PGFtypes.h:180
struct ROIBlockHeader::RBH rbh
ROI block header.