libpgf 6.14.12
PGF - Progressive Graphics File
CPGFImage Class Reference

PGF main class. More...

#include <PGFimage.h>

Public Member Functions

 CPGFImage ()
 Standard constructor: It is used to create a PGF instance for opening and reading. More...
 
virtual ~CPGFImage ()
 Destructor: Destroy internal data structures. More...
 
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. More...
 
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. More...
 
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_
 
DataTGetChannel (int c=0)
 
void GetColorTable (UINT32 iFirstColor, UINT32 nColors, RGBQUAD *prgbColors) const THROW_
 
const RGBQUAD * GetColorTable () const
 
const PGFHeaderGetHeader () 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. More...
 
static BYTE CurrentChannelDepth (BYTE version=PGFVersion)
 

Protected Attributes

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

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 More...
 
void * m_cbArg
 refresh callback argument More...
 
double m_percent
 progress [0..1] More...
 
ProgressMode m_progressMode
 progress mode used in Read and Write; PM_Relative is default mode More...
 

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::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)
60, m_quant(0)
62, m_downsample(false)
66, m_skipUserData(false)
67#ifdef __PGFROISUPPORT__
69#endif
70, m_cb(0)
71, m_cbArg(0)
73, m_percent(0)
74{
75
76 // init preHeader
77 memcpy(m_preHeader.magic, PGFMagic, 3);
80
81 // init postHeader
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}
@ PM_Relative
Definition: PGFimage.h:36
#define PGFMagic
PGF identification.
Definition: PGFtypes.h:55
#define MaxChannels
maximum number of (color) channels
Definition: PGFtypes.h:58
#define PGFVersion
current standard version
Definition: PGFtypes.h:69
bool m_useOMPinDecoder
use Open MP in decoder
Definition: PGFimage.h:527
CDecoder * m_decoder
PGF decoder.
Definition: PGFimage.h:513
bool m_useOMPinEncoder
use Open MP in encoder
Definition: PGFimage.h:526
UINT32 * m_levelLength
length of each level in bytes; first level starts immediately after this array
Definition: PGFimage.h:515
UINT32 m_height[MaxChannels]
height of each channel at current level
Definition: PGFimage.h:517
int m_currentLevel
transform level of current image
Definition: PGFimage.h:522
DataT * m_channel[MaxChannels]
untransformed channels in YUV format
Definition: PGFimage.h:512
void * m_cbArg
refresh callback argument
Definition: PGFimage.h:536
BYTE m_quant
quantization parameter
Definition: PGFimage.h:523
bool m_favorSpeedOverSize
favor encoding speed over compression ratio
Definition: PGFimage.h:525
CEncoder * m_encoder
PGF encoder.
Definition: PGFimage.h:514
ProgressMode m_progressMode
progress mode used in Read and Write; PM_Relative is default mode
Definition: PGFimage.h:538
bool m_downsample
chrominance channels are downsampled
Definition: PGFimage.h:524
UINT32 m_width[MaxChannels]
width of each channel at current level
Definition: PGFimage.h:516
PGFPostHeader m_postHeader
PGF post-header.
Definition: PGFimage.h:520
RefreshCB m_cb
pointer to refresh callback procedure
Definition: PGFimage.h:535
UINT64 m_userDataPos
stream position of user data
Definition: PGFimage.h:521
bool m_skipUserData
skip user data (metadata) during open
Definition: PGFimage.h:528
PGFPreHeader m_preHeader
PGF pre-header.
Definition: PGFimage.h:518
double m_percent
progress [0..1]
Definition: PGFimage.h:537
CWaveletTransform * m_wtChannel[MaxChannels]
wavelet transformed color channels
Definition: PGFimage.h:511
bool m_streamReinitialized
stream has been reinitialized
Definition: PGFimage.h:530
char magic[3]
PGF identification = "PGF".
Definition: PGFtypes.h:105
UINT8 version
PGF version.
Definition: PGFtypes.h:106
UINT32 userDataLen
user data size in bytes
Definition: PGFtypes.h:144
UINT8 * userData
user data of size userDataLen
Definition: PGFtypes.h:143
UINT32 hSize
total size of PGFHeader, [ColorTable], and [UserData] in bytes
Definition: PGFtypes.h:115

