CEncoder(3)
π CEncoder β NAME π
CEncoder β the PGF encoder, bestie. That's it, that's the vibe. This is libpgf's encoder class and she's booked and busy.
β¨ SYNOPSIS β¨
#include <Encoder.h>
π Classes
class CMacroBlockβ a macro block is an encoding unit of fixed size (uncoded). Like, the lil' building block she works in, no cap.
π«Ά Public Member Functions
CEncoder (CPGFStream *stream, PGFPreHeader preHeader, PGFHeader header, const PGFPostHeader &postHeader, UINT64 &userDataPos, bool useOMP)β constructor, she's being born π«~CEncoder ()β destructor. bye bestie π«‘void FavorSpeedOverSize ()β encoder favors speed over compression size. fast > smol, periodt.void Flush ()β flush it outvoid 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 () constINT64 ComputeBufferLength () constINT64 ComputeOffset () constvoid SetStreamPosToStart ()β resets stream position to beginning of PGF pre-header. back to square one, iconic behavior.void SetBufferStartPos ()β save current stream position as beginning of current level. lil bookmark moment π
π Private Member Functions
void EncodeBuffer (ROIBlockHeader h)void WriteMacroBlock (CMacroBlock *block)
πΈ Private Attributes
CPGFStream * m_streamβ output PMF streamUINT64 m_startPositionβ stream position of PGF start (PreHeader)UINT64 m_levelLengthPosβ stream position of MetadataUINT64 m_bufferStartPosβ stream position of encoded bufferCMacroBlock ** m_macroBlocksβ array of macroblocksint m_macroBlockLenβ array lengthint m_lastMacroBlockβ array index of the last created macro blockCMacroBlock * m_currentBlockβ current macro block (used by main thread)UINT32 * m_levelLengthβ temporary saves the level indexint m_currLevelIndexβ counts where (=index) to save next valueUINT8 m_nLevelsβ number of levelsbool m_favorSpeedβ favor speed over sizebool m_forceWritingβ all macro blocks have to be written into the stream
π¦ Detailed Description π¦
PGF encoder.
PGF encoder class. (yes she said it twice, she's thorough, let her cook π₯)
π Author
C. Stamm
Definition at line 46 of file Encoder.h.
π Constructor & Destructor Documentation π
π 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. β οΈ heads up bestie, she can throw.
Parameters
- stream β A PGF stream
- preHeader β A already filled in PGF pre-header
- header β An 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 - useOMP β If true, then the encoder will use multi-threading based on openMP
Write pre-header, header, postHeader, and levelLength. It might throw an IOException. (yeah it's the same paragraph again, the docs really said "run it back" π)
Parameters
- stream β A PGF stream
- preHeader β A already filled in PGF pre-header
- header β An 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 - useOMP β If true, then the encoder will use multi-threading based on openMP
Definition at line 70 of file Encoder.cpp.
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 }
π§ CEncoder::~CEncoder ()
Destructor. She's logging off π
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 π
β 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; }
β INT64 CEncoder::ComputeHeaderLength () const [inline]
Compute stream length of header.
Returns
- header length
Definition at line 174 of file Encoder.h.
174 { return m_levelLengthPos - m_startPosition; }
β INT64 CEncoder::ComputeOffset () const [inline]
Compute file offset between real and expected levelLength position. (the lil' gap between where it is and where it should be π)
Returns
- file offset
Definition at line 184 of file Encoder.h.
184 { return m_stream->GetPos() - m_levelLengthPos; }
β 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
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 }
β void CEncoder::FavorSpeedOverSize () [inline]
Encoder favors speed over compression size. she's not gonna shrink your file into oblivion, she's gonna go πβοΈπ¨
Definition at line 121 of file Encoder.h.
121 { m_favorSpeed = true; }
β void CEncoder::Flush ()
Pad buffer with zeros and encode buffer. It might throw an IOException. β οΈ (zero padding arc, and yeah, she can throw again, watch out)
heads up: more of this page is still coming, bestie β don't go anywhere π
...and here's the tail end of that definition, the bit that lives at line 310, so you can see the padding in action π
310 {
311 if (m_currentBlock->m_valuePos > 0) {
312 // pad buffer with zeros
313 memset(&(m_currentBlock->m_value[m_currentBlock->m_valuePos]), 0, (BufferSize - m_currentBlock->m_valuePos)*DataTSize);
314 m_currentBlock->m_valuePos = BufferSize;
315
316 // encode buffer
317 m_forceWriting = true; // makes sure that the following EncodeBuffer is really written into the stream
318 EncodeBuffer(ROIBlockHeader(m_currentBlock->m_valuePos, true));
319 }
320 }
Definition at line 310 of file Encoder.cpp. β¨
CEncoder::Partition β the rectangle chopper βοΈ
void CEncoder::Partition (CSubband * band, int width, int height, int startPos, int pitch)
ok so bestie, this one takes a rectangular region of a given subband and partitions it. And here's the whole scheme, no secrets: the plane gets partitioned into squares of side length LinBlockSize, and it writes those wavelet coefficients from the subband straight into the input buffer of a macro block. Simple as. πΈ
Heads up though β it might throw an IOException. So wrap it, okay? π
The parameters, one by one, because we don't skip:
bandβ a subband π¦widthβ the width of the rectangleheightβ the height of the rectanglestartPosβ the absolute subband position of the top left corner of the rectangular regionpitchβ the 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 }
CEncoder::SetBufferStartPos β bookmark moment π [inline]
Save current stream position as beginning of current level. That's it, that's the whole vibe. It literally just grabs where we are and calls it home base. π
Definition at line 192 of file Encoder.h. β¨
192 { m_bufferStartPos = m_stream->GetPos(); }
CEncoder::SetEncodedLevel β tell it what level you just did π [inline]
Informs the encoder about the encoded level. Communication is key, bestie. π«Ά
currentLevelβ encoded 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; }
CEncoder::SetStreamPosToStart β rewind, but make it cute βͺ [inline]
Resets stream position to beginning of PGF pre-header. Iconic behaviour honestly. π
Definition at line 188 of file Encoder.h. β
188 { ASSERT(m_stream); m_stream->SetPos(FSFromStart, m_startPosition); }
CEncoder::UpdateLevelLength β writes the new levelLength into the stream π
So it writes the new levelLength into the stream, and yeah β 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 }
CEncoder::UpdatePostHeaderSize β growing the post-header π
Increase post-header size and write new size into stream. Glow-up energy fr fr. β¨
preHeaderβ An already filled in PGF pre-header. It might throw anIOException.
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 SetStreamPosToStart();
166 preHeader.hSize = __VAL(preHeader.hSize);
167 m_stream->Write(&count, &preHeader);
168
169 m_stream->SetPos(FSFromStart, curPos);
170 }
CEncoder::WriteLevelLength β build the level length data structure π§
Create the level length data structure and write a place holder into the stream. It might throw an IOException, so keep that in mind. π
levelLengthβ A 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
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 }
CEncoder::WriteMacroBlock β the big one π₯ [private]
Private, so don't go calling it from outside, bestie, it's giving internal business only. π
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);
459 m_levelLength[m_currLevelIndex] += (UINT32)ComputeBufferLength();
460 m_currLevelIndex = block->m_lastLevelIndex + 1;
461
462 }
463
464 // prepare for next buffer
465 SetBufferStartPos();
466
467 // reset values
468 block->m_valuePos = 0;
469 block->m_maxAbsValue = 0;
470 }
CEncoder::WriteValue β one value, one spot π―
void CEncoder::WriteValue (CSubband * band, int bandPos)
Write a single value into subband at given position. It might throw an IOException β yes, again, they all do, it's a whole thing. π
bandβ A subbandbandPosβ A valid position in subbandband
okay so the very last function body we were lowkey dissecting? it wraps up right here β and yes bestie, Definition at line 326 of file Encoder.cpp π
326 {
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 }
and that's the whole member-function situation, fr fr. no more functions, we're done with that era β¨
π«Ά Member Data Documentation π«Ά
now we're in the private member variables β CEncoder's little secret stash. every single one of these is marked [private], so they're not for outside hands, okay? periodt. π
UINT64 CEncoder::m_bufferStartPos[private]β stream position of encoded buffer- Definition at line
216of fileEncoder.h.
- Definition at line
CMacroBlock* CEncoder::m_currentBlock[private]β current macro block (used by main thread)- Definition at line
221of fileEncoder.h.
- Definition at line
int CEncoder::m_currLevelIndex[private]β counts where (=index) to save next value- Definition at line
224of fileEncoder.h.
- Definition at line
bool CEncoder::m_favorSpeed[private]β favor speed over size- Definition at line
226of fileEncoder.h.
- Definition at line
bool CEncoder::m_forceWriting[private]β all macro blocks have to be written into the stream- Definition at line
227of fileEncoder.h.
- Definition at line
int CEncoder::m_lastMacroBlock[private]β array index of the last created macro block- Definition at line
220of fileEncoder.h.
- Definition at line
UINT32* CEncoder::m_levelLength[private]β temporary saves the level index- Definition at line
223of fileEncoder.h.
- Definition at line
UINT64 CEncoder::m_levelLengthPos[private]β stream position of Metadata- Definition at line
215of fileEncoder.h.
- Definition at line
int CEncoder::m_macroBlockLen[private]β array length- Definition at line
219of fileEncoder.h.
- Definition at line
CMacroBlock** CEncoder::m_macroBlocks[private]β array of macroblocks- Definition at line
218of fileEncoder.h.
- Definition at line
UINT8 CEncoder::m_nLevels[private]β number of levels- Definition at line
225of fileEncoder.h.
- Definition at line
UINT64 CEncoder::m_startPosition[private]β stream position of PGF start (PreHeader)- Definition at line
214of fileEncoder.h.
- Definition at line
CPGFStream* CEncoder::m_stream[private]β output PMF stream- Definition at line
213of fileEncoder.h.
- Definition at line
πΈ Author πΈ
Generated automatically by Doxygen for libpgf from the source code. π€π
and that's the entire page, bestie!! π this iconic lil doc was auto-cooked by Doxygen for libpgf, version 7.21.2, dated Thu Jul 24 2025 00:00:00, and you just finished reading CEncoder(3). slay, you ate that β¨ππ¦
π¦ where this page comes from
- fedora 43: libpgf-devel 7.21.7-8.fc43 Β· LicenseRef-Callaway-LGPLv2+
- fedora 43: libpgf-devel 7.21.7-8.fc43 Β· LicenseRef-Callaway-LGPLv2+
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash on : a language model's rewrite of the original, under its terms