File indexing completed on 2025-01-05 03:56:36
0001 /* 0002 * The Progressive Graphics File; http://www.libpgf.org 0003 * 0004 * $Date: 2006-06-04 22:05:59 +0200 (So, 04 Jun 2006) $ 0005 * $Revision: 229 $ 0006 * 0007 * This file Copyright (C) 2006 xeraina GmbH, Switzerland 0008 * 0009 * This program is free software; you can redistribute it and/or 0010 * modify it under the terms of the GNU LESSER GENERAL PUBLIC LICENSE 0011 * as published by the Free Software Foundation; either version 2.1 0012 * of the License, or (at your option) any later version. 0013 * 0014 * This program is distributed in the hope that it will be useful, 0015 * but WITHOUT ANY WARRANTY; without even the implied warranty of 0016 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 0017 * GNU General Public License for more details. 0018 * 0019 * You should have received a copy of the GNU General Public License 0020 * along with this program; if not, write to the Free Software 0021 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 0022 */ 0023 0024 ////////////////////////////////////////////////////////////////////// 0025 /// @file Decoder.h 0026 /// @brief PGF decoder class 0027 /// @author C. Stamm, R. Spuler 0028 0029 #ifndef PGF_DECODER_H 0030 #define PGF_DECODER_H 0031 0032 #include "PGFstream.h" 0033 #include "BitStream.h" 0034 #include "Subband.h" 0035 #include "WaveletTransform.h" 0036 0037 #include "digikam_export.h" 0038 0039 ///////////////////////////////////////////////////////////////////// 0040 // Constants 0041 #define BufferLen (BufferSize/WordWidth) ///< number of words per buffer 0042 #define CodeBufferLen BufferSize ///< number of words in code buffer (CodeBufferLen > BufferLen) 0043 0044 ///////////////////////////////////////////////////////////////////// 0045 /// PGF decoder class. 0046 /// @author C. Stamm, R. Spuler 0047 /// @brief PGF decoder 0048 class DIGIKAM_EXPORT CDecoder { 0049 ////////////////////////////////////////////////////////////////////// 0050 /// PGF decoder macro block class. 0051 /// @author C. Stamm, I. Bauersachs 0052 /// @brief A macro block is a decoding unit of fixed size (uncoded) 0053 class CMacroBlock { 0054 public: 0055 ////////////////////////////////////////////////////////////////////// 0056 /// Constructor: Initializes new macro block. 0057 CMacroBlock() 0058 : m_header(0) // makes sure that IsCompletelyRead() returns true for an empty macro block 0059 #ifdef _MSC_VER 0060 #pragma warning( suppress : 4351 ) 0061 #endif 0062 , m_value() 0063 , m_codeBuffer() 0064 , m_valuePos(0) 0065 , m_sigFlagVector() 0066 { 0067 } 0068 0069 ////////////////////////////////////////////////////////////////////// 0070 /// Returns true if this macro block has been completely read. 0071 /// @return true if current value position is at block end 0072 bool IsCompletelyRead() const { return m_valuePos >= m_header.rbh.bufferSize; } 0073 0074 ////////////////////////////////////////////////////////////////////// 0075 /// Decodes already read input data into this macro block. 0076 /// Several macro blocks can be decoded in parallel. 0077 /// Call CDecoder::ReadMacroBlock before this method. 0078 void BitplaneDecode(); 0079 0080 ROIBlockHeader m_header; ///< block header 0081 DataT m_value[BufferSize]; ///< output buffer of values with index m_valuePos 0082 UINT32 m_codeBuffer[CodeBufferLen]; ///< input buffer for encoded bitstream 0083 UINT32 m_valuePos; ///< current position in m_value 0084 0085 private: 0086 UINT32 ComposeBitplane(UINT32 bufferSize, DataT planeMask, UINT32* sigBits, UINT32* refBits, UINT32* signBits); 0087 UINT32 ComposeBitplaneRLD(UINT32 bufferSize, DataT planeMask, UINT32 sigPos, UINT32* refBits); 0088 UINT32 ComposeBitplaneRLD(UINT32 bufferSize, DataT planeMask, UINT32* sigBits, UINT32* refBits, UINT32 signPos); 0089 void SetBitAtPos(UINT32 pos, DataT planeMask) { (m_value[pos] >= 0) ? m_value[pos] |= planeMask : m_value[pos] -= planeMask; } 0090 void SetSign(UINT32 pos, bool sign) { m_value[pos] = -m_value[pos]*sign + m_value[pos]*(!sign); } 0091 0092 bool m_sigFlagVector[BufferSize+1]; // see paper from Malvar, Fast Progressive Wavelet Coder 0093 }; 0094 0095 public: 0096 ///////////////////////////////////////////////////////////////////// 0097 /// Constructor: Read pre-header, header, and levelLength at current stream position. 0098 /// It might throw an IOException. 0099 /// @param stream A PGF stream 0100 /// @param preHeader [out] A PGF pre-header 0101 /// @param header [out] A PGF header 0102 /// @param postHeader [out] A PGF post-header 0103 /// @param levelLength The location of the levelLength array. The array is allocated in this method. The caller has to delete this array. 0104 /// @param userDataPos The stream position of the user data (metadata) 0105 /// @param useOMP If true, then the decoder will use multi-threading based on openMP 0106 /// @param userDataPolicy Policy of user data (meta-data) handling while reading PGF headers. 0107 CDecoder(CPGFStream* stream, PGFPreHeader& preHeader, PGFHeader& header, 0108 PGFPostHeader& postHeader, UINT32*& levelLength, UINT64& userDataPos, 0109 bool useOMP, UINT32 userDataPolicy); // throws IOException 0110 0111 ///////////////////////////////////////////////////////////////////// 0112 /// Destructor 0113 ~CDecoder(); 0114 0115 ///////////////////////////////////////////////////////////////////// 0116 /// Unpartitions a rectangular region of a given subband. 0117 /// Partitioning scheme: The plane is partitioned in squares of side length LinBlockSize. 0118 /// Read wavelet coefficients from the output buffer of a macro block. 0119 /// It might throw an IOException. 0120 /// @param band A subband 0121 /// @param quantParam Dequantization value 0122 /// @param width The width of the rectangle 0123 /// @param height The height of the rectangle 0124 /// @param startPos The relative subband position of the top left corner of the rectangular region 0125 /// @param pitch The number of bytes in row of the subband 0126 void Partition(CSubband* band, int quantParam, int width, int height, int startPos, int pitch); 0127 0128 ///////////////////////////////////////////////////////////////////// 0129 /// Deccoding and dequantization of HL and LH subband (interleaved) using partitioning scheme. 0130 /// Partitioning scheme: The plane is partitioned in squares of side length InterBlockSize. 0131 /// It might throw an IOException. 0132 /// @param wtChannel A wavelet transform channel containing the HL and HL band 0133 /// @param level Wavelet transform level 0134 /// @param quantParam Dequantization value 0135 void DecodeInterleaved(CWaveletTransform* wtChannel, int level, int quantParam); 0136 0137 ////////////////////////////////////////////////////////////////////// 0138 /// Returns the length of all encoded headers in bytes. 0139 /// @return The length of all encoded headers in bytes 0140 UINT32 GetEncodedHeaderLength() const { return m_encodedHeaderLength; } 0141 0142 //////////////////////////////////////////////////////////////////// 0143 /// Resets stream position to beginning of PGF pre-header 0144 void SetStreamPosToStart() { ASSERT(m_stream); m_stream->SetPos(FSFromStart, m_startPos); } 0145 0146 //////////////////////////////////////////////////////////////////// 0147 /// Resets stream position to beginning of data block 0148 void SetStreamPosToData() { ASSERT(m_stream); m_stream->SetPos(FSFromStart, m_startPos + m_encodedHeaderLength); } 0149 0150 //////////////////////////////////////////////////////////////////// 0151 /// Skips a given number of bytes in the open stream. 0152 /// It might throw an IOException. 0153 void Skip(UINT64 offset); 0154 0155 ///////////////////////////////////////////////////////////////////// 0156 /// Dequantization of a single value at given position in subband. 0157 /// It might throw an IOException. 0158 /// @param band A subband 0159 /// @param bandPos A valid position in subband band 0160 /// @param quantParam The quantization parameter 0161 void DequantizeValue(CSubband* band, UINT32 bandPos, int quantParam); 0162 0163 ////////////////////////////////////////////////////////////////////// 0164 /// Copies data from the open stream to a target buffer. 0165 /// It might throw an IOException. 0166 /// @param target The target buffer 0167 /// @param len The number of bytes to read 0168 /// @return The number of bytes copied to the target buffer 0169 UINT32 ReadEncodedData(UINT8* target, UINT32 len) const; 0170 0171 ///////////////////////////////////////////////////////////////////// 0172 /// Reads next block(s) from stream and decodes them 0173 /// It might throw an IOException. 0174 void DecodeBuffer(); 0175 0176 ///////////////////////////////////////////////////////////////////// 0177 /// @return Stream 0178 CPGFStream* GetStream() { return m_stream; } 0179 0180 ///////////////////////////////////////////////////////////////////// 0181 /// Gets next macro block 0182 /// It might throw an IOException. 0183 void GetNextMacroBlock(); 0184 0185 #ifdef __PGFROISUPPORT__ 0186 ///////////////////////////////////////////////////////////////////// 0187 /// Resets stream position to next tile. 0188 /// Used with ROI encoding scheme only. 0189 /// It might throw an IOException. 0190 void SkipTileBuffer(); 0191 0192 ///////////////////////////////////////////////////////////////////// 0193 /// Enables region of interest (ROI) status. 0194 void SetROI() { m_roi = true; } 0195 #endif 0196 0197 #ifdef TRACE 0198 void DumpBuffer(); 0199 #endif 0200 0201 private: 0202 void ReadMacroBlock(CMacroBlock* block); ///< throws IOException 0203 0204 CPGFStream *m_stream; ///< input PGF stream 0205 UINT64 m_startPos; ///< stream position at the beginning of the PGF pre-header 0206 UINT64 m_streamSizeEstimation; ///< estimation of stream size 0207 UINT32 m_encodedHeaderLength; ///< stream offset from startPos to the beginning of the data part (highest level) 0208 0209 CMacroBlock **m_macroBlocks; ///< array of macroblocks 0210 int m_currentBlockIndex; ///< index of current macro block 0211 int m_macroBlockLen; ///< array length 0212 int m_macroBlocksAvailable; ///< number of decoded macro blocks (including currently used macro block) 0213 CMacroBlock *m_currentBlock; ///< current macro block (used by main thread) 0214 0215 #ifdef __PGFROISUPPORT__ 0216 bool m_roi; ///< true: ensures region of interest (ROI) decoding 0217 #endif 0218 }; 0219 0220 #endif //PGF_DECODER_H