◆ ~CPGFImage()

CPGFImage::~CPGFImage ( )
virtual

Destructor: Destroy internal data structures.

Definition at line 98 of file PGFimage.cpp.

98 {
99 Destroy();
100}
virtual void Destroy()
Definition: PGFimage.cpp:105

Member Function Documentation

◆ BPP()

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; }
PGFHeader m_header
PGF file header.
Definition: PGFimage.h:519
UINT8 bpp
bits per pixel
Definition: PGFtypes.h:129

◆ ChannelDepth()

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.

static BYTE CurrentChannelDepth(BYTE version=PGFVersion)
Definition: PGFimage.h:508

◆ ChannelHeight()

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
cA 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]; }

◆ Channels()

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; }
UINT8 channels
number of channels
Definition: PGFtypes.h:130

◆ ChannelWidth()

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
cA 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]; }

◆ Clamp16()

UINT16 CPGFImage::Clamp16 ( DataT  v) const
inlineprivate

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 }

◆ Clamp31()

UINT32 CPGFImage::Clamp31 ( DataT  v) const
inlineprivate

Definition at line 564 of file PGFimage.h.

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

◆ Clamp4()

UINT8 CPGFImage::Clamp4 ( DataT  v) const
inlineprivate

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 }

◆ Clamp6()

UINT16 CPGFImage::Clamp6 ( DataT  v) const
inlineprivate

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 }

◆ Clamp8()

UINT8 CPGFImage::Clamp8 ( DataT  v) const
inlineprivate

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 }

◆ Close()

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}

◆ CompleteHeader()

bool CPGFImage::CompleteHeader ( )
private

Definition at line 208 of file PGFimage.cpp.

208 {
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;
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;
241 m_header.bpp = 24;
242 break;
243 case ImageModeRGBA:
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
263 }
264
265 if (m_header.mode == ImageModeBitmap && m_header.bpp != 1) return false;
266 if (m_header.mode == ImageModeIndexedColor && m_header.bpp != 8) return false;
267 if (m_header.mode == ImageModeGrayScale && m_header.bpp != 8) return false;
268 if (m_header.mode == ImageModeGray16 && m_header.bpp != 16) return false;
269 if (m_header.mode == ImageModeGray32 && m_header.bpp != 32) return false;
270 if (m_header.mode == ImageModeRGBColor && m_header.bpp != 24) return false;
271 if (m_header.mode == ImageModeRGBA && m_header.bpp != 32) return false;
272 if (m_header.mode == ImageModeRGB12 && m_header.bpp != 12) return false;
273 if (m_header.mode == ImageModeRGB16 && m_header.bpp != 16) return false;
274 if (m_header.mode == ImageModeRGB48 && m_header.bpp != 48) return false;
275 if (m_header.mode == ImageModeLabColor && m_header.bpp != 24) return false;
276 if (m_header.mode == ImageModeLab48 && m_header.bpp != 48) return false;
277 if (m_header.mode == ImageModeCMYKColor && m_header.bpp != 32) return false;
278 if (m_header.mode == ImageModeCMYK64 && m_header.bpp != 64) return false;
279
280 // set number of channels
281 if (!m_header.channels) {
282 switch(m_header.mode) {
283 case ImageModeBitmap:
286 case ImageModeGray16:
287 case ImageModeGray32:
288 m_header.channels = 1;
289 break;
291 case ImageModeRGB12:
292 case ImageModeRGB16:
293 case ImageModeRGB48:
295 case ImageModeLab48:
296 m_header.channels = 3;
297 break;
298 case ImageModeRGBA:
300 case ImageModeCMYK64:
301 m_header.channels = 4;
302 break;
303 default:
304 return false;
305 }
306 }
307
308 // store used bits per channel
309 UINT8 bpc = m_header.bpp/m_header.channels;
310 if (bpc > 31) bpc = 31;
313 }
314
315 return true;
316}
#define ImageModeRGBColor
Definition: PGFplatform.h:101
#define ImageModeRGB12
Definition: PGFplatform.h:117
#define ImageModeGray32
Definition: PGFplatform.h:116
#define ImageModeUnknown
Definition: PGFplatform.h:119
#define ImageModeBitmap
Definition: PGFplatform.h:98
#define ImageModeLabColor
Definition: PGFplatform.h:107
#define ImageModeRGB16
Definition: PGFplatform.h:118
#define ImageModeRGBA
Definition: PGFplatform.h:115
#define ImageModeRGB48
Definition: PGFplatform.h:109
#define ImageModeCMYK64
Definition: PGFplatform.h:111
#define ImageModeGrayScale
Definition: PGFplatform.h:99
#define ImageModeLab48
Definition: PGFplatform.h:110
#define ImageModeGray16
Definition: PGFplatform.h:108
#define ImageModeIndexedColor
Definition: PGFplatform.h:100
#define ImageModeCMYKColor
Definition: PGFplatform.h:102
UINT8 mode
image mode according to Adobe's image modes
Definition: PGFtypes.h:131
UINT8 usedBitsPerChannel
number of used bits per channel in 16- and 32-bit per channel modes
Definition: PGFtypes.h:132

