CPGFImage man page

CPGFImage — PGF main class.

Synopsis

#include <PGFimage.h>

Public Member Functions

CPGFImage ()
Standard constructor: It is used to create a PGF instance for opening and reading.
virtual ~CPGFImage ()
Destructor: Destroy internal data structures.
virtual void Close ()

virtual void Destroy ()

void Open (CPGFStream *stream) THROW_

bool IsOpen () const
Returns true if the PGF has been opened and not closed.
void Read (int level=0, CallbackPtr cb=NULL, void *data=NULL) THROW_

void Read (PGFRect &rect, int level=0, CallbackPtr cb=NULL, void *data=NULL) THROW_

void ReadPreview () THROW_

void Reconstruct (int level=0) THROW_

void GetBitmap (int pitch, UINT8 *buff, BYTE bpp, int channelMap[]=NULL, CallbackPtr cb=NULL, void *data=NULL) const THROW_

void GetYUV (int pitch, DataT *buff, BYTE bpp, int channelMap[]=NULL, CallbackPtr cb=NULL, void *data=NULL) const THROW_

void ImportBitmap (int pitch, UINT8 *buff, BYTE bpp, int channelMap[]=NULL, CallbackPtr cb=NULL, void *data=NULL) THROW_

void ImportYUV (int pitch, DataT *buff, BYTE bpp, int channelMap[]=NULL, CallbackPtr cb=NULL, void *data=NULL) THROW_

void Write (CPGFStream *stream, UINT32 *nWrittenBytes=NULL, CallbackPtr cb=NULL, void *data=NULL) THROW_

UINT32 WriteHeader (CPGFStream *stream) THROW_

UINT32 WriteImage (CPGFStream *stream, CallbackPtr cb=NULL, void *data=NULL) THROW_

UINT32 Write (int level, CallbackPtr cb=NULL, void *data=NULL) THROW_

void ConfigureEncoder (bool useOMP=true, bool favorSpeedOverSize=false)

void ConfigureDecoder (bool useOMP=true, bool skipUserData=false)

void ResetStreamPos () THROW_
Reset stream position to start of PGF pre-header.
void SetChannel (DataT *channel, int c=0)

void SetHeader (const PGFHeader &header, BYTE flags=0, UINT8 *userData=0, UINT32 userDataLength=0) THROW_

void SetMaxValue (UINT32 maxValue)

void SetProgressMode (ProgressMode pm)

void SetRefreshCallback (RefreshCB callback, void *arg)

void SetColorTable (UINT32 iFirstColor, UINT32 nColors, const RGBQUAD *prgbColors) THROW_

DataT * GetChannel (int c=0)

void GetColorTable (UINT32 iFirstColor, UINT32 nColors, RGBQUAD *prgbColors) const THROW_

const RGBQUAD * GetColorTable () const

const PGFHeader * GetHeader () const

UINT32 GetMaxValue () const

UINT64 GetUserDataPos () const

const UINT8 * GetUserData (UINT32 &size) const

UINT32 GetEncodedHeaderLength () const

UINT32 GetEncodedLevelLength (int level) const

UINT32 ReadEncodedHeader (UINT8 *target, UINT32 targetLen) const THROW_

UINT32 ReadEncodedData (int level, UINT8 *target, UINT32 targetLen) const THROW_

UINT32 ChannelWidth (int c=0) const

UINT32 ChannelHeight (int c=0) const

BYTE ChannelDepth () const

UINT32 Width (int level=0) const

UINT32 Height (int level=0) const

BYTE Level () const

BYTE Levels () const

BYTE Quality () const

BYTE Channels () const

BYTE Mode () const

BYTE BPP () const

bool ROIisSupported () const

BYTE UsedBitsPerChannel () const

BYTE Version () const

Static Public Member Functions

static bool ImportIsSupported (BYTE mode)

static UINT32 LevelWidth (UINT32 width, int level)

static UINT32 LevelHeight (UINT32 height, int level)

static BYTE CurrentVersion (BYTE version=PGFVersion)
Return version.
static BYTE CurrentChannelDepth (BYTE version=PGFVersion)

Protected Attributes

CWaveletTransform * m_wtChannel [MaxChannels]
wavelet transformed color channels
DataT * m_channel [MaxChannels]
untransformed channels in YUV format
CDecoder * m_decoder
PGF decoder.
CEncoder * m_encoder
PGF encoder.
UINT32 * m_levelLength
length of each level in bytes; first level starts immediately after this array
UINT32 m_width [MaxChannels]
width of each channel at current level
UINT32 m_height [MaxChannels]
height of each channel at current level
PGFPreHeader m_preHeader
PGF pre-header.
PGFHeader m_header
PGF file header.
PGFPostHeader m_postHeader
PGF post-header.
UINT64 m_userDataPos
stream position of user data
int m_currentLevel
transform level of current image
BYTE m_quant
quantization parameter
bool m_downsample
chrominance channels are downsampled
bool m_favorSpeedOverSize
favor encoding speed over compression ratio
bool m_useOMPinEncoder
use Open MP in encoder
bool m_useOMPinDecoder
use Open MP in decoder
bool m_skipUserData
skip user data (metadata) during open
bool m_streamReinitialized
stream has been reinitialized
PGFRect m_roi
region of interest

Private Member Functions

void ComputeLevels ()

bool CompleteHeader ()

void RgbToYuv (int pitch, UINT8 *rgbBuff, BYTE bpp, int channelMap[], CallbackPtr cb, void *data) THROW_

void Downsample (int nChannel)

UINT32 UpdatePostHeaderSize () THROW_

void WriteLevel () THROW_

void SetROI (PGFRect rect)

UINT8 Clamp4 (DataT v) const

UINT16 Clamp6 (DataT v) const

UINT8 Clamp8 (DataT v) const

UINT16 Clamp16 (DataT v) const

UINT32 Clamp31 (DataT v) const

Private Attributes

RefreshCB m_cb
pointer to refresh callback procedure
void * m_cbArg
refresh callback argument
double m_percent
progress [0..1]
ProgressMode m_progressMode
progress mode used in Read and Write; PM_Relative is default mode

Detailed Description

PGF main class.

PGF image class is the main class. You always need a PGF object for encoding or decoding image data. Decoding: pgf.Open(...) pgf.Read(...) pgf.GetBitmap(...) Encoding: pgf.SetHeader(...) pgf.ImportBitmap(...) pgf.Write(...)

Author:

C. Stamm, R. Spuler

Definition at line 57 of file PGFimage.h.

Constructor & Destructor Documentation

CPGFImage::CPGFImage ()

Standard constructor: It is used to create a PGF instance for opening and reading.

Definition at line 55 of file PGFimage.cpp.

56 : m_decoder(0)
57 , m_encoder(0)
58 , m_levelLength(0)
59 , m_currentLevel(0)
60 , m_quant(0)
61 , m_userDataPos(0)
62 , m_downsample(false)
63 , m_favorSpeedOverSize(false)
64 , m_useOMPinEncoder(true)
65 , m_useOMPinDecoder(true)
66 , m_skipUserData(false)
67 #ifdef __PGFROISUPPORT__
68 , m_streamReinitialized(false)
69 #endif
70 , m_cb(0)
71 , m_cbArg(0)
72 , m_progressMode(PM_Relative)
73 , m_percent(0)
74 {
75 
76         // init preHeader
77         memcpy(m_preHeader.magic, PGFMagic, 3);
78         m_preHeader.version = PGFVersion;
79         m_preHeader.hSize = 0;
80 
81         // init postHeader
82         m_postHeader.userData = 0;
83         m_postHeader.userDataLen = 0;
84 
85         // init channels
86         for (int i=0; i < MaxChannels; i++) {
87                 m_channel[i] = 0;
88                 m_wtChannel[i] = 0;
89         }
90 
91         // set image width and height
92         m_width[0] = 0;
93         m_height[0] = 0;
94 }

CPGFImage::~CPGFImage () [virtual]

Destructor: Destroy internal data structures.

Definition at line 98 of file PGFimage.cpp.

98                       {
99         Destroy();
100 }

Member Function Documentation

BYTE CPGFImage::BPP () const [inline]

Return the number of bits per pixel. Valid values can be 1, 8, 12, 16, 24, 32, 48, 64.

Returns:

Number of bits per pixel.

Definition at line 460 of file PGFimage.h.

460 { return m_header.bpp; }

BYTE CPGFImage::ChannelDepth () const [inline]

Return bits per channel of the image's encoder.

Returns:

Bits per channel

Definition at line 409 of file PGFimage.h.

409 { return CurrentChannelDepth(m_preHeader.version); }

UINT32 CPGFImage::ChannelHeight (int c = 0) const [inline]

Return current image height of given channel in pixels. The returned height depends on the levels read so far and on ROI.

Parameters:

c A channel index

Returns:

Channel height in pixels

Definition at line 404 of file PGFimage.h.

404 { ASSERT(c >= 0 && c < MaxChannels); return m_height[c]; }

BYTE CPGFImage::Channels () const [inline]

Return the number of image channels. An image of type RGB contains 3 image channels (B, G, R).

Returns:

Number of image channels

Definition at line 447 of file PGFimage.h.

447 { return m_header.channels; }

UINT32 CPGFImage::ChannelWidth (int c = 0) const [inline]

Return current image width of given channel in pixels. The returned width depends on the levels read so far and on ROI.

Parameters:

c A channel index

Returns:

Channel width in pixels

Definition at line 397 of file PGFimage.h.

397 { ASSERT(c >= 0 && c < MaxChannels); return m_width[c]; }

UINT16 CPGFImage::Clamp16 (DataT v) const [inline], [private]

Definition at line 561 of file PGFimage.h.

561                                       {
562                 if (v & 0xFFFF0000) return (v < 0) ? (UINT16)0: (UINT16)65535; else return (UINT16)v;
563         }

UINT32 CPGFImage::Clamp31 (DataT v) const [inline], [private]

Definition at line 564 of file PGFimage.h.

564                                       {
565                 return (v < 0) ? 0 : (UINT32)v;
566         }

UINT8 CPGFImage::Clamp4 (DataT v) const [inline], [private]

Definition at line 551 of file PGFimage.h.

551                                     {
552                 if (v & 0xFFFFFFF0) return (v < 0) ? (UINT8)0: (UINT8)15; else return (UINT8)v;
553         }

UINT16 CPGFImage::Clamp6 (DataT v) const [inline], [private]

Definition at line 554 of file PGFimage.h.

554                                      {
555                 if (v & 0xFFFFFFC0) return (v < 0) ? (UINT16)0: (UINT16)63; else return (UINT16)v;
556         }

UINT8 CPGFImage::Clamp8 (DataT v) const [inline], [private]

Definition at line 557 of file PGFimage.h.

557                                     {
558                 // needs only one test in the normal case
559                 if (v & 0xFFFFFF00) return (v < 0) ? (UINT8)0 : (UINT8)255; else return (UINT8)v;
560         }

void CPGFImage::Close () [virtual]

Close PGF image after opening and reading. Destructor calls this method during destruction.

Definition at line 122 of file PGFimage.cpp.

122                       {
123         delete m_decoder; m_decoder = 0;
124 }

bool CPGFImage::CompleteHeader () [private]

Definition at line 208 of file PGFimage.cpp.

208                                {
209         if (m_header.mode == ImageModeUnknown) {
210                 // undefined mode
211                 switch(m_header.bpp) {
212                 case 1: m_header.mode = ImageModeBitmap; break;
213                 case 8: m_header.mode = ImageModeGrayScale; break;
214                 case 12: m_header.mode = ImageModeRGB12; break;
215                 case 16: m_header.mode = ImageModeRGB16; break;
216                 case 24: m_header.mode = ImageModeRGBColor; break;
217                 case 32: m_header.mode = ImageModeRGBA; break;
218                 case 48: m_header.mode = ImageModeRGB48; break;
219                 default: m_header.mode = ImageModeRGBColor; break;
220                 }
221         }
222         if (!m_header.bpp) {
223                 // undefined bpp
224                 switch(m_header.mode) {
225                 case ImageModeBitmap: 
226                         m_header.bpp = 1;
227                         break;
228                 case ImageModeIndexedColor:
229                 case ImageModeGrayScale:
230                         m_header.bpp = 8;
231                         break;
232                 case ImageModeRGB12:
233                         m_header.bpp = 12;
234                         break;
235                 case ImageModeRGB16:
236                 case ImageModeGray16:
237                         m_header.bpp = 16;
238                         break;
239                 case ImageModeRGBColor:
240                 case ImageModeLabColor:
241                         m_header.bpp = 24;
242                         break;
243                 case ImageModeRGBA:
244                 case ImageModeCMYKColor:
245                 case ImageModeGray32:
246                         m_header.bpp = 32;
247                         break;
248                 case ImageModeRGB48:
249                 case ImageModeLab48:
250                         m_header.bpp = 48;
251                         break;
252                 case ImageModeCMYK64:
253                         m_header.bpp = 64;
254                         break;
255                 default:
256                         ASSERT(false);
257                         m_header.bpp = 24;
258                 }
259         } 
260         if (m_header.mode == ImageModeRGBColor && m_header.bpp == 32) {
261                 // change mode
262                 m_header.mode = ImageModeRGBA;
263         }
264         if (m_header.mode == ImageModeBitmap && m_header.bpp != 1) return false;
265         if (m_header.mode == ImageModeIndexedColor && m_header.bpp != 8) return false;
266         if (m_header.mode == ImageModeGrayScale && m_header.bpp != 8) return false;
267         if (m_header.mode == ImageModeGray16 && m_header.bpp != 16) return false;
268         if (m_header.mode == ImageModeGray32 && m_header.bpp != 32) return false;
269         if (m_header.mode == ImageModeRGBColor && m_header.bpp != 24) return false;
270         if (m_header.mode == ImageModeRGBA && m_header.bpp != 32) return false;
271         if (m_header.mode == ImageModeRGB12 && m_header.bpp != 12) return false;
272         if (m_header.mode == ImageModeRGB16 && m_header.bpp != 16) return false;
273         if (m_header.mode == ImageModeRGB48 && m_header.bpp != 48) return false;
274         if (m_header.mode == ImageModeLabColor && m_header.bpp != 24) return false;
275         if (m_header.mode == ImageModeLab48 && m_header.bpp != 48) return false;
276         if (m_header.mode == ImageModeCMYKColor && m_header.bpp != 32) return false;
277         if (m_header.mode == ImageModeCMYK64 && m_header.bpp != 64) return false;
278 
279         // set number of channels
280         if (!m_header.channels) {
281                 switch(m_header.mode) {
282                 case ImageModeBitmap: 
283                 case ImageModeIndexedColor:
284                 case ImageModeGrayScale:
285                 case ImageModeGray16:
286                 case ImageModeGray32:
287                         m_header.channels = 1; 
288                         break;
289                 case ImageModeRGBColor:
290                 case ImageModeRGB12:
291                 case ImageModeRGB16:
292                 case ImageModeRGB48:
293                 case ImageModeLabColor:
294                 case ImageModeLab48:
295                         m_header.channels = 3;
296                         break;
297                 case ImageModeRGBA:
298                 case ImageModeCMYKColor:
299                 case ImageModeCMYK64:
300                         m_header.channels = 4;
301                         break;
302                 default:
303                         return false;
304                 }
305         }
306 
307         // store used bits per channel
308         UINT8 bpc = m_header.bpp/m_header.channels;
309         if (bpc > 31) bpc = 31;
310         if (!m_header.usedBitsPerChannel || m_header.usedBitsPerChannel > bpc) {
311                 m_header.usedBitsPerChannel = bpc;
312         }
313 
314         return true;
315 }

void CPGFImage::ComputeLevels () [private]

Definition at line 804 of file PGFimage.cpp.

