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