◆ ComputeLevels()

void CPGFImage::ComputeLevels ( )
private

Definition at line 805 of file PGFimage.cpp.

805 {
806 const int maxThumbnailWidth = 20*FilterWidth;
807 const int m = __min(m_header.width, m_header.height);
808 int s = m;
809
811 m_header.nLevels = 1;
812 // compute a good value depending on the size of the image
813 while (s > maxThumbnailWidth) {
815 s = s/2;
816 }
817 }
818
819 int levels = m_header.nLevels; // we need a signed value during level reduction
820
821 // reduce number of levels if the image size is smaller than FilterWidth*2^levels
822 s = FilterWidth*(1 << levels); // must be at least the double filter size because of subsampling
823 while (m < s) {
824 levels--;
825 s = s/2;
826 }
827 if (levels > MaxLevel) m_header.nLevels = MaxLevel;
828 else if (levels < 0) m_header.nLevels = 0;
829 else m_header.nLevels = (UINT8)levels;
830
831 // used in Write when PM_Absolute
832 m_percent = pow(0.25, m_header.nLevels);
833
834 ASSERT(0 <= m_header.nLevels && m_header.nLevels <= MaxLevel);
835}
#define __min(x, y)
Definition: PGFplatform.h:91
#define MaxLevel
maximum number of transform levels
Definition: PGFtypes.h:56
#define FilterWidth
number of coefficients of the row wavelet filter
UINT32 height
image height in pixels
Definition: PGFtypes.h:126
UINT32 width
image width in pixels
Definition: PGFtypes.h:125
UINT8 nLevels
number of DWT levels
Definition: PGFtypes.h:127

◆ ConfigureDecoder()

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

Configures the decoder.

Parameters
useOMPUse parallel threading with Open MP during decoding. Default value: true. Influences the decoding only if the codec has been compiled with OpenMP support.
skipUserDataThe 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; }

◆ ConfigureEncoder()

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

Configures the encoder.

Parameters
useOMPUse parallel threading with Open MP during encoding. Default value: true. Influences the encoding only if the codec has been compiled with OpenMP support.
favorSpeedOverSizeFavors encoding speed over compression ratio. Default value: false

Definition at line 260 of file PGFimage.h.

260{ m_useOMPinEncoder = useOMP; m_favorSpeedOverSize = favorSpeedOverSize; }

◆ CurrentChannelDepth()

static BYTE CPGFImage::CurrentChannelDepth ( BYTE  version = PGFVersion)
inlinestatic

Compute and return codec version.

Returns
current PGF codec version

Definition at line 508 of file PGFimage.h.

508{ return (version & PGF32) ? 32 : 16; }
#define PGF32
32 bit values are used -> allows at maximum 31 bits, otherwise 16 bit values are used -> allows at ma...
Definition: PGFtypes.h:63

◆ CurrentVersion()

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

Return version.

Compute and return codec version.

Returns
current PGF codec version