804                               {
805         const int maxThumbnailWidth = 20*FilterWidth;
806         const int m = __min(m_header.width, m_header.height);
807         int s = m;
808 
809         if (m_header.nLevels < 1 || m_header.nLevels > MaxLevel) {
810                 m_header.nLevels = 1;
811                 // compute a good value depending on the size of the image
812                 while (s > maxThumbnailWidth) {
813                         m_header.nLevels++;
814                         s = s/2;
815                 }
816         }
817 
818         int levels = m_header.nLevels; // we need a signed value during level reduction
819 
820         // reduce number of levels if the image size is smaller than FilterWidth*2^levels
821         s = FilterWidth*(1 << levels);  // must be at least the double filter size because of subsampling
822         while (m < s) {
823                 levels--;
824                 s = s/2;
825         }
826         if (levels > MaxLevel) m_header.nLevels = MaxLevel;
827         else if (levels < 0) m_header.nLevels = 0;
828         else m_header.nLevels = (UINT8)levels;
829 
830         // used in Write when PM_Absolute
831         m_percent = pow(0.25, m_header.nLevels);
832 
833         ASSERT(0 <= m_header.nLevels && m_header.nLevels <= MaxLevel);
834 }

void CPGFImage::ConfigureDecoder (bool useOMP = true, bool skipUserData = false) [inline]

Configures the decoder.

Parameters:

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.
skipUserData The file might contain user data (metadata). User data ist usually read during Open and stored in memory. Set this flag to false when storing in memory is not needed.

Definition at line 266 of file PGFimage.h.

266 { m_useOMPinDecoder = useOMP; m_skipUserData = skipUserData; }

void CPGFImage::ConfigureEncoder (bool useOMP = true, bool favorSpeedOverSize = false) [inline]

Configures the encoder.

Parameters:

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.
favorSpeedOverSize Favors encoding speed over compression ratio. Default value: false

Definition at line 260 of file PGFimage.h.

260 { m_useOMPinEncoder = useOMP; m_favorSpeedOverSize = favorSpeedOverSize; }

static BYTE CPGFImage::CurrentChannelDepth (BYTE version = PGFVersion) [inline], [static]

Compute and return codec version.

Returns:

current PGF codec version

Definition at line 508 of file PGFimage.h.

508 { return (version & PGF32) ? 32 : 16; }

BYTE CPGFImage::CurrentVersion (BYTE version = PGFVersion) [static]

Return version. Compute and return codec version.

Returns:

current PGF codec version

Definition at line 720 of file PGFimage.cpp.

720                                            {
721         if (version & Version6) return 6;
722         if (version & Version5) return 5;
723         if (version & Version2) return 2;
724         return 1;
725 }

void CPGFImage::Destroy () [virtual]

Destroy internal data structures. Destructor calls this method during destruction.

Definition at line 105 of file PGFimage.cpp.

105                         {
106         Close();
107 
108         for (int i=0; i < m_header.channels; i++) {
109                 delete m_wtChannel[i]; m_wtChannel[i]=0; // also deletes m_channel
110                 m_channel[i] = 0;
111         }
112         delete[] m_postHeader.userData; m_postHeader.userData = 0; m_postHeader.userDataLen = 0;
113         delete[] m_levelLength; m_levelLength = 0;
114         delete m_encoder; m_encoder = NULL;
115         
116         m_userDataPos = 0;
117 }

void CPGFImage::Downsample (int nChannel) [private]

Definition at line 760 of file PGFimage.cpp.

760                                  {
761         ASSERT(ch > 0);
762 
763         const int w = m_width[0];
764         const int w2 = w/2;
765         const int h2 = m_height[0]/2;
766         const int oddW = w%2;                           // don't use bool -> problems with MaxSpeed optimization
767         const int oddH = m_height[0]%2;         // "
768         int loPos = 0;
769         int hiPos = w;
770         int sampledPos = 0;
771         DataT* buff = m_channel[ch]; ASSERT(buff);
772 
773         for (int i=0; i < h2; i++) {
774                 for (int j=0; j < w2; j++) {
775                         // compute average of pixel block
776                         buff[sampledPos] = (buff[loPos] + buff[loPos + 1] + buff[hiPos] + buff[hiPos + 1]) >> 2;
777                         loPos += 2; hiPos += 2;
778                         sampledPos++;
779                 }
780                 if (oddW) { 
781                         buff[sampledPos] = (buff[loPos] + buff[hiPos]) >> 1;
782                         loPos++; hiPos++;
783                         sampledPos++;
784                 }
785                 loPos += w; hiPos += w;
786         }
787         if (oddH) {
788                 for (int j=0; j < w2; j++) {
789                         buff[sampledPos] = (buff[loPos] + buff[loPos+1]) >> 1;
790                         loPos += 2; hiPos += 2;
791                         sampledPos++;
792                 }
793                 if (oddW) {
794                         buff[sampledPos] = buff[loPos];
795                 }
796         }
797 
798         // downsampled image has half width and half height
799         m_width[ch] = (m_width[ch] + 1)/2;
800         m_height[ch] = (m_height[ch] + 1)/2;
801 }

void CPGFImage::GetBitmap (int pitch, UINT8 * buff, BYTE bpp, int channelMap[] = NULL, CallbackPtr cb = NULL, void * data = NULL) const

Get image data in interleaved format: (ordering of RGB data is BGR[A]) Upsampling, YUV to RGB transform and interleaving are done here to reduce the number of passes over the data. The absolute value of pitch is the number of bytes of an image row of the given image buffer. If pitch is negative, then the image buffer must point to the last row of a bottom-up image (first byte on last row). if pitch is positive, then the image buffer must point to the first row of a top-down image (first byte). 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 provide a channelMap of size of expected channels (depending on image mode). For example, PGF provides a channel sequence BGR in RGB color mode. If your provided image buffer expects a channel sequence ARGB, then the channelMap looks like { 3, 2, 1, 0 }. It might throw an IOException.

Parameters:

pitch The number of bytes of a row of the image buffer.
buff An image buffer.
bpp The number of bits per pixel used in image buffer.
channelMap A integer array containing the mapping of PGF channel ordering to expected channel ordering.
cb A pointer to a callback procedure. The procedure is called after each copied buffer row. If cb returns true, then it stops proceeding.
data Data Pointer to C++ class container to host callback procedure.

Definition at line 1720 of file PGFimage.cpp.

