libpgf 6.14.12
PGF - Progressive Graphics File
CEncoder Class Reference

PGF encoder. More...

#include <Encoder.h>

Classes

class  CMacroBlock
 A macro block is an encoding unit of fixed size (uncoded) More...
 

Public Member Functions

 CEncoder (CPGFStream *stream, PGFPreHeader preHeader, PGFHeader header, const PGFPostHeader &postHeader, UINT64 &userDataPos, bool useOMP) THROW_
 
 ~CEncoder ()
 Destructor. More...
 
void FavorSpeedOverSize ()
 Encoder favors speed over compression size. More...
 
void Flush () THROW_
 
void UpdatePostHeaderSize (PGFPreHeader preHeader) THROW_
 
UINT32 WriteLevelLength (UINT32 *&levelLength) THROW_
 
UINT32 UpdateLevelLength () THROW_
 
void Partition (CSubband *band, int width, int height, int startPos, int pitch) THROW_
 
void SetEncodedLevel (int currentLevel)
 
void WriteValue (CSubband *band, int bandPos) THROW_
 
INT64 ComputeHeaderLength () const
 
INT64 ComputeBufferLength () const
 
INT64 ComputeOffset () const
 
void SetBufferStartPos ()
 Save current stream position as beginning of current level. More...
 

Private Member Functions

void EncodeBuffer (ROIBlockHeader h) THROW_
 
void WriteMacroBlock (CMacroBlock *block) THROW_
 

Private Attributes

CPGFStreamm_stream
 output PMF stream More...
 
UINT64 m_startPosition
 stream position of PGF start (PreHeader) More...
 
UINT64 m_levelLengthPos
 stream position of Metadata More...
 
UINT64 m_bufferStartPos
 stream position of encoded buffer More...
 
CMacroBlock ** m_macroBlocks
 array of macroblocks More...
 
int m_macroBlockLen
 array length More...
 
int m_lastMacroBlock
 array index of the last created macro block More...
 
CMacroBlockm_currentBlock
 current macro block (used by main thread) More...
 
UINT32 * m_levelLength
 temporary saves the level index More...
 
int m_currLevelIndex
 counts where (=index) to save next value More...
 
UINT8 m_nLevels
 number of levels More...
 
bool m_favorSpeed
 favor speed over size More...
 
bool m_forceWriting
 all macro blocks have to be written into the stream More...
 

Detailed Description

PGF encoder.

PGF encoder class.

Author
C. Stamm

Definition at line 46 of file Encoder.h.

Constructor & Destructor Documentation

◆ CEncoder()

CEncoder::CEncoder ( CPGFStream stream,
PGFPreHeader  preHeader,
PGFHeader  header,
const PGFPostHeader postHeader,
UINT64 &  userDataPos,
bool  useOMP 
)

Write pre-header, header, post-Header, and levelLength. It might throw an IOException.

Parameters
streamA PGF stream
preHeaderA already filled in PGF pre-header
headerAn already filled in PGF header
postHeader[in] An already filled in PGF post-header (containing color table, user data, ...)
userDataPos[out] File position of user data
useOMPIf true, then the encoder will use multi-threading based on openMP

Write pre-header, header, postHeader, and levelLength. It might throw an IOException.

Parameters
streamA PGF stream
preHeaderA already filled in PGF pre-header
headerAn already filled in PGF header
postHeader[in] An already filled in PGF post-header (containing color table, user data, ...)
userDataPos[out] File position of user data
useOMPIf true, then the encoder will use multi-threading based on openMP

Definition at line 70 of file Encoder.cpp.

71: m_stream(stream)
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;
85 m_levelLength = NULL;
86
87 // set number of threads
88#ifdef LIBPGF_USE_OPENMP
89 m_macroBlockLen = omp_get_num_procs();
90#else
92#endif
93
94 if (useOMP && m_macroBlockLen > 1) {
95#ifdef LIBPGF_USE_OPENMP
96 omp_set_num_threads(m_macroBlockLen);
97#endif
98 // create macro block array
99 m_macroBlocks = new(std::nothrow) CMacroBlock*[m_macroBlockLen];
100 if (!m_macroBlocks) ReturnWithError(InsufficientMemory);
101 for (int i=0; i < m_macroBlockLen; i++) m_macroBlocks[i] = new CMacroBlock(this);
103 } else {
104 m_macroBlocks = 0;
105 m_macroBlockLen = 1;
106 m_currentBlock = new CMacroBlock(this);
107 }
108
109 // save file position
111
112 // write preHeader
113 preHeader.hSize = __VAL(preHeader.hSize);
114 count = PreHeaderSize;
115 m_stream->Write(&count, &preHeader);
116
117 // write file header
118 header.height = __VAL(header.height);
119 header.width = __VAL(header.width);
120 count = HeaderSize;
121 m_stream->Write(&count, &header);
122
123 // write postHeader
124 if (header.mode == ImageModeIndexedColor) {
125 // write color table
126 count = ColorTableSize;
127 m_stream->Write(&count, (void *)postHeader.clut);
128 }
129 // save user data file position
130 userDataPos = m_stream->GetPos();
131 if (postHeader.userDataLen) {
132 if (postHeader.userData) {
133 // write user data
134 count = postHeader.userDataLen;
135 m_stream->Write(&count, postHeader.userData);
136 } else {
137 m_stream->SetPos(FSFromCurrent, count);
138 }
139 }
140
141 // save level length file position
143}
#define __VAL(x)
Definition: PGFplatform.h:604
#define ImageModeIndexedColor
Definition: PGFplatform.h:100
#define PreHeaderSize
Definition: PGFtypes.h:230
#define HeaderSize
Definition: PGFtypes.h:231
#define ColorTableSize
Definition: PGFtypes.h:232
UINT64 m_bufferStartPos
stream position of encoded buffer
Definition: Encoder.h:212
bool m_favorSpeed
favor speed over size
Definition: Encoder.h:222
UINT64 m_startPosition
stream position of PGF start (PreHeader)
Definition: Encoder.h:210
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
UINT32 * m_levelLength
temporary saves the level index
Definition: Encoder.h:219
CMacroBlock ** m_macroBlocks
array of macroblocks
Definition: Encoder.h:214
UINT8 m_nLevels
number of levels
Definition: Encoder.h:221
int m_currLevelIndex
counts where (=index) to save next value
Definition: Encoder.h:220
int m_lastMacroBlock
array index of the last created macro block
Definition: Encoder.h:216
CPGFStream * m_stream
output PMF stream
Definition: Encoder.h:209
int m_macroBlockLen
array length
Definition: Encoder.h:215
virtual void Write(int *count, void *buffer)=0
virtual void SetPos(short posMode, INT64 posOff)=0
virtual UINT64 GetPos() const =0
UINT8 mode
image mode according to Adobe's image modes
Definition: PGFtypes.h:131
UINT32 height
image height in pixels
Definition: PGFtypes.h:126
UINT32 width
image width in pixels
Definition: PGFtypes.h:125
UINT8 nLevels
number of DWT levels
Definition: PGFtypes.h:127
UINT32 userDataLen
user data size in bytes
Definition: PGFtypes.h:144
RGBQUAD clut[ColorTableLen]
color table for indexed color images
Definition: PGFtypes.h:142
UINT8 * userData
user data of size userDataLen
Definition: PGFtypes.h:143
UINT32 hSize
total size of PGFHeader, [ColorTable], and [UserData] in bytes
Definition: PGFtypes.h:115

◆ ~CEncoder()

CEncoder::~CEncoder ( )

Destructor.

Definition at line 147 of file Encoder.cpp.

147 {
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}

Member Function Documentation

◆ ComputeBufferLength()

INT64 CEncoder::ComputeBufferLength ( ) const
inline

Compute stream length of encoded buffer.

Returns
encoded buffer length

Definition at line 179 of file Encoder.h.

179{ return m_stream->GetPos() - m_bufferStartPos; }

◆ ComputeHeaderLength()

INT64 CEncoder::ComputeHeaderLength ( ) const
inline

Compute stream length of header.

Returns
header length

Definition at line 174 of file Encoder.h.

◆ ComputeOffset()

INT64 CEncoder::ComputeOffset ( ) const
inline

Compute file offset between real and expected levelLength position.

Returns
file offset

Definition at line 184 of file Encoder.h.

184{ return m_stream->GetPos() - m_levelLengthPos; }

◆ EncodeBuffer()

void CEncoder::EncodeBuffer ( ROIBlockHeader  h)
private

Definition at line 341 of file Encoder.cpp.