Definition at line 721 of file PGFimage.cpp.

721 {
722 if (version & Version6) return 6;
723 if (version & Version5) return 5;
724 if (version & Version2) return 2;
725 return 1;
726}
#define Version5
new coding scheme since major version 5
Definition: PGFtypes.h:65
#define Version2
data structure PGFHeader of major version 2
Definition: PGFtypes.h:62
#define Version6
new HeaderSize: 32 bits instead of 16 bits
Definition: PGFtypes.h:66

◆ Destroy()

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 }
113 delete[] m_levelLength; m_levelLength = 0;
114 delete m_encoder; m_encoder = NULL;
115
116 m_userDataPos = 0;
117}
virtual void Close()
Definition: PGFimage.cpp:122

◆ Downsample()

void CPGFImage::Downsample ( int  nChannel)
private

Definition at line 761 of file PGFimage.cpp.

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

◆ GetBitmap()

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
pitchThe number of bytes of a row of the image buffer.
buffAn image buffer.
bppThe number of bits per pixel used in image buffer.
channelMapA integer array containing the mapping of PGF channel ordering to expected channel ordering.
cbA pointer to a callback procedure. The procedure is called after each copied buffer row. If cb returns true, then it stops proceeding.
dataData Pointer to C++ class container to host callback procedure.

Definition at line 1721 of file PGFimage.cpp.

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

◆ GetChannel()

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

Return an internal YUV image channel.

Parameters
cA 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]; }

◆ GetColorTable() [1/2]

const RGBQUAD * CPGFImage::GetColorTable ( ) const
inline
Returns
Address of color table

Definition at line 334 of file PGFimage.h.

334{ return m_postHeader.clut; }
RGBQUAD clut[ColorTableLen]
color table for indexed color images
Definition: PGFtypes.h:142

◆ GetColorTable() [2/2]

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
iFirstColorThe color table index of the first entry to retrieve.
nColorsThe number of color table entries to retrieve.
prgbColorsA pointer to the array of RGBQUAD structures to retrieve the color table entries.

Definition at line 1293 of file PGFimage.cpp.

1293 {
1294 if (iFirstColor + nColors > ColorTableLen) ReturnWithError(ColorTableError);
1295
1296 for (UINT32 i=iFirstColor, j=0; j < nColors; i++, j++) {
1297 prgbColors[j] = m_postHeader.clut[i];
1298 }
1299}
#define ColorTableLen
size of color lookup table (clut)
Definition: PGFtypes.h:60

◆ GetEncodedHeaderLength()

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 614 of file PGFimage.cpp.

614 {
615 ASSERT(m_decoder);
617}
UINT32 GetEncodedHeaderLength() const
Definition: Decoder.h:137

◆ GetEncodedLevelLength()

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
levelThe 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]; }

◆ GetHeader()

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; }

◆ GetMaxValue()

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; }

◆ GetUserData()

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 323 of file PGFimage.cpp.

323 {
325 return m_postHeader.userData;
326}

◆ GetUserDataPos()

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; }

◆ GetYUV()

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
pitchThe number of bytes of a row of the image buffer.
buffAn image buffer.
bppThe number of bits per pixel used in image buffer.
channelMapA integer array containing the mapping of PGF channel ordering to expected channel ordering.
cbA pointer to a callback procedure. The procedure is called after each copied buffer row. If cb returns true, then it stops proceeding.
dataData 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
pitchThe number of bytes of a row of the image buffer.
buffAn image buffer.
bppThe number of bits per pixel used in image buffer.
channelMapA integer array containing the mapping of PGF channel ordering to expected channel ordering.
cbA 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 2479 of file PGFimage.cpp.

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

◆ Height()

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
levelA 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); }

◆ ImportBitmap()

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
pitchThe number of bytes of a row of the image buffer.
buffAn image buffer.
bppThe number of bits per pixel used in image buffer.
channelMapA integer array containing the mapping of input channel ordering to expected channel ordering.
cbA pointer to a callback procedure. The procedure is called after each imported buffer row. If cb returns true, then it stops proceeding.
dataData Pointer to C++ class container to host callback procedure.

