libpgf  6.11.42
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, UINT32 *&levelLength, bool useOMP=true) THROW_
 ~CEncoder ()
void FavorSpeedOverSize ()
void Flush () THROW_
UINT32 WriteLevelLength () 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_
UINT32 ComputeHeaderLength () const
UINT32 ComputeBufferLength () const
void SetBufferStartPos ()

Private Member Functions

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

Private Attributes

CPGFStreamm_stream
UINT64 m_startPosition
 file position of PGF start (PreHeader)
UINT64 m_levelLengthPos
 file position of Metadata
UINT64 m_bufferStartPos
 file 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 45 of file Encoder.h.


Constructor & Destructor Documentation

CEncoder::CEncoder ( CPGFStream stream,
PGFPreHeader  preHeader,
PGFHeader  header,
const PGFPostHeader postHeader,
UINT32 *&  levelLength,
bool  useOMP = true 
)

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] A already filled in PGF post header (containing color table, user data, ...)
levelLengthA reference to an integer array, large enough to save the relative file positions of all PGF levels
useOMPIf true, then the encoder will use multi-threading based on openMP

Definition at line 66 of file Encoder.cpp.

: m_stream(stream)
, m_startPosition(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;

        // 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 CMacroBlock*[m_macroBlockLen];
                for (int i=0; i < m_macroBlockLen; i++) m_macroBlocks[i] = new CMacroBlock(this);
                m_lastMacroBlock = 0;
                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);
        }
        if (postHeader.userData && postHeader.userDataLen) {
                // write user data
                count = postHeader.userDataLen;
                m_stream->Write(&count, postHeader.userData);
        }

        // renew levelLength
        delete[] levelLength;
        levelLength = new UINT32[m_nLevels];
        for (UINT8 l = 0; l < m_nLevels; l++) levelLength[l] = 0;
        m_levelLength = levelLength;

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

        // save current file position
        SetBufferStartPos();
}

Destructor

Definition at line 146 of file Encoder.cpp.

                    {   
        delete m_currentBlock;
        delete[] m_macroBlocks;
}

Member Function Documentation

UINT32 CEncoder::ComputeBufferLength ( ) const [inline]

Compute stream length of encoded buffer.

Returns:
encoded buffer length

Definition at line 161 of file Encoder.h.

{ return UINT32(m_stream->GetPos() - m_bufferStartPos); }
UINT32 CEncoder::ComputeHeaderLength ( ) const [inline]

Compute stream length of header.

Returns:
header length

Definition at line 156 of file Encoder.h.

{ return UINT32(m_bufferStartPos - m_startPosition); }
void CEncoder::EncodeBuffer ( ROIBlockHeader  h) [private]

Definition at line 287 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;
                        #pragma omp parallel for ordered default(shared)
                        for (int i=0; i < m_lastMacroBlock; i++) {
                                if (error == NoError) {
                                        m_macroBlocks[i]->BitplaneEncode();
                                        #pragma omp ordered
                                        {
                                                try {
                                                        WriteMacroBlock(m_macroBlocks[i]);
                                                } catch (IOException& e) {
                                                        error = e.error;
                                                }
                                                delete m_macroBlocks[i]; m_macroBlocks[i] = 0;
                                        }
                                }
                        }
                        if (error != NoError) ReturnWithError(error);
                        */
                        #pragma omp parallel for default(shared) //no declared exceptions in next block
                        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 116 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 225 of file Encoder.cpp.

                            {
        // 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 into buffer. It might throw an IOException.

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

Definition at line 161 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 165 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 144 of file Encoder.h.

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

Write levelLength into header.

Returns:
number of bytes written into stream It might throw an IOException.

Definition at line 239 of file Encoder.cpp.

                                         {
        UINT64 curPos = m_stream->GetPos();
        UINT32 retValue = UINT32(curPos - m_startPosition);

        if (m_levelLength) {
                // append levelLength to file, directly after post-header
                // set file pos to levelLength
                m_stream->SetPos(FSFromStart, m_levelLengthPos);
        #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 

                // restore file position
                m_stream->SetPos(FSFromStart, curPos);
        }

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

Definition at line 346 of file Encoder.cpp.

                                                        {
        ASSERT(block);

        ROIBlockHeader h = block->m_header;
        UINT16 wordLen = UINT16(NumberOfWords(block->m_codePos)); ASSERT(wordLen <= BufferSize);
        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
                m_levelLength[m_currLevelIndex] += 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 272 of file Encoder.cpp.


Member Data Documentation

UINT64 CEncoder::m_bufferStartPos [private]

file position of encoded buffer

Definition at line 189 of file Encoder.h.

current macro block (used by main thread)

Definition at line 194 of file Encoder.h.

counts where (=index) to save next value

Definition at line 197 of file Encoder.h.

bool CEncoder::m_favorSpeed [private]

favor speed over size

Definition at line 199 of file Encoder.h.

bool CEncoder::m_forceWriting [private]

all macro blocks have to be written into the stream

Definition at line 200 of file Encoder.h.

array index of the last created macro block

Definition at line 193 of file Encoder.h.

UINT32* CEncoder::m_levelLength [private]

temporary saves the level index

Definition at line 196 of file Encoder.h.

UINT64 CEncoder::m_levelLengthPos [private]

file position of Metadata

Definition at line 188 of file Encoder.h.

array length

Definition at line 192 of file Encoder.h.

array of macroblocks

Definition at line 191 of file Encoder.h.

UINT8 CEncoder::m_nLevels [private]

number of levels

Definition at line 198 of file Encoder.h.

UINT64 CEncoder::m_startPosition [private]

file position of PGF start (PreHeader)

Definition at line 187 of file Encoder.h.

Definition at line 186 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