| libpgf 7.21.2 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
231 CDecoder::~CDecoder() {
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
465 if (m_currentBlock->IsCompletelyRead()) {
466 // all data of current macro block has been read --> prepare next macro block
467 GetNextMacroBlock();
468 }
469
470 band->SetData(bandPos, m_currentBlock->m_value[m_currentBlock->m_valuePos] << quantParam);
471 m_currentBlock->m_valuePos++;
472 }
473
475 // Gets next macro block
476 // It might throw an IOException.
477 void CDecoder::GetNextMacroBlock() {
478 // current block has been read --> prepare next current block
479 m_macroBlocksAvailable--;
480
481 if (m_macroBlocksAvailable > 0) {
482 m_currentBlock = m_macroBlocks[++m_currentBlockIndex];
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.
494 void CDecoder::DecodeBuffer() {
495 ASSERT(m_macroBlocksAvailable <= 0);
496
497 // macro block management
498 if (m_macroBlockLen == 1) {
499 ASSERT(m_currentBlock);
500 ReadMacroBlock(m_currentBlock);
501 m_currentBlock->BitplaneDecode();
502 m_macroBlocksAvailable = 1;
503 } else {
504 m_macroBlocksAvailable = 0;
505 for (int i=0; i < m_macroBlockLen; i++) {
506 // read sequentially several blocks
507 try {
508 ReadMacroBlock(m_macroBlocks[i]);
509 m_macroBlocksAvailable++;
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++) {
523 m_macroBlocks[i]->BitplaneDecode();
524 }
525
526 // prepare current macro block
527 m_currentBlockIndex = 0;
528 m_currentBlock = m_macroBlocks[m_currentBlockIndex];
529 }
530 }
531
533 // Reads next block from stream and stores it in the given macro block
534 // It might throw an IOException.
535 void CDecoder::ReadMacroBlock(CMacroBlock* block) {
536 ASSERT(block);
537
538 UINT16 wordLen;
539 ROIBlockHeader h(BufferSize);
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
598 m_macroBlocksAvailable--;
599 m_currentBlockIndex++;
600
601 // check if pre-decoded data is available
602 while (m_macroBlocksAvailable > 0 && !m_macroBlocks[m_currentBlockIndex]->m_header.rbh.tileEnd) {
603 m_macroBlocksAvailable--;
604 m_currentBlockIndex++;
605 }
606 if (m_macroBlocksAvailable > 0) {
607 // set new current macro block
608 m_currentBlock = m_macroBlocks[m_currentBlockIndex];
609 ASSERT(m_currentBlock->m_header.rbh.tileEnd);
610 return;
611 }
612
613 ASSERT(m_macroBlocksAvailable <= 0);
614 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
650 void CDecoder::CMacroBlock::BitplaneDecode() {
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
GetBit
bool GetBit(UINT32 *stream, UINT32 pos)
Definition: BitStream.h:79
ImageModeIndexedColor
#define ImageModeIndexedColor
Definition: PGFplatform.h:100
ROIBlockHeader::rbh
struct ROIBlockHeader::RBH rbh
ROI block header.
CPGFStream::Read
virtual void Read(int *count, void *buffer)=0
ROIBlockHeader::RBH::bufferSize
UINT16 bufferSize
number of uncoded UINT32 values in a block
Definition: PGFtypes.h:187
PGFMagicVersion::version
UINT8 version
PGF version.
Definition: PGFtypes.h:115
CDecoder::CMacroBlock::ComposeBitplane
UINT32 ComposeBitplane(UINT32 bufferSize, DataT planeMask, UINT32 *sigBits, UINT32 *refBits, UINT32 *signBits)
Definition: Decoder.cpp:763
PGFHeader::mode
UINT8 mode
image mode according to Adobe's image modes
Definition: PGFtypes.h:158
MaxCodeLen
#define MaxCodeLen
max length of RL encoded block
Definition: Decoder.cpp:59
UP_Skip
Definition: PGFtypes.h:101
AlignWordPos
UINT32 AlignWordPos(UINT32 pos)
Definition: BitStream.h:328
CDecoder::m_macroBlocks
CMacroBlock ** m_macroBlocks
array of macroblocks
Definition: Decoder.h:205
CPGFStream
Abstract stream base class.
Definition: PGFstream.h:39
PGFHeader::width
UINT32 width
image width in pixels
Definition: PGFtypes.h:152
LinBlockSize
#define LinBlockSize
side length of a coefficient block in a HH or LL subband
Definition: PGFtypes.h:86
ColorTableSize
#define ColorTableSize
Definition: PGFtypes.h:281
UP_CachePrefix
Definition: PGFtypes.h:101
DataT
INT32 DataT
Definition: PGFtypes.h:268
__VAL
#define __VAL(x)
Definition: PGFplatform.h:603
PGFPostHeader::userDataLen
UINT32 userDataLen
user data size in bytes (not part of file header)
Definition: PGFtypes.h:171
ROIBlockHeader::RBH::tileEnd
UINT16 tileEnd
1: last part of a tile
Definition: PGFtypes.h:188
PGFPostHeader::userData
UINT8 * userData
user data of size userDataLen (optional part of file header)
Definition: PGFtypes.h:170
CSubband::AllocMemory
bool AllocMemory()
Definition: Subband.cpp:77
CDecoder::CMacroBlock::m_valuePos
UINT32 m_valuePos
current position in m_value
Definition: Decoder.h:79
CDecoder::DecodeInterleaved
void DecodeInterleaved(CWaveletTransform *wtChannel, int level, int quantParam)
Definition: Decoder.cpp:333
BufferSize
#define BufferSize
must be a multiple of WordWidth, BufferSize <= UINT16_MAX
Definition: PGFtypes.h:84
HeaderSize
#define HeaderSize
Definition: PGFtypes.h:280
CDecoder::~CDecoder
~CDecoder()
Destructor.
Definition: Decoder.cpp:231
CPGFStream::SetPos
virtual void SetPos(short posMode, INT64 posOff)=0
PGFPreHeader
PGF pre-header.
Definition: PGFtypes.h:123
PGFHeader::nLevels
UINT8 nLevels
number of FWT transforms
Definition: PGFtypes.h:154
RLblockSizeLen
#define RLblockSizeLen
block size length (< 16): ld(BufferSize) < RLblockSizeLen <= 2*ld(BufferSize)
Definition: PGFtypes.h:85
CSubband
Wavelet channel class.
Definition: Subband.h:42
CDecoder::DecodeBuffer
void DecodeBuffer()
Definition: Decoder.cpp:494
CDecoder::m_macroBlockLen
int m_macroBlockLen
array length
Definition: Decoder.h:207
CDecoder::Partition
void Partition(CSubband *band, int quantParam, int width, int height, int startPos, int pitch)
Definition: Decoder.cpp:266
CWaveletTransform
PGF wavelet transform.
Definition: WaveletTransform.h:55
CDecoder::CMacroBlock::m_value
DataT m_value[BufferSize]
output buffer of values with index m_valuePos
Definition: Decoder.h:77
PGFMagic
#define PGFMagic
PGF identification.
Definition: PGFtypes.h:61
ROIBlockHeader
Block header used with ROI coding scheme.
Definition: PGFtypes.h:179
CSubband::GetHeight
int GetHeight() const
Definition: Subband.h:123
PGFHeader
PGF header.
Definition: PGFtypes.h:150
WordWidthLog
#define WordWidthLog
ld of WordWidth
Definition: PGFplatform.h:74
Version6
#define Version6
hSize in PGFPreHeader uses 32 bits instead of 16 bits
Definition: PGFtypes.h:72
PGFPostHeader::cachedUserDataLen
UINT32 cachedUserDataLen
cached user data size in bytes (not part of file header)
Definition: PGFtypes.h:172
CDecoder::m_currentBlockIndex
int m_currentBlockIndex
index of current macro block
Definition: Decoder.h:206
CDecoder::CMacroBlock::BitplaneDecode
void BitplaneDecode()
Definition: Decoder.cpp:650
SeekBitRange
UINT32 SeekBitRange(UINT32 *stream, UINT32 pos, UINT32 len)
Definition: BitStream.h:220
MaxBitPlanesLog
#define MaxBitPlanesLog
number of bits to code the maximum number of bit planes (in 32 or 16 bit mode)
Definition: PGFtypes.h:93
CDecoder::m_currentBlock
CMacroBlock * m_currentBlock
current macro block (used by main thread)
Definition: Decoder.h:209
__PGFROISUPPORT__
#define __PGFROISUPPORT__
Definition: PGFplatform.h:60
LH
Definition: PGFtypes.h:99
WordBytes
#define WordBytes
sizeof(UINT32)
Definition: PGFplatform.h:76
Decoder.h
PGF decoder class.
CDecoder::CMacroBlock::IsCompletelyRead
bool IsCompletelyRead() const
Definition: Decoder.h:68
HL
Definition: PGFtypes.h:99
CWaveletTransform::GetSubband
CSubband * GetSubband(int level, Orientation orientation)
Definition: WaveletTransform.h:93
CDecoder::CMacroBlock
A macro block is a decoding unit of fixed size (uncoded)
Definition: Decoder.h:51
PGFPostHeader
Optional PGF post-header.
Definition: PGFtypes.h:168
__min
#define __min(x, y)
Definition: PGFplatform.h:91
CDecoder::m_stream
CPGFStream * m_stream
input PGF stream
Definition: Decoder.h:200
CDecoder::Skip
void Skip(UINT64 offset)
Definition: Decoder.cpp:449
CDecoder::m_macroBlocksAvailable
int m_macroBlocksAvailable
number of decoded macro blocks (including currently used macro block)
Definition: Decoder.h:208
CDecoder::GetNextMacroBlock
void GetNextMacroBlock()
Definition: Decoder.cpp:477
PGFROI
#define PGFROI
supports Regions Of Interest
Definition: PGFtypes.h:70
UserdataPolicy
UserdataPolicy
Definition: PGFtypes.h:101
ROIBlockHeader::val
UINT16 val
Definition: PGFtypes.h:180
GetValueBlock
UINT32 GetValueBlock(UINT32 *stream, UINT32 pos, UINT32 k)
Definition: BitStream.h:142
MaxBitPlanes
#define MaxBitPlanes
maximum number of bit planes of m_value: 32 minus sign bit
Definition: PGFtypes.h:89
InterBlockSize
#define InterBlockSize
side length of a coefficient block in a HL or LH subband
Definition: PGFtypes.h:87
CDecoder::ReadEncodedData
UINT32 ReadEncodedData(UINT8 *target, UINT32 len) const
Definition: Decoder.cpp:246
IOException::error
OSError error
operating system error code
Definition: PGFtypes.h:210
MagicVersionSize
#define MagicVersionSize
Definition: PGFtypes.h:278
CDecoder::ReadMacroBlock
void ReadMacroBlock(CMacroBlock *block)
throws IOException
Definition: Decoder.cpp:535
CDecoder::CDecoder
CDecoder(CPGFStream *stream, PGFPreHeader &preHeader, PGFHeader &header, PGFPostHeader &postHeader, UINT32 *&levelLength, UINT64 &userDataPos, bool useOMP, UINT32 userDataPolicy)
Definition: Decoder.cpp:73
CDecoder::CMacroBlock::ComposeBitplaneRLD
UINT32 ComposeBitplaneRLD(UINT32 bufferSize, DataT planeMask, UINT32 sigPos, UINT32 *refBits)
Definition: Decoder.cpp:824
CSubband::GetWidth
int GetWidth() const
Definition: Subband.h:128
MaxUserDataSize
#define MaxUserDataSize
Definition: PGFtypes.h:283
CDecoder::DequantizeValue
void DequantizeValue(CSubband *band, UINT32 bandPos, int quantParam)
Definition: Decoder.cpp:462
IOException
PGF exception.
Definition: PGFtypes.h:209
PGFHeader::height
UINT32 height
image height in pixels
Definition: PGFtypes.h:153
PGFPostHeader::clut
RGBQUAD clut[ColorTableLen]
color table for indexed color images (optional part of file header)
Definition: PGFtypes.h:169
CDecoder::CMacroBlock::m_header
ROIBlockHeader m_header
block header
Definition: Decoder.h:76
CSubband::SetData
void SetData(UINT32 pos, DataT v)
Definition: Subband.h:102
CodeBufferBitLen
#define CodeBufferBitLen
max number of bits in m_codeBuffer
Definition: Decoder.cpp:58
CDecoder::CMacroBlock::m_sigFlagVector
bool m_sigFlagVector[BufferSize+1]
Definition: Decoder.h:88
WordWidth
#define WordWidth
WordBytes*8.
Definition: PGFplatform.h:73
CDecoder::CMacroBlock::m_codeBuffer
UINT32 m_codeBuffer[CodeBufferLen]
input buffer for encoded bitstream
Definition: Decoder.h:78