Definition at line 744 of file PGFimage.cpp.

744 {
745 ASSERT(buff);
746 ASSERT(m_channel[0]);
747
748 // color transform
749 RgbToYuv(pitch, buff, bpp, channelMap, cb, data);
750
751 if (m_downsample) {
752 // Subsampling of the chrominance and alpha channels
753 for (int i=1; i < m_header.channels; i++) {
754 Downsample(i);
755 }
756 }
757}
void RgbToYuv(int pitch, UINT8 *rgbBuff, BYTE bpp, int channelMap[], CallbackPtr cb, void *data) THROW_
Definition: PGFimage.cpp:1332
void Downsample(int nChannel)
Definition: PGFimage.cpp:761

◆ ImportIsSupported()

bool CPGFImage::ImportIsSupported ( BYTE  mode)
static

Check for valid import image mode.

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

Definition at line 1248 of file PGFimage.cpp.

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

◆ ImportYUV()

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
pitchThe number of bytes of a row of the image buffer.
buffAn image buffer.
bppThe number of bits per pixel used in image buffer.
channelMapA integer array containing the mapping of input channel ordering to expected channel ordering.
cbA pointer to a callback procedure. The procedure is called after each imported buffer row. If cb returns true, then it stops proceeding.
dataData 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
pitchThe number of bytes of a row of the image buffer.
buffAn image buffer.
bppThe number of bits per pixel used in image buffer.
channelMapA integer array containing the mapping of input channel ordering to expected channel ordering.
cbA 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 2590 of file PGFimage.cpp.

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

◆ IsOpen()

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; }

◆ Level()

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; }

◆ LevelHeight()

static UINT32 CPGFImage::LevelHeight ( UINT32  height,
int  level 
)
inlinestatic

Compute and return image height at given level.

Parameters
heightOriginal image height (at level 0)
levelAn 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; }

◆ Levels()

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; }

◆ LevelWidth()

static UINT32 CPGFImage::LevelWidth ( UINT32  width,
int  level 
)
inlinestatic

Compute and return image width at given level.

Parameters
widthOriginal image width (at level 0)
levelAn 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; }

◆ Mode()

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; }

◆ Open()

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
streamA PGF stream

Definition at line 131 of file PGFimage.cpp.

131 {
132 ASSERT(stream);
133
134 // create decoder and read PGFPreHeader PGFHeader PGFPostHeader LevelLengths
137
138 if (m_header.nLevels > MaxLevel) ReturnWithError(FormatCannotRead);
139
140 // set current level
142
143 // set image width and height
146
147 // complete header
148 if (!CompleteHeader()) ReturnWithError(FormatCannotRead);
149
150 // interpret quant parameter
159 m_downsample = true;
161 } else {
162 m_downsample = false;
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++) {
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}
#define DownsampleThreshold
if quality is larger than this threshold than downsampling is used
Definition: PGFtypes.h:59
PGF decoder.
Definition: Decoder.h:46
bool CompleteHeader()
Definition: PGFimage.cpp:208
virtual void Read(int *count, void *buffer)=0
PGF wavelet transform.
UINT8 quality
quantization parameter: 0=lossless, 4=standard, 6=poor quality
Definition: PGFtypes.h:128

◆ Quality()

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; }

◆ Read() [1/2]

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.
cbA pointer to a callback procedure. The procedure is called after reading a single level. If cb returns true, then it stops proceeding.
dataData Pointer to C++ class container to host callback procedure.

Definition at line 385 of file PGFimage.cpp.

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

◆ Read() [2/2]

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.
cbA pointer to a callback procedure. The procedure is called after reading a single level. If cb returns true, then it stops proceeding.
dataData Pointer to C++ class container to host callback procedure.

◆ ReadEncodedData()

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
levelThe image level
targetThe target buffer
targetLenThe length of the target buffer in bytes
Returns
The number of bytes copied to the target buffer

Definition at line 660 of file PGFimage.cpp.

660 {
661 ASSERT(level >= 0 && level < m_header.nLevels);
662 ASSERT(target);
663 ASSERT(targetLen > 0);
664 ASSERT(m_decoder);
665
666 // reset stream position
668
669 // position stream
670 UINT64 offset = 0;
671
672 for (int i=m_header.nLevels - 1; i > level; i--) {
673 offset += m_levelLength[m_header.nLevels - 1 - i];
674 }
675 m_decoder->Skip(offset);
676
677 // compute number of bytes to read
678 UINT32 len = __min(targetLen, GetEncodedLevelLength(level));
679
680 // read data
681 len = m_decoder->ReadEncodedData(target, len);
682 ASSERT(len >= 0 && len <= targetLen);
683
684 return len;
685}
void SetStreamPosToData() THROW_
Reset stream position to beginning of data block.
Definition: Decoder.h:145
UINT32 ReadEncodedData(UINT8 *target, UINT32 len) const THROW_
Definition: Decoder.cpp:232
void Skip(UINT64 offset) THROW_
Definition: Decoder.cpp:435
UINT32 GetEncodedLevelLength(int level) const
Definition: PGFimage.h:370

◆ ReadEncodedHeader()

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
targetThe target buffer
targetLenThe length of the target buffer in bytes
Returns
The number of bytes copied to the target buffer

Definition at line 626 of file PGFimage.cpp.

626 {
627 ASSERT(target);
628 ASSERT(targetLen > 0);
629 ASSERT(m_decoder);
630
631 // reset stream position
633
634 // compute number of bytes to read
635 UINT32 len = __min(targetLen, GetEncodedHeaderLength());
636
637 // read data
638 len = m_decoder->ReadEncodedData(target, len);
639 ASSERT(len >= 0 && len <= targetLen);
640
641 return len;
642}
void SetStreamPosToStart() THROW_
Reset stream position to beginning of PGF pre-header.
Definition: Decoder.h:141
UINT32 GetEncodedHeaderLength() const
Definition: PGFimage.cpp:614

◆ ReadPreview()

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); }
BYTE Levels() const
Definition: PGFimage.h:435

◆ Reconstruct()

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
levelThe image level of the resulting image in the internal image buffer.

Definition at line 333 of file PGFimage.cpp.

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

◆ ResetStreamPos()

void CPGFImage::ResetStreamPos ( )

Reset stream position to start of PGF pre-header.

Definition at line 646 of file PGFimage.cpp.

646 {
647 ASSERT(m_decoder);
649}

◆ RgbToYuv()

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

Definition at line 1332 of file PGFimage.cpp.

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

◆ ROIisSupported()

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; }
#define PGFROI
supports Regions Of Interest
Definition: PGFtypes.h:64

◆ SetChannel()

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

Set internal PGF image buffer channel.

Parameters
channelA YUV data channel
cA channel index

Definition at line 276 of file PGFimage.h.

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

◆ SetColorTable()

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
iFirstColorThe color table index of the first entry to set.
nColorsThe number of color table entries to set.
prgbColorsA pointer to the array of RGBQUAD structures to set the color table entries.

Definition at line 1307 of file PGFimage.cpp.

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

◆ SetHeader()

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
headerA valid and already filled in PGF header structure
flagsA combination of additional version flags. In case you use level-wise encoding then set flag = PGFROI.
userDataA user-defined memory block containing any kind of cached metadata.
userDataLengthThe size of user-defined memory block in bytes

Definition at line 845 of file PGFimage.cpp.

845 {
846 ASSERT(!m_decoder); // current image must be closed
847 ASSERT(header.quality <= MaxQuality);
848
849 // init state
850#ifdef __PGFROISUPPORT__
851 m_streamReinitialized = false;
852#endif
853
854 // init preHeader
855 memcpy(m_preHeader.magic, PGFMagic, 3);
858
859 // copy header
860 memcpy(&m_header, &header, HeaderSize);
861
862 // complete header
864
865 // check and set number of levels
867
868 // check for downsample
876 m_downsample = true;
878 } else {
879 m_downsample = false;
881 }
882
883 // update header size and copy user data
885 // update header size
887 }
888 if (userDataLength && userData) {
889 m_postHeader.userData = new(std::nothrow) UINT8[userDataLength];
890 if (!m_postHeader.userData) ReturnWithError(InsufficientMemory);
891 m_postHeader.userDataLen = userDataLength;
892 memcpy(m_postHeader.userData, userData, userDataLength);
893 // update header size
894 m_preHeader.hSize += userDataLength;
895 }
896
897 // allocate channels
898 for (int i=0; i < m_header.channels; i++) {
899 // set current width and height
902
903 // allocate channels
904 ASSERT(!m_channel[i]);
905 m_channel[i] = new(std::nothrow) DataT[m_header.width*m_header.height];
906 if (!m_channel[i]) {
907 if (i) i--;
908 while(i) {
909 delete[] m_channel[i]; m_channel[i] = 0;
910 i--;
911 }
912 ReturnWithError(InsufficientMemory);
913 }
914 }
915}
#define HeaderSize
Definition: PGFtypes.h:231
#define ColorTableSize
Definition: PGFtypes.h:232
#define MaxQuality
maximum quality
Definition: PGFtypes.h:87
void ComputeLevels()
Definition: PGFimage.cpp:805

◆ SetMaxValue()

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
maxValueThe maximum intensity value.

Definition at line 691 of file PGFimage.cpp.

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

◆ SetProgressMode()

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; }

◆ SetRefreshCallback()

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
callbackA refresh callback procedure
argA parameter of the refresh callback procedure

Definition at line 307 of file PGFimage.h.

307{ m_cb = callback; m_cbArg = arg; }

◆ SetROI()

void CPGFImage::SetROI ( PGFRect  rect)
private

◆ UpdatePostHeaderSize()

UINT32 CPGFImage::UpdatePostHeaderSize ( )
private

Definition at line 1068 of file PGFimage.cpp.

1068 {
1069 ASSERT(m_encoder);
1070
1071 INT64 offset = m_encoder->ComputeOffset(); ASSERT(offset >= 0);
1072
1073 if (offset > 0) {
1074 // update post-header size and rewrite pre-header
1075 m_preHeader.hSize += (UINT32)offset;
1077 }
1078
1079 // write dummy levelLength into stream
1081}
INT64 ComputeOffset() const
Definition: Encoder.h:184
UINT32 WriteLevelLength(UINT32 *&levelLength) THROW_
Definition: Encoder.cpp:177
void UpdatePostHeaderSize(PGFPreHeader preHeader) THROW_
Definition: Encoder.cpp:160

◆ UsedBitsPerChannel()

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 709 of file PGFimage.cpp.

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

◆ Version()

BYTE CPGFImage::Version ( ) const
inline

Returns images' PGF version

Returns
PGF codec version of the image

Definition at line 476 of file PGFimage.h.

static BYTE CurrentVersion(BYTE version=PGFVersion)
Return version.
Definition: PGFimage.cpp:721

◆ Width()

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
levelA 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); }

◆ Write() [1/2]

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
streamA PGF stream
nWrittenBytes[in-out] The number of bytes written into stream are added to the input value.
cbA pointer to a callback procedure. The procedure is called after writing a single level. If cb returns true, then it stops proceeding.
dataData Pointer to C++ class container to host callback procedure.

Definition at line 1164 of file PGFimage.cpp.

1164 {
1165 ASSERT(stream);
1166 ASSERT(m_preHeader.hSize);
1167
1168 // create wavelet transform channels and encoder
1169 UINT32 nBytes = WriteHeader(stream);
1170
1171 // write image
1172 nBytes += WriteImage(stream, cb, data);
1173
1174 // return written bytes
1175 if (nWrittenBytes) *nWrittenBytes += nBytes;
1176}
UINT32 WriteImage(CPGFStream *stream, CallbackPtr cb=NULL, void *data=NULL) THROW_
Definition: PGFimage.cpp:1093
UINT32 WriteHeader(CPGFStream *stream) THROW_
Definition: PGFimage.cpp:924

◆ Write() [2/2]

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.
cbA pointer to a callback procedure. The procedure is called after writing a single level. If cb returns true, then it stops proceeding.
dataData Pointer to C++ class container to host callback procedure.
Returns
The number of bytes written into stream.