341 {
342 ASSERT(m_currentBlock);
343#ifdef __PGFROISUPPORT__
344 ASSERT(m_roi && h.rbh.bufferSize <= BufferSize || h.rbh.bufferSize == BufferSize);
345#else
346 ASSERT(h.rbh.bufferSize == BufferSize);
347#endif
349
350 // macro block management
351 if (m_macroBlockLen == 1) {
354 } else {
355 // save last level index
356 int lastLevelIndex = m_currentBlock->m_lastLevelIndex;
357
359 // encode macro blocks
360 /*
361 volatile OSError error = NoError;
362 #ifdef LIBPGF_USE_OPENMP
363 #pragma omp parallel for ordered default(shared)
364 #endif
365 for (int i=0; i < m_lastMacroBlock; i++) {
366 if (error == NoError) {
367 m_macroBlocks[i]->BitplaneEncode();
368 #ifdef LIBPGF_USE_OPENMP
369 #pragma omp ordered
370 #endif
371 {
372 try {
373 WriteMacroBlock(m_macroBlocks[i]);
374 } catch (IOException& e) {
375 error = e.error;
376 }
377 delete m_macroBlocks[i]; m_macroBlocks[i] = 0;
378 }
379 }
380 }
381 if (error != NoError) ReturnWithError(error);
382 */
383#ifdef LIBPGF_USE_OPENMP
384 #pragma omp parallel for default(shared) //no declared exceptions in next block
385#endif
386 for (int i=0; i < m_lastMacroBlock; i++) {
388 }
389 for (int i=0; i < m_lastMacroBlock; i++) {
391 }
392
393 // prepare for next round
394 m_forceWriting = false;
396 }
397 // re-initialize macro block
399 m_currentBlock->Init(lastLevelIndex);
400 }
401}
#define BufferSize
must be a multiple of WordWidth
Definition: PGFtypes.h:77
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
ROIBlockHeader m_header
block header
Definition: Encoder.h:86
void Init(int lastLevelIndex)
Definition: Encoder.h:71
void WriteMacroBlock(CMacroBlock *block) THROW_
Definition: Encoder.cpp:406
UINT16 bufferSize
number of uncoded UINT32 values in a block
Definition: PGFtypes.h:167
struct ROIBlockHeader::RBH rbh
ROI block header.

◆ FavorSpeedOverSize()

void CEncoder::FavorSpeedOverSize ( )
inline

Encoder favors speed over compression size.

Definition at line 121 of file Encoder.h.

121{ m_favorSpeed = true; }

◆ Flush()

void CEncoder::Flush ( )

Pad buffer with zeros and encode buffer. It might throw an IOException.

Definition at line 310 of file Encoder.cpp.

310 {
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}
#define DataTSize
Definition: PGFtypes.h:233
DataT m_value[BufferSize]
input buffer of values with index m_valuePos
Definition: Encoder.h:84
UINT32 m_valuePos
current buffer position
Definition: Encoder.h:87
void EncodeBuffer(ROIBlockHeader h) THROW_
Definition: Encoder.cpp:341
Block header used with ROI coding scheme
Definition: PGFtypes.h:151

◆ Partition()

void CEncoder::Partition ( CSubband band,
int  width,
int  height,
int  startPos,
int  pitch 
)

Partitions a rectangular region of a given subband. Partitioning scheme: The plane is partitioned in squares of side length LinBlockSize. Write wavelet coefficients from subband into the input buffer of a macro block. It might throw an IOException.

Parameters
bandA subband
widthThe width of the rectangle
heightThe height of the rectangle
startPosThe absolute subband position of the top left corner of the rectangular region
pitchThe number of bytes in row of the subband

Definition at line 246 of file Encoder.cpp.

246 {
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}
#define LinBlockSize
side length of a coefficient block in a HH or LL subband
Definition: PGFtypes.h:79
void WriteValue(CSubband *band, int bandPos) THROW_
Definition: Encoder.cpp:326

◆ SetBufferStartPos()

void CEncoder::SetBufferStartPos ( )
inline

Save current stream position as beginning of current level.

Definition at line 188 of file Encoder.h.

◆ SetEncodedLevel()

void CEncoder::SetEncodedLevel ( int  currentLevel)
inline

Informs the encoder about the encoded level.

Parameters
currentLevelencoded level [0, nLevels)

Definition at line 162 of file Encoder.h.

162{ ASSERT(currentLevel >= 0); m_currentBlock->m_lastLevelIndex = m_nLevels - currentLevel - 1; m_forceWriting = true; }

◆ UpdateLevelLength()

UINT32 CEncoder::UpdateLevelLength ( )

Write new levelLength into stream. It might throw an IOException.

Returns
Written image bytes.

Definition at line 202 of file Encoder.cpp.

202 {
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}
#define WordBytes
sizeof(UINT32)
Definition: PGFplatform.h:76

◆ UpdatePostHeaderSize()

void CEncoder::UpdatePostHeaderSize ( PGFPreHeader  preHeader)

Increase post-header size and write new size into stream.

Parameters
preHeaderAn already filled in PGF pre-header It might throw an IOException.

Definition at line 160 of file Encoder.cpp.

160 {
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}

◆ WriteLevelLength()

UINT32 CEncoder::WriteLevelLength ( UINT32 *&  levelLength)

Create level length data structure and write a place holder into stream. It might throw an IOException.

Parameters
levelLengthA reference to an integer array, large enough to save the relative file positions of all PGF levels
Returns
number of bytes written into stream

Definition at line 177 of file Encoder.cpp.

177 {
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}
void SetBufferStartPos()
Save current stream position as beginning of current level.
Definition: Encoder.h:188

◆ WriteMacroBlock()

void CEncoder::WriteMacroBlock ( CMacroBlock block)
private

Definition at line 406 of file Encoder.cpp.

406 {
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);
458 m_currLevelIndex = block->m_lastLevelIndex + 1;
459
460 }
461
462 // prepare for next buffer
464
465 // reset values
466 block->m_valuePos = 0;
467 block->m_maxAbsValue = 0;
468}
UINT32 NumberOfWords(UINT32 pos)
Definition: BitStream.h:269
#define CodeBufferLen
number of words in code buffer (CodeBufferLen > BufferLen)
Definition: Decoder.h:40
INT64 ComputeBufferLength() const
Definition: Encoder.h:179
UINT16 val
Definition: PGFtypes.h:160

◆ WriteValue()

void CEncoder::WriteValue ( CSubband band,
int  bandPos 
)

Write a single value into subband at given position. It might throw an IOException.

Parameters
bandA subband
bandPosA valid position in subband band

Definition at line 326 of file Encoder.cpp.

326 {
329 }
330 DataT val = m_currentBlock->m_value[m_currentBlock->m_valuePos++] = band->GetData(bandPos);
331 UINT32 v = abs(val);
333}
INT32 DataT
Definition: PGFtypes.h:219
UINT32 m_maxAbsValue
maximum absolute coefficient in each buffer
Definition: Encoder.h:88
DataT GetData(UINT32 pos) const
Definition: Subband.h:112

Member Data Documentation

◆ m_bufferStartPos

UINT64 CEncoder::m_bufferStartPos
private

stream position of encoded buffer

Definition at line 212 of file Encoder.h.

◆ m_currentBlock

CMacroBlock* CEncoder::m_currentBlock
private

current macro block (used by main thread)

Definition at line 217 of file Encoder.h.

◆ m_currLevelIndex

int CEncoder::m_currLevelIndex
private

counts where (=index) to save next value

Definition at line 220 of file Encoder.h.

◆ m_favorSpeed

bool CEncoder::m_favorSpeed
private

favor speed over size

Definition at line 222 of file Encoder.h.

◆ m_forceWriting

bool CEncoder::m_forceWriting
private

all macro blocks have to be written into the stream

Definition at line 223 of file Encoder.h.

◆ m_lastMacroBlock

int CEncoder::m_lastMacroBlock
private

array index of the last created macro block

Definition at line 216 of file Encoder.h.

◆ m_levelLength

UINT32* CEncoder::m_levelLength
private

temporary saves the level index

Definition at line 219 of file Encoder.h.

◆ m_levelLengthPos

UINT64 CEncoder::m_levelLengthPos
private

stream position of Metadata

Definition at line 211 of file Encoder.h.

◆ m_macroBlockLen

int CEncoder::m_macroBlockLen
private

array length

Definition at line 215 of file Encoder.h.

◆ m_macroBlocks

CMacroBlock** CEncoder::m_macroBlocks
private

array of macroblocks

Definition at line 214 of file Encoder.h.

◆ m_nLevels

UINT8 CEncoder::m_nLevels
private

number of levels

Definition at line 221 of file Encoder.h.

◆ m_startPosition

UINT64 CEncoder::m_startPosition
private

stream position of PGF start (PreHeader)

Definition at line 210 of file Encoder.h.

◆ m_stream

CPGFStream* CEncoder::m_stream
private

output PMF stream

Definition at line 209 of file Encoder.h.


The documentation for this class was generated from the following files: