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

◆ ~CPGFImage()

CPGFImage::~CPGFImage ( )
virtual

Destructor: Destroy internal data structures.

Definition at line 97 of file PGFimage.cpp.

97  {
98  Destroy();
99 }
virtual void Destroy()
Definition: PGFimage.cpp:104

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.

UINT8 version
PGF version.
Definition: PGFtypes.h:106
PGFPreHeader m_preHeader
PGF pre-header.
Definition: PGFimage.h:518
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]; }
#define MaxChannels
maximum number of (color) channels
Definition: PGFtypes.h:58
UINT32 m_height[MaxChannels]
height of each channel at current level
Definition: PGFimage.h:517

◆ 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; }
PGFHeader m_header
PGF file header.
Definition: PGFimage.h:519
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]; }
#define MaxChannels
maximum number of (color) channels
Definition: PGFtypes.h:58
UINT32 m_width[MaxChannels]
width of each channel at current level
Definition: PGFimage.h:516

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

121  {
122  delete m_decoder; m_decoder = 0;
123 }
CDecoder * m_decoder
PGF decoder.
Definition: PGFimage.h:513

◆ CompleteHeader()

bool CPGFImage::CompleteHeader ( )
private

Definition at line 207 of file PGFimage.cpp.

207  {
208  if (m_header.mode == ImageModeUnknown) {
209  // undefined mode
210  switch(m_header.bpp) {
211  case 1: m_header.mode = ImageModeBitmap; break;
212  case 8: m_header.mode = ImageModeGrayScale; break;
213  case 12: m_header.mode = ImageModeRGB12; break;
214  case 16: m_header.mode = ImageModeRGB16; break;
215  case 24: m_header.mode = ImageModeRGBColor; break;
216  case 32: m_header.mode = ImageModeRGBA; break;
217  case 48: m_header.mode = ImageModeRGB48; break;
218  default: m_header.mode = ImageModeRGBColor; break;
219  }
220  }
221  if (!m_header.bpp) {
222  // undefined bpp
223  switch(m_header.mode) {
224  case ImageModeBitmap:
225  m_header.bpp = 1;
226  break;
228  case ImageModeGrayScale:
229  m_header.bpp = 8;
230  break;
231  case ImageModeRGB12:
232  m_header.bpp = 12;
233  break;
234  case ImageModeRGB16:
235  case ImageModeGray16:
236  m_header.bpp = 16;
237  break;
238  case ImageModeRGBColor:
239  case ImageModeLabColor:
240  m_header.bpp = 24;
241  break;
242  case ImageModeRGBA:
243  case ImageModeCMYKColor:
244  case ImageModeGray32:
245  m_header.bpp = 32;
246  break;
247  case ImageModeRGB48:
248  case ImageModeLab48:
249  m_header.bpp = 48;
250  break;
251  case ImageModeCMYK64:
252  m_header.bpp = 64;
253  break;
254  default:
255  ASSERT(false);
256  m_header.bpp = 24;
257  }
258  }
259  if (m_header.mode == ImageModeRGBColor && m_header.bpp == 32) {
260  // change mode
262  }
263  if (m_header.mode == ImageModeBitmap && m_header.bpp != 1) return false;
264  if (m_header.mode == ImageModeIndexedColor && m_header.bpp != 8) return false;
265  if (m_header.mode == ImageModeGrayScale && m_header.bpp != 8) return false;
266  if (m_header.mode == ImageModeGray16 && m_header.bpp != 16) return false;
267  if (m_header.mode == ImageModeGray32 && m_header.bpp != 32) return false;
268  if (m_header.mode == ImageModeRGBColor && m_header.bpp != 24) return false;
269  if (m_header.mode == ImageModeRGBA && m_header.bpp != 32) return false;
270  if (m_header.mode == ImageModeRGB12 && m_header.bpp != 12) return false;
271  if (m_header.mode == ImageModeRGB16 && m_header.bpp != 16) return false;
272  if (m_header.mode == ImageModeRGB48 && m_header.bpp != 48) return false;
273  if (m_header.mode == ImageModeLabColor && m_header.bpp != 24) return false;
274  if (m_header.mode == ImageModeLab48 && m_header.bpp != 48) return false;
275  if (m_header.mode == ImageModeCMYKColor && m_header.bpp != 32) return false;
276  if (m_header.mode == ImageModeCMYK64 && m_header.bpp != 64) return false;
277 
278  // set number of channels
279  if (!m_header.channels) {
280  switch(m_header.mode) {
281  case ImageModeBitmap:
283  case ImageModeGrayScale:
284  case ImageModeGray16:
285  case ImageModeGray32:
286  m_header.channels = 1;
287  break;
288  case ImageModeRGBColor:
289  case ImageModeRGB12:
290  case ImageModeRGB16:
291  case ImageModeRGB48:
292  case ImageModeLabColor:
293  case ImageModeLab48:
294  m_header.channels = 3;
295  break;
296  case ImageModeRGBA:
297  case ImageModeCMYKColor:
298  case ImageModeCMYK64:
299  m_header.channels = 4;
300  break;
301  default:
302  return false;
303  }
304  }
305 
306  // store used bits per channel
307  UINT8 bpc = m_header.bpp/m_header.channels;
308  if (bpc > 31) bpc = 31;
311  }
312 
313  return true;
314 }
#define ImageModeIndexedColor
Definition: PGFplatform.h:100
#define ImageModeRGB12
Definition: PGFplatform.h:117
UINT8 mode
image mode according to Adobe&#39;s image modes
Definition: PGFtypes.h:131
#define ImageModeRGBA
Definition: PGFplatform.h:115
PGFHeader m_header
PGF file header.
Definition: PGFimage.h:519
#define ImageModeLabColor
Definition: PGFplatform.h:107
#define ImageModeGray16
Definition: PGFplatform.h:108
UINT8 usedBitsPerChannel
number of used bits per channel in 16- and 32-bit per channel modes
Definition: PGFtypes.h:132
#define ImageModeLab48
Definition: PGFplatform.h:110
#define ImageModeCMYKColor
Definition: PGFplatform.h:102
#define ImageModeGrayScale
Definition: PGFplatform.h:99
UINT8 bpp
bits per pixel
Definition: PGFtypes.h:129
#define ImageModeGray32
Definition: PGFplatform.h:116
#define ImageModeUnknown
Definition: PGFplatform.h:119
#define ImageModeRGBColor
Definition: PGFplatform.h:101
#define ImageModeBitmap
Definition: PGFplatform.h:98
UINT8 channels
number of channels
Definition: PGFtypes.h:130
#define ImageModeCMYK64
Definition: PGFplatform.h:111
#define ImageModeRGB16
Definition: PGFplatform.h:118
#define ImageModeRGB48
Definition: PGFplatform.h:109

◆ ComputeLevels()

void CPGFImage::ComputeLevels ( )
private

Definition at line 799 of file PGFimage.cpp.

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

◆ 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; }
bool m_useOMPinDecoder
use Open MP in decoder
Definition: PGFimage.h:527
bool m_skipUserData
skip user data (metadata) during open
Definition: PGFimage.h:528

◆ 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; }
bool m_favorSpeedOverSize
favor encoding speed over compression ratio
Definition: PGFimage.h:525
bool m_useOMPinEncoder
use Open MP in encoder
Definition: PGFimage.h:526

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

715  {
716  if (version & Version6) return 6;
717  if (version & Version5) return 5;
718  if (version & Version2) return 2;
719  return 1;
720 }
#define Version6
new HeaderSize: 32 bits instead of 16 bits
Definition: PGFtypes.h:66
#define Version2
data structure PGFHeader of major version 2
Definition: PGFtypes.h:62
#define Version5
new coding scheme since major version 5
Definition: PGFtypes.h:65

◆ Destroy()

void CPGFImage::Destroy ( )
virtual

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

Definition at line 104 of file PGFimage.cpp.

104  {
105  Close();
106 
107  for (int i=0; i < m_header.channels; i++) {
108  delete m_wtChannel[i]; m_wtChannel[i]=0; // also deletes m_channel
109  m_channel[i] = 0;
110  }
112  delete[] m_levelLength; m_levelLength = 0;
113  delete m_encoder; m_encoder = NULL;
114 
115  m_userDataPos = 0;
116 }
UINT64 m_userDataPos
stream position of user data
Definition: PGFimage.h:521
UINT32 userDataLen
user data size in bytes
Definition: PGFtypes.h:144
UINT8 * userData
user data of size userDataLen
Definition: PGFtypes.h:143
PGFHeader m_header
PGF file header.
Definition: PGFimage.h:519
DataT * m_channel[MaxChannels]
untransformed channels in YUV format
Definition: PGFimage.h:512
CWaveletTransform * m_wtChannel[MaxChannels]
wavelet transformed color channels
Definition: PGFimage.h:511
PGFPostHeader m_postHeader
PGF post-header.
Definition: PGFimage.h:520
UINT32 * m_levelLength
length of each level in bytes; first level starts immediately after this array
Definition: PGFimage.h:515
UINT8 channels
number of channels
Definition: PGFtypes.h:130
virtual void Close()
Definition: PGFimage.cpp:121
CEncoder * m_encoder
PGF encoder.
Definition: PGFimage.h:514

◆ Downsample()

void CPGFImage::Downsample ( int  nChannel)
private

Definition at line 755 of file PGFimage.cpp.

755  {
756  ASSERT(ch > 0);
757 
758  const int w = m_width[0];
759  const int w2 = w/2;
760  const int h2 = m_height[0]/2;
761  const int oddW = w%2; // don't use bool -> problems with MaxSpeed optimization
762  const int oddH = m_height[0]%2; // "
763  int loPos = 0;
764  int hiPos = w;
765  int sampledPos = 0;
766  DataT* buff = m_channel[ch]; ASSERT(buff);
767 
768  for (int i=0; i < h2; i++) {
769  for (int j=0; j < w2; j++) {
770  // compute average of pixel block
771  buff[sampledPos] = (buff[loPos] + buff[loPos + 1] + buff[hiPos] + buff[hiPos + 1]) >> 2;
772  loPos += 2; hiPos += 2;
773  sampledPos++;
774  }
775  if (oddW) {
776  buff[sampledPos] = (buff[loPos] + buff[hiPos]) >> 1;
777  loPos++; hiPos++;
778  sampledPos++;
779  }
780  loPos += w; hiPos += w;
781  }
782  if (oddH) {
783  for (int j=0; j < w2; j++) {
784  buff[sampledPos] = (buff[loPos] + buff[loPos+1]) >> 1;
785  loPos += 2; hiPos += 2;
786  sampledPos++;
787  }
788  if (oddW) {
789  buff[sampledPos] = buff[loPos];
790  }
791  }
792 
793  // downsampled image has half width and half height
794  m_width[ch] = (m_width[ch] + 1)/2;
795  m_height[ch] = (m_height[ch] + 1)/2;
796 }
INT32 DataT
Definition: PGFtypes.h:219
DataT * m_channel[MaxChannels]
untransformed channels in YUV format
Definition: PGFimage.h:512
UINT32 m_width[MaxChannels]
width of each channel at current level
Definition: PGFimage.h:516
UINT32 m_height[MaxChannels]
height of each channel at current level
Definition: PGFimage.h:517

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

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

◆ 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]; }
#define MaxChannels
maximum number of (color) channels
Definition: PGFtypes.h:58
DataT * m_channel[MaxChannels]
untransformed channels in YUV format
Definition: PGFimage.h:512

◆ GetColorTable() [1/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 1270 of file PGFimage.cpp.

1270  {
1271  if (iFirstColor + nColors > ColorTableLen) ReturnWithError(ColorTableError);
1272 
1273  for (UINT32 i=iFirstColor, j=0; j < nColors; i++, j++) {
1274  prgbColors[j] = m_postHeader.clut[i];
1275  }
1276 }
#define ColorTableLen
size of color lookup table (clut)
Definition: PGFtypes.h:60
PGFPostHeader m_postHeader
PGF post-header.
Definition: PGFimage.h:520
RGBQUAD clut[ColorTableLen]
color table for indexed color images
Definition: PGFtypes.h:142

◆ GetColorTable() [2/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; }
PGFPostHeader m_postHeader
PGF post-header.
Definition: PGFimage.h:520
RGBQUAD clut[ColorTableLen]
color table for indexed color images
Definition: PGFtypes.h:142

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

608  {
609  ASSERT(m_decoder);
611 }
CDecoder * m_decoder
PGF decoder.
Definition: PGFimage.h:513
UINT32 GetEncodedHeaderLength() const
Definition: Decoder.h:136

◆ 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]; }
PGFHeader m_header
PGF file header.
Definition: PGFimage.h:519
UINT8 nLevels
number of DWT levels
Definition: PGFtypes.h:127
UINT32 * m_levelLength
length of each level in bytes; first level starts immediately after this array
Definition: PGFimage.h:515

◆ 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; }
PGFHeader m_header
PGF file header.
Definition: PGFimage.h:519

◆ 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; }
PGFHeader m_header
PGF file header.
Definition: PGFimage.h:519
UINT8 usedBitsPerChannel
number of used bits per channel in 16- and 32-bit per channel modes
Definition: PGFtypes.h:132

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

321  {
322  size = m_postHeader.userDataLen;
323  return m_postHeader.userData;
324 }
UINT32 userDataLen
user data size in bytes
Definition: PGFtypes.h:144
UINT8 * userData
user data of size userDataLen
Definition: PGFtypes.h:143
PGFPostHeader m_postHeader
PGF post-header.
Definition: PGFimage.h:520

◆ 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; }
UINT64 m_userDataPos
stream position of user data
Definition: PGFimage.h:521

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

