libpgf 7.21.2
PGF - Progressive Graphics File
Loading...
Searching...
No Matches
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)
 
 ~CEncoder ()
 Destructor.
 
void FavorSpeedOverSize ()
 Encoder favors speed over compression size.
 
void Flush ()
 
void UpdatePostHeaderSize (PGFPreHeader preHeader)
 
UINT32 WriteLevelLength (UINT32 *&levelLength)
 
UINT32 UpdateLevelLength ()
 
void Partition (CSubband *band, int width, int height, int startPos, int pitch)
 
void SetEncodedLevel (int currentLevel)
 
void WriteValue (CSubband *band, int bandPos)
 
INT64 ComputeHeaderLength () const
 
INT64 ComputeBufferLength () const
 
INT64 ComputeOffset () const
 
void SetStreamPosToStart ()
 Resets stream position to beginning of PGF pre-header.
 
void SetBufferStartPos ()
 Save current stream position as beginning of current level.
 

Private Member Functions

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

Private Attributes

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

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 = nullptr;
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)
#define ImageModeIndexedColor
#define PreHeaderSize
Definition PGFtypes.h:280
#define HeaderSize
Definition PGFtypes.h:281
#define ColorTableSize
Definition PGFtypes.h:282
UINT64 m_bufferStartPos
stream position of encoded buffer
Definition Encoder.h:216
bool m_favorSpeed
favor speed over size
Definition Encoder.h:226
UINT64 m_startPosition
stream position of PGF start (PreHeader)
Definition Encoder.h:214
bool m_forceWriting
all macro blocks have to be written into the stream
Definition Encoder.h:227
UINT64 m_levelLengthPos
stream position of Metadata
Definition Encoder.h:215
CMacroBlock * m_currentBlock
current macro block (used by main thread)
Definition Encoder.h:221
UINT32 * m_levelLength
temporary saves the level index
Definition Encoder.h:223
CMacroBlock ** m_macroBlocks
array of macroblocks
Definition Encoder.h:218
UINT8 m_nLevels
number of levels
Definition Encoder.h:225
int m_currLevelIndex
counts where (=index) to save next value
Definition Encoder.h:224
int m_lastMacroBlock
array index of the last created macro block
Definition Encoder.h:220
CPGFStream * m_stream
output PMF stream
Definition Encoder.h:213
int m_macroBlockLen
array length
Definition Encoder.h:219
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:159
UINT32 height
image height in pixels
Definition PGFtypes.h:154
UINT32 width
image width in pixels
Definition PGFtypes.h:153
UINT8 nLevels
number of FWT transforms
Definition PGFtypes.h:155
UINT32 userDataLen
user data size in bytes (not part of file header)
Definition PGFtypes.h:172
RGBQUAD clut[ColorTableLen]
color table for indexed color images (optional part of file header)
Definition PGFtypes.h:170
UINT8 * userData
user data of size userDataLen (optional part of file header)
Definition PGFtypes.h:171
UINT32 hSize
total size of PGFHeader, [ColorTable], and [UserData] in bytes (since Version 6: 4 Bytes)
Definition PGFtypes.h:124

◆ ~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, BufferSize <= UINT16_MAX
Definition PGFtypes.h:84
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)
Definition Encoder.cpp:406
UINT16 bufferSize
number of uncoded UINT32 values in a block
Definition PGFtypes.h:188
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:283
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)
Definition Encoder.cpp:341
Block header used with ROI coding scheme
Definition PGFtypes.h:180

◆ 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:86
void WriteValue(CSubband *band, int bandPos)
Definition Encoder.cpp:326

◆ SetBufferStartPos()

void CEncoder::SetBufferStartPos ( )
inline

Save current stream position as beginning of current level.

Definition at line 192 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; }

◆ SetStreamPosToStart()

void CEncoder::SetStreamPosToStart ( )
inline

Resets stream position to beginning of PGF pre-header.

Definition at line 188 of file Encoder.h.

188{ ASSERT(m_stream); m_stream->SetPos(FSFromStart, m_startPosition); }

◆ 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
166 preHeader.hSize = __VAL(preHeader.hSize);
167 m_stream->Write(&count, &preHeader);
168
169 m_stream->SetPos(FSFromStart, curPos);
170}
void SetStreamPosToStart()
Resets stream position to beginning of PGF pre-header.
Definition Encoder.h:188

◆ 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:192

◆ 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 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}
UINT32 NumberOfWords(UINT32 pos)
Definition BitStream.h:337
#define CodeBufferLen
number of words in code buffer (CodeBufferLen > BufferLen)
Definition Encoder.h:40
INT64 ComputeBufferLength() const
Definition Encoder.h:179

◆ 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:269
UINT32 m_maxAbsValue
maximum absolute coefficient in each buffer
Definition Encoder.h:88
DataT GetData(UINT32 pos) const
Definition Subband.h:113

Member Data Documentation

◆ m_bufferStartPos

UINT64 CEncoder::m_bufferStartPos
private

stream position of encoded buffer

Definition at line 216 of file Encoder.h.

◆ m_currentBlock

CMacroBlock* CEncoder::m_currentBlock
private

current macro block (used by main thread)

Definition at line 221 of file Encoder.h.

◆ m_currLevelIndex

int CEncoder::m_currLevelIndex
private

counts where (=index) to save next value

Definition at line 224 of file Encoder.h.

◆ m_favorSpeed

bool CEncoder::m_favorSpeed
private

favor speed over size

Definition at line 226 of file Encoder.h.

◆ m_forceWriting

bool CEncoder::m_forceWriting
private

all macro blocks have to be written into the stream

Definition at line 227 of file Encoder.h.

◆ m_lastMacroBlock

int CEncoder::m_lastMacroBlock
private

array index of the last created macro block

Definition at line 220 of file Encoder.h.

◆ m_levelLength

UINT32* CEncoder::m_levelLength
private

temporary saves the level index

Definition at line 223 of file Encoder.h.

◆ m_levelLengthPos

UINT64 CEncoder::m_levelLengthPos
private

stream position of Metadata

Definition at line 215 of file Encoder.h.

◆ m_macroBlockLen

int CEncoder::m_macroBlockLen
private

array length

Definition at line 219 of file Encoder.h.

◆ m_macroBlocks

CMacroBlock** CEncoder::m_macroBlocks
private

array of macroblocks

Definition at line 218 of file Encoder.h.

◆ m_nLevels

UINT8 CEncoder::m_nLevels
private

number of levels

Definition at line 225 of file Encoder.h.

◆ m_startPosition

UINT64 CEncoder::m_startPosition
private

stream position of PGF start (PreHeader)

Definition at line 214 of file Encoder.h.

◆ m_stream

CPGFStream* CEncoder::m_stream
private

output PMF stream

Definition at line 213 of file Encoder.h.


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