1720                                                                                                                            {
1721         ASSERT(buff);
1722         UINT32 w = m_width[0];
1723         UINT32 h = m_height[0];
1724         UINT8* targetBuff = 0;  // used if ROI is used
1725         UINT8* buffStart = 0;   // used if ROI is used
1726         int targetPitch = 0;    // used if ROI is used
1727 
1728 #ifdef __PGFROISUPPORT__
1729         const PGFRect& roi = (ROIisSupported()) ? m_wtChannel[0]->GetROI(m_currentLevel) : PGFRect(0, 0, w, h); // roi is usually larger than m_roi
1730         const PGFRect levelRoi(LevelWidth(m_roi.left, m_currentLevel), LevelHeight(m_roi.top, m_currentLevel), LevelWidth(m_roi.Width(), m_currentLevel), LevelHeight(m_roi.Height(), m_currentLevel));
1731         ASSERT(w <= roi.Width() && h <= roi.Height()); 
1732         ASSERT(roi.left <= levelRoi.left && levelRoi.right <= roi.right); 
1733         ASSERT(roi.top <= levelRoi.top && levelRoi.bottom <= roi.bottom); 
1734 
1735         if (ROIisSupported() && (levelRoi.Width() < w || levelRoi.Height() < h)) {
1736                 // ROI is used -> create a temporary image buffer for roi
1737                 // compute pitch
1738                 targetPitch = pitch;
1739                 pitch = AlignWordPos(w*bpp)/8;
1740 
1741                 // create temporary output buffer
1742                 targetBuff = buff;
1743                 buff = buffStart = new(std::nothrow) UINT8[pitch*h];
1744                 if (!buff) ReturnWithError(InsufficientMemory);
1745         }
1746 #endif
1747 
1748         const bool wOdd = (1 == w%2);
1749 
1750         const double dP = 1.0/h;
1751         int defMap[] = { 0, 1, 2, 3, 4, 5, 6, 7 }; ASSERT(sizeof(defMap)/sizeof(defMap[0]) == MaxChannels);
1752         if (channelMap == NULL) channelMap = defMap;
1753         int sampledPos = 0, yPos = 0;
1754         DataT uAvg, vAvg;
1755         double percent = 0;
1756         UINT32 i, j;
1757 
1758         switch(m_header.mode) {
1759         case ImageModeBitmap:
1760                 {
1761                         ASSERT(m_header.channels == 1);
1762                         ASSERT(m_header.bpp == 1);
1763                         ASSERT(bpp == 1);
1764 
1765                         const UINT32 w2 = (w + 7)/8;
1766                         DataT* y = m_channel[0]; ASSERT(y);
1767 
1768                         for (i=0; i < h; i++) {
1769                                 
1770                                 for (j=0; j < w2; j++) {
1771                                         buff[j] = Clamp8(y[yPos++] + YUVoffset8);
1772                                 }
1773                                 yPos += w - w2;
1774                                 
1775                                 //UINT32 cnt = w;
1776                                 //for (j=0; j < w2; j++) {
1777                                 //      buff[j] = 0;
1778                                 //      for (int k=0; k < 8; k++) {
1779                                 //              if (cnt) {
1780                                 //                      buff[j] <<= 1;
1781                                 //                      buff[j] |= (1 & (y[yPos++] - YUVoffset8)); 
1782                                 //                      cnt--;
1783                                 //              }
1784                                 //      }
1785                                 //}
1786                                 buff += pitch;
1787 
1788                                 if (cb) {
1789                                         percent += dP;
1790                                         if ((*cb)(percent, true, data)) ReturnWithError(EscapePressed);
1791                                 }
1792                         }
1793                         break;
1794                 }
1795         case ImageModeIndexedColor:
1796         case ImageModeGrayScale:
1797         case ImageModeHSLColor:
1798         case ImageModeHSBColor:
1799                 {
1800                         ASSERT(m_header.channels >= 1);
1801                         ASSERT(m_header.bpp == m_header.channels*8);
1802                         ASSERT(bpp%8 == 0);
1803 
1804                         int cnt, channels = bpp/8; ASSERT(channels >= m_header.channels);
1805 
1806                         for (i=0; i < h; i++) {
1807                                 cnt = 0;
1808                                 for (j=0; j < w; j++) {
1809                                         for (int c=0; c < m_header.channels; c++) {
1810                                                 buff[cnt + channelMap[c]] = Clamp8(m_channel[c][yPos] + YUVoffset8);
1811                                         }
1812                                         cnt += channels;
1813                                         yPos++;
1814                                 }
1815                                 buff += pitch;
1816 
1817                                 if (cb) {
1818                                         percent += dP;
1819                                         if ((*cb)(percent, true, data)) ReturnWithError(EscapePressed);
1820                                 }
1821                         }
1822                         break;
1823                 }
1824         case ImageModeGray16:
1825                 {
1826                         ASSERT(m_header.channels >= 1);
1827                         ASSERT(m_header.bpp == m_header.channels*16);
1828 
1829                         const DataT yuvOffset16 = 1 << (UsedBitsPerChannel() - 1);
1830                         int cnt, channels;
1831 
1832                         if (bpp%16 == 0) {
1833                                 const int shift = 16 - UsedBitsPerChannel(); ASSERT(shift >= 0);
1834                                 UINT16 *buff16 = (UINT16 *)buff;
1835                                 int pitch16 = pitch/2;
1836                                 channels = bpp/16; ASSERT(channels >= m_header.channels);
1837 
1838                                 for (i=0; i < h; i++) {
1839                                         cnt = 0;
1840                                         for (j=0; j < w; j++) {
1841                                                 for (int c=0; c < m_header.channels; c++) {
1842                                                         buff16[cnt + channelMap[c]] = Clamp16((m_channel[c][yPos] + yuvOffset16) << shift);
1843                                                 }
1844                                                 cnt += channels;
1845                                                 yPos++;
1846                                         }
1847                                         buff16 += pitch16;
1848 
1849                                         if (cb) {
1850                                                 percent += dP;
1851                                                 if ((*cb)(percent, true, data)) ReturnWithError(EscapePressed);
1852                                         }
1853                                 }
1854                         } else {
1855                                 ASSERT(bpp%8 == 0);
1856                                 const int shift = __max(0, UsedBitsPerChannel() - 8);
1857                                 channels = bpp/8; ASSERT(channels >= m_header.channels);
1858                                 
1859                                 for (i=0; i < h; i++) {
1860                                         cnt = 0;
1861                                         for (j=0; j < w; j++) {
1862                                                 for (int c=0; c < m_header.channels; c++) {
1863                                                         buff[cnt + channelMap[c]] = Clamp8((m_channel[c][yPos] + yuvOffset16) >> shift);
1864                                                 }
1865                                                 cnt += channels;
1866                                                 yPos++;
1867                                         }
1868                                         buff += pitch;
1869 
1870                                         if (cb) {
1871                                                 percent += dP;
1872                                                 if ((*cb)(percent, true, data)) ReturnWithError(EscapePressed);
1873                                         }
1874                                 }
1875                         }
1876                         break;
1877                 }
1878         case ImageModeRGBColor:
1879                 {
1880                         ASSERT(m_header.channels == 3);
1881                         ASSERT(m_header.bpp == m_header.channels*8);
1882                         ASSERT(bpp%8 == 0);
1883                         ASSERT(bpp >= m_header.bpp);
1884 
1885                         DataT* y = m_channel[0]; ASSERT(y);
1886                         DataT* u = m_channel[1]; ASSERT(u);
1887                         DataT* v = m_channel[2]; ASSERT(v);
1888                         UINT8 *buffg = &buff[channelMap[1]],
1889                                   *buffr = &buff[channelMap[2]],
1890                                   *buffb = &buff[channelMap[0]];
1891                         UINT8 g;
1892                         int cnt, channels = bpp/8;
1893                         if(m_downsample){
1894                                 for (i=0; i < h; i++) {
1895                                         if (i%2) sampledPos -= (w + 1)/2;
1896                                         cnt = 0;
1897                                         for (j=0; j < w; j++) {
1898                                                 // image was downsampled
1899                                                 uAvg = u[sampledPos];
1900                                                 vAvg = v[sampledPos];
1901                                                 // Yuv
1902                                                 buffg[cnt] = g = Clamp8(y[yPos] + YUVoffset8 - ((uAvg + vAvg ) >> 2)); // must be logical shift operator
1903                                                 buffr[cnt] = Clamp8(uAvg + g);
1904                                                 buffb[cnt] = Clamp8(vAvg + g);
1905                                                 yPos++;
1906                                                 cnt += channels;
1907                                                 if (j%2) sampledPos++;
1908                                         }
1909                                         buffb += pitch;
1910                                         buffg += pitch;
1911                                         buffr += pitch;
1912                                         if (wOdd) sampledPos++;
1913                                         if (cb) {
1914                                                 percent += dP;
1915                                                 if ((*cb)(percent, true, data)) ReturnWithError(EscapePressed);
1916                                         }
1917                                 }
1918                         }else{
1919                                 for (i=0; i < h; i++) {
1920                                         cnt = 0;
1921                                         for (j = 0; j < w; j++) {
1922                                                 uAvg = u[yPos];
1923                                                 vAvg = v[yPos];
1924                                                 // Yuv
1925                                                 buffg[cnt] = g = Clamp8(y[yPos] + YUVoffset8 - ((uAvg + vAvg ) >> 2)); // must be logical shift operator
1926                                                 buffr[cnt] = Clamp8(uAvg + g);
1927                                                 buffb[cnt] = Clamp8(vAvg + g);
1928                                                 yPos++;
1929                                                 cnt += channels;
1930                                         }
1931                                         buffb += pitch;
1932                                         buffg += pitch;
1933                                         buffr += pitch;
1934 
1935                                         if (cb) {
1936                                                 percent += dP;
1937                                                 if ((*cb)(percent, true, data)) ReturnWithError(EscapePressed);
1938                                         }
1939                                 }
1940                         }
1941                         break;
1942                 }
1943         case ImageModeRGB48:
1944                 {
1945                         ASSERT(m_header.channels == 3);
1946                         ASSERT(m_header.bpp == 48);
1947 
1948                         const DataT yuvOffset16 = 1 << (UsedBitsPerChannel() - 1);
1949 
1950                         DataT* y = m_channel[0]; ASSERT(y);
1951                         DataT* u = m_channel[1]; ASSERT(u);
1952                         DataT* v = m_channel[2]; ASSERT(v);
1953                         int cnt, channels;
1954                         DataT g;
1955 
1956                         if (bpp >= 48 && bpp%16 == 0) {
1957                                 const int shift = 16 - UsedBitsPerChannel(); ASSERT(shift >= 0);
1958                                 UINT16 *buff16 = (UINT16 *)buff;
1959                                 int pitch16 = pitch/2;
1960                                 channels = bpp/16; ASSERT(channels >= m_header.channels);
1961 
1962                                 for (i=0; i < h; i++) {
1963                                         if (i%2) sampledPos -= (w + 1)/2;
1964                                         cnt = 0;
1965                                         for (j=0; j < w; j++) {
1966                                                 if (m_downsample) {
1967                                                         // image was downsampled
1968                                                         uAvg = u[sampledPos];
1969                                                         vAvg = v[sampledPos];
1970                                                 } else {
1971                                                         uAvg = u[yPos];
1972                                                         vAvg = v[yPos];
1973                                                 }
1974                                                 // Yuv
1975                                                 g = y[yPos] + yuvOffset16 - ((uAvg + vAvg ) >> 2); // must be logical shift operator
1976                                                 buff16[cnt + channelMap[1]] = Clamp16(g << shift);
1977                                                 buff16[cnt + channelMap[2]] = Clamp16((uAvg + g) << shift);
1978                                                 buff16[cnt + channelMap[0]] = Clamp16((vAvg + g) << shift);
1979                                                 yPos++; 
1980                                                 cnt += channels;
1981                                                 if (j%2) sampledPos++;
1982                                         }
1983                                         buff16 += pitch16;
1984                                         if (wOdd) sampledPos++;
1985 
1986                                         if (cb) {
1987                                                 percent += dP;
1988                                                 if ((*cb)(percent, true, data)) ReturnWithError(EscapePressed);
1989                                         }
1990                                 }
1991                         } else {
1992                                 ASSERT(bpp%8 == 0);
1993                                 const int shift = __max(0, UsedBitsPerChannel() - 8);
1994                                 channels = bpp/8; ASSERT(channels >= m_header.channels);
1995 
1996                                 for (i=0; i < h; i++) {
1997                                         if (i%2) sampledPos -= (w + 1)/2;
1998                                         cnt = 0;
1999                                         for (j=0; j < w; j++) {
2000                                                 if (m_downsample) {
2001                                                         // image was downsampled
2002                                                         uAvg = u[sampledPos];
2003                                                         vAvg = v[sampledPos];
2004                                                 } else {
2005                                                         uAvg = u[yPos];
2006                                                         vAvg = v[yPos];
2007                                                 }
2008                                                 // Yuv
2009                                                 g = y[yPos] + yuvOffset16 - ((uAvg + vAvg ) >> 2); // must be logical shift operator
2010                                                 buff[cnt + channelMap[1]] = Clamp8(g >> shift); 
2011                                                 buff[cnt + channelMap[2]] = Clamp8((uAvg + g) >> shift);
2012                                                 buff[cnt + channelMap[0]] = Clamp8((vAvg + g) >> shift);
2013                                                 yPos++; 
2014                                                 cnt += channels;
2015                                                 if (j%2) sampledPos++;
2016                                         }
2017                                         buff += pitch;
2018                                         if (wOdd) sampledPos++;
2019 
2020                                         if (cb) {
2021                                                 percent += dP;
2022                                                 if ((*cb)(percent, true, data)) ReturnWithError(EscapePressed);
2023                                         }
2024                                 }
2025                         }
2026                         break;
2027                 }
2028         case ImageModeLabColor:
2029                 {
2030                         ASSERT(m_header.channels == 3);
2031                         ASSERT(m_header.bpp == m_header.channels*8);
2032                         ASSERT(bpp%8 == 0);
2033 
2034                         DataT* l = m_channel[0]; ASSERT(l);
2035                         DataT* a = m_channel[1]; ASSERT(a);
2036                         DataT* b = m_channel[2]; ASSERT(b);
2037                         int cnt, channels = bpp/8; ASSERT(channels >= m_header.channels);
2038 
2039                         for (i=0; i < h; i++) {
2040                                 if (i%2) sampledPos -= (w + 1)/2;
2041                                 cnt = 0;
2042                                 for (j=0; j < w; j++) {
2043                                         if (m_downsample) {
2044                                                 // image was downsampled
2045                                                 uAvg = a[sampledPos];
2046                                                 vAvg = b[sampledPos];
2047                                         } else {
2048                                                 uAvg = a[yPos];
2049                                                 vAvg = b[yPos];
2050                                         }
2051                                         buff[cnt + channelMap[0]] = Clamp8(l[yPos] + YUVoffset8);
2052                                         buff[cnt + channelMap[1]] = Clamp8(uAvg + YUVoffset8); 
2053                                         buff[cnt + channelMap[2]] = Clamp8(vAvg + YUVoffset8);
2054                                         cnt += channels;
2055                                         yPos++;
2056                                         if (j%2) sampledPos++;
2057                                 }
2058                                 buff += pitch;
2059                                 if (wOdd) sampledPos++;
2060 
2061                                 if (cb) {
2062                                         percent += dP;
2063                                         if ((*cb)(percent, true, data)) ReturnWithError(EscapePressed);
2064                                 }
2065                         }
2066                         break;
2067                 }
2068         case ImageModeLab48:
2069                 {
2070                         ASSERT(m_header.channels == 3);
2071                         ASSERT(m_header.bpp == m_header.channels*16);
2072 
2073                         const DataT yuvOffset16 = 1 << (UsedBitsPerChannel() - 1);
2074 
2075                         DataT* l = m_channel[0]; ASSERT(l);
2076                         DataT* a = m_channel[1]; ASSERT(a);
2077                         DataT* b = m_channel[2]; ASSERT(b);
2078                         int cnt, channels;
2079 
2080                         if (bpp%16 == 0) {
2081                                 const int shift = 16 - UsedBitsPerChannel(); ASSERT(shift >= 0);
2082                                 UINT16 *buff16 = (UINT16 *)buff;
2083                                 int pitch16 = pitch/2;
2084                                 channels = bpp/16; ASSERT(channels >= m_header.channels);
2085 
2086                                 for (i=0; i < h; i++) {
2087                                         if (i%2) sampledPos -= (w + 1)/2;
2088                                         cnt = 0;
2089                                         for (j=0; j < w; j++) {
2090                                                 if (m_downsample) {
2091                                                         // image was downsampled
2092                                                         uAvg = a[sampledPos];
2093                                                         vAvg = b[sampledPos];
2094                                                 } else {
2095                                                         uAvg = a[yPos];
2096                                                         vAvg = b[yPos];
2097                                                 }
2098                                                 buff16[cnt + channelMap[0]] = Clamp16((l[yPos] + yuvOffset16) << shift);
2099                                                 buff16[cnt + channelMap[1]] = Clamp16((uAvg + yuvOffset16) << shift);
2100                                                 buff16[cnt + channelMap[2]] = Clamp16((vAvg + yuvOffset16) << shift);
2101                                                 cnt += channels;
2102                                                 yPos++;
2103                                                 if (j%2) sampledPos++;
2104                                         }
2105                                         buff16 += pitch16;
2106                                         if (wOdd) sampledPos++;
2107 
2108                                         if (cb) {
2109                                                 percent += dP;
2110                                                 if ((*cb)(percent, true, data)) ReturnWithError(EscapePressed);
2111                                         }
2112                                 }
2113                         } else {
2114                                 ASSERT(bpp%8 == 0);
2115                                 const int shift = __max(0, UsedBitsPerChannel() - 8);
2116                                 channels = bpp/8; ASSERT(channels >= m_header.channels);
2117 
2118                                 for (i=0; i < h; i++) {
2119                                         if (i%2) sampledPos -= (w + 1)/2;
2120                                         cnt = 0;
2121                                         for (j=0; j < w; j++) {
2122                                                 if (m_downsample) {
2123                                                         // image was downsampled
2124                                                         uAvg = a[sampledPos];
2125                                                         vAvg = b[sampledPos];
2126                                                 } else {
2127                                                         uAvg = a[yPos];
2128                                                         vAvg = b[yPos];
2129                                                 }
2130                                                 buff[cnt + channelMap[0]] = Clamp8((l[yPos] + yuvOffset16) >> shift);
2131                                                 buff[cnt + channelMap[1]] = Clamp8((uAvg + yuvOffset16) >> shift);
2132                                                 buff[cnt + channelMap[2]] = Clamp8((vAvg + yuvOffset16) >> shift);
2133                                                 cnt += channels;
2134                                                 yPos++;
2135                                                 if (j%2) sampledPos++;
2136                                         }
2137                                         buff += pitch;
2138                                         if (wOdd) sampledPos++;
2139 
2140                                         if (cb) {
2141                                                 percent += dP;
2142                                                 if ((*cb)(percent, true, data)) ReturnWithError(EscapePressed);
2143                                         }
2144                                 }
2145                         }
2146                         break;
2147                 }
2148         case ImageModeRGBA:
2149         case ImageModeCMYKColor:
2150                 {
2151                         ASSERT(m_header.channels == 4);
2152                         ASSERT(m_header.bpp == m_header.channels*8);
2153                         ASSERT(bpp%8 == 0);
2154 
2155                         DataT* y = m_channel[0]; ASSERT(y);
2156                         DataT* u = m_channel[1]; ASSERT(u);
2157                         DataT* v = m_channel[2]; ASSERT(v);
2158                         DataT* a = m_channel[3]; ASSERT(a);
2159                         UINT8 g, aAvg;
2160                         int cnt, channels = bpp/8; ASSERT(channels >= m_header.channels);
2161 
2162                         for (i=0; i < h; i++) {
2163                                 if (i%2) sampledPos -= (w + 1)/2;
2164                                 cnt = 0;
2165                                 for (j=0; j < w; j++) {
2166                                         if (m_downsample) {
2167                                                 // image was downsampled
2168                                                 uAvg = u[sampledPos];
2169                                                 vAvg = v[sampledPos];
2170                                                 aAvg = Clamp8(a[sampledPos] + YUVoffset8);
2171                                         } else {
2172                                                 uAvg = u[yPos];
2173                                                 vAvg = v[yPos];
2174                                                 aAvg = Clamp8(a[yPos] + YUVoffset8);
2175                                         }
2176                                         // Yuv
2177                                         buff[cnt + channelMap[1]] = g = Clamp8(y[yPos] + YUVoffset8 - ((uAvg + vAvg ) >> 2)); // must be logical shift operator
2178                                         buff[cnt + channelMap[2]] = Clamp8(uAvg + g);
2179                                         buff[cnt + channelMap[0]] = Clamp8(vAvg + g);
2180                                         buff[cnt + channelMap[3]] = aAvg;
2181                                         yPos++; 
2182                                         cnt += channels;
2183                                         if (j%2) sampledPos++;
2184                                 }
2185                                 buff += pitch;
2186                                 if (wOdd) sampledPos++;
2187 
2188                                 if (cb) {
2189                                         percent += dP;
2190                                         if ((*cb)(percent, true, data)) ReturnWithError(EscapePressed);
2191                                 }
2192                         }
2193                         break;
2194                 }
2195         case ImageModeCMYK64: 
2196                 {
2197                         ASSERT(m_header.channels == 4);
2198                         ASSERT(m_header.bpp == 64);
2199 
2200                         const DataT yuvOffset16 = 1 << (UsedBitsPerChannel() - 1);
2201 
2202                         DataT* y = m_channel[0]; ASSERT(y);
2203                         DataT* u = m_channel[1]; ASSERT(u);
2204                         DataT* v = m_channel[2]; ASSERT(v);
2205                         DataT* a = m_channel[3]; ASSERT(a);
2206                         DataT g, aAvg;
2207                         int cnt, channels;
2208 
2209                         if (bpp%16 == 0) {
2210                                 const int shift = 16 - UsedBitsPerChannel(); ASSERT(shift >= 0);
2211                                 UINT16 *buff16 = (UINT16 *)buff;
2212                                 int pitch16 = pitch/2;
2213                                 channels = bpp/16; ASSERT(channels >= m_header.channels);
2214 
2215                                 for (i=0; i < h; i++) {
2216                                         if (i%2) sampledPos -= (w + 1)/2;
2217                                         cnt = 0;
2218                                         for (j=0; j < w; j++) {
2219                                                 if (m_downsample) {
2220                                                         // image was downsampled
2221                                                         uAvg = u[sampledPos];
2222                                                         vAvg = v[sampledPos];
2223                                                         aAvg = a[sampledPos] + yuvOffset16;
2224                                                 } else {
2225                                                         uAvg = u[yPos];
2226                                                         vAvg = v[yPos];
2227                                                         aAvg = a[yPos] + yuvOffset16;
2228                                                 }
2229                                                 // Yuv
2230                                                 g = y[yPos] + yuvOffset16 - ((uAvg + vAvg ) >> 2); // must be logical shift operator
2231                                                 buff16[cnt + channelMap[1]] = Clamp16(g << shift);
2232                                                 buff16[cnt + channelMap[2]] = Clamp16((uAvg + g) << shift);
2233                                                 buff16[cnt + channelMap[0]] = Clamp16((vAvg + g) << shift);
2234                                                 buff16[cnt + channelMap[3]] = Clamp16(aAvg << shift);
2235                                                 yPos++; 
2236                                                 cnt += channels;
2237                                                 if (j%2) sampledPos++;
2238                                         }
2239                                         buff16 += pitch16;
2240                                         if (wOdd) sampledPos++;
2241 
2242                                         if (cb) {
2243                                                 percent += dP;
2244                                                 if ((*cb)(percent, true, data)) ReturnWithError(EscapePressed);
2245                                         }
2246                                 }
2247                         } else {
2248                                 ASSERT(bpp%8 == 0);
2249                                 const int shift = __max(0, UsedBitsPerChannel() - 8);
2250                                 channels = bpp/8; ASSERT(channels >= m_header.channels);
2251 
2252                                 for (i=0; i < h; i++) {
2253                                         if (i%2) sampledPos -= (w + 1)/2;
2254                                         cnt = 0;
2255                                         for (j=0; j < w; j++) {
2256                                                 if (m_downsample) {
2257                                                         // image was downsampled
2258                                                         uAvg = u[sampledPos];
2259                                                         vAvg = v[sampledPos];
2260                                                         aAvg = a[sampledPos] + yuvOffset16;
2261                                                 } else {
2262                                                         uAvg = u[yPos];
2263                                                         vAvg = v[yPos];
2264                                                         aAvg = a[yPos] + yuvOffset16;
2265                                                 }
2266                                                 // Yuv
2267                                                 g = y[yPos] + yuvOffset16 - ((uAvg + vAvg ) >> 2); // must be logical shift operator
2268                                                 buff[cnt + channelMap[1]] = Clamp8(g >> shift); 
2269                                                 buff[cnt + channelMap[2]] = Clamp8((uAvg + g) >> shift);
2270                                                 buff[cnt + channelMap[0]] = Clamp8((vAvg + g) >> shift);
2271                                                 buff[cnt + channelMap[3]] = Clamp8(aAvg >> shift);
2272                                                 yPos++; 
2273                                                 cnt += channels;
2274                                                 if (j%2) sampledPos++;
2275                                         }
2276                                         buff += pitch;
2277                                         if (wOdd) sampledPos++;
2278 
2279                                         if (cb) {
2280                                                 percent += dP;
2281                                                 if ((*cb)(percent, true, data)) ReturnWithError(EscapePressed);
2282                                         }
2283                                 }
2284                         }
2285                         break;
2286                 }
2287 #ifdef __PGF32SUPPORT__
2288         case ImageModeGray32:
2289                 {
2290                         ASSERT(m_header.channels == 1);
2291                         ASSERT(m_header.bpp == 32);
2292 
2293                         const int yuvOffset31 = 1 << (UsedBitsPerChannel() - 1);
2294 
2295                         DataT* y = m_channel[0]; ASSERT(y);
2296 
2297                         if (bpp == 32) {
2298                                 const int shift = 31 - UsedBitsPerChannel(); ASSERT(shift >= 0);
2299                                 UINT32 *buff32 = (UINT32 *)buff;
2300                                 int pitch32 = pitch/4;
2301 
2302                                 for (i=0; i < h; i++) {
2303                                         for (j=0; j < w; j++) {
2304                                                 buff32[j] = Clamp31((y[yPos++] + yuvOffset31) << shift);
2305                                         }
2306                                         buff32 += pitch32;
2307 
2308                                         if (cb) {
2309                                                 percent += dP;
2310                                                 if ((*cb)(percent, true, data)) ReturnWithError(EscapePressed);
2311                                         }
2312                                 }
2313                         } else if (bpp == 16) {
2314                                 const int usedBits = UsedBitsPerChannel();
2315                                 UINT16 *buff16 = (UINT16 *)buff;
2316                                 int pitch16 = pitch/2;
2317 
2318                                 if (usedBits < 16) {
2319                                         const int shift = 16 - usedBits;
2320                                         for (i=0; i < h; i++) {
2321                                                 for (j=0; j < w; j++) {
2322                                                         buff16[j] = Clamp16((y[yPos++] + yuvOffset31) << shift);
2323                                                 }
2324                                                 buff16 += pitch16;
2325 
2326                                                 if (cb) {
2327                                                         percent += dP;
2328                                                         if ((*cb)(percent, true, data)) ReturnWithError(EscapePressed);
2329                                                 }
2330                                         }
2331                                 } else {
2332                                         const int shift = __max(0, usedBits - 16);
2333                                         for (i=0; i < h; i++) {
2334                                                 for (j=0; j < w; j++) {
2335                                                         buff16[j] = Clamp16((y[yPos++] + yuvOffset31) >> shift);
2336                                                 }
2337                                                 buff16 += pitch16;
2338 
2339                                                 if (cb) {
2340                                                         percent += dP;
2341                                                         if ((*cb)(percent, true, data)) ReturnWithError(EscapePressed);
2342                                                 }
2343                                         }
2344                                 }
2345                         } else {
2346                                 ASSERT(bpp == 8);
2347                                 const int shift = __max(0, UsedBitsPerChannel() - 8);
2348                                 
2349                                 for (i=0; i < h; i++) {
2350                                         for (j=0; j < w; j++) {
2351                                                 buff[j] = Clamp8((y[yPos++] + yuvOffset31) >> shift);
2352                                         }
2353                                         buff += pitch;
2354 
2355                                         if (cb) {
2356                                                 percent += dP;
2357                                                 if ((*cb)(percent, true, data)) ReturnWithError(EscapePressed);
2358                                         }
2359                                 }
2360                         }
2361                         break;  
2362                 }
2363 #endif
2364         case ImageModeRGB12: 
2365                 {
2366                         ASSERT(m_header.channels == 3);
2367                         ASSERT(m_header.bpp == m_header.channels*4);
2368                         ASSERT(bpp == m_header.channels*4);
2369                         ASSERT(!m_downsample);
2370 
2371                         DataT* y = m_channel[0]; ASSERT(y);
2372                         DataT* u = m_channel[1]; ASSERT(u);
2373                         DataT* v = m_channel[2]; ASSERT(v);
2374                         UINT16 yval;
2375                         int cnt;
2376 
2377                         for (i=0; i < h; i++) {
2378                                 cnt = 0;
2379                                 for (j=0; j < w; j++) {
2380                                         // Yuv
2381                                         uAvg = u[yPos];
2382                                         vAvg = v[yPos];
2383                                         yval = Clamp4(y[yPos++] + YUVoffset4 - ((uAvg + vAvg ) >> 2)); // must be logical shift operator
2384                                         if (j%2 == 0) {
2385                                                 buff[cnt] = UINT8(Clamp4(vAvg + yval) | (yval << 4));
2386                                                 cnt++;
2387                                                 buff[cnt] = Clamp4(uAvg + yval);
2388                                         } else {
2389                                                 buff[cnt] |= Clamp4(vAvg + yval) << 4;
2390                                                 cnt++;
2391                                                 buff[cnt] = UINT8(yval | (Clamp4(uAvg + yval) << 4));
2392                                                 cnt++;
2393                                         }
2394                                 }
2395                                 buff += pitch;
2396 
2397                                 if (cb) {
2398                                         percent += dP;
2399                                         if ((*cb)(percent, true, data)) ReturnWithError(EscapePressed);
2400                                 }
2401                         }
2402                         break;
2403                 }
2404         case ImageModeRGB16: 
2405                 {
2406                         ASSERT(m_header.channels == 3);
2407                         ASSERT(m_header.bpp == 16);
2408                         ASSERT(bpp == 16);
2409                         ASSERT(!m_downsample);
2410 
2411                         DataT* y = m_channel[0]; ASSERT(y);
2412                         DataT* u = m_channel[1]; ASSERT(u);
2413                         DataT* v = m_channel[2]; ASSERT(v);
2414                         UINT16 yval;
2415                         UINT16 *buff16 = (UINT16 *)buff;
2416                         int pitch16 = pitch/2;
2417 
2418                         for (i=0; i < h; i++) {
2419                                 for (j=0; j < w; j++) {
2420                                         // Yuv
2421                                         uAvg = u[yPos];
2422                                         vAvg = v[yPos];
2423                                         yval = Clamp6(y[yPos++] + YUVoffset6 - ((uAvg + vAvg ) >> 2)); // must be logical shift operator
2424                                         buff16[j] = (yval << 5) | ((Clamp6(uAvg + yval) >> 1) << 11) | (Clamp6(vAvg + yval) >> 1);
2425                                 }
2426                                 buff16 += pitch16;
2427 
2428                                 if (cb) {
2429                                         percent += dP;
2430                                         if ((*cb)(percent, true, data)) ReturnWithError(EscapePressed);
2431                                 }
2432                         }
2433                         break;
2434                 }
2435         default:
2436                 ASSERT(false);
2437         }
2438 
2439 #ifdef __PGFROISUPPORT__
2440         if (targetBuff) {
2441                 // copy valid ROI (m_roi) from temporary buffer (roi) to target buffer
2442                 if (bpp%8 == 0) {
2443                         BYTE bypp = bpp/8;
2444                         buff = buffStart + (levelRoi.top - roi.top)*pitch + (levelRoi.left - roi.left)*bypp;
2445                         w = levelRoi.Width()*bypp;
2446                         h = levelRoi.Height();
2447 
2448                         for (i=0; i < h; i++) {
2449                                 for (j=0; j < w; j++) {
2450                                         targetBuff[j] = buff[j];
2451                                 }
2452                                 targetBuff += targetPitch;
2453                                 buff += pitch;
2454                         }
2455                 } else {
2456                         // to do
2457                 }
2458 
2459                 delete[] buffStart; buffStart = 0;
2460         }
2461 #endif
2462 }