2456  {
2457  ASSERT(buff);
2458  const UINT32 w = m_width[0];
2459  const UINT32 h = m_height[0];
2460  const bool wOdd = (1 == w%2);
2461  const int dataBits = DataTSize*8; ASSERT(dataBits == 16 || dataBits == 32);
2462  const int pitch2 = pitch/DataTSize;
2463  const int yuvOffset = (dataBits == 16) ? YUVoffset8 : YUVoffset16;
2464  const double dP = 1.0/h;
2465 
2466  int defMap[] = { 0, 1, 2, 3, 4, 5, 6, 7 }; ASSERT(sizeof(defMap)/sizeof(defMap[0]) == MaxChannels);
2467  if (channelMap == NULL) channelMap = defMap;
2468  int sampledPos = 0, yPos = 0;
2469  DataT uAvg, vAvg;
2470  double percent = 0;
2471  UINT32 i, j;
2472 
2473  if (m_header.channels == 3) {
2474  ASSERT(bpp%dataBits == 0);
2475 
2476  DataT* y = m_channel[0]; ASSERT(y);
2477  DataT* u = m_channel[1]; ASSERT(u);
2478  DataT* v = m_channel[2]; ASSERT(v);
2479  int cnt, channels = bpp/dataBits; ASSERT(channels >= m_header.channels);
2480 
2481  for (i=0; i < h; i++) {
2482  if (i%2) sampledPos -= (w + 1)/2;
2483  cnt = 0;
2484  for (j=0; j < w; j++) {
2485  if (m_downsample) {
2486  // image was downsampled
2487  uAvg = u[sampledPos];
2488  vAvg = v[sampledPos];
2489  } else {
2490  uAvg = u[yPos];
2491  vAvg = v[yPos];
2492  }
2493  buff[cnt + channelMap[0]] = y[yPos];
2494  buff[cnt + channelMap[1]] = uAvg;
2495  buff[cnt + channelMap[2]] = vAvg;
2496  yPos++;
2497  cnt += channels;
2498  if (j%2) sampledPos++;
2499  }
2500  buff += pitch2;
2501  if (wOdd) sampledPos++;
2502 
2503  if (cb) {
2504  percent += dP;
2505  if ((*cb)(percent, true, data)) ReturnWithError(EscapePressed);
2506  }
2507  }
2508  } else if (m_header.channels == 4) {
2509  ASSERT(m_header.bpp == m_header.channels*8);
2510  ASSERT(bpp%dataBits == 0);
2511 
2512  DataT* y = m_channel[0]; ASSERT(y);
2513  DataT* u = m_channel[1]; ASSERT(u);
2514  DataT* v = m_channel[2]; ASSERT(v);
2515  DataT* a = m_channel[3]; ASSERT(a);
2516  UINT8 aAvg;
2517  int cnt, channels = bpp/dataBits; ASSERT(channels >= m_header.channels);
2518 
2519  for (i=0; i < h; i++) {
2520  if (i%2) sampledPos -= (w + 1)/2;
2521  cnt = 0;
2522  for (j=0; j < w; j++) {
2523  if (m_downsample) {
2524  // image was downsampled
2525  uAvg = u[sampledPos];
2526  vAvg = v[sampledPos];
2527  aAvg = Clamp8(a[sampledPos] + yuvOffset);
2528  } else {
2529  uAvg = u[yPos];
2530  vAvg = v[yPos];
2531  aAvg = Clamp8(a[yPos] + yuvOffset);
2532  }
2533  // Yuv
2534  buff[cnt + channelMap[0]] = y[yPos];
2535  buff[cnt + channelMap[1]] = uAvg;
2536  buff[cnt + channelMap[2]] = vAvg;
2537  buff[cnt + channelMap[3]] = aAvg;
2538  yPos++;
2539  cnt += channels;
2540  if (j%2) sampledPos++;
2541  }
2542  buff += pitch2;
2543  if (wOdd) sampledPos++;
2544 
2545  if (cb) {
2546  percent += dP;
2547  if ((*cb)(percent, true, data)) ReturnWithError(EscapePressed);
2548  }
2549  }
2550  }
2551 }
#define YUVoffset16
Definition: PGFimage.cpp:38
#define MaxChannels
maximum number of (color) channels
Definition: PGFtypes.h:58
INT32 DataT
Definition: PGFtypes.h:219
PGFHeader m_header
PGF file header.
Definition: PGFimage.h:519
#define DataTSize
Definition: PGFtypes.h:233
DataT * m_channel[MaxChannels]
untransformed channels in YUV format
Definition: PGFimage.h:512
UINT8 bpp
bits per pixel
Definition: PGFtypes.h:129
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
UINT8 Clamp8(DataT v) const
Definition: PGFimage.h:557
UINT8 channels
number of channels
Definition: PGFtypes.h:130
#define YUVoffset8
Definition: PGFimage.cpp:37
UINT32 m_height[MaxChannels]
height of each channel at current level
Definition: PGFimage.h:517

◆ 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); }
PGFHeader m_header
PGF file header.
Definition: PGFimage.h:519
UINT32 height
image height in pixels
Definition: PGFtypes.h:126
static UINT32 LevelHeight(UINT32 height, int level)
Definition: PGFimage.h:498

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

738  {
739  ASSERT(buff);
740  ASSERT(m_channel[0]);
741 
742  // color transform
743  RgbToYuv(pitch, buff, bpp, channelMap, cb, data);
744 
745  if (m_downsample) {
746  // Subsampling of the chrominance and alpha channels
747  for (int i=1; i < m_header.channels; i++) {
748  Downsample(i);
749  }
750  }
751 }
void RgbToYuv(int pitch, UINT8 *rgbBuff, BYTE bpp, int channelMap[], CallbackPtr cb, void *data) THROW_
Definition: PGFimage.cpp:1309
PGFHeader m_header
PGF file header.
Definition: PGFimage.h:519
DataT * m_channel[MaxChannels]
untransformed channels in YUV format
Definition: PGFimage.h:512
bool m_downsample
chrominance channels are downsampled
Definition: PGFimage.h:524
UINT8 channels
number of channels
Definition: PGFtypes.h:130
void Downsample(int nChannel)
Definition: PGFimage.cpp:755

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

1225  {
1226  size_t size = DataTSize;
1227 
1228  if (size >= 2) {
1229  switch(mode) {
1230  case ImageModeBitmap:
1231  case ImageModeIndexedColor:
1232  case ImageModeGrayScale:
1233  case ImageModeRGBColor:
1234  case ImageModeCMYKColor:
1235  case ImageModeHSLColor:
1236  case ImageModeHSBColor:
1237  //case ImageModeDuotone:
1238  case ImageModeLabColor:
1239  case ImageModeRGB12:
1240  case ImageModeRGB16:
1241  case ImageModeRGBA:
1242  return true;
1243  }
1244  }
1245  if (size >= 3) {
1246  switch(mode) {
1247  case ImageModeGray16:
1248  case ImageModeRGB48:
1249  case ImageModeLab48:
1250  case ImageModeCMYK64:
1251  //case ImageModeDuotone16:
1252  return true;
1253  }
1254  }
1255  if (size >=4) {
1256  switch(mode) {
1257  case ImageModeGray32:
1258  return true;
1259  }
1260  }
1261  return false;
1262 }
#define ImageModeIndexedColor
Definition: PGFplatform.h:100
#define ImageModeRGB12
Definition: PGFplatform.h:117
#define ImageModeHSBColor
Definition: PGFplatform.h:104
#define ImageModeRGBA
Definition: PGFplatform.h:115
#define DataTSize
Definition: PGFtypes.h:233
#define ImageModeLabColor
Definition: PGFplatform.h:107
#define ImageModeGray16
Definition: PGFplatform.h:108
#define ImageModeLab48
Definition: PGFplatform.h:110
#define ImageModeCMYKColor
Definition: PGFplatform.h:102
#define ImageModeGrayScale
Definition: PGFplatform.h:99
#define ImageModeGray32
Definition: PGFplatform.h:116
#define ImageModeRGBColor
Definition: PGFplatform.h:101
#define ImageModeHSLColor
Definition: PGFplatform.h:103
#define ImageModeBitmap
Definition: PGFplatform.h:98
#define ImageModeCMYK64
Definition: PGFplatform.h:111
#define ImageModeRGB16
Definition: PGFplatform.h:118
#define ImageModeRGB48
Definition: PGFplatform.h:109

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

2567  {
2568  ASSERT(buff);
2569  const double dP = 1.0/m_header.height;
2570  const int dataBits = DataTSize*8; ASSERT(dataBits == 16 || dataBits == 32);
2571  const int pitch2 = pitch/DataTSize;
2572  const int yuvOffset = (dataBits == 16) ? YUVoffset8 : YUVoffset16;
2573 
2574  int yPos = 0, cnt = 0;
2575  double percent = 0;
2576  int defMap[] = { 0, 1, 2, 3, 4, 5, 6, 7 }; ASSERT(sizeof(defMap)/sizeof(defMap[0]) == MaxChannels);
2577 
2578  if (channelMap == NULL) channelMap = defMap;
2579 
2580  if (m_header.channels == 3) {
2581  ASSERT(bpp%dataBits == 0);
2582 
2583  DataT* y = m_channel[0]; ASSERT(y);
2584  DataT* u = m_channel[1]; ASSERT(u);
2585  DataT* v = m_channel[2]; ASSERT(v);
2586  const int channels = bpp/dataBits; ASSERT(channels >= m_header.channels);
2587 
2588  for (UINT32 h=0; h < m_header.height; h++) {
2589  if (cb) {
2590  if ((*cb)(percent, true, data)) ReturnWithError(EscapePressed);
2591  percent += dP;
2592  }
2593 
2594  cnt = 0;
2595  for (UINT32 w=0; w < m_header.width; w++) {
2596  y[yPos] = buff[cnt + channelMap[0]];
2597  u[yPos] = buff[cnt + channelMap[1]];
2598  v[yPos] = buff[cnt + channelMap[2]];
2599  yPos++;
2600  cnt += channels;
2601  }
2602  buff += pitch2;
2603  }
2604  } else if (m_header.channels == 4) {
2605  ASSERT(bpp%dataBits == 0);
2606 
2607  DataT* y = m_channel[0]; ASSERT(y);
2608  DataT* u = m_channel[1]; ASSERT(u);
2609  DataT* v = m_channel[2]; ASSERT(v);
2610  DataT* a = m_channel[3]; ASSERT(a);
2611  const int channels = bpp/dataBits; ASSERT(channels >= m_header.channels);
2612 
2613  for (UINT32 h=0; h < m_header.height; h++) {
2614  if (cb) {
2615  if ((*cb)(percent, true, data)) ReturnWithError(EscapePressed);
2616  percent += dP;
2617  }
2618 
2619  cnt = 0;
2620  for (UINT32 w=0; w < m_header.width; w++) {
2621  y[yPos] = buff[cnt + channelMap[0]];
2622  u[yPos] = buff[cnt + channelMap[1]];
2623  v[yPos] = buff[cnt + channelMap[2]];
2624  a[yPos] = buff[cnt + channelMap[3]] - yuvOffset;
2625  yPos++;
2626  cnt += channels;
2627  }
2628  buff += pitch2;
2629  }
2630  }
2631 
2632  if (m_downsample) {
2633  // Subsampling of the chrominance and alpha channels
2634  for (int i=1; i < m_header.channels; i++) {
2635  Downsample(i);
2636  }
2637  }
2638 }
#define YUVoffset16
Definition: PGFimage.cpp:38
#define MaxChannels
maximum number of (color) channels
Definition: PGFtypes.h:58
UINT32 width
image width in pixels
Definition: PGFtypes.h:125
INT32 DataT
Definition: PGFtypes.h:219
PGFHeader m_header
PGF file header.
Definition: PGFimage.h:519
#define DataTSize
Definition: PGFtypes.h:233
DataT * m_channel[MaxChannels]
untransformed channels in YUV format
Definition: PGFimage.h:512
bool m_downsample
chrominance channels are downsampled
Definition: PGFimage.h:524
UINT8 channels
number of channels
Definition: PGFtypes.h:130
void Downsample(int nChannel)
Definition: PGFimage.cpp:755
#define YUVoffset8
Definition: PGFimage.cpp:37
UINT32 height
image height in pixels
Definition: PGFtypes.h:126

◆ 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; }
CDecoder * m_decoder
PGF decoder.
Definition: PGFimage.h:513

◆ 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; }
int m_currentLevel
transform level of current image
Definition: PGFimage.h:522

◆ 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; }
PGFHeader m_header
PGF file header.
Definition: PGFimage.h:519
UINT8 nLevels
number of DWT levels
Definition: PGFtypes.h:127

◆ 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; }
UINT8 mode
image mode according to Adobe&#39;s image modes
Definition: PGFtypes.h:131
PGFHeader m_header
PGF file header.
Definition: PGFimage.h:519

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

130  {
131  ASSERT(stream);
132 
133  // create decoder and read PGFPreHeader PGFHeader PGFPostHeader LevelLengths
136 
137  if (m_header.nLevels > MaxLevel) ReturnWithError(FormatCannotRead);
138 
139  // set current level
141 
142  // set image width and height
143  m_width[0] = m_header.width;
144  m_height[0] = m_header.height;
145 
146  // complete header
147  if (!CompleteHeader()) ReturnWithError(FormatCannotRead);
148 
149  // interpret quant parameter
158  m_downsample = true;
159  m_quant = m_header.quality - 1;
160  } else {
161  m_downsample = false;
163  }
164 
165  // set channel dimensions (chrominance is subsampled by factor 2)
166  if (m_downsample) {
167  for (int i=1; i < m_header.channels; i++) {
168  m_width[i] = (m_width[0] + 1)/2;
169  m_height[i] = (m_height[0] + 1)/2;
170  }
171  } else {
172  for (int i=1; i < m_header.channels; i++) {
173  m_width[i] = m_width[0];
174  m_height[i] = m_height[0];
175  }
176  }
177 
178  if (m_header.nLevels > 0) {
179  // init wavelet subbands
180  for (int i=0; i < m_header.channels; i++) {
182  }
183 
184  // used in Read when PM_Absolute
185  m_percent = pow(0.25, m_header.nLevels);
186 
187  } else {
188  // very small image: we don't use DWT and encoding
189 
190  // read channels
191  for (int c=0; c < m_header.channels; c++) {
192  const UINT32 size = m_width[c]*m_height[c];
193  m_channel[c] = new(std::nothrow) DataT[size];
194  if (!m_channel[c]) ReturnWithError(InsufficientMemory);
195 
196  // read channel data from stream
197  for (UINT32 i=0; i < size; i++) {
198  int count = DataTSize;
199  stream->Read(&count, &m_channel[c][i]);
200  if (count != DataTSize) ReturnWithError(MissingData);
201  }
202  }
203  }
204 }
virtual void Read(int *count, void *buffer)=0
UINT64 m_userDataPos
stream position of user data
Definition: PGFimage.h:521
bool m_useOMPinDecoder
use Open MP in decoder
Definition: PGFimage.h:527
UINT8 mode
image mode according to Adobe&#39;s image modes
Definition: PGFtypes.h:131
UINT32 width
image width in pixels
Definition: PGFtypes.h:125
bool m_skipUserData
skip user data (metadata) during open
Definition: PGFimage.h:528
INT32 DataT
Definition: PGFtypes.h:219
#define ImageModeRGBA
Definition: PGFplatform.h:115
CDecoder * m_decoder
PGF decoder.
Definition: PGFimage.h:513
PGFHeader m_header
PGF file header.
Definition: PGFimage.h:519
bool CompleteHeader()
Definition: PGFimage.cpp:207
BYTE m_quant
quantization parameter
Definition: PGFimage.h:523
#define DataTSize
Definition: PGFtypes.h:233
#define ImageModeLabColor
Definition: PGFplatform.h:107
DataT * m_channel[MaxChannels]
untransformed channels in YUV format
Definition: PGFimage.h:512
PGFPreHeader m_preHeader
PGF pre-header.
Definition: PGFimage.h:518
UINT8 nLevels
number of DWT levels
Definition: PGFtypes.h:127
#define ImageModeLab48
Definition: PGFplatform.h:110
#define ImageModeCMYKColor
Definition: PGFplatform.h:102
#define MaxLevel
maximum number of transform levels
Definition: PGFtypes.h:56
CWaveletTransform * m_wtChannel[MaxChannels]
wavelet transformed color channels
Definition: PGFimage.h:511
PGFPostHeader m_postHeader
PGF post-header.
Definition: PGFimage.h:520
bool m_downsample
chrominance channels are downsampled
Definition: PGFimage.h:524
PGF decoder.
Definition: Decoder.h:46
#define DownsampleThreshold
if quality is larger than this threshold than downsampling is used
Definition: PGFtypes.h:59
friend class CWaveletTransform
Definition: Subband.h:43
UINT32 * m_levelLength
length of each level in bytes; first level starts immediately after this array
Definition: PGFimage.h:515
UINT32 m_width[MaxChannels]
width of each channel at current level
Definition: PGFimage.h:516
#define ImageModeRGBColor
Definition: PGFplatform.h:101
double m_percent
progress [0..1]
Definition: PGFimage.h:537
UINT8 channels
number of channels
Definition: PGFtypes.h:130
#define ImageModeCMYK64
Definition: PGFplatform.h:111
int m_currentLevel
transform level of current image
Definition: PGFimage.h:522
UINT8 quality
quantization parameter: 0=lossless, 4=standard, 6=poor quality
Definition: PGFtypes.h:128
UINT32 height
image height in pixels
Definition: PGFtypes.h:126
#define ImageModeRGB48
Definition: PGFplatform.h:109
UINT32 m_height[MaxChannels]
height of each channel at current level
Definition: PGFimage.h:517

◆ 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; }
PGFHeader m_header
PGF file header.
Definition: PGFimage.h:519
UINT8 quality
quantization parameter: 0=lossless, 4=standard, 6=poor quality
Definition: PGFtypes.h:128

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

