libpgf 7.21.2
PGF - Progressive Graphics File
Loading...
Searching...
No Matches
Encoder.cpp
Go to the documentation of this file.
1/*
2 * The Progressive Graphics File; http://www.libpgf.org
3 *
4 * $Date: 2007-02-03 13:04:21 +0100 (Sa, 03 Feb 2007) $
5 * $Revision: 280 $
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 "Encoder.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// Encoding scheme
43// input: wavelet coefficients stored in subbands
44// output: binary file
45//
46// subband
47// |
48// m_value [BufferSize]
49// | | |
50// m_sign sigBits refBits [BufferSize, BufferLen, BufferLen]
51// | | |
52// m_codeBuffer (for each plane: RLcodeLength (16 bit), RLcoded sigBits + m_sign, refBits)
53// |
54// file (for each buffer: packedLength (16 bit), packed bits)
55//
56
57// Constants
58#define CodeBufferBitLen (CodeBufferLen*WordWidth)
59#define MaxCodeLen ((1 << RLblockSizeLen) - 1)
60
70CEncoder::CEncoder(CPGFStream* stream, PGFPreHeader preHeader, PGFHeader header, const PGFPostHeader& postHeader, UINT64& userDataPos, bool useOMP)
71: m_stream(stream)
72, m_bufferStartPos(0)
73, m_currLevelIndex(0)
74, m_nLevels(header.nLevels)
75, m_favorSpeed(false)
76, m_forceWriting(false)
78, m_roi(false)
79#endif
80{
81 ASSERT(m_stream);
82
83 int count;
85 m_levelLength = nullptr;
86
87 // set number of threads
88#ifdef LIBPGF_USE_OPENMP
89 m_macroBlockLen = omp_get_num_procs();
90#else
92#endif
93
94 if (useOMP && m_macroBlockLen > 1) {
95#ifdef LIBPGF_USE_OPENMP
96 omp_set_num_threads(m_macroBlockLen);
97#endif
98 // create macro block array
99 m_macroBlocks = new(std::nothrow) CMacroBlock*[m_macroBlockLen];
100 if (!m_macroBlocks) ReturnWithError(InsufficientMemory);
101 for (int i=0; i < m_macroBlockLen; i++) m_macroBlocks[i] = new CMacroBlock(this);
103 } else {
104 m_macroBlocks = 0;
105 m_macroBlockLen = 1;
106 m_currentBlock = new CMacroBlock(this);
107 }
108
109 // save file position
111
112 // write preHeader
113 preHeader.hSize = __VAL(preHeader.hSize);
114 count = PreHeaderSize;
115 m_stream->Write(&count, &preHeader);
116
117 // write file header
118 header.height = __VAL(header.height);
119 header.width = __VAL(header.width);
120 count = HeaderSize;
121 m_stream->Write(&count, &header);
122
123 // write postHeader
124 if (header.mode == ImageModeIndexedColor) {
125 // write color table
126 count = ColorTableSize;
127 m_stream->Write(&count, (void *)postHeader.clut);
128 }
129 // save user data file position
130 userDataPos = m_stream->GetPos();
131 if (postHeader.userDataLen) {
132 if (postHeader.userData) {
133 // write user data
134 count = postHeader.userDataLen;
135 m_stream->Write(&count, postHeader.userData);
136 } else {
137 m_stream->SetPos(FSFromCurrent, count);
138 }
139 }
140
141 // save level length file position
143}
144
146// Destructor
148 if (m_macroBlocks) {
149 for (int i=0; i < m_macroBlockLen; i++) delete m_macroBlocks[i];
150 delete[] m_macroBlocks;
151 } else {
152 delete m_currentBlock;
153 }
154}
155
161 UINT64 curPos = m_stream->GetPos(); // end of user data
162 int count = PreHeaderSize;
163
164 // write preHeader
166 preHeader.hSize = __VAL(preHeader.hSize);
167 m_stream->Write(&count, &preHeader);
168
169 m_stream->SetPos(FSFromStart, curPos);
170}
171
177UINT32 CEncoder::WriteLevelLength(UINT32*& levelLength) {
178 // renew levelLength
179 delete[] levelLength;
180 levelLength = new(std::nothrow) UINT32[m_nLevels];
181 if (!levelLength) ReturnWithError(InsufficientMemory);
182 for (UINT8 l = 0; l < m_nLevels; l++) levelLength[l] = 0;
183 m_levelLength = levelLength;
184
185 // save level length file position
187
188 // write dummy levelLength
189 int count = m_nLevels*WordBytes;
190 m_stream->Write(&count, m_levelLength);
191
192 // save current file position
194
195 return count;
196}
197
203 UINT64 curPos = m_stream->GetPos(); // end of image
204
205 // set file pos to levelLength
206 m_stream->SetPos(FSFromStart, m_levelLengthPos);
207
208 if (m_levelLength) {
209 #ifdef PGF_USE_BIG_ENDIAN
210 UINT32 levelLength;
211 int count = WordBytes;
212
213 for (int i=0; i < m_currLevelIndex; i++) {
214 levelLength = __VAL(UINT32(m_levelLength[i]));
215 m_stream->Write(&count, &levelLength);
216 }
217 #else
218 int count = m_currLevelIndex*WordBytes;
219
220 m_stream->Write(&count, m_levelLength);
221 #endif //PGF_USE_BIG_ENDIAN
222 } else {
223 int count = m_currLevelIndex*WordBytes;
224 m_stream->SetPos(FSFromCurrent, count);
225 }
226
227 // begin of image
228 UINT32 retValue = UINT32(curPos - m_stream->GetPos());
229
230 // restore file position
231 m_stream->SetPos(FSFromStart, curPos);
232
233 return retValue;
234}
235
246void CEncoder::Partition(CSubband* band, int width, int height, int startPos, int pitch) {
247 ASSERT(band);
248
249 const div_t hh = div(height, LinBlockSize);
250 const div_t ww = div(width, LinBlockSize);
251 const int ws = pitch - LinBlockSize;
252 const int wr = pitch - ww.rem;
253 int pos, base = startPos, base2;
254
255 // main height
256 for (int i=0; i < hh.quot; i++) {
257 // main width
258 base2 = base;
259 for (int j=0; j < ww.quot; j++) {
260 pos = base2;
261 for (int y=0; y < LinBlockSize; y++) {
262 for (int x=0; x < LinBlockSize; x++) {
263 WriteValue(band, pos);
264 pos++;
265 }
266 pos += ws;
267 }
268 base2 += LinBlockSize;
269 }
270 // rest of width
271 pos = base2;
272 for (int y=0; y < LinBlockSize; y++) {
273 for (int x=0; x < ww.rem; x++) {
274 WriteValue(band, pos);
275 pos++;
276 }
277 pos += wr;
278 base += pitch;
279 }
280 }
281 // main width
282 base2 = base;
283 for (int j=0; j < ww.quot; j++) {
284 // rest of height
285 pos = base2;
286 for (int y=0; y < hh.rem; y++) {
287 for (int x=0; x < LinBlockSize; x++) {
288 WriteValue(band, pos);
289 pos++;
290 }
291 pos += ws;
292 }
293 base2 += LinBlockSize;
294 }
295 // rest of height
296 pos = base2;
297 for (int y=0; y < hh.rem; y++) {
298 // rest of width
299 for (int x=0; x < ww.rem; x++) {
300 WriteValue(band, pos);
301 pos++;
302 }
303 pos += wr;
304 }
305}
306
311 if (m_currentBlock->m_valuePos > 0) {
312 // pad buffer with zeros
315
316 // encode buffer
317 m_forceWriting = true; // makes sure that the following EncodeBuffer is really written into the stream
319 }
320}
321
323// Stores band value from given position bandPos into buffer m_value at position m_valuePos
324// If buffer is full encode it to file
325// It might throw an IOException.
326void CEncoder::WriteValue(CSubband* band, int bandPos) {
329 }
330 DataT val = m_currentBlock->m_value[m_currentBlock->m_valuePos++] = band->GetData(bandPos);
331 UINT32 v = abs(val);
333}
334
336// Encode buffer and write data into stream.
337// h contains buffer size and flag indicating end of tile.
338// Encoding scheme: <wordLen>(16 bits) [ ROI ] data
339// ROI ::= <bufferSize>(15 bits) <eofTile>(1 bit)
340// It might throw an IOException.
342 ASSERT(m_currentBlock);
343#ifdef __PGFROISUPPORT__
344 ASSERT(m_roi && h.rbh.bufferSize <= BufferSize || h.rbh.bufferSize == BufferSize);
345#else
346 ASSERT(h.rbh.bufferSize == BufferSize);
347#endif
349
350 // macro block management
351 if (m_macroBlockLen == 1) {
354 } else {
355 // save last level index
356 int lastLevelIndex = m_currentBlock->m_lastLevelIndex;
357
359 // encode macro blocks
360 /*
361 volatile OSError error = NoError;
362 #ifdef LIBPGF_USE_OPENMP
363 #pragma omp parallel for ordered default(shared)
364 #endif
365 for (int i=0; i < m_lastMacroBlock; i++) {
366 if (error == NoError) {
367 m_macroBlocks[i]->BitplaneEncode();
368 #ifdef LIBPGF_USE_OPENMP
369 #pragma omp ordered
370 #endif
371 {
372 try {
373 WriteMacroBlock(m_macroBlocks[i]);
374 } catch (IOException& e) {
375 error = e.error;
376 }
377 delete m_macroBlocks[i]; m_macroBlocks[i] = 0;
378 }
379 }
380 }
381 if (error != NoError) ReturnWithError(error);
382 */
383#ifdef LIBPGF_USE_OPENMP
384 #pragma omp parallel for default(shared) //no declared exceptions in next block
385#endif
386 for (int i=0; i < m_lastMacroBlock; i++) {
388 }
389 for (int i=0; i < m_lastMacroBlock; i++) {
391 }
392
393 // prepare for next round
394 m_forceWriting = false;
396 }
397 // re-initialize macro block
399 m_currentBlock->Init(lastLevelIndex);
400 }
401}
402
404// Write encoded macro block into stream.
405// It might throw an IOException.
407 ASSERT(block);
408#ifdef __PGFROISUPPORT__
409 ROIBlockHeader h = block->m_header;
410#endif
411 UINT16 wordLen = UINT16(NumberOfWords(block->m_codePos)); ASSERT(wordLen <= CodeBufferLen);
412 int count = sizeof(UINT16);
413
414#ifdef TRACE
415 //UINT32 filePos = (UINT32)m_stream->GetPos();
416 //printf("EncodeBuffer: %d\n", filePos);
417#endif
418
419#ifdef PGF_USE_BIG_ENDIAN
420 // write wordLen
421 UINT16 wl = __VAL(wordLen);
422 m_stream->Write(&count, &wl); ASSERT(count == sizeof(UINT16));
423
424#ifdef __PGFROISUPPORT__
425 // write ROIBlockHeader
426 if (m_roi) {
427 count = sizeof(ROIBlockHeader);
428 h.val = __VAL(h.val);
429 m_stream->Write(&count, &h.val); ASSERT(count == sizeof(ROIBlockHeader));
430 }
431#endif // __PGFROISUPPORT__
432
433 // convert data
434 for (int i=0; i < wordLen; i++) {
435 block->m_codeBuffer[i] = __VAL(block->m_codeBuffer[i]);
436 }
437#else
438 // write wordLen
439 m_stream->Write(&count, &wordLen); ASSERT(count == sizeof(UINT16));
440
441#ifdef __PGFROISUPPORT__
442 // write ROIBlockHeader
443 if (m_roi) {
444 count = sizeof(ROIBlockHeader);
445 m_stream->Write(&count, &h.val); ASSERT(count == sizeof(ROIBlockHeader));
446 }
447#endif // __PGFROISUPPORT__
448#endif // PGF_USE_BIG_ENDIAN
449
450 // write encoded data into stream
451 count = wordLen*WordBytes;
452 m_stream->Write(&count, block->m_codeBuffer);
453
454 // store levelLength
455 if (m_levelLength) {
456 // store level length
457 // EncodeBuffer has been called after m_lastLevelIndex has been updated
458 ASSERT(m_currLevelIndex < m_nLevels);
461
462 }
463
464 // prepare for next buffer
466
467 // reset values
468 block->m_valuePos = 0;
469 block->m_maxAbsValue = 0;
470}
471
473// Encode buffer of given size using bit plane coding.
474// A buffer contains bufferLen UINT32 values, thus, bufferSize bits per bit plane.
475// Following coding scheme is used:
476// Buffer ::= <nPlanes>(5 bits) foreach(plane i): Plane[i]
477// Plane[i] ::= [ Sig1 | Sig2 ] [DWORD alignment] refBits
478// Sig1 ::= 1 <codeLen>(15 bits) codedSigAndSignBits
479// Sig2 ::= 0 <sigLen>(15 bits) [Sign1 | Sign2 ] [DWORD alignment] sigBits
480// Sign1 ::= 1 <codeLen>(15 bits) codedSignBits
481// Sign2 ::= 0 <signLen>(15 bits) [DWORD alignment] signBits
483 UINT8 nPlanes;
484 UINT32 sigLen, codeLen = 0, wordPos, refLen, signLen;
485 UINT32 sigBits[BufferLen] = { 0 };
486 UINT32 refBits[BufferLen] = { 0 };
487 UINT32 signBits[BufferLen] = { 0 };
488 UINT32 planeMask;
489 UINT32 bufferSize = m_header.rbh.bufferSize; ASSERT(bufferSize <= BufferSize);
490 bool useRL;
491
492#ifdef TRACE
493 //printf("which thread: %d\n", omp_get_thread_num());
494#endif
495
496 // clear significance vector
497 for (UINT32 k=0; k < bufferSize; k++) {
498 m_sigFlagVector[k] = false;
499 }
500 m_sigFlagVector[bufferSize] = true; // sentinel
501
502 // clear output buffer
503 for (UINT32 k=0; k < bufferSize; k++) {
504 m_codeBuffer[k] = 0;
505 }
506 m_codePos = 0;
507
508 // compute number of bit planes and split buffer into separate bit planes
509 nPlanes = NumberOfBitplanes();
510
511 // write number of bit planes to m_codeBuffer
512 // <nPlanes>
515
516 // loop through all bit planes
517 if (nPlanes == 0) nPlanes = MaxBitPlanes + 1;
518 planeMask = 1 << (nPlanes - 1);
519
520 for (int plane = nPlanes - 1; plane >= 0; plane--) {
521 // clear significant bitset
522 for (UINT32 k=0; k < BufferLen; k++) {
523 sigBits[k] = 0;
524 }
525
526 // split bitplane in significant bitset and refinement bitset
527 sigLen = DecomposeBitplane(bufferSize, planeMask, m_codePos + RLblockSizeLen + 1, sigBits, refBits, signBits, signLen, codeLen);
528
529 if (sigLen > 0 && codeLen <= MaxCodeLen && codeLen < AlignWordPos(sigLen) + AlignWordPos(signLen) + 2*RLblockSizeLen) {
530 // set RL code bit
531 // <1><codeLen>
533
534 // write length codeLen to m_codeBuffer
536 m_codePos += RLblockSizeLen + codeLen;
537 } else {
538 #ifdef TRACE
539 //printf("new\n");
540 //for (UINT32 i=0; i < bufferSize; i++) {
541 // printf("%s", (GetBit(sigBits, i)) ? "1" : "_");
542 // if (i%120 == 119) printf("\n");
543 //}
544 //printf("\n");
545 #endif // TRACE
546
547 // run-length coding wasn't efficient enough
548 // we don't use RL coding for sigBits
549 // <0><sigLen>
551
552 // write length sigLen to m_codeBuffer
553 ASSERT(sigLen <= MaxCodeLen);
556
557 if (m_encoder->m_favorSpeed || signLen == 0) {
558 useRL = false;
559 } else {
560 // overwrite m_codeBuffer
561 useRL = true;
562 // run-length encode m_sign and append them to the m_codeBuffer
563 codeLen = RLESigns(m_codePos + RLblockSizeLen + 1, signBits, signLen);
564 }
565
566 if (useRL && codeLen <= MaxCodeLen && codeLen < signLen) {
567 // RL encoding of m_sign was efficient
568 // <1><codeLen><codedSignBits>_
569 // write RL code bit
571
572 // write codeLen to m_codeBuffer
574
575 // compute position of sigBits
576 wordPos = NumberOfWords(m_codePos + RLblockSizeLen + codeLen);
577 ASSERT(0 <= wordPos && wordPos < CodeBufferLen);
578 } else {
579 // RL encoding of signBits wasn't efficient
580 // <0><signLen>_<signBits>_
581 // clear RL code bit
583
584 // write signLen to m_codeBuffer
585 ASSERT(signLen <= MaxCodeLen);
587
588 // write signBits to m_codeBuffer
590 ASSERT(0 <= wordPos && wordPos < CodeBufferLen);
591 codeLen = NumberOfWords(signLen);
592
593 for (UINT32 k=0; k < codeLen; k++) {
594 m_codeBuffer[wordPos++] = signBits[k];
595 }
596 }
597
598 // write sigBits
599 // <sigBits>_
600 ASSERT(0 <= wordPos && wordPos < CodeBufferLen);
601 refLen = NumberOfWords(sigLen);
602
603 for (UINT32 k=0; k < refLen; k++) {
604 m_codeBuffer[wordPos++] = sigBits[k];
605 }
606 m_codePos = wordPos << WordWidthLog;
607 }
608
609 // append refinement bitset (aligned to word boundary)
610 // _<refBits>
611 wordPos = NumberOfWords(m_codePos);
612 ASSERT(0 <= wordPos && wordPos < CodeBufferLen);
613 refLen = NumberOfWords(bufferSize - sigLen);
614
615 for (UINT32 k=0; k < refLen; k++) {
616 m_codeBuffer[wordPos++] = refBits[k];
617 }
618 m_codePos = wordPos << WordWidthLog;
619 planeMask >>= 1;
620 }
621 ASSERT(0 <= m_codePos && m_codePos <= CodeBufferBitLen);
622}
623
625// Split bitplane of length bufferSize into significant and refinement bitset
626// returns length [bits] of significant bits
627// input: bufferSize, planeMask, codePos
628// output: sigBits, refBits, signBits, signLen [bits], codeLen [bits]
629// RLE
630// - Encode run of 2^k zeros by a single 0.
631// - Encode run of count 0's followed by a 1 with codeword: 1<count>x
632// - x is 0: if a positive sign is stored, otherwise 1
633// - Store each bit in m_codeBuffer[codePos] and increment codePos.
634UINT32 CEncoder::CMacroBlock::DecomposeBitplane(UINT32 bufferSize, UINT32 planeMask, UINT32 codePos, UINT32* sigBits, UINT32* refBits, UINT32* signBits, UINT32& signLen, UINT32& codeLen) {
635 ASSERT(sigBits);
636 ASSERT(refBits);
637 ASSERT(signBits);
638 ASSERT(codePos < CodeBufferBitLen);
639
640 UINT32 sigPos = 0;
641 UINT32 valuePos = 0, valueEnd;
642 UINT32 refPos = 0;
643
644 // set output value
645 signLen = 0;
646
647 // prepare RLE of Sigs and Signs
648 const UINT32 outStartPos = codePos;
649 UINT32 k = 3;
650 UINT32 runlen = 1 << k; // = 2^k
651 UINT32 count = 0;
652
653 while (valuePos < bufferSize) {
654 // search next 1 in m_sigFlagVector using searching with sentinel
655 valueEnd = valuePos;
656 while(!m_sigFlagVector[valueEnd]) { valueEnd++; }
657
658 // search 1's in m_value[plane][valuePos..valueEnd)
659 // these 1's are significant bits
660 while (valuePos < valueEnd) {
661 if (GetBitAtPos(valuePos, planeMask)) {
662 // RLE encoding
663 // encode run of count 0's followed by a 1
664 // with codeword: 1<count>(signBits[signPos])
665 SetBit(m_codeBuffer, codePos++);
666 if (k > 0) {
667 SetValueBlock(m_codeBuffer, codePos, count, k);
668 codePos += k;
669
670 // adapt k (half the zero run-length)
671 k--;
672 runlen >>= 1;
673 }
674
675 // copy and write sign bit
676 if (m_value[valuePos] < 0) {
677 SetBit(signBits, signLen++);
678 SetBit(m_codeBuffer, codePos++);
679 } else {
680 ClearBit(signBits, signLen++);
681 ClearBit(m_codeBuffer, codePos++);
682 }
683
684 // write a 1 to sigBits
685 SetBit(sigBits, sigPos++);
686
687 // update m_sigFlagVector
688 m_sigFlagVector[valuePos] = true;
689
690 // prepare for next run
691 count = 0;
692 } else {
693 // RLE encoding
694 count++;
695 if (count == runlen) {
696 // encode run of 2^k zeros by a single 0
697 ClearBit(m_codeBuffer, codePos++);
698 // adapt k (double the zero run-length)
699 if (k < WordWidth) {
700 k++;
701 runlen <<= 1;
702 }
703
704 // prepare for next run
705 count = 0;
706 }
707
708 // write 0 to sigBits
709 sigPos++;
710 }
711 valuePos++;
712 }
713 // refinement bit
714 if (valuePos < bufferSize) {
715 // write one refinement bit
716 if (GetBitAtPos(valuePos++, planeMask)) {
717 SetBit(refBits, refPos);
718 } else {
719 ClearBit(refBits, refPos);
720 }
721 refPos++;
722 }
723 }
724 // RLE encoding of the rest of the plane
725 // encode run of count 0's followed by a 1
726 // with codeword: 1<count>(signBits[signPos])
727 SetBit(m_codeBuffer, codePos++);
728 if (k > 0) {
729 SetValueBlock(m_codeBuffer, codePos, count, k);
730 codePos += k;
731 }
732 // write dmmy sign bit
733 SetBit(m_codeBuffer, codePos++);
734
735 // write word filler zeros
736
737 ASSERT(sigPos <= bufferSize);
738 ASSERT(refPos <= bufferSize);
739 ASSERT(signLen <= bufferSize);
740 ASSERT(valuePos == bufferSize);
741 ASSERT(codePos >= outStartPos && codePos < CodeBufferBitLen);
742 codeLen = codePos - outStartPos;
743
744 return sigPos;
745}
746
747
749// Compute number of bit planes needed
751 UINT8 cnt = 0;
752
753 // determine number of bitplanes for max value
754 if (m_maxAbsValue > 0) {
755 while (m_maxAbsValue > 0) {
756 m_maxAbsValue >>= 1; cnt++;
757 }
758 if (cnt == MaxBitPlanes + 1) cnt = 0;
759 // end cs
760 ASSERT(cnt <= MaxBitPlanes);
761 ASSERT((cnt >> MaxBitPlanesLog) == 0);
762 return cnt;
763 } else {
764 return 1;
765 }
766}
767
769// Adaptive Run-Length encoder for long sequences of ones.
770// Returns length of output in bits.
771// - Encode run of 2^k ones by a single 1.
772// - Encode run of count 1's followed by a 0 with codeword: 0<count>.
773// - Store each bit in m_codeBuffer[codePos] and increment codePos.
774UINT32 CEncoder::CMacroBlock::RLESigns(UINT32 codePos, UINT32* signBits, UINT32 signLen) {
775 ASSERT(signBits);
776 ASSERT(0 <= codePos && codePos < CodeBufferBitLen);
777 ASSERT(0 < signLen && signLen <= BufferSize);
778
779 const UINT32 outStartPos = codePos;
780 UINT32 k = 0;
781 UINT32 runlen = 1 << k; // = 2^k
782 UINT32 count = 0;
783 UINT32 signPos = 0;
784
785 while (signPos < signLen) {
786 // search next 0 in signBits starting at position signPos
787 count = SeekBit1Range(signBits, signPos, __min(runlen, signLen - signPos));
788 // count 1's found
789 if (count == runlen) {
790 // encode run of 2^k ones by a single 1
791 signPos += count;
792 SetBit(m_codeBuffer, codePos++);
793 // adapt k (double the 1's run-length)
794 if (k < WordWidth) {
795 k++;
796 runlen <<= 1;
797 }
798 } else {
799 // encode run of count 1's followed by a 0
800 // with codeword: 0(count)
801 signPos += count + 1;
802 ClearBit(m_codeBuffer, codePos++);
803 if (k > 0) {
804 SetValueBlock(m_codeBuffer, codePos, count, k);
805 codePos += k;
806 }
807 // adapt k (half the 1's run-length)
808 if (k > 0) {
809 k--;
810 runlen >>= 1;
811 }
812 }
813 }
814 ASSERT(signPos == signLen || signPos == signLen + 1);
815 ASSERT(codePos >= outStartPos && codePos < CodeBufferBitLen);
816 return codePos - outStartPos;
817}
818
820#ifdef TRACE
821void CEncoder::DumpBuffer() const {
822 //printf("\nDump\n");
823 //for (UINT32 i=0; i < BufferSize; i++) {
824 // printf("%d", m_value[i]);
825 //}
826 //printf("\n");
827}
828#endif //TRACE
829
830
UINT32 AlignWordPos(UINT32 pos)
Definition BitStream.h:328
void SetBit(UINT32 *stream, UINT32 pos)
Definition BitStream.h:62
void SetValueBlock(UINT32 *stream, UINT32 pos, UINT32 val, UINT32 k)
Definition BitStream.h:116
void ClearBit(UINT32 *stream, UINT32 pos)
Definition BitStream.h:70
UINT32 SeekBit1Range(UINT32 *stream, UINT32 pos, UINT32 len)
Definition BitStream.h:249
UINT32 NumberOfWords(UINT32 pos)
Definition BitStream.h:337
#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 encoder class.
#define CodeBufferLen
number of words in code buffer (CodeBufferLen > BufferLen)
Definition Encoder.h:40
#define BufferLen
number of words per buffer
Definition Encoder.h:39
#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 PreHeaderSize
Definition PGFtypes.h:280
#define HeaderSize
Definition PGFtypes.h:281
#define ColorTableSize
Definition PGFtypes.h:282
#define LinBlockSize
side length of a coefficient block in a HH or LL subband
Definition PGFtypes.h:86
#define BufferSize
must be a multiple of WordWidth, BufferSize <= UINT16_MAX
Definition PGFtypes.h:84
#define RLblockSizeLen
block size length (< 16): ld(BufferSize) < RLblockSizeLen <= 2*ld(BufferSize)
Definition PGFtypes.h:85
INT32 DataT
Definition PGFtypes.h:269
#define DataTSize
Definition PGFtypes.h:283
#define MaxBitPlanes
maximum number of bit planes of m_value: 32 minus sign bit
Definition PGFtypes.h:89
A macro block is an encoding unit of fixed size (uncoded)
Definition Encoder.h:51
DataT m_value[BufferSize]
input buffer of values with index m_valuePos
Definition Encoder.h:84
UINT32 DecomposeBitplane(UINT32 bufferSize, UINT32 planeMask, UINT32 codePos, UINT32 *sigBits, UINT32 *refBits, UINT32 *signBits, UINT32 &signLen, UINT32 &codeLen)
Definition Encoder.cpp:634
UINT32 RLESigns(UINT32 codePos, UINT32 *signBits, UINT32 signLen)
Definition Encoder.cpp:774
UINT32 m_codeBuffer[CodeBufferLen]
output buffer for encoded bitstream
Definition Encoder.h:85
int m_lastLevelIndex
index of last encoded level: [0, nLevels); used because a level-end can occur before a buffer is full
Definition Encoder.h:90
UINT32 m_codePos
current position in encoded bitstream
Definition Encoder.h:89
UINT32 m_valuePos
current buffer position
Definition Encoder.h:87
bool m_sigFlagVector[BufferSize+1]
Definition Encoder.h:99
UINT32 m_maxAbsValue
maximum absolute coefficient in each buffer
Definition Encoder.h:88
ROIBlockHeader m_header
block header
Definition Encoder.h:86
CEncoder * m_encoder
Definition Encoder.h:98
void Init(int lastLevelIndex)
Definition Encoder.h:71
void SetBufferStartPos()
Save current stream position as beginning of current level.
Definition Encoder.h:192
bool m_favorSpeed
favor speed over size
Definition Encoder.h:226
void Partition(CSubband *band, int width, int height, int startPos, int pitch)
Definition Encoder.cpp:246
UINT64 m_startPosition
stream position of PGF start (PreHeader)
Definition Encoder.h:214
INT64 ComputeBufferLength() const
Definition Encoder.h:179
void EncodeBuffer(ROIBlockHeader h)
Definition Encoder.cpp:341
bool m_forceWriting
all macro blocks have to be written into the stream
Definition Encoder.h:227
UINT64 m_levelLengthPos
stream position of Metadata
Definition Encoder.h:215
CMacroBlock * m_currentBlock
current macro block (used by main thread)
Definition Encoder.h:221
void WriteValue(CSubband *band, int bandPos)
Definition Encoder.cpp:326
CEncoder(CPGFStream *stream, PGFPreHeader preHeader, PGFHeader header, const PGFPostHeader &postHeader, UINT64 &userDataPos, bool useOMP)
Definition Encoder.cpp:70
UINT32 * m_levelLength
temporary saves the level index
Definition Encoder.h:223
CMacroBlock ** m_macroBlocks
array of macroblocks
Definition Encoder.h:218
UINT8 m_nLevels
number of levels
Definition Encoder.h:225
int m_currLevelIndex
counts where (=index) to save next value
Definition Encoder.h:224
void Flush()
Definition Encoder.cpp:310
UINT32 UpdateLevelLength()
Definition Encoder.cpp:202
~CEncoder()
Destructor.
Definition Encoder.cpp:147
int m_lastMacroBlock
array index of the last created macro block
Definition Encoder.h:220
void WriteMacroBlock(CMacroBlock *block)
Definition Encoder.cpp:406
CPGFStream * m_stream
output PMF stream
Definition Encoder.h:213
UINT32 WriteLevelLength(UINT32 *&levelLength)
Definition Encoder.cpp:177
void UpdatePostHeaderSize(PGFPreHeader preHeader)
Definition Encoder.cpp:160
void SetStreamPosToStart()
Resets stream position to beginning of PGF pre-header.
Definition Encoder.h:188
int m_macroBlockLen
array length
Definition Encoder.h:219
Abstract stream base class.
Definition PGFstream.h:39
virtual void Write(int *count, void *buffer)=0
virtual void SetPos(short posMode, INT64 posOff)=0
virtual UINT64 GetPos() const =0
Wavelet channel class.
Definition Subband.h:42
DataT GetData(UINT32 pos) const
Definition Subband.h:113
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
Optional PGF post-header.
Definition PGFtypes.h:169
UINT32 userDataLen
user data size in bytes (not part of file header)
Definition PGFtypes.h:172
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 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.