DataT* CPGFImage::GetChannel (int c = 0) [inline]

Return an internal YUV image channel.

Parameters:

c A channel index

Returns:

An internal YUV image channel

Definition at line 321 of file PGFimage.h.

321 { ASSERT(c >= 0 && c < MaxChannels); return m_channel[c]; }

void CPGFImage::GetColorTable (UINT32 iFirstColor, UINT32 nColors, RGBQUAD * prgbColors) const

Retrieves red, green, blue (RGB) color values from a range of entries in the palette of the DIB section. It might throw an IOException.

Parameters:

iFirstColor The color table index of the first entry to retrieve.
nColors The number of color table entries to retrieve.
prgbColors A pointer to the array of RGBQUAD structures to retrieve the color table entries.

Definition at line 1292 of file PGFimage.cpp.

1292                                                                                                   {
1293         if (iFirstColor + nColors > ColorTableLen)      ReturnWithError(ColorTableError);
1294 
1295         for (UINT32 i=iFirstColor, j=0; j < nColors; i++, j++) {
1296                 prgbColors[j] = m_postHeader.clut[i];
1297         }
1298 }

const RGBQUAD* CPGFImage::GetColorTable () const [inline]

Returns:

Address of color table

Definition at line 334 of file PGFimage.h.

334 { return m_postHeader.clut; }

UINT32 CPGFImage::GetEncodedHeaderLength () const

Return the length of all encoded headers in bytes. Precondition: The PGF image has been opened with a call of Open(...).

Returns:

The length of all encoded headers in bytes

Definition at line 613 of file PGFimage.cpp.

613                                                { 
614         ASSERT(m_decoder); 
615         return m_decoder->GetEncodedHeaderLength(); 
616 }

UINT32 CPGFImage::GetEncodedLevelLength (int level) const [inline]

Return the length of an encoded PGF level in bytes. Precondition: The PGF image has been opened with a call of Open(...).

Parameters:

level The image level

Returns:

The length of a PGF level in bytes

Definition at line 370 of file PGFimage.h.

370 { ASSERT(level >= 0 && level < m_header.nLevels); return m_levelLength[m_header.nLevels - level - 1]; }

const PGFHeader* CPGFImage::GetHeader () const [inline]

Return the PGF header structure.

Returns:

A PGF header structure

Definition at line 339 of file PGFimage.h.

339 { return &m_header; }

UINT32 CPGFImage::GetMaxValue () const [inline]

Get maximum intensity value for image modes with more than eight bits per channel. Don't call this method before the PGF header has been read.

Returns:

The maximum intensity value.

Definition at line 345 of file PGFimage.h.

345 { return (1 << m_header.usedBitsPerChannel) - 1; }

const UINT8 * CPGFImage::GetUserData (UINT32 & size) const

Return user data and size of user data. Precondition: The PGF image has been opened with a call of Open(...).

Parameters:

size [out] Size of user data in bytes.

Returns:

A pointer to user data or NULL if there is no user data.

Definition at line 322 of file PGFimage.cpp.

322                                                       {
323         size = m_postHeader.userDataLen;
324         return m_postHeader.userData;
325 }

UINT64 CPGFImage::GetUserDataPos () const [inline]

Return the stream position of the user data or 0. Precondition: The PGF image has been opened with a call of Open(...).

Definition at line 350 of file PGFimage.h.

350 { return m_userDataPos; }

void CPGFImage::GetYUV (int pitch, DataT * buff, BYTE bpp, int channelMap[] = NULL, CallbackPtr cb = NULL, void * data = NULL) const

Get YUV image data in interleaved format: (ordering is YUV[A]) The absolute value of pitch is the number of bytes of an image row of the given image buffer. If pitch is negative, then the image buffer must point to the last row of a bottom-up image (first byte on last row). if pitch is positive, then the image buffer must point to the first row of a top-down image (first byte). 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 provide a channelMap of size of expected channels (depending on image mode). For example, PGF provides a channel sequence BGR in RGB color mode. If your provided image buffer expects a channel sequence VUY, then the channelMap looks like { 2, 1, 0 }. It might throw an IOException.

Parameters:

pitch The number of bytes of a row of the image buffer.
buff An image buffer.
bpp The number of bits per pixel used in image buffer.
channelMap A integer array containing the mapping of PGF channel ordering to expected channel ordering.
cb A pointer to a callback procedure. The procedure is called after each copied buffer row. If cb returns true, then it stops proceeding.
data Data Pointer to C++ class container to host callback procedure.

Get YUV image data in interleaved format: (ordering is YUV[A]) The absolute value of pitch is the number of bytes of an image row of the given image buffer. If pitch is negative, then the image buffer must point to the last row of a bottom-up image (first byte on last row). if pitch is positive, then the image buffer must point to the first row of a top-down image (first byte). 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 provide a channelMap of size of expected channels (depending on image mode). For example, PGF provides a channel sequence BGR in RGB color mode. If your provided image buffer expects a channel sequence VUY, then the channelMap looks like { 2, 1, 0 }. It might throw an IOException.

Parameters:

pitch The number of bytes of a row of the image buffer.
buff An image buffer.
bpp The number of bits per pixel used in image buffer.
channelMap A integer array containing the mapping of PGF channel ordering to expected channel ordering.
cb A pointer to a callback procedure. The procedure is called after each copied buffer row. If cb returns true, then it stops proceeding.

Definition at line 2478 of file PGFimage.cpp.

2478                                                                                                                         {
2479         ASSERT(buff);
2480         const UINT32 w = m_width[0];
2481         const UINT32 h = m_height[0];
2482         const bool wOdd = (1 == w%2);
2483         const int dataBits = DataTSize*8; ASSERT(dataBits == 16 || dataBits == 32);
2484         const int pitch2 = pitch/DataTSize;
2485         const int yuvOffset = (dataBits == 16) ? YUVoffset8 : YUVoffset16;
2486         const double dP = 1.0/h;
2487 
2488         int defMap[] = { 0, 1, 2, 3, 4, 5, 6, 7 }; ASSERT(sizeof(defMap)/sizeof(defMap[0]) == MaxChannels);
2489         if (channelMap == NULL) channelMap = defMap;
2490         int sampledPos = 0, yPos = 0;
2491         DataT uAvg, vAvg;
2492         double percent = 0;
2493         UINT32 i, j;
2494 
2495         if (m_header.channels == 3) { 
2496                 ASSERT(bpp%dataBits == 0);
2497 
2498                 DataT* y = m_channel[0]; ASSERT(y);
2499                 DataT* u = m_channel[1]; ASSERT(u);
2500                 DataT* v = m_channel[2]; ASSERT(v);
2501                 int cnt, channels = bpp/dataBits; ASSERT(channels >= m_header.channels);
2502 
2503                 for (i=0; i < h; i++) {
2504                         if (i%2) sampledPos -= (w + 1)/2;
2505                         cnt = 0;
2506                         for (j=0; j < w; j++) {
2507                                 if (m_downsample) {
2508                                         // image was downsampled
2509                                         uAvg = u[sampledPos];
2510                                         vAvg = v[sampledPos];
2511                                 } else {
2512                                         uAvg = u[yPos];
2513                                         vAvg = v[yPos];
2514                                 }
2515                                 buff[cnt + channelMap[0]] = y[yPos];
2516                                 buff[cnt + channelMap[1]] = uAvg;
2517                                 buff[cnt + channelMap[2]] = vAvg;
2518                                 yPos++; 
2519                                 cnt += channels;
2520                                 if (j%2) sampledPos++;
2521                         }
2522                         buff += pitch2;
2523                         if (wOdd) sampledPos++;
2524 
2525                         if (cb) {
2526                                 percent += dP;
2527                                 if ((*cb)(percent, true, data)) ReturnWithError(EscapePressed);
2528                         }
2529                 }
2530         } else if (m_header.channels == 4) {
2531                 ASSERT(m_header.bpp == m_header.channels*8);
2532                 ASSERT(bpp%dataBits == 0);
2533 
2534                 DataT* y = m_channel[0]; ASSERT(y);
2535                 DataT* u = m_channel[1]; ASSERT(u);
2536                 DataT* v = m_channel[2]; ASSERT(v);
2537                 DataT* a = m_channel[3]; ASSERT(a);
2538                 UINT8 aAvg;
2539                 int cnt, channels = bpp/dataBits; ASSERT(channels >= m_header.channels);
2540 
2541                 for (i=0; i < h; i++) {
2542                         if (i%2) sampledPos -= (w + 1)/2;
2543                         cnt = 0;
2544                         for (j=0; j < w; j++) {
2545                                 if (m_downsample) {
2546                                         // image was downsampled
2547                                         uAvg = u[sampledPos];
2548                                         vAvg = v[sampledPos];
2549                                         aAvg = Clamp8(a[sampledPos] + yuvOffset);
2550                                 } else {
2551                                         uAvg = u[yPos];
2552                                         vAvg = v[yPos];
2553                                         aAvg = Clamp8(a[yPos] + yuvOffset);
2554                                 }
2555                                 // Yuv
2556                                 buff[cnt + channelMap[0]] = y[yPos];
2557                                 buff[cnt + channelMap[1]] = uAvg;
2558                                 buff[cnt + channelMap[2]] = vAvg;
2559                                 buff[cnt + channelMap[3]] = aAvg;
2560                                 yPos++; 
2561                                 cnt += channels;
2562                                 if (j%2) sampledPos++;
2563                         }
2564                         buff += pitch2;
2565                         if (wOdd) sampledPos++;
2566 
2567                         if (cb) {
2568                                 percent += dP;
2569                                 if ((*cb)(percent, true, data)) ReturnWithError(EscapePressed);
2570                         }
2571                 }
2572         }
2573 }

UINT32 CPGFImage::Height (int level = 0) const [inline]

Return image height of channel 0 at given level in pixels. The returned height is independent of any Read-operations and ROI.

Parameters:

level A level

Returns:

Image level height in pixels

Definition at line 423 of file PGFimage.h.

423 { ASSERT(level >= 0); return LevelHeight(m_header.height, level); }

void CPGFImage::ImportBitmap (int pitch, UINT8 * buff, BYTE bpp, int channelMap[] = NULL, CallbackPtr cb = NULL, void * data = NULL)

Import an image from a specified image buffer. This method is usually called before Write(...) and after SetHeader(...). The absolute value of pitch is the number of bytes of an image row. If pitch is negative, then buff points to the last row of a bottom-up image (first byte on last row). If pitch is positive, then buff points to the first row of a top-down image (first byte). 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 provide a channelMap of size of expected channels (depending on image mode). For example, PGF expects in RGB color mode a channel sequence BGR. If your provided image buffer contains a channel sequence ARGB, then the channelMap looks like { 3, 2, 1, 0 }. It might throw an IOException.

Parameters:

pitch The number of bytes of a row of the image buffer.
buff An image buffer.
bpp The number of bits per pixel used in image buffer.
channelMap A integer array containing the mapping of input channel ordering to expected channel ordering.
cb A pointer to a callback procedure. The procedure is called after each imported buffer row. If cb returns true, then it stops proceeding.
data Data Pointer to C++ class container to host callback procedure.

Definition at line 743 of file PGFimage.cpp.

743                                                                                                                         {
744         ASSERT(buff);
745         ASSERT(m_channel[0]);
746 
747         // color transform
748         RgbToYuv(pitch, buff, bpp, channelMap, cb, data);
749 
750         if (m_downsample) {
751                 // Subsampling of the chrominance and alpha channels
752                 for (int i=1; i < m_header.channels; i++) {
753                         Downsample(i);
754                 }
755         }
756 }

bool CPGFImage::ImportIsSupported (BYTE mode) [static]

Check for valid import image mode.

Parameters:

mode Image mode

Returns:

True if an image of given mode can be imported with ImportBitmap(...)

Definition at line 1247 of file PGFimage.cpp.

1247                                            {
1248         size_t size = DataTSize;
1249 
1250         if (size >= 2) {
1251                 switch(mode) {
1252                         case ImageModeBitmap:
1253                         case ImageModeIndexedColor:
1254                         case ImageModeGrayScale:
1255                         case ImageModeRGBColor:
1256                         case ImageModeCMYKColor:
1257                         case ImageModeHSLColor:
1258                         case ImageModeHSBColor:
1259                         //case ImageModeDuotone:
1260                         case ImageModeLabColor:
1261                         case ImageModeRGB12:
1262                         case ImageModeRGB16:
1263                         case ImageModeRGBA:
1264                                 return true;
1265                 }
1266         }
1267         if (size >= 3) {
1268                 switch(mode) {
1269                         case ImageModeGray16:
1270                         case ImageModeRGB48:
1271                         case ImageModeLab48:
1272                         case ImageModeCMYK64:
1273                         //case ImageModeDuotone16:
1274                                 return true;
1275                 }
1276         }
1277         if (size >=4) {
1278                 switch(mode) {
1279                         case ImageModeGray32:
1280                                 return true;
1281                 }
1282         }
1283         return false;
1284 }

void CPGFImage::ImportYUV (int pitch, DataT * buff, BYTE bpp, int channelMap[] = NULL, CallbackPtr cb = NULL, void * data = NULL)

Import a YUV image from a specified image buffer. The absolute value of pitch is the number of bytes of an image row. If pitch is negative, then buff points to the last row of a bottom-up image (first byte on last row). If pitch is positive, then buff points to the first row of a top-down image (first byte). 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 provide a channelMap of size of expected channels (depending on image mode). For example, PGF expects in RGB color mode a channel sequence BGR. If your provided image buffer contains a channel sequence VUY, then the channelMap looks like { 2, 1, 0 }. It might throw an IOException.

Parameters:

pitch The number of bytes of a row of the image buffer.
buff An image buffer.
bpp The number of bits per pixel used in image buffer.
channelMap A integer array containing the mapping of input channel ordering to expected channel ordering.
cb A pointer to a callback procedure. The procedure is called after each imported buffer row. If cb returns true, then it stops proceeding.
data Data Pointer to C++ class container to host callback procedure.

Import a YUV image from a specified image buffer. The absolute value of pitch is the number of bytes of an image row. If pitch is negative, then buff points to the last row of a bottom-up image (first byte on last row). If pitch is positive, then buff points to the first row of a top-down image (first byte). 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 provide a channelMap of size of expected channels (depending on image mode). For example, PGF expects in RGB color mode a channel sequence BGR. If your provided image buffer contains a channel sequence VUY, then the channelMap looks like { 2, 1, 0 }. It might throw an IOException.

Parameters:

pitch The number of bytes of a row of the image buffer.
buff An image buffer.
bpp The number of bits per pixel used in image buffer.
channelMap A integer array containing the mapping of input channel ordering to expected channel ordering.
cb A pointer to a callback procedure. The procedure is called after each imported buffer row. If cb returns true, then it stops proceeding.

Definition at line 2589 of file PGFimage.cpp.

2589                                                                                                                      {
2590         ASSERT(buff);
2591         const double dP = 1.0/m_header.height;
2592         const int dataBits = DataTSize*8; ASSERT(dataBits == 16 || dataBits == 32);
2593         const int pitch2 = pitch/DataTSize;
2594         const int yuvOffset = (dataBits == 16) ? YUVoffset8 : YUVoffset16;
2595 
2596         int yPos = 0, cnt = 0;
2597         double percent = 0;
2598         int defMap[] = { 0, 1, 2, 3, 4, 5, 6, 7 }; ASSERT(sizeof(defMap)/sizeof(defMap[0]) == MaxChannels);
2599 
2600         if (channelMap == NULL) channelMap = defMap;
2601 
2602         if (m_header.channels == 3)      {
2603                 ASSERT(bpp%dataBits == 0);
2604 
2605                 DataT* y = m_channel[0]; ASSERT(y);
2606                 DataT* u = m_channel[1]; ASSERT(u);
2607                 DataT* v = m_channel[2]; ASSERT(v);
2608                 const int channels = bpp/dataBits; ASSERT(channels >= m_header.channels);
2609 
2610                 for (UINT32 h=0; h < m_header.height; h++) {
2611                         if (cb) {
2612                                 if ((*cb)(percent, true, data)) ReturnWithError(EscapePressed);
2613                                 percent += dP;
2614                         }
2615 
2616                         cnt = 0;
2617                         for (UINT32 w=0; w < m_header.width; w++) {
2618                                 y[yPos] = buff[cnt + channelMap[0]];
2619                                 u[yPos] = buff[cnt + channelMap[1]];
2620                                 v[yPos] = buff[cnt + channelMap[2]];
2621                                 yPos++;
2622                                 cnt += channels;
2623                         }
2624                         buff += pitch2;
2625                 }       
2626         } else if (m_header.channels == 4) {
2627                 ASSERT(bpp%dataBits == 0);
2628 
2629                 DataT* y = m_channel[0]; ASSERT(y);
2630                 DataT* u = m_channel[1]; ASSERT(u);
2631                 DataT* v = m_channel[2]; ASSERT(v);
2632                 DataT* a = m_channel[3]; ASSERT(a);
2633                 const int channels = bpp/dataBits; ASSERT(channels >= m_header.channels);
2634 
2635                 for (UINT32 h=0; h < m_header.height; h++) {
2636                         if (cb) {
2637                                 if ((*cb)(percent, true, data)) ReturnWithError(EscapePressed);
2638                                 percent += dP;
2639                         }
2640 
2641                         cnt = 0;
2642                         for (UINT32 w=0; w < m_header.width; w++) {
2643                                 y[yPos] = buff[cnt + channelMap[0]];
2644                                 u[yPos] = buff[cnt + channelMap[1]];
2645                                 v[yPos] = buff[cnt + channelMap[2]];
2646                                 a[yPos] = buff[cnt + channelMap[3]] - yuvOffset;
2647                                 yPos++;
2648                                 cnt += channels;
2649                         }
2650                         buff += pitch2;
2651                 }       
2652         }
2653 
2654         if (m_downsample) {
2655                 // Subsampling of the chrominance and alpha channels
2656                 for (int i=1; i < m_header.channels; i++) {
2657                         Downsample(i);
2658                 }
2659         }
2660 }

bool CPGFImage::IsOpen () const [inline]

Returns true if the PGF has been opened and not closed.

Definition at line 87 of file PGFimage.h.

87 { return m_decoder != NULL; }

BYTE CPGFImage::Level () const [inline]

Return current image level. Since Read(...) can be used to read each image level separately, it is helpful to know the current level. The current level immediately after Open(...) is Levels().

Returns:

Current image level

Definition at line 430 of file PGFimage.h.

430 { return (BYTE)m_currentLevel; }

static UINT32 CPGFImage::LevelHeight (UINT32 height, int level) [inline], [static]

Compute and return image height at given level.

Parameters:

height Original image height (at level 0)
level An image level

Returns:

Image level height in pixels

Definition at line 498 of file PGFimage.h.

498 { ASSERT(level >= 0); UINT32 h = (height >> level); return ((h << level) == height) ? h : h + 1; }

BYTE CPGFImage::Levels () const [inline]

Return the number of image levels.

Returns:

Number of image levels

Definition at line 435 of file PGFimage.h.

435 { return m_header.nLevels; }

static UINT32 CPGFImage::LevelWidth (UINT32 width, int level) [inline], [static]

Compute and return image width at given level.

Parameters:

width Original image width (at level 0)
level An image level

Returns:

Image level width in pixels

Definition at line 491 of file PGFimage.h.

491 { ASSERT(level >= 0); UINT32 w = (width >> level); return ((w << level) == width) ? w : w + 1; }

BYTE CPGFImage::Mode () const [inline]

Return the image mode. An image mode is a predefined constant value (see also PGFtypes.h) compatible with Adobe Photoshop. It represents an image type and format.

Returns:

Image mode

Definition at line 454 of file PGFimage.h.

454 { return m_header.mode; }

void CPGFImage::Open (CPGFStream * stream)

Open a PGF image at current stream position: read pre-header, header, and ckeck image type. Precondition: The stream has been opened for reading. It might throw an IOException.

Parameters:

stream A PGF stream

Definition at line 131 of file PGFimage.cpp.

131                                               {
132         ASSERT(stream);
133 
134         // create decoder and read PGFPreHeader PGFHeader PGFPostHeader LevelLengths
135         m_decoder = new CDecoder(stream, m_preHeader, m_header, m_postHeader, m_levelLength, 
136                 m_userDataPos, m_useOMPinDecoder, m_skipUserData);
137 
138         if (m_header.nLevels > MaxLevel) ReturnWithError(FormatCannotRead);
139 
140         // set current level
141         m_currentLevel = m_header.nLevels;
142 
143         // set image width and height
144         m_width[0] = m_header.width;
145         m_height[0] = m_header.height;
146 
147         // complete header
148         if (!CompleteHeader()) ReturnWithError(FormatCannotRead);
149 
150         // interpret quant parameter
151         if (m_header.quality > DownsampleThreshold && 
152                 (m_header.mode == ImageModeRGBColor || 
153                  m_header.mode == ImageModeRGBA || 
154                  m_header.mode == ImageModeRGB48 || 
155                  m_header.mode == ImageModeCMYKColor || 
156                  m_header.mode == ImageModeCMYK64 || 
157                  m_header.mode == ImageModeLabColor || 
158                  m_header.mode == ImageModeLab48)) {
159                 m_downsample = true;
160                 m_quant = m_header.quality - 1;
161         } else {
162                 m_downsample = false;
163                 m_quant = m_header.quality;
164         }
165 
166         // set channel dimensions (chrominance is subsampled by factor 2)
167         if (m_downsample) {
168                 for (int i=1; i < m_header.channels; i++) {
169                         m_width[i] = (m_width[0] + 1)/2;
170                         m_height[i] = (m_height[0] + 1)/2;
171                 }
172         } else {
173                 for (int i=1; i < m_header.channels; i++) {
174                         m_width[i] = m_width[0];
175                         m_height[i] = m_height[0];
176                 }
177         }
178 
179         if (m_header.nLevels > 0) {
180                 // init wavelet subbands
181                 for (int i=0; i < m_header.channels; i++) {
182                         m_wtChannel[i] = new CWaveletTransform(m_width[i], m_height[i], m_header.nLevels);
183                 }
184 
185                 // used in Read when PM_Absolute
186                 m_percent = pow(0.25, m_header.nLevels);
187 
188         } else {
189                 // very small image: we don't use DWT and encoding
190 
191                 // read channels
192                 for (int c=0; c < m_header.channels; c++) {
193                         const UINT32 size = m_width[c]*m_height[c];
194                         m_channel[c] = new(std::nothrow) DataT[size];
195                         if (!m_channel[c]) ReturnWithError(InsufficientMemory);
196 
197                         // read channel data from stream
198                         for (UINT32 i=0; i < size; i++) {
199                                 int count = DataTSize;
200                                 stream->Read(&count, &m_channel[c][i]);
201                                 if (count != DataTSize) ReturnWithError(MissingData);
202                         }
203                 }
204         }
205 }

BYTE CPGFImage::Quality () const [inline]

Return the PGF quality. The quality is inbetween 0 and MaxQuality. PGF quality 0 means lossless quality.

Returns:

PGF quality

Definition at line 441 of file PGFimage.h.

441 { return m_header.quality; }

void CPGFImage::Read (int level = 0, CallbackPtr cb = NULL, void * data = NULL)

Read and decode some levels of a PGF image at current stream position. A PGF image is structered in levels, numbered between 0 and Levels() - 1. Each level can be seen as a single image, containing the same content as all other levels, but in a different size (width, height). The image size at level i is double the size (width, height) of the image at level i+1. The image at level 0 contains the original size. Precondition: The PGF image has been opened with a call of Open(...). It might throw an IOException.

Parameters:

level [0, nLevels) The image level of the resulting image in the internal image buffer.
cb A pointer to a callback procedure. The procedure is called after reading a single level. If cb returns true, then it stops proceeding.
data Data Pointer to C++ class container to host callback procedure.

Definition at line 384 of file PGFimage.cpp.

384                                                                        {
385         ASSERT((level >= 0 && level < m_header.nLevels) || m_header.nLevels == 0); // m_header.nLevels == 0: image didn't use wavelet transform
386         ASSERT(m_decoder);
387 
388 #ifdef __PGFROISUPPORT__
389         if (ROIisSupported() && m_header.nLevels > 0) {
390                 // new encoding scheme supporting ROI
391                 PGFRect rect(0, 0, m_header.width, m_header.height);
392                 Read(rect, level, cb, data);
393                 return;
394         }
395 #endif
396 
397         if (m_header.nLevels == 0) {
398                 if (level == 0) {
399                         // the data has already been read during open
400                         // now update progress
401                         if (cb) {
402                                 if ((*cb)(1.0, true, data)) ReturnWithError(EscapePressed);
403                         }
404                 }
405         } else {
406                 const int levelDiff = m_currentLevel - level;
407                 double percent = (m_progressMode == PM_Relative) ? pow(0.25, levelDiff) : m_percent;
408 
409                 // encoding scheme without ROI
410                 while (m_currentLevel > level) {
411                         for (int i=0; i < m_header.channels; i++) {
412                                 ASSERT(m_wtChannel[i]);
413                                 // decode file and write stream to m_wtChannel
414                                 if (m_currentLevel == m_header.nLevels) { 
415                                         // last level also has LL band
416                                         m_wtChannel[i]->GetSubband(m_currentLevel, LL)->PlaceTile(*m_decoder, m_quant);
417                                 }
418                                 if (m_preHeader.version & Version5) {
419                                         // since version 5
420                                         m_wtChannel[i]->GetSubband(m_currentLevel, HL)->PlaceTile(*m_decoder, m_quant);
421                                         m_wtChannel[i]->GetSubband(m_currentLevel, LH)->PlaceTile(*m_decoder, m_quant);
422                                 } else {
423                                         // until version 4
424                                         m_decoder->DecodeInterleaved(m_wtChannel[i], m_currentLevel, m_quant);
425                                 }
426                                 m_wtChannel[i]->GetSubband(m_currentLevel, HH)->PlaceTile(*m_decoder, m_quant);
427                         }
428 
429                         volatile OSError error = NoError; // volatile prevents optimizations
430 #ifdef LIBPGF_USE_OPENMP
431                         #pragma omp parallel for default(shared) 
432 #endif
433                         for (int i=0; i < m_header.channels; i++) {
434                                 // inverse transform from m_wtChannel to m_channel
435                                 if (error == NoError) {
436                                         OSError err = m_wtChannel[i]->InverseTransform(m_currentLevel, &m_width[i], &m_height[i], &m_channel[i]);       
437                                         if (err != NoError) error = err;
438                                 }
439                                 ASSERT(m_channel[i]);
440                         }
441                         if (error != NoError) ReturnWithError(error);
442 
443                         // set new level: must be done before refresh callback
444                         m_currentLevel--;
445 
446                         // now we have to refresh the display
447                         if (m_cb) m_cb(m_cbArg);
448 
449                         // now update progress
450                         if (cb) {
451                                 percent *= 4;
452                                 if (m_progressMode == PM_Absolute) m_percent = percent;
453                                 if ((*cb)(percent, true, data)) ReturnWithError(EscapePressed);
454                         }
455                 }
456         }
457 
458         // automatically closing
459         if (m_currentLevel == 0) Close();
460 }

void CPGFImage::Read (PGFRect & rect, int level = 0, CallbackPtr cb = NULL, void * data = NULL)

Read a rectangular region of interest of a PGF image at current stream position. The origin of the coordinate axis is the top-left corner of the image. All coordinates are measured in pixels. It might throw an IOException.

Parameters:

rect [inout] Rectangular region of interest (ROI). The rect might be cropped.
level [0, nLevels) The image level of the resulting image in the internal image buffer.
cb A pointer to a callback procedure. The procedure is called after reading a single level. If cb returns true, then it stops proceeding.
data Data Pointer to C++ class container to host callback procedure.

UINT32 CPGFImage::ReadEncodedData (int level, UINT8 * target, UINT32 targetLen) const

Reads the data of an encoded PGF level and copies it to a target buffer without decoding. Precondition: The PGF image has been opened with a call of Open(...). It might throw an IOException.

Parameters:

level The image level
target The target buffer
targetLen The length of the target buffer in bytes

Returns:

The number of bytes copied to the target buffer

Definition at line 659 of file PGFimage.cpp.

659                                                                                          {
660         ASSERT(level >= 0 && level < m_header.nLevels);
661         ASSERT(target);
662         ASSERT(targetLen > 0);
663         ASSERT(m_decoder);
664 
665         // reset stream position
666         m_decoder->SetStreamPosToData();
667 
668         // position stream
669         UINT64 offset = 0;
670 
671         for (int i=m_header.nLevels - 1; i > level; i--) {
672                 offset += m_levelLength[m_header.nLevels - 1 - i];
673         }
674         m_decoder->Skip(offset);
675 
676         // compute number of bytes to read
677         UINT32 len = __min(targetLen, GetEncodedLevelLength(level));
678 
679         // read data
680         len = m_decoder->ReadEncodedData(target, len);
681         ASSERT(len >= 0 && len <= targetLen);
682 
683         return len;
684 }

UINT32 CPGFImage::ReadEncodedHeader (UINT8 * target, UINT32 targetLen) const

Reads the encoded PGF headers and copies it to a target buffer. Precondition: The PGF image has been opened with a call of Open(...). It might throw an IOException.

Parameters:

target The target buffer
targetLen The length of the target buffer in bytes

Returns:

The number of bytes copied to the target buffer

Definition at line 625 of file PGFimage.cpp.

625                                                                                 {
626         ASSERT(target);
627         ASSERT(targetLen > 0);
628         ASSERT(m_decoder);
629 
630         // reset stream position
631         m_decoder->SetStreamPosToStart();
632 
633         // compute number of bytes to read
634         UINT32 len = __min(targetLen, GetEncodedHeaderLength());
635 
636         // read data
637         len = m_decoder->ReadEncodedData(target, len);
638         ASSERT(len >= 0 && len <= targetLen);
639 
640         return len;
641 }

void CPGFImage::ReadPreview () [inline]

Read and decode smallest level of a PGF image at current stream position. For details, please refert to Read(...) Precondition: The PGF image has been opened with a call of Open(...). It might throw an IOException.

Definition at line 121 of file PGFimage.h.

121 { Read(Levels() - 1); }

void CPGFImage::Reconstruct (int level = 0)

After you've written a PGF image, you can call this method followed by GetBitmap/GetYUV to get a quick reconstruction (coded -> decoded image). It might throw an IOException.

Parameters:

level The image level of the resulting image in the internal image buffer.

Definition at line 332 of file PGFimage.cpp.

332                                               {
333         if (m_header.nLevels == 0) {
334                 // image didn't use wavelet transform
335                 if (level == 0) {
336                         for (int i=0; i < m_header.channels; i++) {
337                                 ASSERT(m_wtChannel[i]);
338                                 m_channel[i] = m_wtChannel[i]->GetSubband(0, LL)->GetBuffer();
339                         }
340                 }
341         } else {
342                 int currentLevel = m_header.nLevels;
343 
344                 if (ROIisSupported()) {
345                         // enable ROI reading
346                         SetROI(PGFRect(0, 0, m_header.width, m_header.height));
347                 }
348 
349                 while (currentLevel > level) {
350                         for (int i=0; i < m_header.channels; i++) {
351                                 ASSERT(m_wtChannel[i]);
352                                 // dequantize subbands
353                                 if (currentLevel == m_header.nLevels) { 
354                                         // last level also has LL band
355                                         m_wtChannel[i]->GetSubband(currentLevel, LL)->Dequantize(m_quant);
356                                 }
357                                 m_wtChannel[i]->GetSubband(currentLevel, HL)->Dequantize(m_quant);
358                                 m_wtChannel[i]->GetSubband(currentLevel, LH)->Dequantize(m_quant);
359                                 m_wtChannel[i]->GetSubband(currentLevel, HH)->Dequantize(m_quant);
360 
361                                 // inverse transform from m_wtChannel to m_channel
362                                 OSError err = m_wtChannel[i]->InverseTransform(currentLevel, &m_width[i], &m_height[i], &m_channel[i]);
363                                 if (err != NoError) ReturnWithError(err);
364                                 ASSERT(m_channel[i]);
365                         }
366 
367                         currentLevel--;
368                 }
369         }
370 }

void CPGFImage::ResetStreamPos ()

Reset stream position to start of PGF pre-header.

Definition at line 645 of file PGFimage.cpp.

645                                       {
646         ASSERT(m_decoder);
647         return m_decoder->SetStreamPosToStart(); 
648 }

void CPGFImage::RgbToYuv (int pitch, UINT8 * rgbBuff, BYTE bpp, int channelMap[], CallbackPtr cb, void * data) [private]

Definition at line 1331 of file PGFimage.cpp.

1331                                                                                                                 {
1332         ASSERT(buff);
1333         int yPos = 0, cnt = 0;
1334         double percent = 0;
1335         const double dP = 1.0/m_header.height;
1336         int defMap[] = { 0, 1, 2, 3, 4, 5, 6, 7 }; ASSERT(sizeof(defMap)/sizeof(defMap[0]) == MaxChannels);
1337 
1338         if (channelMap == NULL) channelMap = defMap;
1339 
1340         switch(m_header.mode) {
1341         case ImageModeBitmap:
1342                 {
1343                         ASSERT(m_header.channels == 1);
1344                         ASSERT(m_header.bpp == 1);
1345                         ASSERT(bpp == 1);
1346                         
1347                         const UINT32 w = m_header.width;
1348                         const UINT32 w2 = (m_header.width + 7)/8;
1349                         DataT* y = m_channel[0]; ASSERT(y);
1350 
1351                         for (UINT32 h=0; h < m_header.height; h++) {
1352                                 if (cb) {
1353                                         if ((*cb)(percent, true, data)) ReturnWithError(EscapePressed);
1354                                         percent += dP;
1355                                 }
1356                                 
1357                                 for (UINT32 j=0; j < w2; j++) {
1358                                         y[yPos++] = buff[j] - YUVoffset8;
1359                                 }
1360                                 for (UINT32 j=w2; j < w; j++) {
1361                                         y[yPos++] = YUVoffset8;
1362                                 }
1363                                 
1364                                 //UINT cnt = w;
1365                                 //for (UINT32 j=0; j < w2; j++) {
1366                                 //      for (int k=7; k >= 0; k--) {
1367                                 //              if (cnt) { 
1368                                 //                      y[yPos++] = YUVoffset8 + (1 & (buff[j] >> k));
1369                                 //                      cnt--;
1370                                 //              }
1371                                 //      }
1372                                 //}
1373                                 buff += pitch;  
1374                         }
1375                 }
1376                 break;
1377         case ImageModeIndexedColor:
1378         case ImageModeGrayScale:
1379         case ImageModeHSLColor:
1380         case ImageModeHSBColor:
1381         case ImageModeLabColor:
1382                 {
1383                         ASSERT(m_header.channels >= 1);
1384                         ASSERT(m_header.bpp == m_header.channels*8);
1385                         ASSERT(bpp%8 == 0);
1386                         const int channels = bpp/8; ASSERT(channels >= m_header.channels);
1387 
1388                         for (UINT32 h=0; h < m_header.height; h++) {
1389                                 if (cb) {
1390                                         if ((*cb)(percent, true, data)) ReturnWithError(EscapePressed);
1391                                         percent += dP;
1392                                 }
1393 
1394                                 cnt = 0;
1395                                 for (UINT32 w=0; w < m_header.width; w++) {
1396                                         for (int c=0; c < m_header.channels; c++) {
1397                                                 m_channel[c][yPos] = buff[cnt + channelMap[c]] - YUVoffset8;
1398                                         }
1399                                         cnt += channels;
1400                                         yPos++;
1401                                 }
1402                                 buff += pitch;  
1403                         }
1404                 }
1405                 break;
1406         case ImageModeGray16:
1407         case ImageModeLab48:
1408                 {
1409                         ASSERT(m_header.channels >= 1);
1410                         ASSERT(m_header.bpp == m_header.channels*16);
1411                         ASSERT(bpp%16 == 0);
1412 
1413                         UINT16 *buff16 = (UINT16 *)buff;
1414                         const int pitch16 = pitch/2;
1415                         const int channels = bpp/16; ASSERT(channels >= m_header.channels);
1416                         const int shift = 16 - UsedBitsPerChannel(); ASSERT(shift >= 0);
1417                         const DataT yuvOffset16 = 1 << (UsedBitsPerChannel() - 1);
1418 
1419                         for (UINT32 h=0; h < m_header.height; h++) {
1420                                 if (cb) {
1421                                         if ((*cb)(percent, true, data)) ReturnWithError(EscapePressed);
1422                                         percent += dP;
1423                                 }
1424 
1425                                 cnt = 0;
1426                                 for (UINT32 w=0; w < m_header.width; w++) {
1427                                         for (int c=0; c < m_header.channels; c++) {
1428                                                 m_channel[c][yPos] = (buff16[cnt + channelMap[c]] >> shift) - yuvOffset16;
1429                                         }
1430                                         cnt += channels;
1431                                         yPos++;
1432                                 }
1433                                 buff16 += pitch16;
1434                         }
1435                 }
1436                 break;
1437         case ImageModeRGBColor:
1438                 {
1439                         ASSERT(m_header.channels == 3);
1440                         ASSERT(m_header.bpp == m_header.channels*8);
1441                         ASSERT(bpp%8 == 0);
1442 
1443                         DataT* y = m_channel[0]; ASSERT(y);
1444                         DataT* u = m_channel[1]; ASSERT(u);
1445                         DataT* v = m_channel[2]; ASSERT(v);
1446                         const int channels = bpp/8; ASSERT(channels >= m_header.channels);
1447                         UINT8 b, g, r;
1448 
1449                         for (UINT32 h=0; h < m_header.height; h++) {
1450                                 if (cb) {
1451                                         if ((*cb)(percent, true, data)) ReturnWithError(EscapePressed);
1452                                         percent += dP;
1453                                 }
1454 
1455                                 cnt = 0;
1456                                 for (UINT32 w=0; w < m_header.width; w++) {
1457                                         b = buff[cnt + channelMap[0]];
1458                                         g = buff[cnt + channelMap[1]];
1459                                         r = buff[cnt + channelMap[2]];
1460                                         // Yuv
1461                                         y[yPos] = ((b + (g << 1) + r) >> 2) - YUVoffset8;
1462                                         u[yPos] = r - g;
1463                                         v[yPos] = b - g;
1464                                         yPos++;
1465                                         cnt += channels;
1466                                 }
1467                                 buff += pitch;
1468                         }       
1469                 }
1470                 break;
1471         case ImageModeRGB48:
1472                 {
1473                         ASSERT(m_header.channels == 3);
1474                         ASSERT(m_header.bpp == m_header.channels*16);
1475                         ASSERT(bpp%16 == 0);
1476 
1477                         UINT16 *buff16 = (UINT16 *)buff;
1478                         const int pitch16 = pitch/2;
1479                         const int channels = bpp/16; ASSERT(channels >= m_header.channels);
1480                         const int shift = 16 - UsedBitsPerChannel(); ASSERT(shift >= 0);
1481                         const DataT yuvOffset16 = 1 << (UsedBitsPerChannel() - 1);
1482 
1483                         DataT* y = m_channel[0]; ASSERT(y);
1484                         DataT* u = m_channel[1]; ASSERT(u);
1485                         DataT* v = m_channel[2]; ASSERT(v);
1486                         UINT16 b, g, r;
1487 
1488                         for (UINT32 h=0; h < m_header.height; h++) {
1489                                 if (cb) {
1490                                         if ((*cb)(percent, true, data)) ReturnWithError(EscapePressed);
1491                                         percent += dP;
1492                                 }
1493 
1494                                 cnt = 0;
1495                                 for (UINT32 w=0; w < m_header.width; w++) {
1496                                         b = buff16[cnt + channelMap[0]] >> shift;
1497                                         g = buff16[cnt + channelMap[1]] >> shift;
1498                                         r = buff16[cnt + channelMap[2]] >> shift;
1499                                         // Yuv
1500                                         y[yPos] = ((b + (g << 1) + r) >> 2) - yuvOffset16;
1501                                         u[yPos] = r - g;
1502                                         v[yPos] = b - g;
1503                                         yPos++;
1504                                         cnt += channels;
1505                                 }
1506                                 buff16 += pitch16;
1507                         }       
1508                 }
1509                 break;
1510         case ImageModeRGBA:
1511         case ImageModeCMYKColor:
1512                 {
1513                         ASSERT(m_header.channels == 4);
1514                         ASSERT(m_header.bpp == m_header.channels*8);
1515                         ASSERT(bpp%8 == 0);
1516                         const int channels = bpp/8; ASSERT(channels >= m_header.channels);
1517 
1518                         DataT* y = m_channel[0]; ASSERT(y);
1519                         DataT* u = m_channel[1]; ASSERT(u);
1520                         DataT* v = m_channel[2]; ASSERT(v);
1521                         DataT* a = m_channel[3]; ASSERT(a);
1522                         UINT8 b, g, r;
1523 
1524                         for (UINT32 h=0; h < m_header.height; h++) {
1525                                 if (cb) {
1526                                         if ((*cb)(percent, true, data)) ReturnWithError(EscapePressed);
1527                                         percent += dP;
1528                                 }
1529 
1530                                 cnt = 0;
1531                                 for (UINT32 w=0; w < m_header.width; w++) {
1532                                         b = buff[cnt + channelMap[0]];
1533                                         g = buff[cnt + channelMap[1]];
1534                                         r = buff[cnt + channelMap[2]];
1535                                         // Yuv
1536                                         y[yPos] = ((b + (g << 1) + r) >> 2) - YUVoffset8;
1537                                         u[yPos] = r - g;
1538                                         v[yPos] = b - g;
1539                                         a[yPos++] = buff[cnt + channelMap[3]] - YUVoffset8;
1540                                         cnt += channels;
1541                                 }
1542                                 buff += pitch;
1543                         }       
1544                 }
1545                 break;
1546         case ImageModeCMYK64:
1547                 {
1548                         ASSERT(m_header.channels == 4);
1549                         ASSERT(m_header.bpp == m_header.channels*16);
1550                         ASSERT(bpp%16 == 0);
1551 
1552                         UINT16 *buff16 = (UINT16 *)buff;
1553                         const int pitch16 = pitch/2;
1554                         const int channels = bpp/16; ASSERT(channels >= m_header.channels);
1555                         const int shift = 16 - UsedBitsPerChannel(); ASSERT(shift >= 0);
1556                         const DataT yuvOffset16 = 1 << (UsedBitsPerChannel() - 1);
1557                         
1558                         DataT* y = m_channel[0]; ASSERT(y);
1559                         DataT* u = m_channel[1]; ASSERT(u);
1560                         DataT* v = m_channel[2]; ASSERT(v);
1561                         DataT* a = m_channel[3]; ASSERT(a);
1562                         UINT16 b, g, r;
1563 
1564                         for (UINT32 h=0; h < m_header.height; h++) {
1565                                 if (cb) {
1566                                         if ((*cb)(percent, true, data)) ReturnWithError(EscapePressed);
1567                                         percent += dP;
1568                                 }
1569 
1570                                 cnt = 0;
1571                                 for (UINT32 w=0; w < m_header.width; w++) {
1572                                         b = buff16[cnt + channelMap[0]] >> shift;
1573                                         g = buff16[cnt + channelMap[1]] >> shift;
1574                                         r = buff16[cnt + channelMap[2]] >> shift;
1575                                         // Yuv
1576                                         y[yPos] = ((b + (g << 1) + r) >> 2) - yuvOffset16;
1577                                         u[yPos] = r - g;
1578                                         v[yPos] = b - g;
1579                                         a[yPos++] = (buff16[cnt + channelMap[3]] >> shift) - yuvOffset16;
1580                                         cnt += channels;
1581                                 }
1582                                 buff16 += pitch16;
1583                         }       
1584                 }
1585                 break;
1586 #ifdef __PGF32SUPPORT__
1587         case ImageModeGray32:
1588                 {
1589                         ASSERT(m_header.channels == 1);
1590                         ASSERT(m_header.bpp == 32);
1591                         ASSERT(bpp == 32);
1592                         ASSERT(DataTSize == sizeof(UINT32));
1593 
1594                         DataT* y = m_channel[0]; ASSERT(y);
1595 
1596                         UINT32 *buff32 = (UINT32 *)buff;
1597                         const int pitch32 = pitch/4;
1598                         const int shift = 31 - UsedBitsPerChannel(); ASSERT(shift >= 0);
1599                         const DataT yuvOffset31 = 1 << (UsedBitsPerChannel() - 1);
1600 
1601                         for (UINT32 h=0; h < m_header.height; h++) {
1602                                 if (cb) {
1603                                         if ((*cb)(percent, true, data)) ReturnWithError(EscapePressed);
1604                                         percent += dP;
1605                                 }
1606 
1607                                 for (UINT32 w=0; w < m_header.width; w++) {
1608                                         y[yPos++] = (buff32[w] >> shift) - yuvOffset31;
1609                                 }
1610                                 buff32 += pitch32;
1611                         }
1612                 }
1613                 break;
1614 #endif
1615         case ImageModeRGB12:
1616                 {
1617                         ASSERT(m_header.channels == 3);
1618                         ASSERT(m_header.bpp == m_header.channels*4);
1619                         ASSERT(bpp == m_header.channels*4);
1620 
1621                         DataT* y = m_channel[0]; ASSERT(y);
1622                         DataT* u = m_channel[1]; ASSERT(u);
1623                         DataT* v = m_channel[2]; ASSERT(v);
1624 
1625                         UINT8 rgb = 0, b, g, r;
1626 
1627                         for (UINT32 h=0; h < m_header.height; h++) {
1628                                 if (cb) {
1629                                         if ((*cb)(percent, true, data)) ReturnWithError(EscapePressed);
1630                                         percent += dP;
1631                                 }
1632 
1633                                 cnt = 0;
1634                                 for (UINT32 w=0; w < m_header.width; w++) {
1635                                         if (w%2 == 0) {
1636                                                 // even pixel position
1637                                                 rgb = buff[cnt];
1638                                                 b = rgb & 0x0F;
1639                                                 g = (rgb & 0xF0) >> 4;
1640                                                 cnt++;
1641                                                 rgb = buff[cnt];
1642                                                 r = rgb & 0x0F;
1643                                         } else {
1644                                                 // odd pixel position
1645                                                 b = (rgb & 0xF0) >> 4;
1646                                                 cnt++;
1647                                                 rgb = buff[cnt];
1648                                                 g = rgb & 0x0F;
1649                                                 r = (rgb & 0xF0) >> 4;
1650                                                 cnt++;
1651                                         }
1652 
1653                                         // Yuv
1654                                         y[yPos] = ((b + (g << 1) + r) >> 2) - YUVoffset4;
1655                                         u[yPos] = r - g;
1656                                         v[yPos] = b - g;
1657                                         yPos++;
1658                                 }
1659                                 buff += pitch;
1660                         }       
1661                 }
1662                 break;
1663         case ImageModeRGB16:
1664                 {
1665                         ASSERT(m_header.channels == 3);
1666                         ASSERT(m_header.bpp == 16);
1667                         ASSERT(bpp == 16);
1668                         
1669                         DataT* y = m_channel[0]; ASSERT(y);
1670                         DataT* u = m_channel[1]; ASSERT(u);
1671                         DataT* v = m_channel[2]; ASSERT(v);
1672 
1673                         UINT16 *buff16 = (UINT16 *)buff;
1674                         UINT16 rgb, b, g, r;
1675                         const int pitch16 = pitch/2;
1676 
1677                         for (UINT32 h=0; h < m_header.height; h++) {
1678                                 if (cb) {
1679                                         if ((*cb)(percent, true, data)) ReturnWithError(EscapePressed);
1680                                         percent += dP;
1681                                 }
1682                                 for (UINT32 w=0; w < m_header.width; w++) {
1683                                         rgb = buff16[w]; 
1684                                         r = (rgb & 0xF800) >> 10;       // highest 5 bits
1685                                         g = (rgb & 0x07E0) >> 5;        // middle 6 bits
1686                                         b = (rgb & 0x001F) << 1;        // lowest 5 bits
1687                                         // Yuv
1688                                         y[yPos] = ((b + (g << 1) + r) >> 2) - YUVoffset6;
1689                                         u[yPos] = r - g;
1690                                         v[yPos] = b - g;
1691                                         yPos++;
1692                                 }
1693 
1694                                 buff16 += pitch16;
1695                         }       
1696                 }
1697                 break;
1698         default:
1699                 ASSERT(false);
1700         }
1701 }

bool CPGFImage::ROIisSupported () const [inline]

Return true if the pgf image supports Region Of Interest (ROI).

Returns:

true if the pgf image supports ROI.

Definition at line 465 of file PGFimage.h.

465 { return (m_preHeader.version & PGFROI) == PGFROI; }

void CPGFImage::SetChannel (DataT * channel, int c = 0) [inline]

Set internal PGF image buffer channel.

Parameters:

channel A YUV data channel
c A channel index

Definition at line 276 of file PGFimage.h.

276 { ASSERT(c >= 0 && c < MaxChannels); m_channel[c] = channel; }

void CPGFImage::SetColorTable (UINT32 iFirstColor, UINT32 nColors, const RGBQUAD * prgbColors)

Sets the red, green, blue (RGB) color values for a range of entries in the palette (clut). It might throw an IOException.

Parameters:

iFirstColor The color table index of the first entry to set.
nColors The number of color table entries to set.
prgbColors A pointer to the array of RGBQUAD structures to set the color table entries.

Definition at line 1306 of file PGFimage.cpp.

1306                                                                                                   {
1307         if (iFirstColor + nColors > ColorTableLen)      ReturnWithError(ColorTableError);
1308 
1309         for (UINT32 i=iFirstColor, j=0; j < nColors; i++, j++) {
1310                 m_postHeader.clut[i] = prgbColors[j];
1311         }
1312 }

void CPGFImage::SetHeader (const PGFHeader & header, BYTE flags = 0, UINT8 * userData = 0, UINT32 userDataLength = 0)

Set PGF header and user data. Precondition: The PGF image has been closed with Close(...) or never opened with Open(...). It might throw an IOException.

Parameters:

header A valid and already filled in PGF header structure
flags A combination of additional version flags. In case you use level-wise encoding then set flag = PGFROI.
userData A user-defined memory block containing any kind of cached metadata.
userDataLength The size of user-defined memory block in bytes

Definition at line 844 of file PGFimage.cpp.

844                                                                                                                   {
845         ASSERT(!m_decoder);     // current image must be closed
846         ASSERT(header.quality <= MaxQuality);
847 
848         // init state
849 #ifdef __PGFROISUPPORT__
850         m_streamReinitialized = false;
851 #endif
852 
853         // init preHeader
854         memcpy(m_preHeader.magic, PGFMagic, 3);
855         m_preHeader.version = PGFVersion | flags;
856         m_preHeader.hSize = HeaderSize;
857 
858         // copy header
859         memcpy(&m_header, &header, HeaderSize);
860 
861         // complete header
862         CompleteHeader();
863 
864         // check and set number of levels
865         ComputeLevels();
866 
867         // check for downsample
868         if (m_header.quality > DownsampleThreshold &&  (m_header.mode == ImageModeRGBColor || 
869                                                                                                         m_header.mode == ImageModeRGBA || 
870                                                                                                         m_header.mode == ImageModeRGB48 || 
871                                                                                                         m_header.mode == ImageModeCMYKColor || 
872                                                                                                         m_header.mode == ImageModeCMYK64 || 
873                                                                                                         m_header.mode == ImageModeLabColor || 
874                                                                                                         m_header.mode == ImageModeLab48)) {
875                 m_downsample = true;
876                 m_quant = m_header.quality - 1;
877         } else {
878                 m_downsample = false;
879                 m_quant = m_header.quality;
880         }
881 
882         // update header size and copy user data
883         if (m_header.mode == ImageModeIndexedColor) {
884                 // update header size
885                 m_preHeader.hSize += ColorTableSize;
886         }
887         if (userDataLength && userData) {
888                 m_postHeader.userData = new(std::nothrow) UINT8[userDataLength];
889                 if (!m_postHeader.userData) ReturnWithError(InsufficientMemory);
890                 m_postHeader.userDataLen = userDataLength;
891                 memcpy(m_postHeader.userData, userData, userDataLength);
892                 // update header size
893                 m_preHeader.hSize += userDataLength;
894         }
895 
896         // allocate channels
897         for (int i=0; i < m_header.channels; i++) {
898                 // set current width and height
899                 m_width[i] = m_header.width;
900                 m_height[i] = m_header.height;
901 
902                 // allocate channels
903                 ASSERT(!m_channel[i]);
904                 m_channel[i] = new(std::nothrow) DataT[m_header.width*m_header.height];
905                 if (!m_channel[i]) {
906                         if (i) i--;
907                         while(i) {
908                                 delete[] m_channel[i]; m_channel[i] = 0;
909                                 i--;
910                         }
911                         ReturnWithError(InsufficientMemory);
912                 }
913         }
914 }

void CPGFImage::SetMaxValue (UINT32 maxValue)

Set maximum intensity value for image modes with more than eight bits per channel. Call this method after SetHeader, but before ImportBitmap.

Parameters:

maxValue The maximum intensity value.

Definition at line 690 of file PGFimage.cpp.

690                                            {
691         const BYTE bpc = m_header.bpp/m_header.channels;
692         BYTE pot = 0;
693 
694         while(maxValue > 0) {
695                 pot++;
696                 maxValue >>= 1;
697         }
698         // store bits per channel
699         if (pot > bpc) pot = bpc;
700         if (pot > 31) pot = 31;
701         m_header.usedBitsPerChannel = pot;
702 }

void CPGFImage::SetProgressMode (ProgressMode pm) [inline]

Set progress mode used in Read and Write. Default mode is PM_Relative. This method must be called before Open() or SetHeader(). PM_Relative: 100% = level difference between current level and target level of Read/Write PM_Absolute: 100% = number of levels

Definition at line 300 of file PGFimage.h.

300 { m_progressMode = pm; }

void CPGFImage::SetRefreshCallback (RefreshCB callback, void * arg) [inline]

Set refresh callback procedure and its parameter. The refresh callback is called during Read(...) after each level read.

Parameters:

callback A refresh callback procedure
arg A parameter of the refresh callback procedure

Definition at line 307 of file PGFimage.h.

307 { m_cb = callback; m_cbArg = arg; }

void CPGFImage::SetROI (PGFRect rect) [private]

UINT32 CPGFImage::UpdatePostHeaderSize () [private]

Definition at line 1067 of file PGFimage.cpp.

1067                                               {
1068         ASSERT(m_encoder);
1069 
1070         INT64 offset = m_encoder->ComputeOffset(); ASSERT(offset >= 0);
1071 
1072         if (offset > 0) {
1073                 // update post-header size and rewrite pre-header
1074                 m_preHeader.hSize += (UINT32)offset;
1075                 m_encoder->UpdatePostHeaderSize(m_preHeader);
1076         }
1077 
1078         // write dummy levelLength into stream
1079         return m_encoder->WriteLevelLength(m_levelLength);
1080 }

