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 if (m_header.mode == ImageModeBitmap && m_header.bpp != 1) return false;
265 if (m_header.mode == ImageModeIndexedColor && m_header.bpp != 8) return false;
266 if (m_header.mode == ImageModeGrayScale && m_header.bpp != 8) return false;
267 if (m_header.mode == ImageModeGray16 && m_header.bpp != 16) return false;
268 if (m_header.mode == ImageModeGray32 && m_header.bpp != 32) return false;
269 if (m_header.mode == ImageModeRGBColor && m_header.bpp != 24) return false;
270 if (m_header.mode == ImageModeRGBA && m_header.bpp != 32) return false;
271 if (m_header.mode == ImageModeRGB12 && m_header.bpp != 12) return false;
272 if (m_header.mode == ImageModeRGB16 && m_header.bpp != 16) return false;
273 if (m_header.mode == ImageModeRGB48 && m_header.bpp != 48) return false;
274 if (m_header.mode == ImageModeLabColor && m_header.bpp != 24) return false;
275 if (m_header.mode == ImageModeLab48 && m_header.bpp != 48) return false;
276 if (m_header.mode == ImageModeCMYKColor && m_header.bpp != 32) return false;
277 if (m_header.mode == ImageModeCMYK64 && m_header.bpp != 64) return false;
278
279 // set number of channels
280 if (!m_header.channels) {
281 switch(m_header.mode) {
282 case ImageModeBitmap:
285 case ImageModeGray16:
286 case ImageModeGray32:
287 m_header.channels = 1;
288 break;
290 case ImageModeRGB12:
291 case ImageModeRGB16:
292 case ImageModeRGB48:
294 case ImageModeLab48:
295 m_header.channels = 3;
296 break;
297 case ImageModeRGBA:
299 case ImageModeCMYK64:
300 m_header.channels = 4;
301 break;
302 default:
303 return false;
304 }
305 }
306
307 // store used bits per channel
308 UINT8 bpc = m_header.bpp/m_header.channels;
309 if (bpc > 31) bpc = 31;
312 }
313
314 return true;
315}
#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 804 of file PGFimage.cpp.

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

720 {
721 if (version & Version6) return 6;
722 if (version & Version5) return 5;
723 if (version & Version2) return 2;
724 return 1;
725}
#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 760 of file PGFimage.cpp.

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

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

1292 {
1293 if (iFirstColor + nColors > ColorTableLen) ReturnWithError(ColorTableError);
1294
1295 for (UINT32 i=iFirstColor, j=0; j < nColors; i++, j++) {
1296 prgbColors[j] = m_postHeader.clut[i];
1297 }
1298}
#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 613 of file PGFimage.cpp.

613 {
614 ASSERT(m_decoder);
616}
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 322 of file PGFimage.cpp.

322 {
324 return m_postHeader.userData;
325}

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

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

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

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

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

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

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

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

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

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

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

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

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

645 {
646 ASSERT(m_decoder);
648}

◆ RgbToYuv()

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

Definition at line 1331 of file PGFimage.cpp.

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

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

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

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

844 {
845 ASSERT(!m_decoder); // current image must be closed
846 ASSERT(header.quality <= MaxQuality);
847
848 // init state
849#ifdef __PGFROISUPPORT__
850 m_streamReinitialized = false;
851#endif
852
853 // init preHeader
854 memcpy(m_preHeader.magic, PGFMagic, 3);
857
858 // copy header
859 memcpy(&m_header, &header, HeaderSize);
860
861 // complete header
863
864 // check and set number of levels
866
867 // check for downsample
875 m_downsample = true;
877 } else {
878 m_downsample = false;
880 }
881
882 // update header size and copy user data
884 // update header size
886 }
887 if (userDataLength && userData) {
888 m_postHeader.userData = new(std::nothrow) UINT8[userDataLength];
889 if (!m_postHeader.userData) ReturnWithError(InsufficientMemory);
890 m_postHeader.userDataLen = userDataLength;
891 memcpy(m_postHeader.userData, userData, userDataLength);
892 // update header size
893 m_preHeader.hSize += userDataLength;
894 }
895
896 // allocate channels
897 for (int i=0; i < m_header.channels; i++) {
898 // set current width and height
901
902 // allocate channels
903 ASSERT(!m_channel[i]);
904 m_channel[i] = new(std::nothrow) DataT[m_header.width*m_header.height];
905 if (!m_channel[i]) {
906 if (i) i--;
907 while(i) {
908 delete[] m_channel[i]; m_channel[i] = 0;
909 i--;
910 }
911 ReturnWithError(InsufficientMemory);
912 }
913 }
914}
#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:804

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

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

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

1067 {
1068 ASSERT(m_encoder);
1069
1070 INT64 offset = m_encoder->ComputeOffset(); ASSERT(offset >= 0);
1071
1072 if (offset > 0) {
1073 // update post-header size and rewrite pre-header
1074 m_preHeader.hSize += (UINT32)offset;
1076 }
1077
1078 // write dummy levelLength into stream
1080}
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 708 of file PGFimage.cpp.

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

◆ 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:720

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

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

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

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

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

◆ WriteLevel()

void CPGFImage::WriteLevel ( )
private

Definition at line 1012 of file PGFimage.cpp.

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