libpgf  6.14.12
PGF - Progressive Graphics File
CPGFImage Class Reference

PGF main class. More...

#include <PGFimage.h>

Public Member Functions

 CPGFImage ()
 Standard constructor: It is used to create a PGF instance for opening and reading. More...
 
virtual ~CPGFImage ()
 Destructor: Destroy internal data structures. More...
 
virtual void Close ()
 
virtual void Destroy ()
 
void Open (CPGFStream *stream) THROW_
 
bool IsOpen () const
 Returns true if the PGF has been opened and not closed. More...
 
void Read (int level=0, CallbackPtr cb=NULL, void *data=NULL) THROW_
 
void Read (PGFRect &rect, int level=0, CallbackPtr cb=NULL, void *data=NULL) THROW_
 
void ReadPreview () THROW_
 
void Reconstruct (int level=0) THROW_
 
void GetBitmap (int pitch, UINT8 *buff, BYTE bpp, int channelMap[]=NULL, CallbackPtr cb=NULL, void *data=NULL) const THROW_
 
void GetYUV (int pitch, DataT *buff, BYTE bpp, int channelMap[]=NULL, CallbackPtr cb=NULL, void *data=NULL) const THROW_
 
void ImportBitmap (int pitch, UINT8 *buff, BYTE bpp, int channelMap[]=NULL, CallbackPtr cb=NULL, void *data=NULL) THROW_
 
void ImportYUV (int pitch, DataT *buff, BYTE bpp, int channelMap[]=NULL, CallbackPtr cb=NULL, void *data=NULL) THROW_
 
void Write (CPGFStream *stream, UINT32 *nWrittenBytes=NULL, CallbackPtr cb=NULL, void *data=NULL) THROW_
 
UINT32 WriteHeader (CPGFStream *stream) THROW_
 
UINT32 WriteImage (CPGFStream *stream, CallbackPtr cb=NULL, void *data=NULL) THROW_
 
UINT32 Write (int level, CallbackPtr cb=NULL, void *data=NULL) THROW_
 
void ConfigureEncoder (bool useOMP=true, bool favorSpeedOverSize=false)
 
void ConfigureDecoder (bool useOMP=true, bool skipUserData=false)
 
void ResetStreamPos () THROW_
 Reset stream position to start of PGF pre-header. More...
 
void SetChannel (DataT *channel, int c=0)
 
void SetHeader (const PGFHeader &header, BYTE flags=0, UINT8 *userData=0, UINT32 userDataLength=0) THROW_
 
void SetMaxValue (UINT32 maxValue)
 
void SetProgressMode (ProgressMode pm)
 
void SetRefreshCallback (RefreshCB callback, void *arg)
 
void SetColorTable (UINT32 iFirstColor, UINT32 nColors, const RGBQUAD *prgbColors) THROW_
 
DataTGetChannel (int c=0)
 
void GetColorTable (UINT32 iFirstColor, UINT32 nColors, RGBQUAD *prgbColors) const THROW_
 
const RGBQUAD * GetColorTable () const
 
const PGFHeaderGetHeader () const
 
UINT32 GetMaxValue () const
 
UINT64 GetUserDataPos () const
 
const UINT8 * GetUserData (UINT32 &size) const
 
UINT32 GetEncodedHeaderLength () const
 
UINT32 GetEncodedLevelLength (int level) const
 
UINT32 ReadEncodedHeader (UINT8 *target, UINT32 targetLen) const THROW_
 
UINT32 ReadEncodedData (int level, UINT8 *target, UINT32 targetLen) const THROW_
 
UINT32 ChannelWidth (int c=0) const
 
UINT32 ChannelHeight (int c=0) const
 
BYTE ChannelDepth () const
 
UINT32 Width (int level=0) const
 
UINT32 Height (int level=0) const
 
BYTE Level () const
 
BYTE Levels () const
 
BYTE Quality () const
 
BYTE Channels () const
 
BYTE Mode () const
 
BYTE BPP () const
 
bool ROIisSupported () const
 
BYTE UsedBitsPerChannel () const
 
BYTE Version () const
 

Static Public Member Functions

static bool ImportIsSupported (BYTE mode)
 
static UINT32 LevelWidth (UINT32 width, int level)
 
static UINT32 LevelHeight (UINT32 height, int level)
 
static BYTE CurrentVersion (BYTE version=PGFVersion)
 Return version. More...
 
static BYTE CurrentChannelDepth (BYTE version=PGFVersion)
 

Protected Attributes

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

Private Member Functions

void ComputeLevels ()
 
bool CompleteHeader ()
 
void RgbToYuv (int pitch, UINT8 *rgbBuff, BYTE bpp, int channelMap[], CallbackPtr cb, void *data) THROW_
 
void Downsample (int nChannel)
 
UINT32 UpdatePostHeaderSize () THROW_
 
