File indexing completed on 2025-01-19 03:56:10
0001 /* 0002 * The Progressive Graphics File; http://www.libpgf.org 0003 * 0004 * $Date: 2007-02-03 13:04:21 +0100 (Sa, 03 Feb 2007) $ 0005 * $Revision: 280 $ 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 PGFimage.h 0026 /// @brief PGF image class 0027 /// @author C. Stamm 0028 0029 #ifndef PGF_PGFIMAGE_H 0030 #define PGF_PGFIMAGE_H 0031 0032 #include "PGFstream.h" 0033 0034 #include "digikam_export.h" 0035 0036 ////////////////////////////////////////////////////////////////////// 0037 // prototypes 0038 class CDecoder; 0039 class CEncoder; 0040 class CWaveletTransform; 0041 0042 ////////////////////////////////////////////////////////////////////// 0043 /// PGF image class is the main class. You always need a PGF object 0044 /// for encoding or decoding image data. 0045 /// Decoding: 0046 /// Open() 0047 /// Read() 0048 /// GetBitmap() 0049 /// Encoding: 0050 /// SetHeader() 0051 /// ImportBitmap() 0052 /// Write() 0053 /// @author C. Stamm, R. Spuler 0054 /// @brief PGF main class 0055 class DIGIKAM_EXPORT CPGFImage { 0056 public: 0057 0058 ////////////////////////////////////////////////////////////////////// 0059 /// Standard constructor 0060 CPGFImage(); 0061 0062 ////////////////////////////////////////////////////////////////////// 0063 /// Destructor 0064 virtual ~CPGFImage(); 0065 0066 ////////////////////////////////////////////////////////////////////// 0067 // Destroy internal data structures. Object state after this is the same as after CPGFImage(). 0068 void Destroy(); 0069 0070 ////////////////////////////////////////////////////////////////////// 0071 /// Open a PGF image at current stream position: read pre-header, header, and ckeck image type. 0072 /// Precondition: The stream has been opened for reading. 0073 /// It might throw an IOException. 0074 /// @param stream A PGF stream 0075 void Open(CPGFStream* stream); 0076 0077 ////////////////////////////////////////////////////////////////////// 0078 /// Returns true if the PGF has been opened for reading. 0079 bool IsOpen() const { return m_decoder != nullptr; } 0080 0081 ////////////////////////////////////////////////////////////////////// 0082 /// Read and decode some levels of a PGF image at current stream position. 0083 /// A PGF image is structered in levels, numbered between 0 and Levels() - 1. 0084 /// Each level can be seen as a single image, containing the same content 0085 /// as all other levels, but in a different size (width, height). 0086 /// The image size at level i is double the size (width, height) of the image at level i+1. 0087 /// The image at level 0 contains the original size. 0088 /// Precondition: The PGF image has been opened with a call of Open(...). 0089 /// It might throw an IOException. 0090 /// @param level [0, nLevels) The image level of the resulting image in the internal image buffer. 0091 /// @param cb A pointer to a callback procedure. The procedure is called after reading a single level. If cb returns true, then it stops proceeding. 0092 /// @param data Data Pointer to C++ class container to host callback procedure. 0093 void Read(int level = 0, CallbackPtr cb = nullptr, void *data = nullptr); 0094 0095 #ifdef __PGFROISUPPORT__ 0096 ////////////////////////////////////////////////////////////////////// 0097 /// Read a rectangular region of interest of a PGF image at current stream position. 0098 /// The origin of the coordinate axis is the top-left corner of the image. 0099 /// All coordinates are measured in pixels. 0100 /// It might throw an IOException. 0101 /// @param rect [inout] Rectangular region of interest (ROI) at level 0. The rect might be cropped. 0102 /// @param level [0, nLevels) The image level of the resulting image in the internal image buffer. 0103 /// @param cb A pointer to a callback procedure. The procedure is called after reading a single level. If cb returns true, then it stops proceeding. 0104 /// @param data Data Pointer to C++ class container to host callback procedure. 0105 void Read(PGFRect& rect, int level = 0, CallbackPtr cb = nullptr, void *data = nullptr); 0106 #endif 0107 0108 ////////////////////////////////////////////////////////////////////// 0109 /// Read and decode smallest level of a PGF image at current stream position. 0110 /// For details, please refert to Read(...) 0111 /// Precondition: The PGF image has been opened with a call of Open(...). 0112 /// It might throw an IOException. 0113 void ReadPreview() { Read(Levels() - 1); } 0114 0115 ////////////////////////////////////////////////////////////////////// 0116 /// After you've written a PGF image, you can call this method followed by GetBitmap/GetYUV 0117 /// to get a quick reconstruction (coded -> decoded image). 0118 /// It might throw an IOException. 0119 /// @param level The image level of the resulting image in the internal image buffer. 0120 void Reconstruct(int level = 0); 0121 0122 ////////////////////////////////////////////////////////////////////// 0123 /// Get image data in interleaved format: (ordering of RGB data is BGR[A]) 0124 /// Upsampling, YUV to RGB transform and interleaving are done here to reduce the number 0125 /// of passes over the data. 0126 /// The absolute value of pitch is the number of bytes of an image row of the given image buffer. 0127 /// If pitch is negative, then the image buffer must point to the last row of a bottom-up image (first byte on last row). 0128 /// if pitch is positive, then the image buffer must point to the first row of a top-down image (first byte). 0129 /// The sequence of output channels in the output image buffer does not need to be the same as provided by PGF. In case of different sequences you have to 0130 /// provide a channelMap of size of expected channels (depending on image mode). For example, PGF provides a channel sequence BGR in RGB color mode. 0131 /// If your provided image buffer expects a channel sequence ARGB, then the channelMap looks like { 3, 2, 1, 0 }. 0132 /// It might throw an IOException. 0133 /// @param pitch The number of bytes of a row of the image buffer. 0134 /// @param buff An image buffer. 0135 /// @param bpp The number of bits per pixel used in image buffer. 0136 /// @param channelMap A integer array containing the mapping of PGF channel ordering to expected channel ordering. 0137 /// @param cb A pointer to a callback procedure. The procedure is called after each copied buffer row. If cb returns true, then it stops proceeding. 0138 /// @param data Data Pointer to C++ class container to host callback procedure. 0139 void GetBitmap(int pitch, UINT8* buff, BYTE bpp, int channelMap[] = nullptr, CallbackPtr cb = nullptr, void *data = nullptr) const; // throws IOException 0140 0141 ////////////////////////////////////////////////////////////////////// 0142 /// Get YUV image data in interleaved format: (ordering is YUV[A]) 0143 /// The absolute value of pitch is the number of bytes of an image row of the given image buffer. 0144 /// If pitch is negative, then the image buffer must point to the last row of a bottom-up image (first byte on last row). 0145 /// if pitch is positive, then the image buffer must point to the first row of a top-down image (first byte). 0146 /// The sequence of output channels in the output image buffer does not need to be the same as provided by PGF. In case of different sequences you have to 0147 /// provide a channelMap of size of expected channels (depending on image mode). For example, PGF provides a channel sequence BGR in RGB color mode. 0148 /// If your provided image buffer expects a channel sequence VUY, then the channelMap looks like { 2, 1, 0 }. 0149 /// It might throw an IOException. 0150 /// @param pitch The number of bytes of a row of the image buffer. 0151 /// @param buff An image buffer. 0152 /// @param bpp The number of bits per pixel used in image buffer. 0153 /// @param channelMap A integer array containing the mapping of PGF channel ordering to expected channel ordering. 0154 /// @param cb A pointer to a callback procedure. The procedure is called after each copied buffer row. If cb returns true, then it stops proceeding. 0155 /// @param data Data Pointer to C++ class container to host callback procedure. 0156 void GetYUV(int pitch, DataT* buff, BYTE bpp, int channelMap[] = nullptr, CallbackPtr cb = nullptr, void *data = nullptr) const; // throws IOException 0157 0158 ////////////////////////////////////////////////////////////////////// 0159 /// Import an image from a specified image buffer. 0160 /// This method is usually called before Write(...) and after SetHeader(...). 0161 /// The absolute value of pitch is the number of bytes of an image row. 0162 /// If pitch is negative, then buff points to the last row of a bottom-up image (first byte on last row). 0163 /// If pitch is positive, then buff points to the first row of a top-down image (first byte). 0164 /// The sequence of input channels in the input image buffer does not need to be the same as expected from PGF. In case of different sequences you have to 0165 /// provide a channelMap of size of expected channels (depending on image mode). For example, PGF expects in RGB color mode a channel sequence BGR. 0166 /// If your provided image buffer contains a channel sequence ARGB, then the channelMap looks like { 3, 2, 1, 0 }. 0167 /// It might throw an IOException. 0168 /// @param pitch The number of bytes of a row of the image buffer. 0169 /// @param buff An image buffer. 0170 /// @param bpp The number of bits per pixel used in image buffer. 0171 /// @param channelMap A integer array containing the mapping of input channel ordering to expected channel ordering. 0172 /// @param cb A pointer to a callback procedure. The procedure is called after each imported buffer row. If cb returns true, then it stops proceeding. 0173 /// @param data Data Pointer to C++ class container to host callback procedure. 0174 void ImportBitmap(int pitch, UINT8 *buff, BYTE bpp, int channelMap[] = nullptr, CallbackPtr cb = nullptr, void *data = nullptr); 0175 0176 ////////////////////////////////////////////////////////////////////// 0177 /// Import a YUV image from a specified image buffer. 0178 /// The absolute value of pitch is the number of bytes of an image row. 0179 /// If pitch is negative, then buff points to the last row of a bottom-up image (first byte on last row). 0180 /// If pitch is positive, then buff points to the first row of a top-down image (first byte). 0181 /// The sequence of input channels in the input image buffer does not need to be the same as expected from PGF. In case of different sequences you have to 0182 /// provide a channelMap of size of expected channels (depending on image mode). For example, PGF expects in RGB color mode a channel sequence BGR. 0183 /// If your provided image buffer contains a channel sequence VUY, then the channelMap looks like { 2, 1, 0 }. 0184 /// It might throw an IOException. 0185 /// @param pitch The number of bytes of a row of the image buffer. 0186 /// @param buff An image buffer. 0187 /// @param bpp The number of bits per pixel used in image buffer. 0188 /// @param channelMap A integer array containing the mapping of input channel ordering to expected channel ordering. 0189 /// @param cb A pointer to a callback procedure. The procedure is called after each imported buffer row. If cb returns true, then it stops proceeding. 0190 /// @param data Data Pointer to C++ class container to host callback procedure. 0191 void ImportYUV(int pitch, DataT *buff, BYTE bpp, int channelMap[] = nullptr, CallbackPtr cb = nullptr, void *data = nullptr); 0192 0193 ////////////////////////////////////////////////////////////////////// 0194 /// Encode and write an entire PGF image (header and image) at current stream position. 0195 /// A PGF image is structered in levels, numbered between 0 and Levels() - 1. 0196 /// Each level can be seen as a single image, containing the same content 0197 /// as all other levels, but in a different size (width, height). 0198 /// The image size at level i is double the size (width, height) of the image at level i+1. 0199 /// The image at level 0 contains the original size. 0200 /// Precondition: the PGF image contains a valid header (see also SetHeader(...)). 0201 /// It might throw an IOException. 0202 /// @param stream A PGF stream 0203 /// @param nWrittenBytes [in-out] The number of bytes written into stream are added to the input value. 0204 /// @param cb A pointer to a callback procedure. The procedure is called after writing a single level. If cb returns true, then it stops proceeding. 0205 /// @param data Data Pointer to C++ class container to host callback procedure. 0206 void Write(CPGFStream* stream, UINT32* nWrittenBytes = nullptr, CallbackPtr cb = nullptr, void *data = nullptr); 0207 0208 ////////////////////////////////////////////////////////////////// 0209 /// Create wavelet transform channels and encoder. Write header at current stream position. 0210 /// Call this method before your first call of Write(int level) or WriteImage(), but after SetHeader(). 0211 /// This method is called inside of Write(stream, ...). 0212 /// It might throw an IOException. 0213 /// @param stream A PGF stream 0214 /// @return The number of bytes written into stream. 0215 UINT32 WriteHeader(CPGFStream* stream); 0216 0217 ////////////////////////////////////////////////////////////////////// 0218 /// Encode and write an image at current stream position. 0219 /// Call this method after WriteHeader(). In case you want to write uncached metadata, 0220 /// then do that after WriteHeader() and before WriteImage(). 0221 /// This method is called inside of Write(stream, ...). 0222 /// It might throw an IOException. 0223 /// @param stream A PGF stream 0224 /// @param cb A pointer to a callback procedure. The procedure is called after writing a single level. If cb returns true, then it stops proceeding. 0225 /// @param data Data Pointer to C++ class container to host callback procedure. 0226 /// @return The number of bytes written into stream. 0227 UINT32 WriteImage(CPGFStream* stream, CallbackPtr cb = nullptr, void *data = nullptr); 0228 0229 #ifdef __PGFROISUPPORT__ 0230 ////////////////////////////////////////////////////////////////// 0231 /// Encode and write down to given level at current stream position. 0232 /// A PGF image is structered in levels, numbered between 0 and Levels() - 1. 0233 /// Each level can be seen as a single image, containing the same content 0234 /// as all other levels, but in a different size (width, height). 0235 /// The image size at level i is double the size (width, height) of the image at level i+1. 0236 /// The image at level 0 contains the original size. 0237 /// Preconditions: the PGF image contains a valid header (see also SetHeader(...)) and 0238 /// WriteHeader() has been called before. Levels() > 0. 0239 /// The ROI encoding scheme must be used (see also SetHeader(...)). 0240 /// It might throw an IOException. 0241 /// @param level [0, nLevels) The image level of the resulting image in the internal image buffer. 0242 /// @param cb A pointer to a callback procedure. The procedure is called after writing a single level. If cb returns true, then it stops proceeding. 0243 /// @param data Data Pointer to C++ class container to host callback procedure. 0244 /// @return The number of bytes written into stream. 0245 UINT32 Write(int level, CallbackPtr cb = nullptr, void *data = nullptr); 0246 #endif 0247 0248 ///////////////////////////////////////////////////////////////////// 0249 /// Configures the encoder. 0250 /// @param useOMP Use parallel threading with Open MP during encoding. Default value: true. Influences the encoding only if the codec has been compiled with OpenMP support. 0251 /// @param favorSpeedOverSize Favors encoding speed over compression ratio. Default value: false 0252 void ConfigureEncoder(bool useOMP = true, bool favorSpeedOverSize = false) { m_useOMPinEncoder = useOMP; m_favorSpeedOverSize = favorSpeedOverSize; } 0253 0254 ///////////////////////////////////////////////////////////////////// 0255 /// Configures the decoder. 0256 /// @param useOMP Use parallel threading with Open MP during decoding. Default value: true. Influences the decoding only if the codec has been compiled with OpenMP support. 0257 /// @param policy The file might contain user data (e.g. metadata). The policy defines the behaviour during Open(). 0258 /// UP_CacheAll: User data is read and stored completely in a new allocated memory block. It can be accessed by GetUserData(). 0259 /// UP_CachePrefix: Only prefixSize bytes at the beginning of the user data are stored in a new allocated memory block. It can be accessed by GetUserData(). 0260 /// UP_Skip: User data is skipped and nothing is cached. 0261 /// @param prefixSize Is only used in combination with UP_CachePrefix. It defines the number of bytes cached. 0262 void ConfigureDecoder(bool useOMP = true, UserdataPolicy policy = UP_CacheAll, UINT32 prefixSize = 0) { ASSERT(prefixSize <= MaxUserDataSize); m_useOMPinDecoder = useOMP; m_userDataPolicy = (UP_CachePrefix) ? prefixSize : 0xFFFFFFFF - policy; } 0263 0264 //////////////////////////////////////////////////////////////////// 0265 /// Reset stream position to start of PGF pre-header or start of data. Must not be called before Open() or before Write(). 0266 /// Use this method after Read() if you want to read the same image several times, e.g. reading different ROIs. 0267 /// @param startOfData true: you want to read the same image several times. false: resets stream position to the initial position 0268 void ResetStreamPos(bool startOfData); 0269 0270 ////////////////////////////////////////////////////////////////////// 0271 /// Set internal PGF image buffer channel. 0272 /// @param channel A YUV data channel 0273 /// @param c A channel index 0274 void SetChannel(DataT* channel, int c = 0) { ASSERT(c >= 0 && c < MaxChannels); m_channel[c] = channel; } 0275 0276 ////////////////////////////////////////////////////////////////////// 0277 /// Set PGF header and user data. 0278 /// Precondition: The PGF image has been never opened with Open(...). 0279 /// It might throw an IOException. 0280 /// @param header A valid and already filled in PGF header structure 0281 /// @param flags A combination of additional version flags. In case you use level-wise encoding then set flag = PGFROI. 0282 /// @param userData A user-defined memory block containing any kind of cached metadata. 0283 /// @param userDataLength The size of user-defined memory block in bytes 0284 void SetHeader(const PGFHeader& header, BYTE flags = 0, const UINT8* userData = 0, UINT32 userDataLength = 0); // throws IOException 0285 0286 ////////////////////////////////////////////////////////////////////// 0287 /// Set maximum intensity value for image modes with more than eight bits per channel. 0288 /// Call this method after SetHeader, but before ImportBitmap. 0289 /// @param maxValue The maximum intensity value. 0290 void SetMaxValue(UINT32 maxValue); 0291 0292 ////////////////////////////////////////////////////////////////////// 0293 /// Set progress mode used in Read and Write. 0294 /// Default mode is PM_Relative. 0295 /// This method must be called before Open() or SetHeader(). 0296 /// PM_Relative: 100% = level difference between current level and target level of Read/Write 0297 /// PM_Absolute: 100% = number of levels 0298 void SetProgressMode(ProgressMode pm) { m_progressMode = pm; } 0299 0300 ////////////////////////////////////////////////////////////////////// 0301 /// Set refresh callback procedure and its parameter. 0302 /// The refresh callback is called during Read(...) after each level read. 0303 /// @param callback A refresh callback procedure 0304 /// @param arg A parameter of the refresh callback procedure 0305 void SetRefreshCallback(RefreshCB callback, void* arg) { m_cb = callback; m_cbArg = arg; } 0306 0307 ////////////////////////////////////////////////////////////////////// 0308 /// Sets the red, green, blue (RGB) color values for a range of entries in the palette (clut). 0309 /// It might throw an IOException. 0310 /// @param iFirstColor The color table index of the first entry to set. 0311 /// @param nColors The number of color table entries to set. 0312 /// @param prgbColors A pointer to the array of RGBQUAD structures to set the color table entries. 0313 void SetColorTable(UINT32 iFirstColor, UINT32 nColors, const RGBQUAD* prgbColors); 0314 0315 ////////////////////////////////////////////////////////////////////// 0316 /// Return an internal YUV image channel. 0317 /// @param c A channel index 0318 /// @return An internal YUV image channel 0319 DataT* GetChannel(int c = 0) { ASSERT(c >= 0 && c < MaxChannels); return m_channel[c]; } 0320 0321 ////////////////////////////////////////////////////////////////////// 0322 /// Retrieves red, green, blue (RGB) color values from a range of entries in the palette of the DIB section. 0323 /// It might throw an IOException. 0324 /// @param iFirstColor The color table index of the first entry to retrieve. 0325 /// @param nColors The number of color table entries to retrieve. 0326 /// @param prgbColors A pointer to the array of RGBQUAD structures to retrieve the color table entries. 0327 void GetColorTable(UINT32 iFirstColor, UINT32 nColors, RGBQUAD* prgbColors) const; 0328 0329 ////////////////////////////////////////////////////////////////////// 0330 // Returns address of internal color table 0331 /// @return Address of color table 0332 const RGBQUAD* GetColorTable() const { return m_postHeader.clut; } 0333 0334 ////////////////////////////////////////////////////////////////////// 0335 /// Return the PGF header structure. 0336 /// @return A PGF header structure 0337 const PGFHeader* GetHeader() const { return &m_header; } 0338 0339 ////////////////////////////////////////////////////////////////////// 0340 /// Get maximum intensity value for image modes with more than eight bits per channel. 0341 /// Don't call this method before the PGF header has been read. 0342 /// @return The maximum intensity value. 0343 UINT32 GetMaxValue() const { return (1 << m_header.usedBitsPerChannel) - 1; } 0344 0345 ////////////////////////////////////////////////////////////////////// 0346 /// Return the stream position of the user data or 0. 0347 /// Precondition: The PGF image has been opened with a call of Open(...). 0348 UINT64 GetUserDataPos() const { return m_userDataPos; } 0349 0350 ////////////////////////////////////////////////////////////////////// 0351 /// Return user data and size of user data. 0352 /// Precondition: The PGF image has been opened with a call of Open(...). 0353 /// @param cachedSize [out] Size of returned user data in bytes. 0354 /// @param pTotalSize [optional out] Pointer to return the size of user data stored in image header in bytes. 0355 /// @return A pointer to user data or nullptr if there is no user data available. 0356 const UINT8* GetUserData(UINT32& cachedSize, UINT32* pTotalSize = nullptr) const; 0357 0358 ////////////////////////////////////////////////////////////////////// 0359 /// Return the length of all encoded headers in bytes. 0360 /// Precondition: The PGF image has been opened with a call of Open(...). 0361 /// @return The length of all encoded headers in bytes 0362 UINT32 GetEncodedHeaderLength() const; 0363 0364 ////////////////////////////////////////////////////////////////////// 0365 /// Return the length of an encoded PGF level in bytes. 0366 /// Precondition: The PGF image has been opened with a call of Open(...). 0367 /// @param level The image level 0368 /// @return The length of a PGF level in bytes 0369 UINT32 GetEncodedLevelLength(int level) const { ASSERT(level >= 0 && level < m_header.nLevels); return m_levelLength[m_header.nLevels - level - 1]; } 0370 0371 ////////////////////////////////////////////////////////////////////// 0372 /// Reads the encoded PGF header and copies it to a target buffer. 0373 /// Precondition: The PGF image has been opened with a call of Open(...). 0374 /// It might throw an IOException. 0375 /// @param target The target buffer 0376 /// @param targetLen The length of the target buffer in bytes 0377 /// @return The number of bytes copied to the target buffer 0378 UINT32 ReadEncodedHeader(UINT8* target, UINT32 targetLen) const; 0379 0380 ////////////////////////////////////////////////////////////////////// 0381 /// Reads the data of an encoded PGF level and copies it to a target buffer 0382 /// without decoding. 0383 /// Precondition: The PGF image has been opened with a call of Open(...). 0384 /// It might throw an IOException. 0385 /// @param level The image level 0386 /// @param target The target buffer 0387 /// @param targetLen The length of the target buffer in bytes 0388 /// @return The number of bytes copied to the target buffer 0389 UINT32 ReadEncodedData(int level, UINT8* target, UINT32 targetLen) const; 0390 0391 ////////////////////////////////////////////////////////////////////// 0392 /// Return current image width of given channel in pixels. 0393 /// The returned width depends on the levels read so far and on ROI. 0394 /// @param c A channel index 0395 /// @return Channel width in pixels 0396 UINT32 ChannelWidth(int c = 0) const { ASSERT(c >= 0 && c < MaxChannels); return m_width[c]; } 0397 0398 ////////////////////////////////////////////////////////////////////// 0399 /// Return current image height of given channel in pixels. 0400 /// The returned height depends on the levels read so far and on ROI. 0401 /// @param c A channel index 0402 /// @return Channel height in pixels 0403 UINT32 ChannelHeight(int c = 0) const { ASSERT(c >= 0 && c < MaxChannels); return m_height[c]; } 0404 0405 ////////////////////////////////////////////////////////////////////// 0406 /// Return bits per channel of the image's encoder. 0407 /// @return Bits per channel 0408 BYTE ChannelDepth() const { return MaxChannelDepth(m_preHeader.version); } 0409 0410 ////////////////////////////////////////////////////////////////////// 0411 /// Return image width of channel 0 at given level in pixels. 0412 /// The returned width is independent of any Read-operations and ROI. 0413 /// @param level A level 0414 /// @return Image level width in pixels 0415 UINT32 Width(int level = 0) const { ASSERT(level >= 0); return LevelSizeL(m_header.width, level); } 0416 0417 ////////////////////////////////////////////////////////////////////// 0418 /// Return image height of channel 0 at given level in pixels. 0419 /// The returned height is independent of any Read-operations and ROI. 0420 /// @param level A level 0421 /// @return Image level height in pixels 0422 UINT32 Height(int level = 0) const { ASSERT(level >= 0); return LevelSizeL(m_header.height, level); } 0423 0424 ////////////////////////////////////////////////////////////////////// 0425 /// Return current image level. 0426 /// Since Read(...) can be used to read each image level separately, it is 0427 /// helpful to know the current level. The current level immediately after Open(...) is Levels(). 0428 /// @return Current image level 0429 BYTE Level() const { return (BYTE)m_currentLevel; } 0430 0431 ////////////////////////////////////////////////////////////////////// 0432 /// Return the number of image levels. 0433 /// @return Number of image levels 0434 BYTE Levels() const { return m_header.nLevels; } 0435 0436 ////////////////////////////////////////////////////////////////////// 0437 /// Return true if all levels have been read 0438 bool IsFullyRead() const { return m_currentLevel == 0; } 0439 0440 ////////////////////////////////////////////////////////////////////// 0441 /// Return the PGF quality. The quality is inbetween 0 and MaxQuality. 0442 /// PGF quality 0 means lossless quality. 0443 /// @return PGF quality 0444 BYTE Quality() const { return m_header.quality; } 0445 0446 ////////////////////////////////////////////////////////////////////// 0447 /// Return the number of image channels. 0448 /// An image of type RGB contains 3 image channels (B, G, R). 0449 /// @return Number of image channels 0450 BYTE Channels() const { return m_header.channels; } 0451 0452 ////////////////////////////////////////////////////////////////////// 0453 /// Return the image mode. 0454 /// An image mode is a predefined constant value (see also PGFtypes.h) compatible with Adobe Photoshop. 0455 /// It represents an image type and format. 0456 /// @return Image mode 0457 BYTE Mode() const { return m_header.mode; } 0458 0459 ////////////////////////////////////////////////////////////////////// 0460 /// Return the number of bits per pixel. 0461 /// Valid values can be 1, 8, 12, 16, 24, 32, 48, 64. 0462 /// @return Number of bits per pixel. 0463 BYTE BPP() const { return m_header.bpp; } 0464 0465 ////////////////////////////////////////////////////////////////////// 0466 /// Return true if the pgf image supports Region Of Interest (ROI). 0467 /// @return true if the pgf image supports ROI. 0468 bool ROIisSupported() const { return (m_preHeader.version & PGFROI) == PGFROI; } 0469 0470 #ifdef __PGFROISUPPORT__ 0471 /// Return ROI of channel 0 at current level in pixels. 0472 /// The returned rect is only valid after reading a ROI. 0473 /// @return ROI in pixels 0474 PGFRect ComputeLevelROI() const; 0475 #endif 0476 0477 ////////////////////////////////////////////////////////////////////// 0478 /// Returns number of used bits per input/output image channel. 0479 /// Precondition: header must be initialized. 0480 /// @return number of used bits per input/output image channel. 0481 BYTE UsedBitsPerChannel() const; 0482 0483 ////////////////////////////////////////////////////////////////////// 0484 /// Returns the used codec major version of a pgf image 0485 /// @return PGF codec major version of this image 0486 BYTE Version() const { BYTE ver = CodecMajorVersion(m_preHeader.version); return (ver <= 7) ? ver : (BYTE)m_header.version.major; } 0487 0488 //class methods 0489 0490 ////////////////////////////////////////////////////////////////////// 0491 /// Check for valid import image mode. 0492 /// @param mode Image mode 0493 /// @return True if an image of given mode can be imported with ImportBitmap(...) 0494 static bool ImportIsSupported(BYTE mode); 0495 0496 ////////////////////////////////////////////////////////////////////// 0497 /// Compute and return image width/height of LL subband at given level. 0498 /// @param size Original image size (e.g. width or height at level 0) 0499 /// @param level An image level 0500 /// @return Image width/height at given level in pixels 0501 static UINT32 LevelSizeL(UINT32 size, int level) { ASSERT(level >= 0); UINT32 d = 1 << level; return (size + d - 1) >> level; } 0502 0503 ////////////////////////////////////////////////////////////////////// 0504 /// Compute and return image width/height of HH subband at given level. 0505 /// @param size Original image size (e.g. width or height at level 0) 0506 /// @param level An image level 0507 /// @return high pass size at given level in pixels 0508 static UINT32 LevelSizeH(UINT32 size, int level) { ASSERT(level >= 0); UINT32 d = 1 << (level - 1); return (size + d - 1) >> level; } 0509 0510 ////////////////////////////////////////////////////////////////////// 0511 /// Return codec major version. 0512 /// @param version pgf pre-header version number 0513 /// @return PGF major of given version 0514 static BYTE CodecMajorVersion(BYTE version = PGFVersion); 0515 0516 ////////////////////////////////////////////////////////////////////// 0517 /// Return maximum channel depth. 0518 /// @param version pgf pre-header version number 0519 /// @return maximum channel depth in bit of given version (16 or 32 bit) 0520 static BYTE MaxChannelDepth(BYTE version = PGFVersion) { return (version & PGF32) ? 32 : 16; } 0521 0522 protected: 0523 CWaveletTransform* m_wtChannel[MaxChannels]; ///< wavelet transformed color channels 0524 DataT* m_channel[MaxChannels]; ///< untransformed channels in YUV format 0525 CDecoder* m_decoder; ///< PGF decoder 0526 CEncoder* m_encoder; ///< PGF encoder 0527 UINT32* m_levelLength; ///< length of each level in bytes; first level starts immediately after this array 0528 UINT32 m_width[MaxChannels]; ///< width of each channel at current level 0529 UINT32 m_height[MaxChannels]; ///< height of each channel at current level 0530 PGFPreHeader m_preHeader; ///< PGF pre-header 0531 PGFHeader m_header; ///< PGF file header 0532 PGFPostHeader m_postHeader; ///< PGF post-header 0533 UINT64 m_userDataPos; ///< stream position of user data 0534 int m_currentLevel; ///< transform level of current image 0535 UINT32 m_userDataPolicy; ///< user data (metadata) policy during open 0536 BYTE m_quant; ///< quantization parameter 0537 bool m_downsample; ///< chrominance channels are downsampled 0538 bool m_favorSpeedOverSize; ///< favor encoding speed over compression ratio 0539 bool m_useOMPinEncoder; ///< use Open MP in encoder 0540 bool m_useOMPinDecoder; ///< use Open MP in decoder 0541 #ifdef __PGFROISUPPORT__ 0542 bool m_streamReinitialized; ///< stream has been reinitialized 0543 PGFRect m_roi; ///< region of interest 0544 #endif 0545 0546 private: 0547 RefreshCB m_cb; ///< pointer to refresh callback procedure 0548 void *m_cbArg; ///< refresh callback argument 0549 double m_percent; ///< progress [0..1] 0550 ProgressMode m_progressMode; ///< progress mode used in Read and Write; PM_Relative is default mode 0551 0552 void Init(); 0553 void ComputeLevels(); 0554 bool CompleteHeader(); 0555 void RgbToYuv(int pitch, UINT8* rgbBuff, BYTE bpp, int channelMap[], CallbackPtr cb, void *data); 0556 void Downsample(int nChannel); 0557 UINT32 UpdatePostHeaderSize(); 0558 void WriteLevel(); 0559 0560 #ifdef __PGFROISUPPORT__ 0561 PGFRect GetAlignedROI(int c = 0) const; 0562 void SetROI(PGFRect rect); 0563 #endif 0564 0565 UINT8 Clamp4(DataT v) const { 0566 if (v & 0xFFFFFFF0) return (v < 0) ? (UINT8)0: (UINT8)15; else return (UINT8)v; 0567 } 0568 UINT16 Clamp6(DataT v) const { 0569 if (v & 0xFFFFFFC0) return (v < 0) ? (UINT16)0: (UINT16)63; else return (UINT16)v; 0570 } 0571 UINT8 Clamp8(DataT v) const { 0572 // needs only one test in the normal case 0573 if (v & 0xFFFFFF00) return (v < 0) ? (UINT8)0 : (UINT8)255; else return (UINT8)v; 0574 } 0575 UINT16 Clamp16(DataT v) const { 0576 if (v & 0xFFFF0000) return (v < 0) ? (UINT16)0: (UINT16)65535; else return (UINT16)v; 0577 } 0578 UINT32 Clamp31(DataT v) const { 0579 return (v < 0) ? 0 : (UINT32)v; 0580 } 0581 }; 0582 0583 #endif //PGF_PGFIMAGE_H