libpgf  6.14.12
PGF - Progressive Graphics File
CEncoder Class Reference

PGF encoder. More...

#include <Encoder.h>

List of all members.

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 ()
void FavorSpeedOverSize ()
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 ()

Private Member Functions

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

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 ( 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.

: m_stream(stream)
, m_bufferStartPos(0)
, m_currLevelIndex(0)
, m_nLevels(header.nLevels)
, m_favorSpeed(false)
, m_forceWriting(false)
#ifdef __PGFROISUPPORT__
, m_roi(false)
#endif
{
        ASSERT(m_stream);

        int count;
        m_lastMacroBlock = 0;
        m_levelLength = NULL;

        // set number of threads
#ifdef LIBPGF_USE_OPENMP
        m_macroBlockLen = omp_get_num_procs();
#else
        m_macroBlockLen = 1;
#endif
        
        if (useOMP && m_macroBlockLen > 1) {
#ifdef LIBPGF_USE_OPENMP
                omp_set_num_threads(m_macroBlockLen);
#endif
                // create macro block array
                m_macroBlocks = new(std::nothrow) CMacroBlock*[m_macroBlockLen];
                if (!m_macroBlocks) ReturnWithError(InsufficientMemory);
                for (int i=0; i < m_macroBlockLen; i++) m_macroBlocks[i] = new CMacroBlock(this);
                m_currentBlock = m_macroBlocks[m_lastMacroBlock++];
        } else {
                m_macroBlocks = 0;
                m_macroBlockLen = 1;
                m_currentBlock = new CMacroBlock(this);
        }

        // save file position
        m_startPosition = m_stream->GetPos();

        // write preHeader
        preHeader.hSize = __VAL(preHeader.hSize);
        count = PreHeaderSize;
        m_stream->Write(&count, &preHeader);

        // write file header
        header.height = __VAL(header.height);
        header.width = __VAL(header.width);
        count = HeaderSize;
        m_stream->Write(&count, &header);

        // write postHeader
        if (header.mode == ImageModeIndexedColor) {
                // write color table
                count = ColorTableSize;
                m_stream->Write(&count, (void *)postHeader.clut);
        }
        // save user data file position
        userDataPos = m_stream->GetPos();
        if (postHeader.userDataLen) {
                if (postHeader.userData) {
                        // write user data
                        count = postHeader.userDataLen;
                        m_stream->Write(&count, postHeader.userData);
                } else {
                        m_stream->SetPos(FSFromCurrent, count);
                }
        }

        // save level length file position
        m_levelLengthPos = m_stream->GetPos();
}

Destructor

Definition at line 147 of file Encoder.cpp.

                    {   
        if (m_macroBlocks) {
                for (int i=0; i < m_macroBlockLen; i++) delete m_macroBlocks[i];
                delete[] m_macroBlocks;
        } else {
                delete m_currentBlock;
        }
}

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.

{ 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.

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.

{ return m_stream->GetPos() - m_levelLengthPos; }
void CEncoder::EncodeBuffer ( ROIBlockHeader  h) [private]

Definition at line 341 of file Encoder.cpp.

                                                   {
        ASSERT(m_currentBlock);
#ifdef __PGFROISUPPORT__
        ASSERT(m_roi && h.rbh.bufferSize <= BufferSize || h.rbh.bufferSize == BufferSize);
#else
        ASSERT(h.rbh.bufferSize == BufferSize);
#endif
        m_currentBlock->m_header = h;

        // macro block management
        if (m_macroBlockLen == 1) {
                m_currentBlock->BitplaneEncode();
                WriteMacroBlock(m_currentBlock);
        } else {
                // save last level index
                int lastLevelIndex = m_currentBlock->m_lastLevelIndex;

                if (m_forceWriting || m_lastMacroBlock == m_macroBlockLen) {
                        // encode macro blocks
                        /*
                        volatile OSError error = NoError;
                        #ifdef LIBPGF_USE_OPENMP
                        #pragma omp parallel for ordered default(shared)
                        #endif
                        for (int i=0; i < m_lastMacroBlock; i++) {
                                if (error == NoError) {
                                        m_macroBlocks[i]->BitplaneEncode();
                                        #ifdef LIBPGF_USE_OPENMP
                                        #pragma omp ordered
                                        #endif
                                        {
                                                try {
                                                        WriteMacroBlock(m_macroBlocks[i]);
                                                } catch (IOException& e) {
                                                        error = e.error;
                                                }
                                                delete m_macroBlocks[i]; m_macroBlocks[i] = 0;
                                        }
                                }
                        }
                        if (error != NoError) ReturnWithError(error);
                        */
#ifdef LIBPGF_USE_OPENMP
                        #pragma omp parallel for default(shared) //no declared exceptions in next block
#endif
                        for (int i=0; i < m_lastMacroBlock; i++) {
                                m_macroBlocks[i]->BitplaneEncode();
                        }
                        for (int i=0; i < m_lastMacroBlock; i++) {
                                WriteMacroBlock(m_macroBlocks[i]);
                        }
                        
                        // prepare for next round
                        m_forceWriting = false;
                        m_lastMacroBlock = 0;
                }
                // re-initialize macro block
                m_currentBlock = m_macroBlocks[m_lastMacroBlock++];
                m_currentBlock->Init(lastLevelIndex);
        }
}
void CEncoder::FavorSpeedOverSize ( ) [inline]

Encoder favors speed over compression size

Definition at line 121 of file Encoder.h.

{ m_favorSpeed = true; }
void CEncoder::Flush ( )

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

Definition at line 310 of file Encoder.cpp.

                            {
        if (m_currentBlock->m_valuePos > 0) {
                // pad buffer with zeros
                memset(&(m_currentBlock->m_value[m_currentBlock->m_valuePos]), 0, (BufferSize - m_currentBlock->m_valuePos)*DataTSize);
                m_currentBlock->m_valuePos = BufferSize;

                // encode buffer
                m_forceWriting = true;  // makes sure that the following EncodeBuffer is really written into the stream
                EncodeBuffer(ROIBlockHeader(m_currentBlock->m_valuePos, true));
        }
}
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.

                                                                                              {
        ASSERT(band);

        const div_t hh = div(height, LinBlockSize);
        const div_t ww = div(width, LinBlockSize);
        const int ws = pitch - LinBlockSize;
        const int wr = pitch - ww.rem;
        int pos, base = startPos, base2;

        // main height
        for (int i=0; i < hh.quot; i++) {
                // main width
                base2 = base;
                for (int j=0; j < ww.quot; j++) {
                        pos = base2;
                        for (int y=0; y < LinBlockSize; y++) {
                                for (int x=0; x < LinBlockSize; x++) {
                                        WriteValue(band, pos);
                                        pos++;
                                }
                                pos += ws;
                        }
                        base2 += LinBlockSize;
                }
                // rest of width
                pos = base2;
                for (int y=0; y < LinBlockSize; y++) {
                        for (int x=0; x < ww.rem; x++) {
                                WriteValue(band, pos);
                                pos++;
                        }
                        pos += wr;
                        base += pitch;
                }
        }
        // main width 
        base2 = base;
        for (int j=0; j < ww.quot; j++) {
                // rest of height
                pos = base2;
                for (int y=0; y < hh.rem; y++) {
                        for (int x=0; x < LinBlockSize; x++) {
                                WriteValue(band, pos);
                                pos++;
                        }
                        pos += ws;
                }
                base2 += LinBlockSize;
        }
        // rest of height
        pos = base2;
        for (int y=0; y < hh.rem; y++) {
                // rest of width
                for (int x=0; x < ww.rem; x++) {
                        WriteValue(band, pos);
                        pos++;
                }
                pos += wr;
        }
}
void CEncoder::SetBufferStartPos ( ) [inline]

Save current stream position as beginning of current level.

Definition at line 188 of file Encoder.h.

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.

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

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

Returns:
Written image bytes.

Definition at line 202 of file Encoder.cpp.

                                          {
        UINT64 curPos = m_stream->GetPos(); // end of image

        // set file pos to levelLength
        m_stream->SetPos(FSFromStart, m_levelLengthPos);

        if (m_levelLength) {
        #ifdef PGF_USE_BIG_ENDIAN 
                UINT32 levelLength;
                int count = WordBytes;
                
                for (int i=0; i < m_currLevelIndex; i++) {
                        levelLength = __VAL(UINT32(m_levelLength[i]));
                        m_stream->Write(&count, &levelLength);
                }
        #else
                int count = m_currLevelIndex*WordBytes;
                
                m_stream->Write(&count, m_levelLength);
        #endif //PGF_USE_BIG_ENDIAN 
        } else {
                int count = m_currLevelIndex*WordBytes;
                m_stream->SetPos(FSFromCurrent, count);
        }

        // begin of image
        UINT32 retValue = UINT32(curPos - m_stream->GetPos());
                
        // restore file position
        m_stream->SetPos(FSFromStart, curPos);

        return retValue;
}

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.

                                                                 {
        UINT64 curPos = m_stream->GetPos(); // end of user data
        int count = PreHeaderSize;

        // write preHeader
        m_stream->SetPos(FSFromStart, m_startPosition);
        preHeader.hSize = __VAL(preHeader.hSize);
        m_stream->Write(&count, &preHeader);

        m_stream->SetPos(FSFromStart, curPos);
}
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.

                                                             {
        // renew levelLength
        delete[] levelLength;
        levelLength = new(std::nothrow) UINT32[m_nLevels];
        if (!levelLength) ReturnWithError(InsufficientMemory);
        for (UINT8 l = 0; l < m_nLevels; l++) levelLength[l] = 0;
        m_levelLength = levelLength;

        // save level length file position
        m_levelLengthPos = m_stream->GetPos();

        // write dummy levelLength
        int count = m_nLevels*WordBytes;
        m_stream->Write(&count, m_levelLength);

        // save current file position
        SetBufferStartPos();

        return count;
}
void CEncoder::WriteMacroBlock ( CMacroBlock block) [private]

Definition at line 406 of file Encoder.cpp.

                                                        {
        ASSERT(block);
#ifdef __PGFROISUPPORT__
        ROIBlockHeader h = block->m_header;
#endif
        UINT16 wordLen = UINT16(NumberOfWords(block->m_codePos)); ASSERT(wordLen <= CodeBufferLen);
        int count = sizeof(UINT16);
        
#ifdef TRACE
        //UINT32 filePos = (UINT32)m_stream->GetPos();
        //printf("EncodeBuffer: %d\n", filePos);
#endif

#ifdef PGF_USE_BIG_ENDIAN 
        // write wordLen
        UINT16 wl = __VAL(wordLen);
        m_stream->Write(&count, &wl); ASSERT(count == sizeof(UINT16));

#ifdef __PGFROISUPPORT__
        // write ROIBlockHeader
        if (m_roi) {
                h.val = __VAL(h.val);
                m_stream->Write(&count, &h.val); ASSERT(count == sizeof(UINT16));
        }
#endif // __PGFROISUPPORT__

        // convert data
        for (int i=0; i < wordLen; i++) {
                block->m_codeBuffer[i] = __VAL(block->m_codeBuffer[i]);
        }
#else
        // write wordLen
        m_stream->Write(&count, &wordLen); ASSERT(count == sizeof(UINT16));

#ifdef __PGFROISUPPORT__
        // write ROIBlockHeader
        if (m_roi) {
                m_stream->Write(&count, &h.val); ASSERT(count == sizeof(UINT16));
        }
#endif // __PGFROISUPPORT__
#endif // PGF_USE_BIG_ENDIAN

        // write encoded data into stream
        count = wordLen*WordBytes;
        m_stream->Write(&count, block->m_codeBuffer);

        // store levelLength
        if (m_levelLength) {
                // store level length
                // EncodeBuffer has been called after m_lastLevelIndex has been updated
                ASSERT(m_currLevelIndex < m_nLevels);
                m_levelLength[m_currLevelIndex] += (UINT32)ComputeBufferLength();
                m_currLevelIndex = block->m_lastLevelIndex + 1;

        }

        // prepare for next buffer
        SetBufferStartPos();

        // reset values
        block->m_valuePos = 0;
        block->m_maxAbsValue = 0;
}
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.


Member Data Documentation

UINT64 CEncoder::m_bufferStartPos [private]

stream position of encoded buffer

Definition at line 212 of file Encoder.h.

current macro block (used by main thread)

Definition at line 217 of file Encoder.h.

counts where (=index) to save next value

Definition at line 220 of file Encoder.h.

bool CEncoder::m_favorSpeed [private]

favor speed over size

Definition at line 222 of file Encoder.h.

bool CEncoder::m_forceWriting [private]

all macro blocks have to be written into the stream

Definition at line 223 of file Encoder.h.

array index of the last created macro block

Definition at line 216 of file Encoder.h.

UINT32* CEncoder::m_levelLength [private]

temporary saves the level index

Definition at line 219 of file Encoder.h.

UINT64 CEncoder::m_levelLengthPos [private]

stream position of Metadata

Definition at line 211 of file Encoder.h.

array length

Definition at line 215 of file Encoder.h.

array of macroblocks

Definition at line 214 of file Encoder.h.

UINT8 CEncoder::m_nLevels [private]

number of levels

Definition at line 221 of file Encoder.h.

UINT64 CEncoder::m_startPosition [private]

stream position of PGF start (PreHeader)

Definition at line 210 of file Encoder.h.

output PMF stream

Definition at line 209 of file Encoder.h.


The documentation for this class was generated from the following files:
 All Classes Files Functions Variables Typedefs Enumerations Enumerator Friends Defines