void WriteLevel () THROW_
 
void SetROI (PGFRect rect)
 
UINT8 Clamp4 (DataT v) const
 
UINT16 Clamp6 (DataT v) const
 
UINT8 Clamp8 (DataT v) const
 
UINT16 Clamp16 (DataT v) const
 
UINT32 Clamp31 (DataT v) const
 

Private Attributes

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

Detailed Description

PGF main class.

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

Author
C. Stamm, R. Spuler

Definition at line 57 of file PGFimage.h.

Constructor & Destructor Documentation

◆ CPGFImage()

CPGFImage::CPGFImage ( )

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

Definition at line 55 of file PGFimage.cpp.

56 : m_decoder(0)
57 , m_encoder(0)
58 , m_levelLength(0)
59 , m_currentLevel(0)
60 , m_quant(0)
61 , m_userDataPos(0)
62 , m_downsample(false)
63 , m_favorSpeedOverSize(false)
64 , m_useOMPinEncoder(true)
65 , m_useOMPinDecoder(true)
66 , m_skipUserData(false)
67 #ifdef __PGFROISUPPORT__
68 , m_streamReinitialized(false)
69 #endif
70 , m_cb(0)
71 , m_cbArg(0)
73 , m_percent(0)
74 {
75 
76  // init preHeader
77  memcpy(m_preHeader.magic, PGFMagic, 3);
79  m_preHeader.hSize = 0;
80 
81  // init postHeader
84 
85  // init channels
86  for (int i=0; i < MaxChannels; i++) {
87  m_channel[i] = 0;
88  m_wtChannel[i] = 0;
89  }
90 
91  // set image width and height
92  m_width[0] = 0;
93  m_height[0] = 0;
94 }
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
#define PGFMagic
PGF identification.
Definition: PGFtypes.h:55
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
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

◆ ~CPGFImage()

CPGFImage::~CPGFImage ( )
virtual

Destructor: Destroy internal data structures.

Definition at line 98 of file PGFimage.cpp.

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

Member Function Documentation

◆ BPP()

BYTE CPGFImage::BPP ( ) const
inline

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

Returns
Number of bits per pixel.

Definition at line 460 of file PGFimage.h.

460 { return m_header.bpp; }
PGFHeader m_header
PGF file header.
Definition: PGFimage.h:519
UINT8 bpp
bits per pixel
Definition: PGFtypes.h:129

◆ ChannelDepth()

BYTE CPGFImage::ChannelDepth ( ) const
inline

Return bits per channel of the image's encoder.

Returns
Bits per channel

Definition at line 409 of file PGFimage.h.

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

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

◆ CompleteHeader()

bool CPGFImage::CompleteHeader ( )
private

Definition at line 208 of file PGFimage.cpp.

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

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

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

105  {
106  Close();
107 
108  for (int i=0; i < m_header.channels; i++) {
109  delete m_wtChannel[i]; m_wtChannel[i]=0; // also deletes m_channel
110  m_channel[i] = 0;
111  }
113  delete[] m_levelLength; m_levelLength = 0;
114  delete m_encoder; m_encoder = NULL;
115 
116  m_userDataPos = 0;
117 }
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:122
CEncoder * m_encoder
PGF encoder.
Definition: PGFimage.h:514

◆ Downsample()

void CPGFImage::Downsample ( int  nChannel)
private

Definition at line 760 of file PGFimage.cpp.

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

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

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

613  {
614  ASSERT(m_decoder);
616 }
CDecoder * m_decoder
PGF decoder.
Definition: PGFimage.h:513
UINT32 GetEncodedHeaderLength() const
Definition: Decoder.h:137

◆ GetEncodedLevelLength()

UINT32 CPGFImage::GetEncodedLevelLength ( int  level) const
inline

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

Parameters
levelThe image level
Returns
The length of a PGF level in bytes

Definition at line 370 of file PGFimage.h.

370 { ASSERT(level >= 0 && level < m_header.nLevels); return m_levelLength[m_header.nLevels - level - 1]; }
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 322 of file PGFimage.cpp.

322  {
323  size = m_postHeader.userDataLen;
324  return m_postHeader.userData;
325 }
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 2478 of file PGFimage.cpp.

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

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

◆ ImportIsSupported()

bool CPGFImage::ImportIsSupported ( BYTE  mode)
static

Check for valid import image mode.

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

Definition at line 1247 of file PGFimage.cpp.

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

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

