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