383  {
384  ASSERT((level >= 0 && level < m_header.nLevels) || m_header.nLevels == 0); // m_header.nLevels == 0: image didn't use wavelet transform
385  ASSERT(m_decoder);
386 
387 #ifdef __PGFROISUPPORT__
388  if (ROIisSupported() && m_header.nLevels > 0) {
389  // new encoding scheme supporting ROI
390  PGFRect rect(0, 0, m_header.width, m_header.height);
391  Read(rect, level, cb, data);
392  return;
393  }
394 #endif
395 
396  if (m_header.nLevels == 0) {
397  if (level == 0) {
398  // the data has already been read during open
399  // now update progress
400  if (cb) {
401  if ((*cb)(1.0, true, data)) ReturnWithError(EscapePressed);
402  }
403  }
404  } else {
405  const int levelDiff = m_currentLevel - level;
406  double percent = (m_progressMode == PM_Relative) ? pow(0.25, levelDiff) : m_percent;
407 
408  // encoding scheme without ROI
409  while (m_currentLevel > level) {
410  for (int i=0; i < m_header.channels; i++) {
411  ASSERT(m_wtChannel[i]);
412  // decode file and write stream to m_wtChannel
413  if (m_currentLevel == m_header.nLevels) {
414  // last level also has LL band
416  }
417  if (m_preHeader.version & Version5) {
418  // since version 5
421  } else {
422  // until version 4
424  }
426  }
427 
428  volatile OSError error = NoError; // volatile prevents optimizations
429  #pragma omp parallel for default(shared)
430  for (int i=0; i < m_header.channels; i++) {
431  // inverse transform from m_wtChannel to m_channel
432  if (error == NoError) {
433  OSError err = m_wtChannel[i]->InverseTransform(m_currentLevel, &m_width[i], &m_height[i], &m_channel[i]);
434  if (err != NoError) error = err;
435  }
436  ASSERT(m_channel[i]);
437  }
438  if (error != NoError) ReturnWithError(error);
439 
440  // set new level: must be done before refresh callback
441  m_currentLevel--;
442 
443  // now we have to refresh the display
444  if (m_cb) m_cb(m_cbArg);
445 
446  // now update progress
447  if (cb) {
448  percent *= 4;
449  if (m_progressMode == PM_Absolute) m_percent = percent;
450  if ((*cb)(percent, true, data)) ReturnWithError(EscapePressed);
451  }
452  }
453  }
454 
455  // automatically closing
456  if (m_currentLevel == 0) Close();
457 }
OSError InverseTransform(int level, UINT32 *width, UINT32 *height, DataT **data)
UINT8 version
PGF version.
Definition: PGFtypes.h:106
Definition: PGFtypes.h:92
void DecodeInterleaved(CWaveletTransform *wtChannel, int level, int quantParam) THROW_
Definition: Decoder.cpp:319
UINT32 width
image width in pixels
Definition: PGFtypes.h:125
CDecoder * m_decoder
PGF decoder.
Definition: PGFimage.h:513
PGFHeader m_header
PGF file header.
Definition: PGFimage.h:519
BYTE m_quant
quantization parameter
Definition: PGFimage.h:523
void * m_cbArg
refresh callback argument
Definition: PGFimage.h:536
DataT * m_channel[MaxChannels]
untransformed channels in YUV format
Definition: PGFimage.h:512
PGFPreHeader m_preHeader
PGF pre-header.
Definition: PGFimage.h:518
UINT8 nLevels
number of DWT levels
Definition: PGFtypes.h:127
ProgressMode m_progressMode
progress mode used in Read and Write; PM_Relative is default mode
Definition: PGFimage.h:538
CWaveletTransform * m_wtChannel[MaxChannels]
wavelet transformed color channels
Definition: PGFimage.h:511
void Read(int level=0, CallbackPtr cb=NULL, void *data=NULL) THROW_
Definition: PGFimage.cpp:383
Definition: PGFtypes.h:92
UINT32 m_width[MaxChannels]
width of each channel at current level
Definition: PGFimage.h:516
Definition: PGFtypes.h:92
CSubband * GetSubband(int level, Orientation orientation)
bool ROIisSupported() const
Definition: PGFimage.h:465
Definition: PGFtypes.h:92
double m_percent
progress [0..1]
Definition: PGFimage.h:537
UINT8 channels
number of channels
Definition: PGFtypes.h:130
virtual void Close()
Definition: PGFimage.cpp:121
Rectangle.
Definition: PGFtypes.h:194
RefreshCB m_cb
pointer to refresh callback procedure
Definition: PGFimage.h:535
void PlaceTile(CDecoder &decoder, int quantParam, bool tile=false, UINT32 tileX=0, UINT32 tileY=0) THROW_
Definition: Subband.cpp:197
int m_currentLevel
transform level of current image
Definition: PGFimage.h:522
UINT32 height
image height in pixels
Definition: PGFtypes.h:126
#define Version5
new coding scheme since major version 5
Definition: PGFtypes.h:65
UINT32 m_height[MaxChannels]
height of each channel at current level
Definition: PGFimage.h:517

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

654  {
655  ASSERT(level >= 0 && level < m_header.nLevels);
656  ASSERT(target);
657  ASSERT(targetLen > 0);
658  ASSERT(m_decoder);
659 
660  // reset stream position
662 
663  // position stream
664  UINT64 offset = 0;
665 
666  for (int i=m_header.nLevels - 1; i > level; i--) {
667  offset += m_levelLength[m_header.nLevels - 1 - i];
668  }
669  m_decoder->Skip(offset);
670 
671  // compute number of bytes to read
672  UINT32 len = __min(targetLen, GetEncodedLevelLength(level));
673 
674  // read data
675  len = m_decoder->ReadEncodedData(target, len);
676  ASSERT(len >= 0 && len <= targetLen);
677 
678  return len;
679 }
UINT32 ReadEncodedData(UINT8 *target, UINT32 len) const THROW_
Definition: Decoder.cpp:232
CDecoder * m_decoder
PGF decoder.
Definition: PGFimage.h:513
UINT32 GetEncodedLevelLength(int level) const
Definition: PGFimage.h:370
PGFHeader m_header
PGF file header.
Definition: PGFimage.h:519
UINT8 nLevels
number of DWT levels
Definition: PGFtypes.h:127
void SetStreamPosToData() THROW_
Reset stream position to beginning of data block.
Definition: Decoder.h:144
UINT32 * m_levelLength
length of each level in bytes; first level starts immediately after this array
Definition: PGFimage.h:515
#define __min(x, y)
Definition: PGFplatform.h:91
void Skip(UINT64 offset) THROW_
Definition: Decoder.cpp:435

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

620  {
621  ASSERT(target);
622  ASSERT(targetLen > 0);
623  ASSERT(m_decoder);
624 
625  // reset stream position
627 
628  // compute number of bytes to read
629  UINT32 len = __min(targetLen, GetEncodedHeaderLength());
630 
631  // read data
632  len = m_decoder->ReadEncodedData(target, len);
633  ASSERT(len >= 0 && len <= targetLen);
634 
635  return len;
636 }
UINT32 ReadEncodedData(UINT8 *target, UINT32 len) const THROW_
Definition: Decoder.cpp:232
CDecoder * m_decoder
PGF decoder.
Definition: PGFimage.h:513
#define __min(x, y)
Definition: PGFplatform.h:91
UINT32 GetEncodedHeaderLength() const
Definition: PGFimage.cpp:608
void SetStreamPosToStart() THROW_
Reset stream position to beginning of PGF pre-header.
Definition: Decoder.h:140

◆ 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); }
void Read(int level=0, CallbackPtr cb=NULL, void *data=NULL) THROW_
Definition: PGFimage.cpp:383
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 331 of file PGFimage.cpp.

331  {
332  if (m_header.nLevels == 0) {
333  // image didn't use wavelet transform
334  if (level == 0) {
335  for (int i=0; i < m_header.channels; i++) {
336  ASSERT(m_wtChannel[i]);
337  m_channel[i] = m_wtChannel[i]->GetSubband(0, LL)->GetBuffer();
338  }
339  }
340  } else {
341  int currentLevel = m_header.nLevels;
342 
343  if (ROIisSupported()) {
344  // enable ROI reading
346  }
347 
348  while (currentLevel > level) {
349  for (int i=0; i < m_header.channels; i++) {
350  ASSERT(m_wtChannel[i]);
351  // dequantize subbands
352  if (currentLevel == m_header.nLevels) {
353  // last level also has LL band
354  m_wtChannel[i]->GetSubband(currentLevel, LL)->Dequantize(m_quant);
355  }
356  m_wtChannel[i]->GetSubband(currentLevel, HL)->Dequantize(m_quant);
357  m_wtChannel[i]->GetSubband(currentLevel, LH)->Dequantize(m_quant);
358  m_wtChannel[i]->GetSubband(currentLevel, HH)->Dequantize(m_quant);
359 
360  // inverse transform from m_wtChannel to m_channel
361  OSError err = m_wtChannel[i]->InverseTransform(currentLevel, &m_width[i], &m_height[i], &m_channel[i]);
362  if (err != NoError) ReturnWithError(err);
363  ASSERT(m_channel[i]);
364  }
365 
366  currentLevel--;
367  }
368  }
369 }
OSError InverseTransform(int level, UINT32 *width, UINT32 *height, DataT **data)
Definition: PGFtypes.h:92
void Dequantize(int quantParam)
Definition: Subband.cpp:149
DataT * GetBuffer()
Definition: Subband.h:106
UINT32 width
image width in pixels
Definition: PGFtypes.h:125
PGFHeader m_header
PGF file header.
Definition: PGFimage.h:519
BYTE m_quant
quantization parameter
Definition: PGFimage.h:523
DataT * m_channel[MaxChannels]
untransformed channels in YUV format
Definition: PGFimage.h:512
UINT8 nLevels
number of DWT levels
Definition: PGFtypes.h:127
void SetROI(PGFRect rect)
CWaveletTransform * m_wtChannel[MaxChannels]
wavelet transformed color channels
Definition: PGFimage.h:511
Definition: PGFtypes.h:92
UINT32 m_width[MaxChannels]
width of each channel at current level
Definition: PGFimage.h:516
Definition: PGFtypes.h:92
CSubband * GetSubband(int level, Orientation orientation)
bool ROIisSupported() const
Definition: PGFimage.h:465
Definition: PGFtypes.h:92
UINT8 channels
number of channels
Definition: PGFtypes.h:130
Rectangle.
Definition: PGFtypes.h:194
UINT32 height
image height in pixels
Definition: PGFtypes.h:126
UINT32 m_height[MaxChannels]
height of each channel at current level
Definition: PGFimage.h:517

◆ ResetStreamPos()

void CPGFImage::ResetStreamPos ( )

Reset stream position to start of PGF pre-header.

Definition at line 640 of file PGFimage.cpp.

640  {
641  ASSERT(m_decoder);
642  return m_decoder->SetStreamPosToStart();
643 }
CDecoder * m_decoder
PGF decoder.
Definition: PGFimage.h:513
void SetStreamPosToStart() THROW_
Reset stream position to beginning of PGF pre-header.
Definition: Decoder.h:140

◆ RgbToYuv()

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

Definition at line 1309 of file PGFimage.cpp.

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

◆ 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; }
UINT8 version
PGF version.
Definition: PGFtypes.h:106
PGFPreHeader m_preHeader
PGF pre-header.
Definition: PGFimage.h:518
#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; }
#define MaxChannels
maximum number of (color) channels
Definition: PGFtypes.h:58
DataT * m_channel[MaxChannels]
untransformed channels in YUV format
Definition: PGFimage.h:512

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

1284  {
1285  if (iFirstColor + nColors > ColorTableLen) ReturnWithError(ColorTableError);
1286 
1287  for (UINT32 i=iFirstColor, j=0; j < nColors; i++, j++) {
1288  m_postHeader.clut[i] = prgbColors[j];
1289  }
1290 }
#define ColorTableLen
size of color lookup table (clut)
Definition: PGFtypes.h:60
PGFPostHeader m_postHeader
PGF post-header.
Definition: PGFimage.h:520
RGBQUAD clut[ColorTableLen]
color table for indexed color images
Definition: PGFtypes.h:142

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

839  {
840  ASSERT(!m_decoder); // current image must be closed
841  ASSERT(header.quality <= MaxQuality);
842 
843  // init state
844 #ifdef __PGFROISUPPORT__
845  m_streamReinitialized = false;
846 #endif
847 
848  // init preHeader
849  memcpy(m_preHeader.magic, Magic, 3);
850  m_preHeader.version = PGFVersion | flags;
852 
853  // copy header
854  memcpy(&m_header, &header, HeaderSize);
855 
856  // complete header
857  CompleteHeader();
858 
859  // check and set number of levels
860  ComputeLevels();
861 
862  // check for downsample
870  m_downsample = true;
871  m_quant = m_header.quality - 1;
872  } else {
873  m_downsample = false;
875  }
876 
877  // update header size and copy user data
879  // update header size
881  }
882  if (userDataLength && userData) {
883  m_postHeader.userData = new(std::nothrow) UINT8[userDataLength];
884  if (!m_postHeader.userData) ReturnWithError(InsufficientMemory);
885  m_postHeader.userDataLen = userDataLength;
886  memcpy(m_postHeader.userData, userData, userDataLength);
887  // update header size
888  m_preHeader.hSize += userDataLength;
889  }
890 
891  // allocate channels
892  for (int i=0; i < m_header.channels; i++) {
893  // set current width and height
894  m_width[i] = m_header.width;
895  m_height[i] = m_header.height;
896 
897  // allocate channels
898  ASSERT(!m_channel[i]);
899  m_channel[i] = new(std::nothrow) DataT[m_header.width*m_header.height];
900  if (!m_channel[i]) {
901  if (i) i--;
902  while(i) {
903  delete[] m_channel[i]; m_channel[i] = 0;
904  i--;
905  }
906  ReturnWithError(InsufficientMemory);
907  }
908  }
909 }
#define ImageModeIndexedColor
Definition: PGFplatform.h:100
UINT8 version
PGF version.
Definition: PGFtypes.h:106
UINT8 mode
image mode according to Adobe&#39;s image modes
Definition: PGFtypes.h:131
#define PGFVersion
current standard version
Definition: PGFtypes.h:69
UINT32 width
image width in pixels
Definition: PGFtypes.h:125
#define ColorTableSize
Definition: PGFtypes.h:232
INT32 DataT
Definition: PGFtypes.h:219
UINT32 userDataLen
user data size in bytes
Definition: PGFtypes.h:144
#define ImageModeRGBA
Definition: PGFplatform.h:115
CDecoder * m_decoder
PGF decoder.
Definition: PGFimage.h:513
UINT8 * userData
user data of size userDataLen
Definition: PGFtypes.h:143
PGFHeader m_header
PGF file header.
Definition: PGFimage.h:519
bool m_streamReinitialized
stream has been reinitialized
Definition: PGFimage.h:530
bool CompleteHeader()
Definition: PGFimage.cpp:207
BYTE m_quant
quantization parameter
Definition: PGFimage.h:523
#define HeaderSize
Definition: PGFtypes.h:231
#define ImageModeLabColor
Definition: PGFplatform.h:107
DataT * m_channel[MaxChannels]
untransformed channels in YUV format
Definition: PGFimage.h:512
PGFPreHeader m_preHeader
PGF pre-header.
Definition: PGFimage.h:518
#define ImageModeLab48
Definition: PGFplatform.h:110
#define ImageModeCMYKColor
Definition: PGFplatform.h:102
char magic[3]
PGF identification = "PGF".
Definition: PGFtypes.h:105
PGFPostHeader m_postHeader
PGF post-header.
Definition: PGFimage.h:520
void ComputeLevels()
Definition: PGFimage.cpp:799
bool m_downsample
chrominance channels are downsampled
Definition: PGFimage.h:524
#define DownsampleThreshold
if quality is larger than this threshold than downsampling is used
Definition: PGFtypes.h:59
UINT32 hSize
total size of PGFHeader, [ColorTable], and [UserData] in bytes
Definition: PGFtypes.h:115
UINT32 m_width[MaxChannels]
width of each channel at current level
Definition: PGFimage.h:516
#define MaxQuality
maximum quality
Definition: PGFtypes.h:87
#define ImageModeRGBColor
Definition: PGFplatform.h:101
UINT8 channels
number of channels
Definition: PGFtypes.h:130
#define ImageModeCMYK64
Definition: PGFplatform.h:111
#define Magic
PGF identification.
Definition: PGFtypes.h:55
UINT8 quality
quantization parameter: 0=lossless, 4=standard, 6=poor quality
Definition: PGFtypes.h:128
UINT32 height
image height in pixels
Definition: PGFtypes.h:126
#define ImageModeRGB48
Definition: PGFplatform.h:109
UINT32 m_height[MaxChannels]
height of each channel at current level
Definition: PGFimage.h:517

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