131  {
132  ASSERT(stream);
133 
134  // create decoder and read PGFPreHeader PGFHeader PGFPostHeader LevelLengths
137 
138  if (m_header.nLevels > MaxLevel) ReturnWithError(FormatCannotRead);
139 
140  // set current level
142 
143  // set image width and height
144  m_width[0] = m_header.width;
145  m_height[0] = m_header.height;
146 
147  // complete header
148  if (!CompleteHeader()) ReturnWithError(FormatCannotRead);
149 
150  // interpret quant parameter
159  m_downsample = true;
160  m_quant = m_header.quality - 1;
161  } else {
162  m_downsample = false;
164  }
165 
166  // set channel dimensions (chrominance is subsampled by factor 2)
167  if (m_downsample) {
168  for (int i=1; i < m_header.channels; i++) {
169  m_width[i] = (m_width[0] + 1)/2;
170  m_height[i] = (m_height[0] + 1)/2;
171  }
172  } else {
173  for (int i=1; i < m_header.channels; i++) {
174  m_width[i] = m_width[0];
175  m_height[i] = m_height[0];
176  }
177  }
178 
179  if (m_header.nLevels > 0) {
180  // init wavelet subbands
181  for (int i=0; i < m_header.channels; i++) {
183  }
184 
185  // used in Read when PM_Absolute
186  m_percent = pow(0.25, m_header.nLevels);
187 
188  } else {
189  // very small image: we don't use DWT and encoding
190 
191  // read channels
192  for (int c=0; c < m_header.channels; c++) {
193  const UINT32 size = m_width[c]*m_height[c];
194  m_channel[c] = new(std::nothrow) DataT[size];
195  if (!m_channel[c]) ReturnWithError(InsufficientMemory);
196 
197  // read channel data from stream
198  for (UINT32 i=0; i < size; i++) {
199  int count = DataTSize;
200  stream->Read(&count, &m_channel[c][i]);
201  if (count != DataTSize) ReturnWithError(MissingData);
202  }
203  }
204  }
205 }
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:208
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 384 of file PGFimage.cpp.

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

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

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

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

◆ Reconstruct()

void CPGFImage::Reconstruct ( int  level = 0)

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

Parameters
levelThe image level of the resulting image in the internal image buffer.

Definition at line 332 of file PGFimage.cpp.

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

645  {
646  ASSERT(m_decoder);
647  return m_decoder->SetStreamPosToStart();
648 }
CDecoder * m_decoder
PGF decoder.
Definition: PGFimage.h:513
void SetStreamPosToStart() THROW_
Reset stream position to beginning of PGF pre-header.
Definition: Decoder.h:141

◆ RgbToYuv()

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

Definition at line 1331 of file PGFimage.cpp.

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

1306  {
1307  if (iFirstColor + nColors > ColorTableLen) ReturnWithError(ColorTableError);
1308 
1309  for (UINT32 i=iFirstColor, j=0; j < nColors; i++, j++) {
1310  m_postHeader.clut[i] = prgbColors[j];
1311  }
1312 }
#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 844 of file PGFimage.cpp.

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

690  {
691  const BYTE bpc = m_header.bpp/m_header.channels;
692  BYTE pot = 0;
693 
694  while(maxValue > 0) {
695  pot++;
696  maxValue >>= 1;
697  }
698  // store bits per channel
699  if (pot > bpc) pot = bpc;
700  if (pot > 31) pot = 31;
702 }
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 1067 of file PGFimage.cpp.

1067  {
1068  ASSERT(m_encoder);
1069 
1070  INT64 offset = m_encoder->ComputeOffset(); ASSERT(offset >= 0);
1071 
1072  if (offset > 0) {
1073  // update post-header size and rewrite pre-header
1074  m_preHeader.hSize += (UINT32)offset;
1076  }
1077 
1078  // write dummy levelLength into stream
1080 }
PGFPreHeader m_preHeader
PGF pre-header.
Definition: PGFimage.h:518
UINT32 WriteLevelLength(UINT32 *&levelLength) THROW_
Definition: Encoder.cpp:177
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:184
void UpdatePostHeaderSize(PGFPreHeader preHeader) THROW_
Definition: Encoder.cpp:160

◆ UsedBitsPerChannel()

BYTE CPGFImage::UsedBitsPerChannel ( ) const

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

Returns
number of used bits per input/output image channel.

Definition at line 708 of file PGFimage.cpp.

708  {
709  const BYTE bpc = m_header.bpp/m_header.channels;
710 
711  if (bpc > 8) {
713  } else {
714  return bpc;
715  }
716 }
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:720
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 1163 of file PGFimage.cpp.

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

◆ Write() [2/2]

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

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

Parameters
level[0, nLevels) The image level of the resulting image in the internal image buffer.
cbA pointer to a callback procedure. The procedure is called after writing a single level. If cb returns true, then it stops proceeding.
dataData Pointer to C++ class container to host callback procedure.
Returns
The number of bytes written into stream.

◆ WriteHeader()

UINT32 CPGFImage::WriteHeader ( CPGFStream stream)

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

Parameters
streamA PGF stream
Returns
The number of bytes written into stream.

Definition at line 923 of file PGFimage.cpp.

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

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

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

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: