libpgf  7.15.32
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)
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 = nullptr;
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
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) {
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 
246 void 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.
326 void 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;
395  m_lastMacroBlock = 0;
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);
460  m_currLevelIndex = block->m_lastLevelIndex + 1;
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.
634 UINT32 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.
774 UINT32 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
821 void 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 
CEncoder(CPGFStream *stream, PGFPreHeader preHeader, PGFHeader header, const PGFPostHeader &postHeader, UINT64 &userDataPos, bool useOMP)
Definition: Encoder.cpp:70
#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:195
UINT8 mode
image mode according to Adobe&#39;s image modes
Definition: PGFtypes.h:158
UINT8 NumberOfBitplanes()
Definition: Encoder.cpp:750
int m_macroBlockLen
array length
Definition: Encoder.h:219
void SetBufferStartPos()
Save current stream position as beginning of current level.
Definition: Encoder.h:192
virtual void Write(int *count, void *buffer)=0
UINT32 AlignWordPos(UINT32 pos)
Definition: BitStream.h:328
UINT32 m_valuePos
current buffer position
Definition: Encoder.h:87
Abstract stream base class.
Definition: PGFstream.h:39
UINT32 width
image width in pixels
Definition: PGFtypes.h:152
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
#define LinBlockSize
side length of a coefficient block in a HH or LL subband
Definition: PGFtypes.h:86
DataT GetData(UINT32 pos) const
Definition: Subband.h:113
#define ColorTableSize
Definition: PGFtypes.h:275
INT32 DataT
Definition: PGFtypes.h:262
~CEncoder()
Destructor.
Definition: Encoder.cpp:147
#define __VAL(x)
Definition: PGFplatform.h:601
UINT32 userDataLen
user data size in bytes (not part of file header)
Definition: PGFtypes.h:171
UINT8 * userData
user data of size userDataLen (optional part of file header)
Definition: PGFtypes.h:170
void EncodeBuffer(ROIBlockHeader h)
Definition: Encoder.cpp:341
#define BufferSize
must be a multiple of WordWidth, BufferSize <= UINT16_MAX
Definition: PGFtypes.h:84
UINT32 m_maxAbsValue
maximum absolute coefficient in each buffer
Definition: Encoder.h:88
UINT32 m_codePos
current position in encoded bitstream
Definition: Encoder.h:89
UINT32 RLESigns(UINT32 codePos, UINT32 *signBits, UINT32 signLen)
Definition: Encoder.cpp:774
#define DataTSize
Definition: PGFtypes.h:276
#define HeaderSize
Definition: PGFtypes.h:274
virtual void SetPos(short posMode, INT64 posOff)=0
PGF pre-header.
Definition: PGFtypes.h:123
#define RLblockSizeLen
block size length (< 16): ld(BufferSize) < RLblockSizeLen <= 2*ld(BufferSize)
Definition: PGFtypes.h:85
Wavelet channel class.
Definition: Subband.h:42
UINT32 WriteLevelLength(UINT32 *&levelLength)
Definition: Encoder.cpp:177
bool m_sigFlagVector[BufferSize+1]
Definition: Encoder.h:99
UINT32 * m_levelLength
temporary saves the level index
Definition: Encoder.h:223
Block header used with ROI coding scheme.
Definition: PGFtypes.h:179
void WriteMacroBlock(CMacroBlock *block)
Definition: Encoder.cpp:406
PGF header.
Definition: PGFtypes.h:150
#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:70
void UpdatePostHeaderSize(PGFPreHeader preHeader)
Definition: Encoder.cpp:160
#define MaxBitPlanesLog
number of bits to code the maximum number of bit planes (in 32 or 16 bit mode)
Definition: PGFtypes.h:93
#define __PGFROISUPPORT__
Definition: PGFplatform.h:60
#define PreHeaderSize
Definition: PGFtypes.h:273
UINT32 DecomposeBitplane(UINT32 bufferSize, UINT32 planeMask, UINT32 codePos, UINT32 *sigBits, UINT32 *refBits, UINT32 *signBits, UINT32 &signLen, UINT32 &codeLen)
Definition: Encoder.cpp:634
INT64 ComputeBufferLength() const
Definition: Encoder.h:179
#define WordBytes
sizeof(UINT32)
Definition: PGFplatform.h:76
bool m_forceWriting
all macro blocks have to be written into the stream
Definition: Encoder.h:227
UINT32 SeekBit1Range(UINT32 *stream, UINT32 pos, UINT32 len)
Definition: BitStream.h:249
CMacroBlock * m_currentBlock
current macro block (used by main thread)
Definition: Encoder.h:221
UINT32 hSize
total size of PGFHeader, [ColorTable], and [UserData] in bytes (since Version 6: 4 Bytes) ...
Definition: PGFtypes.h:124
PGF encoder class.
CEncoder * m_encoder
Definition: Encoder.h:98
Optional PGF post-header.
Definition: PGFtypes.h:168
#define __min(x, y)
Definition: PGFplatform.h:91
CMacroBlock ** m_macroBlocks
array of macroblocks
Definition: Encoder.h:218
void Partition(CSubband *band, int width, int height, int startPos, int pitch)
Definition: Encoder.cpp:246
void SetStreamPosToStart()
Resets stream position to beginning of PGF pre-header.
Definition: Encoder.h:188
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:62
void Flush()
Definition: Encoder.cpp:310
virtual UINT64 GetPos() const =0
CPGFStream * m_stream
output PMF stream
Definition: Encoder.h:213
UINT64 m_levelLengthPos
stream position of Metadata
Definition: Encoder.h:215
UINT16 val
Definition: PGFtypes.h:188
UINT32 NumberOfWords(UINT32 pos)
Definition: BitStream.h:337
UINT32 UpdateLevelLength()
Definition: Encoder.cpp:202
#define MaxBitPlanes
maximum number of bit planes of m_value: 32 minus sign bit
Definition: PGFtypes.h:89
bool m_favorSpeed
favor speed over size
Definition: Encoder.h:226
int m_currLevelIndex
counts where (=index) to save next value
Definition: Encoder.h:224
void SetValueBlock(UINT32 *stream, UINT32 pos, UINT32 val, UINT32 k)
Definition: BitStream.h:116
DataT m_value[BufferSize]
input buffer of values with index m_valuePos
Definition: Encoder.h:84
void WriteValue(CSubband *band, int bandPos)
Definition: Encoder.cpp:326
ROIBlockHeader m_header
block header
Definition: Encoder.h:86
int m_lastMacroBlock
array index of the last created macro block
Definition: Encoder.h:220
UINT8 m_nLevels
number of levels
Definition: Encoder.h:225
UINT32 height
image height in pixels
Definition: PGFtypes.h:153
RGBQUAD clut[ColorTableLen]
color table for indexed color images (optional part of file header)
Definition: PGFtypes.h:169
#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:71
#define CodeBufferBitLen
max number of bits in m_codeBuffer
Definition: Encoder.cpp:58