685  {
686  const BYTE bpc = m_header.bpp/m_header.channels;
687  BYTE pot = 0;
688 
689  while(maxValue > 0) {
690  pot++;
691  maxValue >>= 1;
692  }
693  // store bits per channel
694  if (pot > bpc) pot = bpc;
695  if (pot > 31) pot = 31;
697 }
PGFHeader m_header
PGF file header.
Definition: PGFimage.h:519
UINT8 usedBitsPerChannel
number of used bits per channel in 16- and 32-bit per channel modes
Definition: PGFtypes.h:132
UINT8 bpp
bits per pixel
Definition: PGFtypes.h:129
UINT8 channels
number of channels
Definition: PGFtypes.h:130

◆ 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; }
ProgressMode m_progressMode
progress mode used in Read and Write; PM_Relative is default mode
Definition: PGFimage.h:538

◆ 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; }
void * m_cbArg
refresh callback argument
Definition: PGFimage.h:536
RefreshCB m_cb
pointer to refresh callback procedure
Definition: PGFimage.h:535

◆ SetROI()

void CPGFImage::SetROI ( PGFRect  rect)
private

◆ UpdatePostHeaderSize()

UINT32 CPGFImage::UpdatePostHeaderSize ( )
private

Definition at line 1045 of file PGFimage.cpp.

1045  {
1046  ASSERT(m_encoder);
1047 
1048  INT64 offset = m_encoder->ComputeOffset(); ASSERT(offset >= 0);
1049 
1050  if (offset > 0) {
1051  // update post-header size and rewrite pre-header
1052  m_preHeader.hSize += (UINT32)offset;
1054  }
1055 
1056  // write dummy levelLength into stream
1058 }
PGFPreHeader m_preHeader
PGF pre-header.
Definition: PGFimage.h:518
UINT32 WriteLevelLength(UINT32 *&levelLength) THROW_
Definition: Encoder.cpp:172
UINT32 * m_levelLength
length of each level in bytes; first level starts immediately after this array
Definition: PGFimage.h:515
UINT32 hSize
total size of PGFHeader, [ColorTable], and [UserData] in bytes
Definition: PGFtypes.h:115
CEncoder * m_encoder
PGF encoder.
Definition: PGFimage.h:514
INT64 ComputeOffset() const
Definition: Encoder.h:180
void UpdatePostHeaderSize(PGFPreHeader preHeader) THROW_
Definition: Encoder.cpp:155

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

703  {
704  const BYTE bpc = m_header.bpp/m_header.channels;
705 
706  if (bpc > 8) {
708  } else {
709  return bpc;
710  }
711 }
PGFHeader m_header
PGF file header.
Definition: PGFimage.h:519
UINT8 usedBitsPerChannel
number of used bits per channel in 16- and 32-bit per channel modes
Definition: PGFtypes.h:132
UINT8 bpp
bits per pixel
Definition: PGFtypes.h:129
UINT8 channels
number of channels
Definition: PGFtypes.h:130

◆ 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.

UINT8 version
PGF version.
Definition: PGFtypes.h:106
static BYTE CurrentVersion(BYTE version=PGFVersion)
Return version.
Definition: PGFimage.cpp:715
PGFPreHeader m_preHeader
PGF pre-header.
Definition: PGFimage.h:518

◆ 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); }
UINT32 width
image width in pixels
Definition: PGFtypes.h:125
PGFHeader m_header
PGF file header.
Definition: PGFimage.h:519
static UINT32 LevelWidth(UINT32 width, int level)
Definition: PGFimage.h:491

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

1141  {
1142  ASSERT(stream);
1143  ASSERT(m_preHeader.hSize);
1144 
1145  // create wavelet transform channels and encoder
1146  UINT32 nBytes = WriteHeader(stream);
1147 
1148  // write image
1149  nBytes += WriteImage(stream, cb, data);
1150 
1151  // return written bytes
1152  if (nWrittenBytes) *nWrittenBytes += nBytes;
1153 }
PGFPreHeader m_preHeader
PGF pre-header.
Definition: PGFimage.h:518
UINT32 hSize
total size of PGFHeader, [ColorTable], and [UserData] in bytes
Definition: PGFtypes.h:115
UINT32 WriteHeader(CPGFStream *stream) THROW_
Definition: PGFimage.cpp:918
UINT32 WriteImage(CPGFStream *stream, CallbackPtr cb=NULL, void *data=NULL) THROW_
Definition: PGFimage.cpp:1070

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

918  {
919  ASSERT(m_header.nLevels <= MaxLevel);
920  ASSERT(m_header.quality <= MaxQuality); // quality is already initialized
921 
922  if (m_header.nLevels > 0) {
923  volatile OSError error = NoError; // volatile prevents optimizations
924  // create new wt channels
925  #pragma omp parallel for default(shared)
926  for (int i=0; i < m_header.channels; i++) {
927  DataT *temp = NULL;
928  if (error == NoError) {
929  if (m_wtChannel[i]) {
930  ASSERT(m_channel[i]);
931  // copy m_channel to temp
932  int size = m_height[i]*m_width[i];
933  temp = new(std::nothrow) DataT[size];
934  if (temp) {
935  memcpy(temp, m_channel[i], size*DataTSize);
936  delete m_wtChannel[i]; // also deletes m_channel
937  } else {
938  error = InsufficientMemory;
939  }
940  }
941  if (error == NoError) {
942  if (temp) m_channel[i] = temp;
943  m_wtChannel[i] = new CWaveletTransform(m_width[i], m_height[i], m_header.nLevels, m_channel[i]);
944  #ifdef __PGFROISUPPORT__
945  m_wtChannel[i]->SetROI(PGFRect(0, 0, m_header.width, m_header.height));
946  #endif
947 
948  // wavelet subband decomposition
949  for (int l=0; error == NoError && l < m_header.nLevels; l++) {
950  OSError err = m_wtChannel[i]->ForwardTransform(l, m_quant);
951  if (err != NoError) error = err;
952  }
953  }
954  }
955  }
956  if (error != NoError) ReturnWithError(error);
957 
959 
960  // create encoder and eventually write headers and levelLength
963 
964  #ifdef __PGFROISUPPORT__
965  if (ROIisSupported()) {
966  // new encoding scheme supporting ROI
967  m_encoder->SetROI();
968  }
969  #endif
970 
971  } else {
972  // very small image: we don't use DWT and encoding
973 
974  // create encoder and eventually write headers and levelLength
976  }
977 
978  INT64 nBytes = m_encoder->ComputeHeaderLength();
979  return (nBytes > 0) ? (UINT32)nBytes : 0;
980 }
bool m_favorSpeedOverSize
favor encoding speed over compression ratio
Definition: PGFimage.h:525
UINT64 m_userDataPos
stream position of user data
Definition: PGFimage.h:521
UINT32 width
image width in pixels
Definition: PGFtypes.h:125
INT32 DataT
Definition: PGFtypes.h:219
PGFHeader m_header
PGF file header.
Definition: PGFimage.h:519
BYTE m_quant
quantization parameter
Definition: PGFimage.h:523
#define DataTSize
Definition: PGFtypes.h:233
DataT * m_channel[MaxChannels]
untransformed channels in YUV format
Definition: PGFimage.h:512
PGFPreHeader m_preHeader
PGF pre-header.
Definition: PGFimage.h:518
UINT8 nLevels
number of DWT levels
Definition: PGFtypes.h:127
OSError ForwardTransform(int level, int quant)
#define MaxLevel
maximum number of transform levels
Definition: PGFtypes.h:56
CWaveletTransform * m_wtChannel[MaxChannels]
wavelet transformed color channels
Definition: PGFimage.h:511
PGFPostHeader m_postHeader
PGF post-header.
Definition: PGFimage.h:520
friend class CWaveletTransform
Definition: Subband.h:43
UINT32 m_width[MaxChannels]
width of each channel at current level
Definition: PGFimage.h:516
bool ROIisSupported() const
Definition: PGFimage.h:465
#define MaxQuality
maximum quality
Definition: PGFtypes.h:87
bool m_useOMPinEncoder
use Open MP in encoder
Definition: PGFimage.h:526
INT64 ComputeHeaderLength() const
Definition: Encoder.h:170
void FavorSpeedOverSize()
Encoder favors speed over compression size.
Definition: Encoder.h:117
UINT8 channels
number of channels
Definition: PGFtypes.h:130
Rectangle.
Definition: PGFtypes.h:194
CEncoder * m_encoder
PGF encoder.
Definition: PGFimage.h:514
int m_currentLevel
transform level of current image
Definition: PGFimage.h:522
UINT8 quality
quantization parameter: 0=lossless, 4=standard, 6=poor quality
Definition: PGFtypes.h:128
UINT32 height
image height in pixels
Definition: PGFtypes.h:126
UINT32 m_height[MaxChannels]
height of each channel at current level
Definition: PGFimage.h:517
PGF encoder.
Definition: Encoder.h:46

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

1070  {
1071  ASSERT(stream);
1072  ASSERT(m_preHeader.hSize);
1073 
1074  int levels = m_header.nLevels;
1075  double percent = pow(0.25, levels);
1076 
1077  // update post-header size, rewrite pre-header, and write dummy levelLength
1078  UINT32 nWrittenBytes = UpdatePostHeaderSize();
1079 
1080  if (levels == 0) {
1081  // write channels
1082  for (int c=0; c < m_header.channels; c++) {
1083  const UINT32 size = m_width[c]*m_height[c];
1084 
1085  // write channel data into stream
1086  for (UINT32 i=0; i < size; i++) {
1087  int count = DataTSize;
1088  stream->Write(&count, &m_channel[c][i]);
1089  }
1090  }
1091 
1092  // now update progress
1093  if (cb) {
1094  if ((*cb)(1, true, data)) ReturnWithError(EscapePressed);
1095  }
1096 
1097  } else {
1098  // encode quantized wavelet coefficients and write to PGF file
1099  // encode subbands, higher levels first
1100  // color channels are interleaved
1101 
1102  // encode all levels
1103  for (m_currentLevel = levels; m_currentLevel > 0; ) {
1104  WriteLevel(); // decrements m_currentLevel
1105 
1106  // now update progress
1107  if (cb) {
1108  percent *= 4;
1109  if ((*cb)(percent, true, data)) ReturnWithError(EscapePressed);
1110  }
1111  }
1112 
1113  // flush encoder and write level lengths
1114  m_encoder->Flush();
1115  }
1116 
1117  // update level lengths
1118  nWrittenBytes = m_encoder->UpdateLevelLength(); // return written image bytes
1119 
1120  // delete encoder
1121  delete m_encoder; m_encoder = NULL;
1122 
1123  ASSERT(!m_encoder);
1124 
1125  return nWrittenBytes;
1126 }
virtual void Write(int *count, void *buffer)=0
void Flush() THROW_
Definition: Encoder.cpp:305
PGFHeader m_header
PGF file header.
Definition: PGFimage.h:519
#define DataTSize
Definition: PGFtypes.h:233
DataT * m_channel[MaxChannels]
untransformed channels in YUV format
Definition: PGFimage.h:512
PGFPreHeader m_preHeader
PGF pre-header.
Definition: PGFimage.h:518
UINT8 nLevels
number of DWT levels
Definition: PGFtypes.h:127
void WriteLevel() THROW_
Definition: PGFimage.cpp:990
UINT32 UpdatePostHeaderSize() THROW_
Definition: PGFimage.cpp:1045
UINT32 hSize
total size of PGFHeader, [ColorTable], and [UserData] in bytes
Definition: PGFtypes.h:115
UINT32 m_width[MaxChannels]
width of each channel at current level
Definition: PGFimage.h:516
UINT32 UpdateLevelLength() THROW_
Definition: Encoder.cpp:197
UINT8 channels
number of channels
Definition: PGFtypes.h:130
CEncoder * m_encoder
PGF encoder.
Definition: PGFimage.h:514
int m_currentLevel
transform level of current image
Definition: PGFimage.h:522
UINT32 m_height[MaxChannels]
height of each channel at current level
Definition: PGFimage.h:517

◆ WriteLevel()

void CPGFImage::WriteLevel ( )
private

Definition at line 990 of file PGFimage.cpp.

990  {
991  ASSERT(m_encoder);
992  ASSERT(m_currentLevel > 0);
993  ASSERT(m_header.nLevels > 0);
994 
995 #ifdef __PGFROISUPPORT__
996  if (ROIisSupported()) {
997  const int lastChannel = m_header.channels - 1;
998 
999  for (int i=0; i < m_header.channels; i++) {
1000  // get number of tiles and tile indices
1001  const UINT32 nTiles = m_wtChannel[i]->GetNofTiles(m_currentLevel);
1002  const UINT32 lastTile = nTiles - 1;
1003 
1004  if (m_currentLevel == m_header.nLevels) {
1005  // last level also has LL band
1006  ASSERT(nTiles == 1);
1008  m_encoder->EncodeTileBuffer();
1009  }
1010  for (UINT32 tileY=0; tileY < nTiles; tileY++) {
1011  for (UINT32 tileX=0; tileX < nTiles; tileX++) {
1012  m_wtChannel[i]->GetSubband(m_currentLevel, HL)->ExtractTile(*m_encoder, true, tileX, tileY);
1013  m_wtChannel[i]->GetSubband(m_currentLevel, LH)->ExtractTile(*m_encoder, true, tileX, tileY);
1014  m_wtChannel[i]->GetSubband(m_currentLevel, HH)->ExtractTile(*m_encoder, true, tileX, tileY);
1015  if (i == lastChannel && tileY == lastTile && tileX == lastTile) {
1016  // all necessary data are buffered. next call of EncodeBuffer will write the last piece of data of the current level.
1018  }
1019  m_encoder->EncodeTileBuffer();
1020  }
1021  }
1022  }
1023  } else
1024 #endif
1025  {
1026  for (int i=0; i < m_header.channels; i++) {
1027  ASSERT(m_wtChannel[i]);
1028  if (m_currentLevel == m_header.nLevels) {
1029  // last level also has LL band
1031  }
1032  //encoder.EncodeInterleaved(m_wtChannel[i], m_currentLevel, m_quant); // until version 4
1033  m_wtChannel[i]->GetSubband(m_currentLevel, HL)->ExtractTile(*m_encoder); // since version 5
1034  m_wtChannel[i]->GetSubband(m_currentLevel, LH)->ExtractTile(*m_encoder); // since version 5
1036  }
1037 
1038  // all necessary data are buffered. next call of EncodeBuffer will write the last piece of data of the current level.
1040  }
1041 }
Definition: PGFtypes.h:92
void ExtractTile(CEncoder &encoder, bool tile=false, UINT32 tileX=0, UINT32 tileY=0) THROW_
Definition: Subband.cpp:172
PGFHeader m_header
PGF file header.
Definition: PGFimage.h:519
UINT8 nLevels
number of DWT levels
Definition: PGFtypes.h:127
CWaveletTransform * m_wtChannel[MaxChannels]
wavelet transformed color channels
Definition: PGFimage.h:511
Definition: PGFtypes.h:92
Definition: PGFtypes.h:92
CSubband * GetSubband(int level, Orientation orientation)
bool ROIisSupported() const
Definition: PGFimage.h:465
Definition: PGFtypes.h:92
UINT8 channels
number of channels
Definition: PGFtypes.h:130
CEncoder * m_encoder
PGF encoder.
Definition: PGFimage.h:514
int m_currentLevel
transform level of current image
Definition: PGFimage.h:522
void SetEncodedLevel(int currentLevel)
Definition: Encoder.h:158

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: