libpgf  6.14.12
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  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 
177 UINT32 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 
246 void 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 
310 void 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.
326 void 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.
632 UINT32 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.
772 UINT32 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
819 void 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 
#define ImageModeIndexedColor
Definition: PGFplatform.h:100
struct ROIBlockHeader::RBH rbh
ROI block header.
UINT16 bufferSize
number of uncoded UINT32 values in a block
Definition: PGFtypes.h:167
UINT8 NumberOfBitplanes()
Definition: Encoder.cpp:748
int m_macroBlockLen
array length
Definition: Encoder.h:215
virtual void Write(int *count, void *buffer)=0
UINT32 AlignWordPos(UINT32 pos)
Definition: BitStream.h:260
void WriteMacroBlock(CMacroBlock *block) THROW_
Definition: Encoder.cpp:406
UINT32 m_valuePos
current buffer position
Definition: Encoder.h:87
Abstract stream base class.
Definition: PGFstream.h:39
void Flush() THROW_
Definition: Encoder.cpp:310
#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:147
#define __VAL(x)
Definition: PGFplatform.h:604
#define BufferSize
must be a multiple of WordWidth
Definition: PGFtypes.h:77
UINT32 m_codePos
current position in encoded bitstream
Definition: Encoder.h:89
UINT32 RLESigns(UINT32 codePos, UINT32 *signBits, UINT32 signLen)
Definition: Encoder.cpp:772
#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:177
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
bool m_sigFlagVector[BufferSize+1]
Definition: Encoder.h:99
UINT32 * m_levelLength
temporary saves the level index
Definition: Encoder.h:219
void EncodeBuffer(ROIBlockHeader h) THROW_
Definition: Encoder.cpp:341
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:632
void Partition(CSubband *band, int width, int height, int startPos, int pitch) THROW_
Definition: Encoder.cpp:246
#define WordBytes
sizeof(UINT32)
Definition: PGFplatform.h:76
bool m_forceWriting
all macro blocks have to be written into the stream
Definition: Encoder.h:223
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:217
PGF encoder class.
UINT32 UpdateLevelLength() THROW_
Definition: Encoder.cpp:202
CEncoder * m_encoder
Definition: Encoder.h:98
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:214
UINT32 m_codeBuffer[CodeBufferLen]
output buffer for encoded bitstream
Definition: Encoder.h:85
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:209
UINT64 m_levelLengthPos
stream position of Metadata
Definition: Encoder.h:211
UINT16 val
Definition: PGFtypes.h:160
void WriteValue(CSubband *band, int bandPos) THROW_
Definition: Encoder.cpp:326
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
bool m_favorSpeed
favor speed over size
Definition: Encoder.h:222
int m_currLevelIndex
counts where (=index) to save next value
Definition: Encoder.h:220
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:84
ROIBlockHeader m_header
block header
Definition: Encoder.h:86
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 UpdatePostHeaderSize(PGFPreHeader preHeader) THROW_
Definition: Encoder.cpp:160
#define CodeBufferBitLen
max number of bits in m_codeBuffer
Definition: Encoder.cpp:58