◆ WriteHeader()

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
streamA PGF stream
Returns
The number of bytes written into stream.

Definition at line 924 of file PGFimage.cpp.

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

◆ WriteImage()

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
streamA PGF stream
cbA pointer to a callback procedure. The procedure is called after writing a single level. If cb returns true, then it stops proceeding.
dataData Pointer to C++ class container to host callback procedure.
Returns
The number of bytes written into stream.

Definition at line 1093 of file PGFimage.cpp.

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

◆ WriteLevel()

void CPGFImage::WriteLevel ( )
private

Definition at line 1013 of file PGFimage.cpp.

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

Member Data Documentation

◆ m_cb

RefreshCB CPGFImage::m_cb
private

pointer to refresh callback procedure

Definition at line 535 of file PGFimage.h.

◆ m_cbArg

void* CPGFImage::m_cbArg
private

refresh callback argument

Definition at line 536 of file PGFimage.h.

◆ m_channel

DataT* CPGFImage::m_channel[MaxChannels]
protected

untransformed channels in YUV format

Definition at line 512 of file PGFimage.h.

◆ m_currentLevel

int CPGFImage::m_currentLevel
protected

transform level of current image

Definition at line 522 of file PGFimage.h.

◆ m_decoder

CDecoder* CPGFImage::m_decoder
protected

PGF decoder.

Definition at line 513 of file PGFimage.h.

◆ m_downsample

bool CPGFImage::m_downsample
protected

chrominance channels are downsampled

Definition at line 524 of file PGFimage.h.

◆ m_encoder

CEncoder* CPGFImage::m_encoder
protected

PGF encoder.

Definition at line 514 of file PGFimage.h.

◆ m_favorSpeedOverSize

bool CPGFImage::m_favorSpeedOverSize
protected

favor encoding speed over compression ratio

Definition at line 525 of file PGFimage.h.

◆ m_header

PGFHeader CPGFImage::m_header
protected

PGF file header.

Definition at line 519 of file PGFimage.h.

◆ m_height

UINT32 CPGFImage::m_height[MaxChannels]
protected

height of each channel at current level

Definition at line 517 of file PGFimage.h.

◆ m_levelLength

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.

◆ m_percent

double CPGFImage::m_percent
private

progress [0..1]

Definition at line 537 of file PGFimage.h.

◆ m_postHeader

PGFPostHeader CPGFImage::m_postHeader
protected

PGF post-header.

Definition at line 520 of file PGFimage.h.

◆ m_preHeader

PGFPreHeader CPGFImage::m_preHeader
protected

PGF pre-header.

Definition at line 518 of file PGFimage.h.

◆ m_progressMode

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.

◆ m_quant

BYTE CPGFImage::m_quant
protected

quantization parameter

Definition at line 523 of file PGFimage.h.

◆ m_roi

PGFRect CPGFImage::m_roi
protected

region of interest

Definition at line 531 of file PGFimage.h.

◆ m_skipUserData

bool CPGFImage::m_skipUserData
protected

skip user data (metadata) during open

Definition at line 528 of file PGFimage.h.

◆ m_streamReinitialized

bool CPGFImage::m_streamReinitialized
protected

stream has been reinitialized

Definition at line 530 of file PGFimage.h.

◆ m_useOMPinDecoder

bool CPGFImage::m_useOMPinDecoder
protected

use Open MP in decoder

Definition at line 527 of file PGFimage.h.

◆ m_useOMPinEncoder

bool CPGFImage::m_useOMPinEncoder
protected

use Open MP in encoder

Definition at line 526 of file PGFimage.h.

◆ m_userDataPos

UINT64 CPGFImage::m_userDataPos
protected

stream position of user data

Definition at line 521 of file PGFimage.h.

◆ m_width

UINT32 CPGFImage::m_width[MaxChannels]
protected

width of each channel at current level

Definition at line 516 of file PGFimage.h.

◆ m_wtChannel

CWaveletTransform* CPGFImage::m_wtChannel[MaxChannels]
protected

wavelet transformed color channels

Definition at line 511 of file PGFimage.h.


The documentation for this class was generated from the following files: