Commit 46c8af58 authored by Gilles Caulier's avatar Gilles Caulier 🗼
Browse files

update libpgf from digiKam core to last 6.11.24 including OpenMP support

CCBUGS: 273765
parent 65939f9a
......@@ -160,6 +160,27 @@ ENDIF(Boost_FOUND)
#-------------------------------------------------------------------------------------
MACRO_BOOL_TO_01(PGF_FOUND USE_EXT_LIBPGF)
# LibPGF need to be linked to OpenMP if necessary.
# OpenMP detection (requires CMake >= 2.6.3)
# NOTE: OpenMP under MacOSX do not support multithreading.
IF(NOT APPLE AND NOT USE_EXT_LIBPGF)
MACRO_OPTIONAL_FIND_PACKAGE(OpenMP)
IF(OPENMP_FOUND)
ADD_DEFINITIONS(${OpenMP_CXX_FLAGS})
IF("${OpenMP_CXX_FLAGS}" STREQUAL "-fopenmp" )
SET(OPENMP_LDFLAGS "-lgomp")
ENDIF("${OpenMP_CXX_FLAGS}" STREQUAL "-fopenmp" )
IF("${OpenMP_CXX_FLAGS}" STREQUAL "-xopenmp" )
SET(OPENMP_LDFLAGS "-xopenmp")
ENDIF("${OpenMP_CXX_FLAGS}" STREQUAL "-xopenmp" )
ENDIF(OPENMP_FOUND)
ENDIF(NOT APPLE AND NOT USE_EXT_LIBPGF)
#-------------------------------------------------------------------------------------
IF(NOT APPLE)
MACRO_BOOL_TO_01(CLAPACK_FOUND USE_EXT_LIBCLAPACK)
ELSE(NOT APPLE)
......@@ -541,7 +562,7 @@ IF(DIGIKAM_CAN_BE_COMPILED)
${CMAKE_CURRENT_SOURCE_DIR}/libs/3rdparty/libpgf/Decoder.cpp
${CMAKE_CURRENT_SOURCE_DIR}/libs/3rdparty/libpgf/Encoder.cpp
${CMAKE_CURRENT_SOURCE_DIR}/libs/3rdparty/libpgf/PGFimage.cpp
${CMAKE_CURRENT_SOURCE_DIR}/libs/3rdparty/libpgf/Stream.cpp
${CMAKE_CURRENT_SOURCE_DIR}/libs/3rdparty/libpgf/PGFstream.cpp
${CMAKE_CURRENT_SOURCE_DIR}/libs/3rdparty/libpgf/Subband.cpp
${CMAKE_CURRENT_SOURCE_DIR}/libs/3rdparty/libpgf/WaveletTransform.cpp
)
......
......@@ -12,6 +12,7 @@ General : Pick Labels support to improve photograph selection.
General : Color Theme engine is now ported to KDE color theme manager.
General : MySQl support improvements. Dependency is now optional.
General : Added JPEGTurbo library support.
General : Update internal LibPGF to 6.11.24 with OpenMP support.
AlbumGUI : Re-designed Filters view on right sidebar to perform icon-view items filtering.
AlbumGUI : Add options to group/ungroup items from icon-view.
......
......@@ -86,6 +86,7 @@ TARGET_LINK_LIBRARIES(digikamcore
${PNG_LIBRARIES}
${LCMS_LIBRARIES}
${JASPER_LIBRARIES}
${OPENMP_LDFLAGS}
# Required by CImg library which is using pthread internally.
${CMAKE_THREAD_LIBS_INIT}
......@@ -162,6 +163,8 @@ TARGET_LINK_LIBRARIES(digikamdatabase
${KDCRAW_LIBRARIES}
${KFACE_LIBRARIES}
${KMAP_LIBRARIES}
${OPENMP_LDFLAGS}
)
IF(USE_SCRIPT_IFACE)
......
/*
* The Progressive Graphics File; http://www.libpgf.org
*
*
* $Date: 2006-06-04 22:05:59 +0200 (So, 04 Jun 2006) $
* $Revision: 229 $
*
*
* This file Copyright (C) 2006 xeraina GmbH, Switzerland
*
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU LESSER GENERAL PUBLIC LICENSE
* as published by the Free Software Foundation; either version 2.1
* of the License, or (at your option) any later version.
*
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
//////////////////////////////////////////////////////////////////////
/// @file Bitstream.h
/// @brief PGF bit-stream operations
/// @author C. Stamm
#ifndef PGF_BITSTREAM_H
#define PGF_BITSTREAM_H
......@@ -31,13 +36,14 @@
//static const WordWidthLog = 5;
static const UINT32 Filled = 0xFFFFFFFF;
#define MAKEU64(a, b) ((UINT64) (((UINT32) (a)) | ((UINT64) ((UINT32) (b))) << 32))
/// @brief Make 64 bit unsigned integer from two 32 bit unsigned integers
#define MAKEU64(a, b) ((UINT64) (((UINT32) (a)) | ((UINT64) ((UINT32) (b))) << 32))
// these procedures have to be inlined because of performance reasons
//////////////////////////////////////////////////////////////////////
/// Set one bit of a bit stream to 1
/// @param stream A bit stream composed of unsigned integer arrays
/// @param stream A bit stream stored in array of unsigned integers
/// @param pos A valid zero-based position in the bit stream
inline void SetBit(UINT32* stream, UINT32 pos) {
stream[pos >> WordWidthLog] |= (1 << (pos%WordWidth));
......@@ -45,15 +51,15 @@ inline void SetBit(UINT32* stream, UINT32 pos) {
//////////////////////////////////////////////////////////////////////
/// Set one bit of a bit stream to 0
/// @param stream A bit stream composed of unsigned integer arrays
/// @param stream A bit stream stored in array of unsigned integers
/// @param pos A valid zero-based position in the bit stream
inline void ClearBit(UINT32* stream, UINT32 pos) {
stream[pos >> WordWidthLog] &= ~(1 << (pos%WordWidth));
stream[pos >> WordWidthLog] &= ~(1 << (pos%WordWidth));
}
//////////////////////////////////////////////////////////////////////
/// Return one bit of a bit stream
/// @param stream A bit stream composed of unsigned integer arrays
/// @param stream A bit stream stored in array of unsigned integers
/// @param pos A valid zero-based position in the bit stream
/// @return bit at position pos of bit stream stream
inline bool GetBit(UINT32* stream, UINT32 pos) {
......@@ -62,10 +68,11 @@ inline bool GetBit(UINT32* stream, UINT32 pos) {
}
//////////////////////////////////////////////////////////////////////
/// Compare k-bit binary representation of stream at postition pos with val
/// @param stream A bit stream composed of unsigned integer arrays
/// Compare k-bit binary representation of stream at position pos with val
/// @param stream A bit stream stored in array of unsigned integers
/// @param pos A valid zero-based position in the bit stream
/// @param k Number of bits to compare
/// @param val Value to compare with
/// @return true if equal
inline bool CompareBitBlock(UINT32* stream, UINT32 pos, UINT32 k, UINT32 val) {
const UINT32 iLoInt = pos >> WordWidthLog;
......@@ -87,33 +94,35 @@ inline bool CompareBitBlock(UINT32* stream, UINT32 pos, UINT32 k, UINT32 val) {
}
//////////////////////////////////////////////////////////////////////
/// Store k-bit binary representation of val in stream at postition pos
/// @param stream A bit stream composed of unsigned integer arrays
/// Store k-bit binary representation of val in stream at position pos
/// @param stream A bit stream stored in array of unsigned integers
/// @param pos A valid zero-based position in the bit stream
/// @param val Value to store in stream at position pos
/// @param k Number of bits of integer representation of val
inline void SetValueBlock(UINT32* stream, UINT32 pos, UINT32 val, UINT32 k) {
const UINT32 offset = pos%WordWidth;
const UINT32 iLoInt = pos >> WordWidthLog;
const UINT32 iHiInt = (pos + k - 1) >> WordWidthLog;
ASSERT(iLoInt <= iHiInt);
const UINT32 loMask = Filled << (pos%WordWidth);
const UINT32 loMask = Filled << offset;
const UINT32 hiMask = Filled >> (WordWidth - 1 - ((pos + k - 1)%WordWidth));
if (iLoInt == iHiInt) {
// fits into one integer
stream[iLoInt] &= ~(loMask & hiMask);
stream[iLoInt] |= val << (pos%WordWidth);
stream[iLoInt] &= ~(loMask & hiMask); // clear bits
stream[iLoInt] |= val << offset; // write value
} else {
// must be splitted over integer boundary
stream[iLoInt] &= ~loMask;
stream[iLoInt] |= val << (pos%WordWidth);
stream[iHiInt] &= ~hiMask;
stream[iHiInt] |= val >> (WordWidth - (pos%WordWidth));
stream[iLoInt] &= ~loMask; // clear bits
stream[iLoInt] |= val << offset; // write lower part of value
stream[iHiInt] &= ~hiMask; // clear bits
stream[iHiInt] |= val >> (WordWidth - offset); // write higher part of value
}
}
//////////////////////////////////////////////////////////////////////
/// Read k-bit number from stream at position pos
/// @param stream A bit stream composed of unsigned integer arrays
/// @param stream A bit stream stored in array of unsigned integers
/// @param pos A valid zero-based position in the bit stream
/// @param k Number of bits to read: 1 <= k <= 32
inline UINT32 GetValueBlock(UINT32* stream, UINT32 pos, UINT32 k) {
......@@ -122,7 +131,7 @@ inline UINT32 GetValueBlock(UINT32* stream, UINT32 pos, UINT32 k) {
const UINT32 iHiInt = (pos + k - 1) >> WordWidthLog; // integer of last bit
const UINT32 loMask = Filled << (pos%WordWidth);
const UINT32 hiMask = Filled >> (WordWidth - 1 - ((pos + k - 1)%WordWidth));
if (iLoInt == iHiInt) {
// inside integer boundary
count = stream[iLoInt] & (loMask & hiMask);
......@@ -140,7 +149,7 @@ inline UINT32 GetValueBlock(UINT32* stream, UINT32 pos, UINT32 k) {
//////////////////////////////////////////////////////////////////////
/// Clear block of size at least len at position pos in stream
/// @param stream A bit stream composed of unsigned integer arrays
/// @param stream A bit stream stored in array of unsigned integers
/// @param pos A valid zero-based position in the bit stream
/// @param len Number of bits set to 0
inline void ClearBitBlock(UINT32* stream, UINT32 pos, UINT32 len) {
......@@ -164,7 +173,7 @@ inline void ClearBitBlock(UINT32* stream, UINT32 pos, UINT32 len) {
//////////////////////////////////////////////////////////////////////
/// Set block of size at least len at position pos in stream
/// @param stream A bit stream composed of unsigned integer arrays
/// @param stream A bit stream stored in array of unsigned integers
/// @param pos A valid zero-based position in the bit stream
/// @param len Number of bits set to 1
inline void SetBitBlock(UINT32* stream, UINT32 pos, UINT32 len) {
......@@ -190,25 +199,24 @@ inline void SetBitBlock(UINT32* stream, UINT32 pos, UINT32 len) {
//////////////////////////////////////////////////////////////////////
/// Returns the distance to the next 1 in stream at position pos.
/// If no 1 is found within len bits, then len is returned.
/// @param stream A bit stream composed of unsigned integer arrays
/// @param stream A bit stream stored in array of unsigned integers
/// @param pos A valid zero-based position in the bit stream
/// @param len size of search area (in bits)
/// return The distance to the next 1 in stream at position pos
inline UINT32 SeekBitRange(UINT32* stream, UINT32 pos, UINT32 len) {
UINT32 count = 0;
UINT32 wordPos = pos >> WordWidthLog;
UINT32 testMask = 1 << (pos%WordWidth);
UINT32* word = stream + wordPos;
UINT32* word = stream + (pos >> WordWidthLog);
while (((*word & testMask) == 0) && (count < len)) {
count++;
count++;
testMask <<= 1;
if (!testMask) {
word++; testMask = 1;
// fast steps if all bits in a word are zero
while ((count + WordWidth <= len) && (*word == 0)) {
word++;
word++;
count += WordWidth;
}
}
......@@ -220,28 +228,24 @@ inline UINT32 SeekBitRange(UINT32* stream, UINT32 pos, UINT32 len) {
//////////////////////////////////////////////////////////////////////
/// Returns the distance to the next 0 in stream at position pos.
/// If no 0 is found within len bits, then len is returned.
/// @param stream A bit stream composed of unsigned integer arrays
/// @param stream A bit stream stored in array of unsigned integers
/// @param pos A valid zero-based position in the bit stream
/// @param len size of search area (in bits)
/// return The distance to the next 0 in stream at position pos
inline UINT32 SeekBit1Range(UINT32* stream, UINT32 pos, UINT32 len) {
UINT32 count = 0;
UINT32 wordPos = pos >> WordWidthLog;
UINT32 bitPos = pos%WordWidth;
UINT32 testMask = 1 << bitPos;
while (((stream[wordPos] & testMask) != 0) && (count < len)) {
ASSERT(bitPos < WordWidth);
count++;
bitPos++;
if (bitPos < WordWidth) {
testMask <<= 1;
} else {
wordPos++; bitPos = 0; testMask = 1;
UINT32 testMask = 1 << (pos%WordWidth);
UINT32* word = stream + (pos >> WordWidthLog);
// fast steps if all bits in a word are zero
while ((count + WordWidth <= len) && (stream[wordPos] == Filled)) {
wordPos++;
while (((*word & testMask) != 0) && (count < len)) {
count++;
testMask <<= 1;
if (!testMask) {
word++; testMask = 1;
// fast steps if all bits in a word are one
while ((count + WordWidth <= len) && (*word == Filled)) {
word++;
count += WordWidth;
}
}
......@@ -250,13 +254,12 @@ inline UINT32 SeekBit1Range(UINT32* stream, UINT32 pos, UINT32 len) {
}
//////////////////////////////////////////////////////////////////////
/// Compute position to beginning of the next 32-bit word
/// @param pos Current bit stream position
/// @return Position of next 32-bit word
/// Compute bit position of the next 32-bit word
/// @param pos current bit stream position
/// @return bit position of next 32-bit word
inline UINT32 AlignWordPos(UINT32 pos) {
// return (pos%WordWidth) ? pos + (WordWidth - pos%WordWidth) : pos;
// return pos + (WordWidth - pos%WordWidth)%WordWidth;
return ((pos + WordWidth - 1) >> WordWidthLog) << WordWidthLog;
// return ((pos + WordWidth - 1) >> WordWidthLog) << WordWidthLog;
return (pos + WordWidth - 1) & WordMask;
}
//////////////////////////////////////////////////////////////////////
......
This diff is collapsed.
/*
* The Progressive Graphics File; http://www.libpgf.org
*
*
* $Date: 2006-06-04 22:05:59 +0200 (So, 04 Jun 2006) $
* $Revision: 229 $
*
*
* This file Copyright (C) 2006 xeraina GmbH, Switzerland
*
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU LESSER GENERAL PUBLIC LICENSE
* as published by the Free Software Foundation; either version 2.1
* of the License, or (at your option) any later version.
*
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
//////////////////////////////////////////////////////////////////////
/// @file Decoder.h
/// @brief PGF decoder class
/// @author C. Stamm, R. Spuler
#ifndef PGF_DECODER_H
#define PGF_DECODER_H
#include "PGFtypes.h"
#include "PGFstream.h"
#include "BitStream.h"
#include "Subband.h"
#include "WaveletTransform.h"
#include "Stream.h"
/////////////////////////////////////////////////////////////////////
// Constants
......@@ -37,13 +41,41 @@
/////////////////////////////////////////////////////////////////////
/// PGF decoder class.
/// @author C. Stamm, R. Spuler
/// @brief PGF decoder
class CDecoder {
public:
/////////////////////////////////////////////////////////////////////
/// Constructor: Initialize PGF stream and buffer position.
/// @param stream A PGF stream or NULL
CDecoder(CPGFStream* stream = NULL);
//////////////////////////////////////////////////////////////////////
/// PGF decoder macro block class.
/// @author C. Stamm, I. Bauersachs
/// @brief A macro block is a decoding unit of fixed size (uncoded)
class CMacroBlock {
public:
CMacroBlock(CDecoder *decoder)
: m_decoder(decoder)
, m_header(0)
, m_valuePos(0)
{
ASSERT(m_decoder);
}
void BitplaneDecode(); // several macro blocks can be encoded in parallel
ROIBlockHeader m_header; // block header
DataT m_value[BufferSize]; // output buffer of values with index m_valuePos
UINT32 m_codeBuffer[BufferSize]; // input buffer for encoded bitstream
UINT32 m_valuePos; // current position in m_value
private:
UINT32 ComposeBitplane(UINT32 bufferSize, DataT planeMask, UINT32* sigBits, UINT32* refBits, UINT32* signBits);
UINT32 ComposeBitplaneRLD(UINT32 bufferSize, DataT planeMask, UINT32 sigPos, UINT32* refBits);
UINT32 ComposeBitplaneRLD(UINT32 bufferSize, DataT planeMask, UINT32* sigBits, UINT32* refBits, UINT32* signBits);
void SetBitAtPos(UINT32 pos, DataT planeMask) { (m_value[pos] >= 0) ? m_value[pos] |= planeMask : m_value[pos] -= planeMask; }
void SetSign(UINT32 pos, bool sign) { m_value[pos] = -m_value[pos]*sign + m_value[pos]*(!sign); }
CDecoder *m_decoder; // outer class
bool m_sigFlagVector[BufferSize+1]; // see paper from Malvar, Fast Progressive Wavelet Coder
};
public:
/////////////////////////////////////////////////////////////////////
/// Constructor: Read pre-header, header, and levelLength at current stream position.
/// It might throw an IOException.
......@@ -52,7 +84,8 @@ public:
/// @param header [out] A PGF header
/// @param postHeader [out] A PGF post-header
/// @param levelLength The location of the levelLength array. The array is allocated in this method. The caller has to delete this array.
CDecoder(CPGFStream* stream, PGFPreHeader& preHeader, PGFHeader& header, PGFPostHeader& postHeader, UINT32*& levelLength) THROW_; // throws IOException
/// @param useOMP If true, then the decoder will use multi-threading based on openMP
CDecoder(CPGFStream* stream, PGFPreHeader& preHeader, PGFHeader& header, PGFPostHeader& postHeader, UINT32*& levelLength, bool useOMP = true) THROW_; // throws IOException
/////////////////////////////////////////////////////////////////////
/// Destructor
......@@ -90,7 +123,7 @@ public:
void SetStreamPosToStart() THROW_ { ASSERT(m_stream); m_stream->SetPos(FSFromStart, m_startPos); }
////////////////////////////////////////////////////////////////////
/// Reset stream position to beginning of PGF pre header
/// Reset stream position to beginning of data block
void SetStreamPosToData() THROW_ { ASSERT(m_stream); m_stream->SetPos(FSFromStart, m_startPos + m_encodedHeaderLength); }
////////////////////////////////////////////////////////////////////
......@@ -113,16 +146,21 @@ public:
/// @return The number of bytes copied to the target buffer
UINT32 ReadEncodedData(UINT8* target, UINT32 len) const THROW_;
/////////////////////////////////////////////////////////////////////
/// Reads stream and decodes tile buffer
/// It might throw an IOException.
void DecodeBuffer() THROW_;
#ifdef __PGFROISUPPORT__
/////////////////////////////////////////////////////////////////////
/// Reads stream and decodes tile buffer
/// It might throw an IOException.
void DecodeTileBuffer() THROW_ { ASSERT(m_valuePos >= 0 && m_valuePos <= BufferSize); DecodeBuffer(); }
void DecodeTileBuffer() THROW_;
/////////////////////////////////////////////////////////////////////
/// Resets stream position to next tile.
/// It might throw an IOException.
void SkipTileBuffer() THROW_ { ASSERT(m_valuePos >= 0 && m_valuePos <= BufferSize); SkipBuffer(); }
void SkipTileBuffer() THROW_;
/////////////////////////////////////////////////////////////////////
/// Enables region of interest (ROI) status.
......@@ -134,30 +172,19 @@ public:
#endif
private:
void BitplaneDecode(UINT32 bufferSize);
UINT32 RLDSigsAndSigns(UINT32 bufferSize, UINT32 codeLen, UINT32* sigBits, UINT32* signBits);
UINT32 RLDSigns(UINT32 bufferSize, UINT32 codeLen, UINT32* signBits);
UINT32 ComposeBitplane(UINT32 bufferSize, UINT32 planeMask, UINT32* sigBits, UINT32* refBits, UINT32* signBits);
void DecodeBuffer() THROW_; // throws IOException
void SetBitAtPos(UINT32 pos, UINT32 planeMask) { (m_value[pos] >= 0) ? m_value[pos] |= planeMask : m_value[pos] -= planeMask; }
void SetSign(UINT32 pos, bool sign) { m_value[pos] = -m_value[pos]*sign + m_value[pos]*(!sign); }
//void SetSign(UINT32 pos, bool sign) { if (sign && m_value[pos] >= 0) m_value[pos] = -m_value[pos]; }
void SkipBuffer() THROW_; //throws IOException
protected:
void ReadMacroBlock(CMacroBlock* block) THROW_; // throws IOException
CPGFStream *m_stream; // input pgf stream
UINT64 m_startPos; // stream position at the beginning of the PGF pre header
UINT64 m_streamSizeEstimation; // estimation of stream size
UINT32 m_encodedHeaderLength; // stream offset from startPos to the beginning of the data part (highest level)
DataT m_value[BufferSize]; // buffer of values with index m_valuePos
UINT32 m_codeBuffer[BufferSize]; // buffer for encoded bitstream
UINT32 m_sigFlagVector[BufferLen]; // see paper from Malvar, Fast Progressive Wavelet Coder
UINT32 m_valuePos; // current position in m_value
UINT32 m_codePos; // current bit position in m_codeBuffer
CMacroBlock **m_macroBlocks; // array of macroblocks
int m_currentBlockIndex; // index of current macro block
int m_macroBlockLen; // array length
int m_macroBlocksAvailable; // number of decoded macro blocks
CMacroBlock *m_currentBlock; // current macro block (used by main thread)
bool m_bufferIsAvailable; // buffer contains needed coefficients
#ifdef __PGFROISUPPORT__
bool m_roi; // true: ensures region of interest (ROI) decoding
#endif
......
This diff is collapsed.
/*
* The Progressive Graphics File; http://www.libpgf.org
*
*
* $Date: 2006-06-04 22:05:59 +0200 (So, 04 Jun 2006) $
* $Revision: 229 $
*
*
* This file Copyright (C) 2006 xeraina GmbH, Switzerland
*
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU LESSER GENERAL PUBLIC LICENSE
* as published by the Free Software Foundation; either version 2.1
* of the License, or (at your option) any later version.
*
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
//////////////////////////////////////////////////////////////////////
/// @file Encoder.h
/// @brief PGF encoder class
/// @author C. Stamm, R. Spuler
#ifndef PGF_ENCODER_H
#define PGF_ENCODER_H
#include "PGFtypes.h"
#include "PGFstream.h"
#include "BitStream.h"
#include "Subband.h"
#include "WaveletTransform.h"
#include "Stream.h"
/////////////////////////////////////////////////////////////////////
// Constants
......@@ -36,8 +40,49 @@
/////////////////////////////////////////////////////////////////////
/// PGF encoder class.
/// @author C. Stamm, R. Spuler
/// @author C. Stamm
/// @brief PGF encoder
class CEncoder {
//////////////////////////////////////////////////////////////////////
/// PGF encoder macro block class.
/// @author C. Stamm, I. Bauersachs
/// @brief A macro block is an encoding unit of fixed size (uncoded)
class CMacroBlock {
public:
CMacroBlock(CEncoder *encoder)
: m_encoder(encoder)
, m_header(0)
{
ASSERT(m_encoder);
Init(-1);
}
DataT m_value[BufferSize]; // input buffer of values with index m_valuePos
UINT32 m_codeBuffer[BufferSize]; // output buffer for encoded bitstream
ROIBlockHeader m_header; // block header
UINT32 m_valuePos; // current buffer position
UINT32 m_maxAbsValue; // maximum absolute coefficient in each buffer
UINT32 m_codePos; // current position in encoded bitstream
int m_lastLevelIndex; // index of last encoded level: [0, nLevels); used because a level-end can occur before a buffer is full
void Init(int lastLevelIndex) { // initialize for reusage
m_valuePos = 0;
m_maxAbsValue = 0;
m_codePos = 0;
m_lastLevelIndex = lastLevelIndex;
}
void BitplaneEncode(); // several macro blocks can be encoded in parallel
private:
UINT32 RLESigns(UINT32 codePos, UINT32* signBits, UINT32 signLen);
UINT32 DecomposeBitplane(UINT32 bufferSize, UINT32 planeMask, UINT32 codePos, UINT32* sigBits, UINT32* refBits, UINT32* signBits, UINT32& signLen, UINT32& codeLen);
UINT8 NumberOfBitplanes();
bool GetBitAtPos(UINT32 pos, UINT32 planeMask) const { return (abs(m_value[pos]) & planeMask) > 0; }
CEncoder *m_encoder; // encoder instance
bool m_sigFlagVector[BufferSize+1]; // see paper from Malvar, Fast Progressive Wavelet Coder
};
public:
/////////////////////////////////////////////////////////////////////
/// Write pre-header, header, postHeader, and levelLength.
......@@ -47,17 +92,27 @@ public:
/// @param header An already filled in PGF header
/// @param postHeader [in] A already filled in PGF post header (containing color table, user data, ...)
/// @param levelLength A reference to an integer array, large enough to save the relative file positions of all PGF levels
CEncoder(CPGFStream* stream, PGFPreHeader preHeader, PGFHeader header, const PGFPostHeader& postHeader, UINT32*& levelLength) THROW_; // throws IOException
/// @param useOMP If true, then the encoder will use multi-threading based on openMP
CEncoder(CPGFStream* stream, PGFPreHeader preHeader, PGFHeader header, const PGFPostHeader& postHeader, UINT32*& levelLength, bool useOMP = true) THROW_; // throws IOException
/////////////////////////////////////////////////////////////////////
/// Destructor
~CEncoder();
/////////////////////////////////////////////////////////////////////
/// Pad buffer with zeros, encode buffer, write levelLength into header
/// Return number of bytes written into stream
/// Encoder favors speed over compression size
void FavorSpeedOverSize() { m_favorSpeed = true; }
/////////////////////////////////////////////////////////////////////
/// Pad buffer with zeros and encode buffer.
/// It might throw an IOException.
void Flush() THROW_;
/////////////////////////////////////////////////////////////////////
/// Write levelLength into header.
/// @return number of bytes written into stream
/// It might throw an IOException.
UINT32 Flush() THROW_;
UINT32 WriteLevelLength() THROW_;
/////////////////////////////////////////////////////////////////////
/// Partitions a rectangular region of a given subband.
......@@ -72,10 +127,9 @@ public:
void Partition(CSubband* band, int width, int height, int startPos, int pitch) THROW_;
/////////////////////////////////////////////////////////////////////
/// Set or clear flag. The flag must be set to true as soon a wavelet