BYTE CPGFImage::UsedBitsPerChannel () const

Returns number of used bits per input/output image channel. Precondition: header must be initialized.

Returns:

number of used bits per input/output image channel.

Definition at line 708 of file PGFimage.cpp.

708                                          {
709         const BYTE bpc = m_header.bpp/m_header.channels;
710 
711         if (bpc > 8) {
712                 return m_header.usedBitsPerChannel;
713         } else {
714                 return bpc;
715         }
716 }

BYTE CPGFImage::Version () const [inline]

Returns images' PGF version

Returns:

PGF codec version of the image

Definition at line 476 of file PGFimage.h.

476 { return CurrentVersion(m_preHeader.version); }

UINT32 CPGFImage::Width (int level = 0) const [inline]

Return image width of channel 0 at given level in pixels. The returned width is independent of any Read-operations and ROI.

Parameters:

level A level

Returns:

Image level width in pixels

Definition at line 416 of file PGFimage.h.

416 { ASSERT(level >= 0); return LevelWidth(m_header.width, level); }

void CPGFImage::Write (CPGFStream * stream, UINT32 * nWrittenBytes = NULL, CallbackPtr cb = NULL, void * data = NULL)

Encode and write a entire PGF image (header and image) at current stream position. A PGF image is structered in levels, numbered between 0 and Levels() - 1. Each level can be seen as a single image, containing the same content as all other levels, but in a different size (width, height). The image size at level i is double the size (width, height) of the image at level i+1. The image at level 0 contains the original size. Precondition: the PGF image contains a valid header (see also SetHeader(...)). It might throw an IOException.

Parameters:

stream A PGF stream
nWrittenBytes [in-out] The number of bytes written into stream are added to the input value.
cb A pointer to a callback procedure. The procedure is called after writing a single level. If cb returns true, then it stops proceeding.
data Data Pointer to C++ class container to host callback procedure.

Definition at line 1163 of file PGFimage.cpp.

1163                                                                                                         {
1164         ASSERT(stream);
1165         ASSERT(m_preHeader.hSize);
1166 
1167         // create wavelet transform channels and encoder
1168         UINT32 nBytes = WriteHeader(stream);
1169 
1170         // write image
1171         nBytes += WriteImage(stream, cb, data);
1172 
1173         // return written bytes
1174         if (nWrittenBytes) *nWrittenBytes += nBytes;
1175 }

UINT32 CPGFImage::Write (int level, CallbackPtr cb = NULL, void * data = NULL)

Encode and write down to given level at current stream position. A PGF image is structered in levels, numbered between 0 and Levels() - 1. Each level can be seen as a single image, containing the same content as all other levels, but in a different size (width, height). The image size at level i is double the size (width, height) of the image at level i+1. The image at level 0 contains the original size. Preconditions: the PGF image contains a valid header (see also SetHeader(...)) and WriteHeader() has been called before. Levels() > 0. The ROI encoding scheme must be used (see also SetHeader(...)). It might throw an IOException.

Parameters:

level [0, nLevels) The image level of the resulting image in the internal image buffer.
cb A pointer to a callback procedure. The procedure is called after writing a single level. If cb returns true, then it stops proceeding.
data Data Pointer to C++ class container to host callback procedure.

Returns:

The number of bytes written into stream.

UINT32 CPGFImage::WriteHeader (CPGFStream * stream)

Create wavelet transform channels and encoder. Write header at current stream position. Call this method before your first call of Write(int level) or WriteImage(), but after SetHeader(). This method is called inside of Write(stream, ...). It might throw an IOException.

Parameters:

stream A PGF stream

Returns:

The number of bytes written into stream.

Definition at line 923 of file PGFimage.cpp.

923                                                        {
924         ASSERT(m_header.nLevels <= MaxLevel);
925         ASSERT(m_header.quality <= MaxQuality); // quality is already initialized
926 
927         if (m_header.nLevels > 0) {
928                 volatile OSError error = NoError; // volatile prevents optimizations
929                 // create new wt channels
930 #ifdef LIBPGF_USE_OPENMP
931                 #pragma omp parallel for default(shared)
932 #endif
933                 for (int i=0; i < m_header.channels; i++) {
934                         DataT *temp = NULL;
935                         if (error == NoError) {
936                                 if (m_wtChannel[i]) {
937                                         ASSERT(m_channel[i]);
938                                         // copy m_channel to temp
939                                         int size = m_height[i]*m_width[i];
940                                         temp = new(std::nothrow) DataT[size];
941                                         if (temp) {
942                                                 memcpy(temp, m_channel[i], size*DataTSize);
943                                                 delete m_wtChannel[i];  // also deletes m_channel
944                                                 m_channel[i] = NULL;
945                                         } else {
946                                                 error = InsufficientMemory;
947                                         }
948                                 }
949                                 if (error == NoError) {
950                                         if (temp) {
951                                                 ASSERT(!m_channel[i]);
952                                                 m_channel[i] = temp;
953                                         }
954                                         m_wtChannel[i] = new CWaveletTransform(m_width[i], m_height[i], m_header.nLevels, m_channel[i]);
955                                         if (m_wtChannel[i]) {
956                                         #ifdef __PGFROISUPPORT__
957                                                 m_wtChannel[i]->SetROI(PGFRect(0, 0, m_width[i], m_height[i]));
958                                         #endif
959                                         
960                                                 // wavelet subband decomposition 
961                                                 for (int l=0; error == NoError && l < m_header.nLevels; l++) {
962                                                         OSError err = m_wtChannel[i]->ForwardTransform(l, m_quant);
963                                                         if (err != NoError) error = err;
964                                                 }
965                                         } else {
966                                                 delete[] m_channel[i];
967                                                 error = InsufficientMemory;
968                                         }
969                                 }
970                         }
971                 }
972                 if (error != NoError) {
973                         // free already allocated memory
974                         for (int i=0; i < m_header.channels; i++) {
975                                 delete m_wtChannel[i];
976                         }
977                         ReturnWithError(error);
978                 }
979 
980                 m_currentLevel = m_header.nLevels;
981 
982                 // create encoder and eventually write headers and levelLength
983                 m_encoder = new CEncoder(stream, m_preHeader, m_header, m_postHeader, m_userDataPos, m_useOMPinEncoder);
984                 if (m_favorSpeedOverSize) m_encoder->FavorSpeedOverSize();
985 
986         #ifdef __PGFROISUPPORT__
987                 if (ROIisSupported()) {
988                         // new encoding scheme supporting ROI
989                         m_encoder->SetROI();
990                 }
991         #endif
992 
993         } else {
994                 // very small image: we don't use DWT and encoding
995 
996                 // create encoder and eventually write headers and levelLength
997                 m_encoder = new CEncoder(stream, m_preHeader, m_header, m_postHeader, m_userDataPos, m_useOMPinEncoder);
998         }
999 
1000         INT64 nBytes = m_encoder->ComputeHeaderLength();
1001         return (nBytes > 0) ? (UINT32)nBytes : 0;
1002 }

UINT32 CPGFImage::WriteImage (CPGFStream * stream, CallbackPtr cb = NULL, void * data = NULL)

Encode and write the one and only image at current stream position. Call this method after WriteHeader(). In case you want to write uncached metadata, then do that after WriteHeader() and before WriteImage(). This method is called inside of Write(stream, ...). It might throw an IOException.

Parameters:

stream A PGF stream
cb A pointer to a callback procedure. The procedure is called after writing a single level. If cb returns true, then it stops proceeding.
data Data Pointer to C++ class container to host callback procedure.

Returns:

The number of bytes written into stream.

Definition at line 1092 of file PGFimage.cpp.

1092                                                                                       {
1093         ASSERT(stream);
1094         ASSERT(m_preHeader.hSize);
1095 
1096         int levels = m_header.nLevels;
1097         double percent = pow(0.25, levels);
1098 
1099         // update post-header size, rewrite pre-header, and write dummy levelLength
1100         UINT32 nWrittenBytes = UpdatePostHeaderSize();
1101 
1102         if (levels == 0) {
1103                 // write channels
1104                 for (int c=0; c < m_header.channels; c++) {
1105                         const UINT32 size = m_width[c]*m_height[c];
1106 
1107                         // write channel data into stream
1108                         for (UINT32 i=0; i < size; i++) {
1109                                 int count = DataTSize;
1110                                 stream->Write(&count, &m_channel[c][i]);
1111                         }
1112                 }
1113 
1114                 // now update progress
1115                 if (cb) {
1116                         if ((*cb)(1, true, data)) ReturnWithError(EscapePressed);
1117                 }
1118 
1119         } else {
1120                 // encode quantized wavelet coefficients and write to PGF file
1121                 // encode subbands, higher levels first
1122                 // color channels are interleaved
1123 
1124                 // encode all levels
1125                 for (m_currentLevel = levels; m_currentLevel > 0; ) {
1126                         WriteLevel(); // decrements m_currentLevel
1127 
1128                         // now update progress
1129                         if (cb) {
1130                                 percent *= 4;
1131                                 if ((*cb)(percent, true, data)) ReturnWithError(EscapePressed);
1132                         }
1133                 }
1134 
1135                 // flush encoder and write level lengths
1136                 m_encoder->Flush();
1137         }
1138 
1139         // update level lengths
1140         nWrittenBytes += m_encoder->UpdateLevelLength(); // return written image bytes 
1141 
1142         // delete encoder
1143         delete m_encoder; m_encoder = NULL;
1144 
1145         ASSERT(!m_encoder);
1146 
1147         return nWrittenBytes;
1148 }

void CPGFImage::WriteLevel () [private]

Definition at line 1012 of file PGFimage.cpp.

1012                                   {
1013         ASSERT(m_encoder);
1014         ASSERT(m_currentLevel > 0);
1015         ASSERT(m_header.nLevels > 0);
1016 
1017 #ifdef __PGFROISUPPORT__
1018         if (ROIisSupported()) {
1019                 const int lastChannel = m_header.channels - 1;
1020 
1021                 for (int i=0; i < m_header.channels; i++) {
1022                         // get number of tiles and tile indices
1023                         const UINT32 nTiles = m_wtChannel[i]->GetNofTiles(m_currentLevel);
1024                         const UINT32 lastTile = nTiles - 1;
1025 
1026                         if (m_currentLevel == m_header.nLevels) {
1027                                 // last level also has LL band
1028                                 ASSERT(nTiles == 1);
1029                                 m_wtChannel[i]->GetSubband(m_currentLevel, LL)->ExtractTile(*m_encoder);
1030                                 m_encoder->EncodeTileBuffer();
1031                         }
1032                         for (UINT32 tileY=0; tileY < nTiles; tileY++) {
1033                                 for (UINT32 tileX=0; tileX < nTiles; tileX++) {
1034                                         m_wtChannel[i]->GetSubband(m_currentLevel, HL)->ExtractTile(*m_encoder, true, tileX, tileY);
1035                                         m_wtChannel[i]->GetSubband(m_currentLevel, LH)->ExtractTile(*m_encoder, true, tileX, tileY);
1036                                         m_wtChannel[i]->GetSubband(m_currentLevel, HH)->ExtractTile(*m_encoder, true, tileX, tileY);
1037                                         if (i == lastChannel && tileY == lastTile && tileX == lastTile) {
1038                                                 // all necessary data are buffered. next call of EncodeBuffer will write the last piece of data of the current level.
1039                                                 m_encoder->SetEncodedLevel(--m_currentLevel);
1040                                         }
1041                                         m_encoder->EncodeTileBuffer();
1042                                 }
1043                         }
1044                 }
1045         } else 
1046 #endif
1047         {
1048                 for (int i=0; i < m_header.channels; i++) {
1049                         ASSERT(m_wtChannel[i]);
1050                         if (m_currentLevel == m_header.nLevels) { 
1051                                 // last level also has LL band
1052                                 m_wtChannel[i]->GetSubband(m_currentLevel, LL)->ExtractTile(*m_encoder);
1053                         }
1054                         //encoder.EncodeInterleaved(m_wtChannel[i], m_currentLevel, m_quant); // until version 4
1055                         m_wtChannel[i]->GetSubband(m_currentLevel, HL)->ExtractTile(*m_encoder); // since version 5
1056                         m_wtChannel[i]->GetSubband(m_currentLevel, LH)->ExtractTile(*m_encoder); // since version 5
1057                         m_wtChannel[i]->GetSubband(m_currentLevel, HH)->ExtractTile(*m_encoder);
1058                 }
1059 
1060                 // all necessary data are buffered. next call of EncodeBuffer will write the last piece of data of the current level.
1061                 m_encoder->SetEncodedLevel(--m_currentLevel);
1062         }
1063 }

Member Data Documentation

RefreshCB CPGFImage::m_cb [private]

pointer to refresh callback procedure

Definition at line 535 of file PGFimage.h.

void* CPGFImage::m_cbArg [private]

refresh callback argument

Definition at line 536 of file PGFimage.h.

DataT* CPGFImage::m_channel[MaxChannels] [protected]

untransformed channels in YUV format

Definition at line 512 of file PGFimage.h.

int CPGFImage::m_currentLevel [protected]

transform level of current image

Definition at line 522 of file PGFimage.h.

CDecoder* CPGFImage::m_decoder [protected]

PGF decoder.

Definition at line 513 of file PGFimage.h.

bool CPGFImage::m_downsample [protected]

chrominance channels are downsampled

Definition at line 524 of file PGFimage.h.

CEncoder* CPGFImage::m_encoder [protected]

PGF encoder.

Definition at line 514 of file PGFimage.h.

bool CPGFImage::m_favorSpeedOverSize [protected]

favor encoding speed over compression ratio

Definition at line 525 of file PGFimage.h.

PGFHeader CPGFImage::m_header [protected]

PGF file header.

Definition at line 519 of file PGFimage.h.

UINT32 CPGFImage::m_height[MaxChannels] [protected]

height of each channel at current level

Definition at line 517 of file PGFimage.h.

UINT32* CPGFImage::m_levelLength [protected]

length of each level in bytes; first level starts immediately after this array

Definition at line 515 of file PGFimage.h.

double CPGFImage::m_percent [private]

progress [0..1]

Definition at line 537 of file PGFimage.h.

PGFPostHeader CPGFImage::m_postHeader [protected]

PGF post-header.

Definition at line 520 of file PGFimage.h.

PGFPreHeader CPGFImage::m_preHeader [protected]

PGF pre-header.

Definition at line 518 of file PGFimage.h.

ProgressMode CPGFImage::m_progressMode [private]

progress mode used in Read and Write; PM_Relative is default mode

Definition at line 538 of file PGFimage.h.

BYTE CPGFImage::m_quant [protected]

quantization parameter

Definition at line 523 of file PGFimage.h.

PGFRect CPGFImage::m_roi [protected]

region of interest

Definition at line 531 of file PGFimage.h.

bool CPGFImage::m_skipUserData [protected]

skip user data (metadata) during open

Definition at line 528 of file PGFimage.h.

bool CPGFImage::m_streamReinitialized [protected]

stream has been reinitialized

Definition at line 530 of file PGFimage.h.

bool CPGFImage::m_useOMPinDecoder [protected]

use Open MP in decoder

Definition at line 527 of file PGFimage.h.

bool CPGFImage::m_useOMPinEncoder [protected]

use Open MP in encoder

Definition at line 526 of file PGFimage.h.

UINT64 CPGFImage::m_userDataPos [protected]

stream position of user data

Definition at line 521 of file PGFimage.h.

UINT32 CPGFImage::m_width[MaxChannels] [protected]

width of each channel at current level

Definition at line 516 of file PGFimage.h.

CWaveletTransform* CPGFImage::m_wtChannel[MaxChannels] [protected]

wavelet transformed color channels

Definition at line 511 of file PGFimage.h.

Author

Generated automatically by Doxygen for libpgf from the source code.

Info

Thu Feb 4 2016 Version 6.14.12 libpgf