libpgf 6.14.12
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) THROW_
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)
77#ifdef __PGFROISUPPORT__
78, m_roi(false)
79#endif
80{
81 ASSERT(m_stream);
82
83 int count;
84 m_lastMacroBlock = 0;
85 m_levelLength = NULL;
86
87 // set number of threads
88#ifdef LIBPGF_USE_OPENMP
89 m_macroBlockLen = omp_get_num_procs();
90#else
91 m_macroBlockLen = 1;
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);
102 m_currentBlock = m_macroBlocks[m_lastMacroBlock++];
103 } else {
104 m_macroBlocks = 0;
105 m_macroBlockLen = 1;
106 m_currentBlock = new CMacroBlock(this);
107 }
108
109 // save file position
110 m_startPosition = m_stream->GetPos();
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
142 m_levelLengthPos = m_stream->GetPos();
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
165 m_stream->SetPos(FSFromStart, m_startPosition);
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) THROW_ {
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
186 m_levelLengthPos = m_stream->GetPos();
187
188 // write dummy levelLength
189 int count = m_nLevels*WordBytes;
190 m_stream->Write(&count, m_levelLength);
191
192 // save current file position
193 SetBufferStartPos();
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) THROW_ {
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
310void CEncoder::Flush() THROW_ {
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) THROW_ {
327 if (m_currentBlock->m_valuePos == BufferSize) {
328 EncodeBuffer(ROIBlockHeader(BufferSize, false));
329 }
330 DataT val = m_currentBlock->m_value[m_currentBlock->m_valuePos++] = band->GetData(bandPos);
331 UINT32 v = abs(val);
332 if (v > m_currentBlock->m_maxAbsValue) m_currentBlock->m_maxAbsValue = v;
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
348 m_currentBlock->m_header = h;
349
350 // macro block management
351 if (m_macroBlockLen == 1) {
352 m_currentBlock->BitplaneEncode();
353 WriteMacroBlock(m_currentBlock);
354 } else {
355 // save last level index
356 int lastLevelIndex = m_currentBlock->m_lastLevelIndex;
357
358 if (m_forceWriting || m_lastMacroBlock == m_macroBlockLen) {
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++) {
387 m_macroBlocks[i]->BitplaneEncode();
388 }
389 for (int i=0; i < m_lastMacroBlock; i++) {
390 WriteMacroBlock(m_macroBlocks[i]);
391 }
392
393 // prepare for next round
394 m_forceWriting = false;
395 m_lastMacroBlock = 0;
396 }
397 // re-initialize macro block
398 m_currentBlock = m_macroBlocks[m_lastMacroBlock++];
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 h.val = __VAL(h.val);
428 m_stream->Write(&count, &h.val); ASSERT(count == sizeof(UINT16));
429 }
430#endif // __PGFROISUPPORT__
431
432 // convert data
433 for (int i=0; i < wordLen; i++) {
434 block->m_codeBuffer[i] = __VAL(block->m_codeBuffer[i]);
435 }
436#else
437 // write wordLen
438 m_stream->Write(&count, &wordLen); ASSERT(count == sizeof(UINT16));
439
440#ifdef __PGFROISUPPORT__
441 // write ROIBlockHeader
442 if (m_roi) {
443 m_stream->Write(&count, &h.val); ASSERT(count == sizeof(UINT16));
444 }
445#endif // __PGFROISUPPORT__
446#endif // PGF_USE_BIG_ENDIAN
447
448 // write encoded data into stream
449 count = wordLen*WordBytes;
450 m_stream->Write(&count, block->m_codeBuffer);
451
452 // store levelLength
453 if (m_levelLength) {
454 // store level length
455 // EncodeBuffer has been called after m_lastLevelIndex has been updated
456 ASSERT(m_currLevelIndex < m_nLevels);
457 m_levelLength[m_currLevelIndex] += (UINT32)ComputeBufferLength();
458 m_currLevelIndex = block->m_lastLevelIndex + 1;
459
460 }
461
462 // prepare for next buffer
463 SetBufferStartPos();
464
465 // reset values
466 block->m_valuePos = 0;
467 block->m_maxAbsValue = 0;
468}
469
471// Encode buffer of given size using bit plane coding.
472// A buffer contains bufferLen UINT32 values, thus, bufferSize bits per bit plane.
473// Following coding scheme is used:
474// Buffer ::= <nPlanes>(5 bits) foreach(plane i): Plane[i]
475// Plane[i] ::= [ Sig1 | Sig2 ] [DWORD alignment] refBits
476// Sig1 ::= 1 <codeLen>(15 bits) codedSigAndSignBits
477// Sig2 ::= 0 <sigLen>(15 bits) [Sign1 | Sign2 ] [DWORD alignment] sigBits
478// Sign1 ::= 1 <codeLen>(15 bits) codedSignBits
479// Sign2 ::= 0 <signLen>(15 bits) [DWORD alignment] signBits
481 UINT8 nPlanes;
482 UINT32 sigLen, codeLen = 0, wordPos, refLen, signLen;
483 UINT32 sigBits[BufferLen] = { 0 };
484 UINT32 refBits[BufferLen] = { 0 };
485 UINT32 signBits[BufferLen] = { 0 };
486 UINT32 planeMask;
487 UINT32 bufferSize = m_header.rbh.bufferSize; ASSERT(bufferSize <= BufferSize);
488 bool useRL;
489
490#ifdef TRACE
491 //printf("which thread: %d\n", omp_get_thread_num());
492#endif
493
494 // clear significance vector
495 for (UINT32 k=0; k < bufferSize; k++) {
496 m_sigFlagVector[k] = false;
497 }
498 m_sigFlagVector[bufferSize] = true; // sentinel
499
500 // clear output buffer
501 for (UINT32 k=0; k < bufferSize; k++) {
502 m_codeBuffer[k] = 0;
503 }
504 m_codePos = 0;
505
506 // compute number of bit planes and split buffer into separate bit planes
507 nPlanes = NumberOfBitplanes();
508
509 // write number of bit planes to m_codeBuffer
510 // <nPlanes>
513
514 // loop through all bit planes
515 if (nPlanes == 0) nPlanes = MaxBitPlanes + 1;
516 planeMask = 1 << (nPlanes - 1);
517
518 for (int plane = nPlanes - 1; plane >= 0; plane--) {
519 // clear significant bitset
520 for (UINT32 k=0; k < BufferLen; k++) {
521 sigBits[k] = 0;
522 }
523
524 // split bitplane in significant bitset and refinement bitset
525 sigLen = DecomposeBitplane(bufferSize, planeMask, m_codePos + RLblockSizeLen + 1, sigBits, refBits, signBits, signLen, codeLen);
526
527 if (sigLen > 0 && codeLen <= MaxCodeLen && codeLen < AlignWordPos(sigLen) + AlignWordPos(signLen) + 2*RLblockSizeLen) {
528 // set RL code bit
529 // <1><codeLen>
531
532 // write length codeLen to m_codeBuffer
534 m_codePos += RLblockSizeLen + codeLen;
535 } else {
536 #ifdef TRACE
537 //printf("new\n");
538 //for (UINT32 i=0; i < bufferSize; i++) {
539 // printf("%s", (GetBit(sigBits, i)) ? "1" : "_");
540 // if (i%120 == 119) printf("\n");
541 //}
542 //printf("\n");
543 #endif // TRACE
544
545 // run-length coding wasn't efficient enough
546 // we don't use RL coding for sigBits
547 // <0><sigLen>
549
550 // write length sigLen to m_codeBuffer
551 ASSERT(sigLen <= MaxCodeLen);
554
555 if (m_encoder->m_favorSpeed || signLen == 0) {
556 useRL = false;
557 } else {
558 // overwrite m_codeBuffer
559 useRL = true;
560 // run-length encode m_sign and append them to the m_codeBuffer
561 codeLen = RLESigns(m_codePos + RLblockSizeLen + 1, signBits, signLen);
562 }
563
564 if (useRL && codeLen <= MaxCodeLen && codeLen < signLen) {
565 // RL encoding of m_sign was efficient
566 // <1><codeLen><codedSignBits>_
567 // write RL code bit
569
570 // write codeLen to m_codeBuffer
572
573 // compute position of sigBits
574 wordPos = NumberOfWords(m_codePos + RLblockSizeLen + codeLen);
575 ASSERT(0 <= wordPos && wordPos < CodeBufferLen);
576 } else {
577 // RL encoding of signBits wasn't efficient
578 // <0><signLen>_<signBits>_
579 // clear RL code bit
581
582 // write signLen to m_codeBuffer
583 ASSERT(signLen <= MaxCodeLen);
585
586 // write signBits to m_codeBuffer
588 ASSERT(0 <= wordPos && wordPos < CodeBufferLen);
589 codeLen = NumberOfWords(signLen);
590
591 for (UINT32 k=0; k < codeLen; k++) {
592 m_codeBuffer[wordPos++] = signBits[k];
593 }
594 }
595
596 // write sigBits
597 // <sigBits>_
598 ASSERT(0 <= wordPos && wordPos < CodeBufferLen);
599 refLen = NumberOfWords(sigLen);
600
601 for (UINT32 k=0; k < refLen; k++) {
602 m_codeBuffer[wordPos++] = sigBits[k];
603 }
604 m_codePos = wordPos << WordWidthLog;
605 }
606
607 // append refinement bitset (aligned to word boundary)
608 // _<refBits>
609 wordPos = NumberOfWords(m_codePos);
610 ASSERT(0 <= wordPos && wordPos < CodeBufferLen);
611 refLen = NumberOfWords(bufferSize - sigLen);
612
613 for (UINT32 k=0; k < refLen; k++) {
614 m_codeBuffer[wordPos++] = refBits[k];
615 }
616 m_codePos = wordPos << WordWidthLog;
617 planeMask >>= 1;
618 }
619 ASSERT(0 <= m_codePos && m_codePos <= CodeBufferBitLen);
620}
621
623// Split bitplane of length bufferSize into significant and refinement bitset
624// returns length [bits] of significant bits
625// input: bufferSize, planeMask, codePos
626// output: sigBits, refBits, signBits, signLen [bits], codeLen [bits]
627// RLE
628// - Encode run of 2^k zeros by a single 0.
629// - Encode run of count 0's followed by a 1 with codeword: 1<count>x
630// - x is 0: if a positive sign is stored, otherwise 1
631// - Store each bit in m_codeBuffer[codePos] and increment codePos.
632UINT32 CEncoder::CMacroBlock::DecomposeBitplane(UINT32 bufferSize, UINT32 planeMask, UINT32 codePos, UINT32* sigBits, UINT32* refBits, UINT32* signBits, UINT32& signLen, UINT32& codeLen) {
633 ASSERT(sigBits);
634 ASSERT(refBits);
635 ASSERT(signBits);
636 ASSERT(codePos < CodeBufferBitLen);
637
638 UINT32 sigPos = 0;
639 UINT32 valuePos = 0, valueEnd;
640 UINT32 refPos = 0;
641
642 // set output value
643 signLen = 0;
644
645 // prepare RLE of Sigs and Signs
646 const UINT32 outStartPos = codePos;
647 UINT32 k = 3;
648 UINT32 runlen = 1 << k; // = 2^k
649 UINT32 count = 0;
650
651 while (valuePos < bufferSize) {
652 // search next 1 in m_sigFlagVector using searching with sentinel
653 valueEnd = valuePos;
654 while(!m_sigFlagVector[valueEnd]) { valueEnd++; }
655
656 // search 1's in m_value[plane][valuePos..valueEnd)
657 // these 1's are significant bits
658 while (valuePos < valueEnd) {
659 if (GetBitAtPos(valuePos, planeMask)) {
660 // RLE encoding
661 // encode run of count 0's followed by a 1
662 // with codeword: 1<count>(signBits[signPos])
663 SetBit(m_codeBuffer, codePos++);
664 if (k > 0) {
665 SetValueBlock(m_codeBuffer, codePos, count, k);
666 codePos += k;
667
668 // adapt k (half the zero run-length)
669 k--;
670 runlen >>= 1;
671 }
672
673 // copy and write sign bit
674 if (m_value[valuePos] < 0) {
675 SetBit(signBits, signLen++);
676 SetBit(m_codeBuffer, codePos++);
677 } else {
678 ClearBit(signBits, signLen++);
679 ClearBit(m_codeBuffer, codePos++);
680 }
681
682 // write a 1 to sigBits
683 SetBit(sigBits, sigPos++);
684
685 // update m_sigFlagVector
686 m_sigFlagVector[valuePos] = true;
687
688 // prepare for next run
689 count = 0;
690 } else {
691 // RLE encoding
692 count++;
693 if (count == runlen) {
694 // encode run of 2^k zeros by a single 0
695 ClearBit(m_codeBuffer, codePos++);
696 // adapt k (double the zero run-length)
697 if (k < WordWidth) {
698 k++;
699 runlen <<= 1;
700 }
701
702 // prepare for next run
703 count = 0;
704 }
705
706 // write 0 to sigBits
707 sigPos++;
708 }
709 valuePos++;
710 }
711 // refinement bit
712 if (valuePos < bufferSize) {
713 // write one refinement bit
714 if (GetBitAtPos(valuePos++, planeMask)) {
715 SetBit(refBits, refPos);
716 } else {
717 ClearBit(refBits, refPos);
718 }
719 refPos++;
720 }
721 }
722 // RLE encoding of the rest of the plane
723 // encode run of count 0's followed by a 1
724 // with codeword: 1<count>(signBits[signPos])
725 SetBit(m_codeBuffer, codePos++);
726 if (k > 0) {
727 SetValueBlock(m_codeBuffer, codePos, count, k);
728 codePos += k;
729 }
730 // write dmmy sign bit
731 SetBit(m_codeBuffer, codePos++);
732
733 // write word filler zeros
734
735 ASSERT(sigPos <= bufferSize);
736 ASSERT(refPos <= bufferSize);
737 ASSERT(signLen <= bufferSize);
738 ASSERT(valuePos == bufferSize);
739 ASSERT(codePos >= outStartPos && codePos < CodeBufferBitLen);
740 codeLen = codePos - outStartPos;
741
742 return sigPos;
743}
744
745
747// Compute number of bit planes needed
749 UINT8 cnt = 0;
750
751 // determine number of bitplanes for max value
752 if (m_maxAbsValue > 0) {
753 while (m_maxAbsValue > 0) {
754 m_maxAbsValue >>= 1; cnt++;
755 }
756 if (cnt == MaxBitPlanes + 1) cnt = 0;
757 // end cs
758 ASSERT(cnt <= MaxBitPlanes);
759 ASSERT((cnt >> MaxBitPlanesLog) == 0);
760 return cnt;
761 } else {
762 return 1;
763 }
764}
765
767// Adaptive Run-Length encoder for long sequences of ones.
768// Returns length of output in bits.
769// - Encode run of 2^k ones by a single 1.
770// - Encode run of count 1's followed by a 0 with codeword: 0<count>.
771// - Store each bit in m_codeBuffer[codePos] and increment codePos.
772UINT32 CEncoder::CMacroBlock::RLESigns(UINT32 codePos, UINT32* signBits, UINT32 signLen) {
773 ASSERT(signBits);
774 ASSERT(0 <= codePos && codePos < CodeBufferBitLen);
775 ASSERT(0 < signLen && signLen <= BufferSize);
776
777 const UINT32 outStartPos = codePos;
778 UINT32 k = 0;
779 UINT32 runlen = 1 << k; // = 2^k
780 UINT32 count = 0;
781 UINT32 signPos = 0;
782
783 while (signPos < signLen) {
784 // search next 0 in signBits starting at position signPos
785 count = SeekBit1Range(signBits, signPos, __min(runlen, signLen - signPos));
786 // count 1's found
787 if (count == runlen) {
788 // encode run of 2^k ones by a single 1
789 signPos += count;
790 SetBit(m_codeBuffer, codePos++);
791 // adapt k (double the 1's run-length)
792 if (k < WordWidth) {
793 k++;
794 runlen <<= 1;
795 }
796 } else {
797 // encode run of count 1's followed by a 0
798 // with codeword: 0(count)
799 signPos += count + 1;
800 ClearBit(m_codeBuffer, codePos++);
801 if (k > 0) {
802 SetValueBlock(m_codeBuffer, codePos, count, k);
803 codePos += k;
804 }
805 // adapt k (half the 1's run-length)
806 if (k > 0) {
807 k--;
808 runlen >>= 1;
809 }
810 }
811 }
812 ASSERT(signPos == signLen || signPos == signLen + 1);
813 ASSERT(codePos >= outStartPos && codePos < CodeBufferBitLen);
814 return codePos - outStartPos;
815}
816
818#ifdef TRACE
819void CEncoder::DumpBuffer() const {
820 //printf("\nDump\n");
821 //for (UINT32 i=0; i < BufferSize; i++) {
822 // printf("%d", m_value[i]);
823 //}
824 //printf("\n");
825}
826#endif //TRACE
827
828
UINT32 AlignWordPos(UINT32 pos)
Definition: BitStream.h:260
void SetBit(UINT32 *stream, UINT32 pos)
Definition: BitStream.h:48
void SetValueBlock(UINT32 *stream, UINT32 pos, UINT32 val, UINT32 k)
Definition: BitStream.h:102
void ClearBit(UINT32 *stream, UINT32 pos)
Definition: BitStream.h:56
UINT32 SeekBit1Range(UINT32 *stream, UINT32 pos, UINT32 len)
Definition: BitStream.h:235
UINT32 NumberOfWords(UINT32 pos)
Definition: BitStream.h:269
#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
#define CodeBufferLen
number of words in code buffer (CodeBufferLen > BufferLen)
Definition: Decoder.h:40
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 __VAL(x)
Definition: PGFplatform.h:604
#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
Definition: PGFplatform.h:100
#define MaxBitPlanesLog
number of bits to code the maximum number of bit planes (in 32 or 16 bit mode)
Definition: PGFtypes.h:86
#define PreHeaderSize
Definition: PGFtypes.h:230
#define HeaderSize
Definition: PGFtypes.h:231
#define ColorTableSize
Definition: PGFtypes.h:232
#define LinBlockSize
side length of a coefficient block in a HH or LL subband
Definition: PGFtypes.h:79
#define BufferSize
must be a multiple of WordWidth
Definition: PGFtypes.h:77
#define RLblockSizeLen
block size length (< 16): ld(BufferSize) < RLblockSizeLen <= 2*ld(BufferSize)
Definition: PGFtypes.h:78
INT32 DataT
Definition: PGFtypes.h:219
#define DataTSize
Definition: PGFtypes.h:233
#define MaxBitPlanes
maximum number of bit planes of m_value: 32 minus sign bit
Definition: PGFtypes.h:82
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
UINT8 NumberOfBitplanes()
Definition: Encoder.cpp:748
UINT32 DecomposeBitplane(UINT32 bufferSize, UINT32 planeMask, UINT32 codePos, UINT32 *sigBits, UINT32 *refBits, UINT32 *signBits, UINT32 &signLen, UINT32 &codeLen)
Definition: Encoder.cpp:632
UINT32 RLESigns(UINT32 codePos, UINT32 *signBits, UINT32 signLen)
Definition: Encoder.cpp:772
UINT32 m_codeBuffer[CodeBufferLen]
output buffer for encoded bitstream
Definition: Encoder.h:85
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
ROIBlockHeader m_header
block header
Definition: Encoder.h:86
CEncoder * m_encoder
Definition: Encoder.h:98
bool m_favorSpeed
favor speed over size
Definition: Encoder.h:222
void Flush() THROW_
Definition: Encoder.cpp:310
bool m_forceWriting
all macro blocks have to be written into the stream
Definition: Encoder.h:223
UINT64 m_levelLengthPos
stream position of Metadata
Definition: Encoder.h:211
CMacroBlock * m_currentBlock
current macro block (used by main thread)
Definition: Encoder.h:217
void WriteMacroBlock(CMacroBlock *block) THROW_
Definition: Encoder.cpp:406
UINT32 * m_levelLength
temporary saves the level index
Definition: Encoder.h:219
CMacroBlock ** m_macroBlocks
array of macroblocks
Definition: Encoder.h:214
void WriteValue(CSubband *band, int bandPos) THROW_
Definition: Encoder.cpp:326
int m_currLevelIndex
counts where (=index) to save next value
Definition: Encoder.h:220
UINT32 WriteLevelLength(UINT32 *&levelLength) THROW_
Definition: Encoder.cpp:177
~CEncoder()
Destructor.
Definition: Encoder.cpp:147
UINT32 UpdateLevelLength() THROW_
Definition: Encoder.cpp:202
void Partition(CSubband *band, int width, int height, int startPos, int pitch) THROW_
Definition: Encoder.cpp:246
CPGFStream * m_stream
output PMF stream
Definition: Encoder.h:209
CEncoder(CPGFStream *stream, PGFPreHeader preHeader, PGFHeader header, const PGFPostHeader &postHeader, UINT64 &userDataPos, bool useOMP) THROW_
Definition: Encoder.cpp:70
void EncodeBuffer(ROIBlockHeader h) THROW_
Definition: Encoder.cpp:341
int m_macroBlockLen
array length
Definition: Encoder.h:215
void UpdatePostHeaderSize(PGFPreHeader preHeader) THROW_
Definition: Encoder.cpp:160
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
PGF header.
Definition: PGFtypes.h:123
Optional PGF post-header.
Definition: PGFtypes.h:141
PGF pre-header.
Definition: PGFtypes.h:114
UINT16 bufferSize
number of uncoded UINT32 values in a block
Definition: PGFtypes.h:167
Block header used with ROI coding scheme
Definition: PGFtypes.h:151
struct ROIBlockHeader::RBH rbh
ROI block header.
UINT16 val
Definition: PGFtypes.h:160