| libpgf 7.21.2 PGF - Progressive Graphics File

Public Member Functions | Static Public Member Functions | Protected Attributes | Private Member Functions | Private Attributes | List of all members
CPGFImage Class Reference

PGF main class. More...

`#include <PGFimage.h>`

## Public Member Functions
| CPGFImage ()
| Standard constructor. More...
virtual | ~CPGFImage ()
| Destructor. More...
void | Destroy ()
void | Open (CPGFStream *stream)
bool | IsOpen () const
| Returns true if the PGF has been opened for reading. More...
void | Read (int level=0, CallbackPtr cb=nullptr, void *data=nullptr)
void | Read (PGFRect &rect, int level=0, CallbackPtr cb=nullptr, void *data=nullptr)
void | ReadPreview ()
void | Reconstruct (int level=0)
void | GetBitmap (int pitch, UINT8 *buff, BYTE bpp, int channelMap[]=nullptr, CallbackPtr cb=nullptr, void *data=nullptr) const
void | GetYUV (int pitch, DataT *buff, BYTE bpp, int channelMap[]=nullptr, CallbackPtr cb=nullptr, void *data=nullptr) const
void | ImportBitmap (int pitch, UINT8 *buff, BYTE bpp, int channelMap[]=nullptr, CallbackPtr cb=nullptr, void *data=nullptr)
void | ImportYUV (int pitch, DataT *buff, BYTE bpp, int channelMap[]=nullptr, CallbackPtr cb=nullptr, void *data=nullptr)
void | Write (CPGFStream *stream, UINT32 *nWrittenBytes=nullptr, CallbackPtr cb=nullptr, void *data=nullptr)
UINT32 | WriteHeader (CPGFStream *stream)
UINT32 | WriteImage (CPGFStream *stream, CallbackPtr cb=nullptr, void *data=nullptr)
UINT32 | Write (int level, CallbackPtr cb=nullptr, void *data=nullptr)
void | ConfigureEncoder (bool useOMP=true, bool favorSpeedOverSize=false)
void | ConfigureDecoder (bool useOMP=true, UserdataPolicy policy=UP_CacheAll, UINT32 prefixSize=0)
void | ResetStreamPos (bool startOfData)
void | SetChannel (DataT *channel, int c=0)
void | SetHeader (const PGFHeader &header, BYTE flags=0, const UINT8 *userData=0, UINT32 userDataLength=0)
void | SetMaxValue (UINT32 maxValue)
void | SetProgressMode (ProgressMode pm)
void | SetRefreshCallback (RefreshCB callback, void *arg)
void | SetColorTable (UINT32 iFirstColor, UINT32 nColors, const RGBQUAD *prgbColors)
DataT * | GetChannel (int c=0)
void | GetColorTable (UINT32 iFirstColor, UINT32 nColors, RGBQUAD *prgbColors) const
const RGBQUAD * | GetColorTable () const
const PGFHeader * | GetHeader () const
UINT32 | GetMaxValue () const
UINT64 | GetUserDataPos () const
const UINT8 * | GetUserData (UINT32 &cachedSize, UINT32 *pTotalSize=nullptr) const
UINT32 | GetEncodedHeaderLength () const
UINT32 | GetEncodedLevelLength (int level) const
UINT32 | ReadEncodedHeader (UINT8 *target, UINT32 targetLen) const
UINT32 | ReadEncodedData (int level, UINT8 *target, UINT32 targetLen) const
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
bool | IsFullyRead () const
| Return true if all levels have been read. More...
BYTE | Quality () const
BYTE | Channels () const
BYTE | Mode () const
BYTE | BPP () const
bool | ROIisSupported () const
PGFRect | ComputeLevelROI () const
BYTE | UsedBitsPerChannel () const
BYTE | Version () const

## Static Public Member Functions
static bool | ImportIsSupported (BYTE mode)
static UINT32 | LevelSizeL (UINT32 size, int level)
static UINT32 | LevelSizeH (UINT32 size, int level)
static BYTE | CodecMajorVersion (BYTE version=PGFVersion)
| Return major version. More...
static BYTE | MaxChannelDepth (BYTE version=PGFVersion)

## Protected Attributes
CWaveletTransform * | m_wtChannel [MaxChannels]
| wavelet transformed color channels More...
DataT * | m_channel [MaxChannels]
| untransformed channels in YUV format More...
CDecoder * | m_decoder
| PGF decoder. More...
CEncoder * | m_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...
UINT32 | m_userDataPolicy
| user data (metadata) policy during open 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_streamReinitialized
| stream has been reinitialized More...
PGFRect | m_roi
| region of interest More...

## Private Member Functions
void | Init ()
void | ComputeLevels ()
bool | CompleteHeader ()
void | RgbToYuv (int pitch, UINT8 *rgbBuff, BYTE bpp, int channelMap[], CallbackPtr cb, void *data)
void | Downsample (int nChannel)
UINT32 | UpdatePostHeaderSize ()
void | WriteLevel ()
PGFRect | GetAlignedROI (int c=0) const
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: Open() Read() GetBitmap() Encoding: SetHeader() ImportBitmap() Write()

Author
  C. Stamm, R. Spuler

Definition at line 53 of file PGFimage.h.

## Constructor & Destructor Documentation

## ◆ CPGFImage()

CPGFImage::CPGFImage | ( |  | ) |

Standard constructor.

Definition at line 64 of file PGFimage.cpp.

64 {
65 Init();
66 }
CPGFImage::Init
void Init()
Definition: PGFimage.cpp:69

## ◆ ~CPGFImage()

CPGFImage::~CPGFImage | ( |  | ) |
| virtual

Destructor.

Definition at line 117 of file PGFimage.cpp.

117 {
118 m_currentLevel = -100; // unusual value used as marker in Destroy()
119 Destroy();
120 }
CPGFImage::Destroy
void Destroy()
Definition: PGFimage.cpp:124
CPGFImage::m_currentLevel
int m_currentLevel
transform level of current image
Definition: PGFimage.h:532

## 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 461 of file PGFimage.h.

461 { return m_header.bpp; }
CPGFImage::m_header
PGFHeader m_header
PGF file header.
Definition: PGFimage.h:529
PGFHeader::bpp
UINT8 bpp
bits per pixel
Definition: PGFtypes.h:156

## ◆ ChannelDepth()

BYTE CPGFImage::ChannelDepth | ( |  | ) | const
| inline

Return bits per channel of the image's encoder.

Returns
  Bits per channel

Definition at line 406 of file PGFimage.h.

406 { return MaxChannelDepth(m_preHeader.version); }
PGFMagicVersion::version
UINT8 version
PGF version.
Definition: PGFtypes.h:115
CPGFImage::m_preHeader
PGFPreHeader m_preHeader
PGF pre-header.
Definition: PGFimage.h:528
CPGFImage::MaxChannelDepth
static BYTE MaxChannelDepth(BYTE version=PGFVersion)
Definition: PGFimage.h:518

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

  c | A channel index

Returns
  Channel height in pixels

Definition at line 401 of file PGFimage.h.

401 { ASSERT(c >= 0 && c < MaxChannels); return m_height[c]; }
MaxChannels
#define MaxChannels
maximum number of (color) channels
Definition: PGFtypes.h:64
CPGFImage::m_height
UINT32 m_height[MaxChannels]
height of each channel at current level
Definition: PGFimage.h:527

## ◆ 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 448 of file PGFimage.h.

448 { return m_header.channels; }
CPGFImage::m_header
PGFHeader m_header
PGF file header.
Definition: PGFimage.h:529
PGFHeader::channels
UINT8 channels
number of channels
Definition: PGFtypes.h:157

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

  c | A channel index

Returns
  Channel width in pixels

Definition at line 394 of file PGFimage.h.

394 { ASSERT(c >= 0 && c < MaxChannels); return m_width[c]; }
MaxChannels
#define MaxChannels
maximum number of (color) channels
Definition: PGFtypes.h:64
CPGFImage::m_width
UINT32 m_width[MaxChannels]
width of each channel at current level
Definition: PGFimage.h:526

## ◆ Clamp16()

UINT16 CPGFImage::Clamp16 | ( | DataT | v | ) | const
| inline private

Definition at line 573 of file PGFimage.h.

573 {
574 if (v & 0xFFFF0000) return (v < 0) ? (UINT16)0: (UINT16)65535; else return (UINT16)v;
575 }

## ◆ Clamp31()

UINT32 CPGFImage::Clamp31 | ( | DataT | v | ) | const
| inline private

Definition at line 576 of file PGFimage.h.

576 {
577 return (v < 0) ? 0 : (UINT32)v;
578 }

## ◆ Clamp4()

UINT8 CPGFImage::Clamp4 | ( | DataT | v | ) | const
| inline private

Definition at line 563 of file PGFimage.h.

563 {
564 if (v & 0xFFFFFFF0) return (v < 0) ? (UINT8)0: (UINT8)15; else return (UINT8)v;
565 }

## ◆ Clamp6()

UINT16 CPGFImage::Clamp6 | ( | DataT | v | ) | const
| inline private

Definition at line 566 of file PGFimage.h.

566 {
567 if (v & 0xFFFFFFC0) return (v < 0) ? (UINT16)0: (UINT16)63; else return (UINT16)v;
568 }

## ◆ Clamp8()

UINT8 CPGFImage::Clamp8 | ( | DataT | v | ) | const
| inline private

Definition at line 569 of file PGFimage.h.

569 {
570 // needs only one test in the normal case
571 if (v & 0xFFFFFF00) return (v < 0) ? (UINT8)0 : (UINT8)255; else return (UINT8)v;
572 }

## ◆ CodecMajorVersion()

BYTE CPGFImage::CodecMajorVersion | ( | BYTE | version = `PGFVersion` | ) |
| static

Return major version.

Return codec major version.

Parameters

  version | pgf pre-header version number

Returns
  PGF major of given version

Definition at line 767 of file PGFimage.cpp.

767 {
768 if (version & Version7) return 7;
769 if (version & Version6) return 6;
770 if (version & Version5) return 5;
771 if (version & Version2) return 2;
772 return 1;
773 }
Version6
#define Version6
hSize in PGFPreHeader uses 32 bits instead of 16 bits
Definition: PGFtypes.h:72
Version2
#define Version2
data structure PGFHeader of major version 2
Definition: PGFtypes.h:68
Version7
#define Version7
Codec major and minor version number stored in PGFHeader.
Definition: PGFtypes.h:73
Version5
#define Version5
new coding scheme since major version 5
Definition: PGFtypes.h:71

## ◆ CompleteHeader()

bool CPGFImage::CompleteHeader | ( |  | ) |
| private

Definition at line 218 of file PGFimage.cpp.

218 {
219 // set current codec version
220 m_header.version = PGFVersionNumber(PGFMajorNumber, PGFYear, PGFWeek);
221
222 if (m_header.mode == ImageModeUnknown) {
223 // undefined mode
224 switch(m_header.bpp) {
225 case 1: m_header.mode = ImageModeBitmap; break;
226 case 8: m_header.mode = ImageModeGrayScale; break;
227 case 12: m_header.mode = ImageModeRGB12; break;
228 case 16: m_header.mode = ImageModeRGB16; break;
229 case 24: m_header.mode = ImageModeRGBColor; break;
230 case 32: m_header.mode = ImageModeRGBA; break;
231 case 48: m_header.mode = ImageModeRGB48; break;
232 default: m_header.mode = ImageModeRGBColor; break;
233 }
234 }
235 if (!m_header.bpp) {
236 // undefined bpp
237 switch(m_header.mode) {
238 case ImageModeBitmap:
239 m_header.bpp = 1;
240 break;
241 case ImageModeIndexedColor:
242 case ImageModeGrayScale:
243 m_header.bpp = 8;
244 break;
245 case ImageModeRGB12:
246 m_header.bpp = 12;
247 break;
248 case ImageModeRGB16:
249 case ImageModeGray16:
250 m_header.bpp = 16;
251 break;
252 case ImageModeRGBColor:
253 case ImageModeLabColor:
254 m_header.bpp = 24;
255 break;
256 case ImageModeRGBA:
257 case ImageModeCMYKColor:
258 case ImageModeGray32:
259 m_header.bpp = 32;
260 break;
261 case ImageModeRGB48:
262 case ImageModeLab48:
263 m_header.bpp = 48;
264 break;
265 case ImageModeCMYK64:
266 m_header.bpp = 64;
267 break;
268 default:
269 ASSERT(false);
270 m_header.bpp = 24;
271 }
272 }
273 if (m_header.mode == ImageModeRGBColor && m_header.bpp == 32) {
274 // change mode
275 m_header.mode = ImageModeRGBA;
276 }
277 if (m_header.mode == ImageModeBitmap && m_header.bpp != 1) return false;
278 if (m_header.mode == ImageModeIndexedColor && m_header.bpp != 8) return false;
279 if (m_header.mode == ImageModeGrayScale && m_header.bpp != 8) return false;
280 if (m_header.mode == ImageModeGray16 && m_header.bpp != 16) return false;
281 if (m_header.mode == ImageModeGray32 && m_header.bpp != 32) return false;
282 if (m_header.mode == ImageModeRGBColor && m_header.bpp != 24) return false;
283 if (m_header.mode == ImageModeRGBA && m_header.bpp != 32) return false;
284 if (m_header.mode == ImageModeRGB12 && m_header.bpp != 12) return false;
285 if (m_header.mode == ImageModeRGB16 && m_header.bpp != 16) return false;
286 if (m_header.mode == ImageModeRGB48 && m_header.bpp != 48) return false;
287 if (m_header.mode == ImageModeLabColor && m_header.bpp != 24) return false;
288 if (m_header.mode == ImageModeLab48 && m_header.bpp != 48) return false;
289 if (m_header.mode == ImageModeCMYKColor && m_header.bpp != 32) return false;
290 if (m_header.mode == ImageModeCMYK64 && m_header.bpp != 64) return false;
291
292 // set number of channels
293 if (!m_header.channels) {
294 switch(m_header.mode) {
295 case ImageModeBitmap:
296 case ImageModeIndexedColor:
297 case ImageModeGrayScale:
298 case ImageModeGray16:
299 case ImageModeGray32:
300 m_header.channels = 1;
301 break;
302 case ImageModeRGBColor:
303 case ImageModeRGB12:
304 case ImageModeRGB16:
305 case ImageModeRGB48:
306 case ImageModeLabColor:
307 case ImageModeLab48:
308 m_header.channels = 3;
309 break;
310 case ImageModeRGBA:
311 case ImageModeCMYKColor:
312 case ImageModeCMYK64:
313 m_header.channels = 4;
314 break;
315 default:
316 return false;
317 }
318 }
319
320 // store used bits per channel
321 UINT8 bpc = m_header.bpp/m_header.channels;
322 if (bpc > 31) bpc = 31;
323 if (!m_header.usedBitsPerChannel || m_header.usedBitsPerChannel > bpc) {
324 m_header.usedBitsPerChannel = bpc;
325 }
326
327 return true;
328 }
ImageModeIndexedColor
#define ImageModeIndexedColor
Definition: PGFplatform.h:100
ImageModeRGB12
#define ImageModeRGB12
Definition: PGFplatform.h:117
PGFHeader::mode
UINT8 mode
image mode according to Adobe's image modes
Definition: PGFtypes.h:158
PGFYear
#define PGFYear
Definition: PGFtypes.h:45
PGFMajorNumber
#define PGFMajorNumber
Definition: PGFtypes.h:44
ImageModeRGBA
#define ImageModeRGBA
Definition: PGFplatform.h:115
CPGFImage::m_header
PGFHeader m_header
PGF file header.
Definition: PGFimage.h:529
ImageModeLabColor
#define ImageModeLabColor
Definition: PGFplatform.h:107
ImageModeGray16
#define ImageModeGray16
Definition: PGFplatform.h:108
PGFHeader::usedBitsPerChannel
UINT8 usedBitsPerChannel
number of used bits per channel in 16- and 32-bit per channel modes
Definition: PGFtypes.h:159
ImageModeLab48
#define ImageModeLab48
Definition: PGFplatform.h:110
ImageModeCMYKColor
#define ImageModeCMYKColor
Definition: PGFplatform.h:102
ImageModeGrayScale
#define ImageModeGrayScale
Definition: PGFplatform.h:99
PGFHeader::bpp
UINT8 bpp
bits per pixel
Definition: PGFtypes.h:156
PGFWeek
#define PGFWeek
Definition: PGFtypes.h:46
ImageModeGray32
#define ImageModeGray32
Definition: PGFplatform.h:116
ImageModeUnknown
#define ImageModeUnknown
Definition: PGFplatform.h:119
ImageModeRGBColor
#define ImageModeRGBColor
Definition: PGFplatform.h:101
ImageModeBitmap
#define ImageModeBitmap
Definition: PGFplatform.h:98
PGFHeader::channels
UINT8 channels
number of channels
Definition: PGFtypes.h:157
PGFHeader::version
PGFVersionNumber version
codec version number: (since Version 7)
Definition: PGFtypes.h:160
ImageModeCMYK64
#define ImageModeCMYK64
Definition: PGFplatform.h:111
ImageModeRGB16
#define ImageModeRGB16
Definition: PGFplatform.h:118
ImageModeRGB48
#define ImageModeRGB48
Definition: PGFplatform.h:109
PGFVersionNumber
version number stored in header since major version 7
Definition: PGFtypes.h:132

## ◆ ComputeLevelROI()

PGFRect CPGFImage::ComputeLevelROI | ( |  | ) | const

Return ROI of channel 0 at current level in pixels. The returned rect is only valid after reading a ROI.

Returns
  ROI in pixels

## ◆ ComputeLevels()

void CPGFImage::ComputeLevels | ( |  | ) |
| private

Definition at line 853 of file PGFimage.cpp.

853 {
854 const int maxThumbnailWidth = 20*FilterSize;
855 const int m = __min(m_header.width, m_header.height);
856 int s = m;
857
858 if (m_header.nLevels < 1 || m_header.nLevels > MaxLevel) {
859 m_header.nLevels = 1;
860 // compute a good value depending on the size of the image
861 while (s > maxThumbnailWidth) {
862 m_header.nLevels++;
863 s >>= 1;
864 }
865 }
866
867 int levels = m_header.nLevels; // we need a signed value during level reduction
868
869 // reduce number of levels if the image size is smaller than FilterSize*(2^levels)
870 s = FilterSize*(1 << levels); // must be at least the double filter size because of subsampling
871 while (m < s) {
872 levels--;
873 s >>= 1;
874 }
875 if (levels > MaxLevel) m_header.nLevels = MaxLevel;
876 else if (levels < 0) m_header.nLevels = 0;
877 else m_header.nLevels = (UINT8)levels;
878
879 // used in Write when PM_Absolute
880 m_percent = pow(0.25, m_header.nLevels);
881
882 ASSERT(0 <= m_header.nLevels && m_header.nLevels <= MaxLevel);
883 }
PGFHeader::width
UINT32 width
image width in pixels
Definition: PGFtypes.h:152
CPGFImage::m_header
PGFHeader m_header
PGF file header.
Definition: PGFimage.h:529
FilterSize
const UINT32 FilterSize
Definition: WaveletTransform.h:39
PGFHeader::nLevels
UINT8 nLevels
number of FWT transforms
Definition: PGFtypes.h:154
MaxLevel
#define MaxLevel
maximum number of transform levels
Definition: PGFtypes.h:62
__min
#define __min(x, y)
Definition: PGFplatform.h:91
CPGFImage::m_percent
double m_percent
progress [0..1]
Definition: PGFimage.h:547
PGFHeader::height
UINT32 height
image height in pixels
Definition: PGFtypes.h:153

## ◆ ConfigureDecoder()

void CPGFImage::ConfigureDecoder | ( | bool | useOMP = `true`,
|  | UserdataPolicy | policy = `UP_CacheAll`,
|  | UINT32 | prefixSize = `0`
| ) |  |
| inline

Configures the decoder.

Parameters

  useOMP | Use parallel threading with Open MP during decoding. Default value: true. Influences the decoding only if the codec has been compiled with OpenMP support.
  policy | The file might contain user data (e.g. metadata). The policy defines the behaviour during Open(). UP_CacheAll: User data is read and stored completely in a new allocated memory block. It can be accessed by GetUserData(). UP_CachePrefix: Only prefixSize bytes at the beginning of the user data are stored in a new allocated memory block. It can be accessed by GetUserData(). UP_Skip: User data is skipped and nothing is cached.
  prefixSize | Is only used in combination with UP_CachePrefix. It defines the number of bytes cached.

Definition at line 260 of file PGFimage.h.

260 { ASSERT(prefixSize <= MaxUserDataSize); m_useOMPinDecoder = useOMP; m_userDataPolicy = (UP_CachePrefix) ? prefixSize : 0xFFFFFFFF - policy; }
CPGFImage::m_useOMPinDecoder
bool m_useOMPinDecoder
use Open MP in decoder
Definition: PGFimage.h:538
UP_CachePrefix
Definition: PGFtypes.h:101
CPGFImage::m_userDataPolicy
UINT32 m_userDataPolicy
user data (metadata) policy during open
Definition: PGFimage.h:533
MaxUserDataSize
#define MaxUserDataSize
Definition: PGFtypes.h:283

## ◆ ConfigureEncoder()

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

Configures the encoder.

Parameters

  useOMP | Use parallel threading with Open MP during encoding. Default value: true. Influences the encoding only if the codec has been compiled with OpenMP support.
  favorSpeedOverSize | Favors encoding speed over compression ratio. Default value: false

Definition at line 250 of file PGFimage.h.

250 { m_useOMPinEncoder = useOMP; m_favorSpeedOverSize = favorSpeedOverSize; }
CPGFImage::m_favorSpeedOverSize
bool m_favorSpeedOverSize
favor encoding speed over compression ratio
Definition: PGFimage.h:536
CPGFImage::m_useOMPinEncoder
bool m_useOMPinEncoder
use Open MP in encoder
Definition: PGFimage.h:537

## ◆ Destroy()

void CPGFImage::Destroy | ( |  | ) |

Definition at line 124 of file PGFimage.cpp.

124 {
125 for (int i = 0; i < m_header.channels; i++) {
126 delete m_wtChannel[i]; // also deletes m_channel
127 }
128 delete[] m_postHeader.userData;
129 delete[] m_levelLength;
130 delete m_decoder;
131 delete m_encoder;
132
133 if (m_currentLevel != -100) Init();
134 }
CPGFImage::m_decoder
CDecoder * m_decoder
PGF decoder.
Definition: PGFimage.h:523
PGFPostHeader::userData
UINT8 * userData
user data of size userDataLen (optional part of file header)
Definition: PGFtypes.h:170
CPGFImage::m_header
PGFHeader m_header
PGF file header.
Definition: PGFimage.h:529
CPGFImage::m_wtChannel
CWaveletTransform * m_wtChannel[MaxChannels]
wavelet transformed color channels
Definition: PGFimage.h:521
CPGFImage::m_postHeader
PGFPostHeader m_postHeader
PGF post-header.
Definition: PGFimage.h:530
CPGFImage::Init
void Init()
Definition: PGFimage.cpp:69
CPGFImage::m_levelLength
UINT32 * m_levelLength
length of each level in bytes; first level starts immediately after this array
Definition: PGFimage.h:525
PGFHeader::channels
UINT8 channels
number of channels
Definition: PGFtypes.h:157
CPGFImage::m_encoder
CEncoder * m_encoder
PGF encoder.
Definition: PGFimage.h:524
CPGFImage::m_currentLevel
int m_currentLevel
transform level of current image
Definition: PGFimage.h:532

## ◆ Downsample()

void CPGFImage::Downsample | ( | int | nChannel | ) |
| private

Definition at line 809 of file PGFimage.cpp.

809 {
810 ASSERT(ch > 0);
811
812 const int w = m_width[0];
813 const int w2 = w/2;
814 const int h2 = m_height[0]/2;
815 const int oddW = w%2; // don't use bool -> problems with MaxSpeed optimization
816 const int oddH = m_height[0]%2; // "
817 int loPos = 0;
818 int hiPos = w;
819 int sampledPos = 0;
820 DataT* buff = m_channel[ch]; ASSERT(buff);
821
822 for (int i=0; i < h2; i++) {
823 for (int j=0; j < w2; j++) {
824 // compute average of pixel block
825 buff[sampledPos] = (buff[loPos] + buff[loPos + 1] + buff[hiPos] + buff[hiPos + 1]) >> 2;
826 loPos += 2; hiPos += 2;
827 sampledPos++;
828 }
829 if (oddW) {
830 buff[sampledPos] = (buff[loPos] + buff[hiPos]) >> 1;
831 loPos++; hiPos++;
832 sampledPos++;
833 }
834 loPos += w; hiPos += w;
835 }
836 if (oddH) {
837 for (int j=0; j < w2; j++) {
838 buff[sampledPos] = (buff[loPos] + buff[loPos+1]) >> 1;
839 loPos += 2; hiPos += 2;
840 sampledPos++;
841 }
842 if (oddW) {
843 buff[sampledPos] = buff[loPos];
844 }
845 }
846
847 // downsampled image has half width and half height
848 m_width[ch] = (m_width[ch] + 1)/2;
849 m_height[ch] = (m_height[ch] + 1)/2;
850 }
DataT
INT32 DataT
Definition: PGFtypes.h:268
CPGFImage::m_channel
DataT * m_channel[MaxChannels]
untransformed channels in YUV format
Definition: PGFimage.h:522
CPGFImage::m_width
UINT32 m_width[MaxChannels]
width of each channel at current level
Definition: PGFimage.h:526
CPGFImage::m_height
UINT32 m_height[MaxChannels]
height of each channel at current level
Definition: PGFimage.h:527

## ◆ GetAlignedROI()

PGFRect CPGFImage::GetAlignedROI | ( | int | c = `0` | ) | const
| private

## ◆ GetBitmap()

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

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

Parameters

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

Definition at line 1788 of file PGFimage.cpp.

1788 {
1789 ASSERT(buff);
1790 UINT32 w = m_width[0]; // width of decoded image
1791 UINT32 h = m_height[0]; // height of decoded image
1792 UINT32 yw = w; // y-channel width
1793 UINT32 uw = m_width[1]; // u-channel width
1794 UINT32 roiOffsetX = 0;
1795 UINT32 roiOffsetY = 0;
1796 UINT32 yOffset = 0;
1797 UINT32 uOffset = 0;
1798
1799 #ifdef __PGFROISUPPORT__
1800 const PGFRect& roi = GetAlignedROI(); // in pixels, roi is usually larger than levelRoi
1801 ASSERT(w == roi.Width() && h == roi.Height());
1802 const PGFRect levelRoi = ComputeLevelROI();
1803 ASSERT(roi.left <= levelRoi.left && levelRoi.right <= roi.right);
1804 ASSERT(roi.top <= levelRoi.top && levelRoi.bottom <= roi.bottom);
1805
1806 if (ROIisSupported() && (levelRoi.Width() < w || levelRoi.Height() < h)) {
1807 // ROI is used
1808 w = levelRoi.Width();
1809 h = levelRoi.Height();
1810 roiOffsetX = levelRoi.left - roi.left;
1811 roiOffsetY = levelRoi.top - roi.top;
1812 yOffset = roiOffsetX + roiOffsetY*yw;
1813
1814 if (m_downsample) {
1815 const PGFRect& downsampledRoi = GetAlignedROI(1);
1816 uOffset = levelRoi.left/2 - downsampledRoi.left + (levelRoi.top/2 - downsampledRoi.top)*m_width[1];
1817 } else {
1818 uOffset = yOffset;
1819 }
1820 }
1821 #endif
1822
1823 const double dP = 1.0/h;
1824 int defMap[] = { 0, 1, 2, 3, 4, 5, 6, 7 }; ASSERT(sizeof(defMap)/sizeof(defMap[0]) == MaxChannels);
1825 if (channelMap == nullptr) channelMap = defMap;
1826 DataT uAvg, vAvg;
1827 double percent = 0;
1828 UINT32 i, j;
1829
1830 switch(m_header.mode) {
1831 case ImageModeBitmap:
1832 {
1833 ASSERT(m_header.channels == 1);
1834 ASSERT(m_header.bpp == 1);
1835 ASSERT(bpp == 1);
1836
1837 const UINT32 w2 = (w + 7)/8;
1838 DataT* y = m_channel[0]; ASSERT(y);
1839
1840 if (m_preHeader.version & Version7) {
1841 // new unpacked version has a little better compression ratio
1842 // since version 7
1843 for (i = 0; i < h; i++) {
1844 UINT32 cnt = 0;
1845 for (j = 0; j < w2; j++) {
1846 UINT8 byte = 0;
1847 for (int k = 0; k < 8; k++) {
1848 byte <<= 1;
1849 UINT8 bit = 0;
1850 if (cnt < w) {
1851 bit = y[yOffset + cnt] & 1;
1852 }
1853 byte |= bit;
1854 cnt++;
1855 }
1856 buff[j] = byte;
1857 }
1858 yOffset += yw;
1859 buff += pitch;
1860
1861 if (cb) {
1862 percent += dP;
1863 if ((*cb)(percent, true, data)) ReturnWithError(EscapePressed);
1864 }
1865 }
1866 } else {
1867 // old versions
1868 // packed pixels: 8 pixel in 1 byte of channel[0]
1869 if (!(m_preHeader.version & Version5)) yw = w2; // not version 5 or 6
1870 yOffset = roiOffsetX/8 + roiOffsetY*yw; // 1 byte in y contains 8 pixel values
1871 for (i = 0; i < h; i++) {
1872 for (j = 0; j < w2; j++) {
1873 buff[j] = Clamp8(y[yOffset + j] + YUVoffset8);
1874 }
1875 yOffset += yw;
1876 buff += pitch;
1877
1878 if (cb) {
1879 percent += dP;
1880 if ((*cb)(percent, true, data)) ReturnWithError(EscapePressed);
1881 }
1882 }
1883 }
1884 break;
1885 }
1886 case ImageModeIndexedColor:
1887 case ImageModeGrayScale:
1888 case ImageModeHSLColor:
1889 case ImageModeHSBColor:
1890 {
1891 ASSERT(m_header.channels >= 1);
1892 ASSERT(m_header.bpp == m_header.channels*8);
1893 ASSERT(bpp%8 == 0);
1894
1895 UINT32 cnt, channels = bpp/8; ASSERT(channels >= m_header.channels);
1896
1897 for (i=0; i < h; i++) {
1898 UINT32 yPos = yOffset;
1899 cnt = 0;
1900 for (j=0; j < w; j++) {
1901 for (UINT32 c=0; c < m_header.channels; c++) {
1902 buff[cnt + channelMap[c]] = Clamp8(m_channel[c][yPos] + YUVoffset8);
1903 }
1904 cnt += channels;
1905 yPos++;
1906 }
1907 yOffset += yw;
1908 buff += pitch;
1909
1910 if (cb) {
1911 percent += dP;
1912 if ((*cb)(percent, true, data)) ReturnWithError(EscapePressed);
1913 }
1914 }
1915 break;
1916 }
1917 case ImageModeGray16:
1918 {
1919 ASSERT(m_header.channels >= 1);
1920 ASSERT(m_header.bpp == m_header.channels*16);
1921
1922 const DataT yuvOffset16 = 1 << (UsedBitsPerChannel() - 1);
1923 UINT32 cnt, channels;
1924
1925 if (bpp%16 == 0) {
1926 const int shift = 16 - UsedBitsPerChannel(); ASSERT(shift >= 0);
1927 UINT16 *buff16 = (UINT16 *)buff;
1928 int pitch16 = pitch/2;
1929 channels = bpp/16; ASSERT(channels >= m_header.channels);
1930
1931 for (i=0; i < h; i++) {
1932 UINT32 yPos = yOffset;
1933 cnt = 0;
1934 for (j=0; j < w; j++) {
1935 for (UINT32 c=0; c < m_header.channels; c++) {
1936 buff16[cnt + channelMap[c]] = Clamp16((m_channel[c][yPos] + yuvOffset16) << shift);
1937 }
1938 cnt += channels;
1939 yPos++;
1940 }
1941 yOffset += yw;
1942 buff16 += pitch16;
1943
1944 if (cb) {
1945 percent += dP;
1946 if ((*cb)(percent, true, data)) ReturnWithError(EscapePressed);
1947 }
1948 }
1949 } else {
1950 ASSERT(bpp%8 == 0);
1951 const int shift = __max(0, UsedBitsPerChannel() - 8);
1952 channels = bpp/8; ASSERT(channels >= m_header.channels);
1953
1954 for (i=0; i < h; i++) {
1955 UINT32 yPos = yOffset;
1956 cnt = 0;
1957 for (j=0; j < w; j++) {
1958 for (UINT32 c=0; c < m_header.channels; c++) {
1959 buff[cnt + channelMap[c]] = Clamp8((m_channel[c][yPos] + yuvOffset16) >> shift);
1960 }
1961 cnt += channels;
1962 yPos++;
1963 }
1964 yOffset += yw;
1965 buff += pitch;
1966
1967 if (cb) {
1968 percent += dP;
1969 if ((*cb)(percent, true, data)) ReturnWithError(EscapePressed);
1970 }
1971 }
1972 }
1973 break;
1974 }
1975 case ImageModeRGBColor:
1976 {
1977 ASSERT(m_header.channels == 3);
1978 ASSERT(m_header.bpp == m_header.channels*8);
1979 ASSERT(bpp%8 == 0);
1980 ASSERT(bpp >= m_header.bpp);
1981
1982 DataT* y = m_channel[0]; ASSERT(y);
1983 DataT* u = m_channel[1]; ASSERT(u);
1984 DataT* v = m_channel[2]; ASSERT(v);
1985 UINT8 *buffg = &buff[channelMap[1]],
1986 *buffr = &buff[channelMap[2]],
1987 *buffb = &buff[channelMap[0]];
1988 UINT8 g;
1989 UINT32 cnt, channels = bpp/8;
1990
1991 if (m_downsample) {
1992 for (i=0; i < h; i++) {
1993 UINT32 uPos = uOffset;
1994 UINT32 yPos = yOffset;
1995 cnt = 0;
1996 for (j=0; j < w; j++) {
1997 // u and v are downsampled
1998 uAvg = u[uPos];
1999 vAvg = v[uPos];
2000 // Yuv
2001 buffg[cnt] = g = Clamp8(y[yPos] + YUVoffset8 - ((uAvg + vAvg ) >> 2)); // must be logical shift operator
2002 buffr[cnt] = Clamp8(uAvg + g);
2003 buffb[cnt] = Clamp8(vAvg + g);
2004 cnt += channels;
2005 if (j & 1) uPos++;
2006 yPos++;
2007 }
2008 if (i & 1) uOffset += uw;
2009 yOffset += yw;
2010 buffb += pitch;
2011 buffg += pitch;
2012 buffr += pitch;
2013
2014 if (cb) {
2015 percent += dP;
2016 if ((*cb)(percent, true, data)) ReturnWithError(EscapePressed);
2017 }
2018 }
2019
2020 } else {
2021 for (i=0; i < h; i++) {
2022 cnt = 0;
2023 UINT32 yPos = yOffset;
2024 for (j = 0; j < w; j++) {
2025 uAvg = u[yPos];
2026 vAvg = v[yPos];
2027 // Yuv
2028 buffg[cnt] = g = Clamp8(y[yPos] + YUVoffset8 - ((uAvg + vAvg ) >> 2)); // must be logical shift operator
2029 buffr[cnt] = Clamp8(uAvg + g);
2030 buffb[cnt] = Clamp8(vAvg + g);
2031 cnt += channels;
2032 yPos++;
2033 }
2034 yOffset += yw;
2035 buffb += pitch;
2036 buffg += pitch;
2037 buffr += pitch;
2038
2039 if (cb) {
2040 percent += dP;
2041 if ((*cb)(percent, true, data)) ReturnWithError(EscapePressed);
2042 }
2043 }
2044 }
2045 break;
2046 }
2047 case ImageModeRGB48:
2048 {
2049 ASSERT(m_header.channels == 3);
2050 ASSERT(m_header.bpp == 48);
2051
2052 const DataT yuvOffset16 = 1 << (UsedBitsPerChannel() - 1);
2053
2054 DataT* y = m_channel[0]; ASSERT(y);
2055 DataT* u = m_channel[1]; ASSERT(u);
2056 DataT* v = m_channel[2]; ASSERT(v);
2057 UINT32 cnt, channels;
2058 DataT g;
2059
2060 if (bpp >= 48 && bpp%16 == 0) {
2061 const int shift = 16 - UsedBitsPerChannel(); ASSERT(shift >= 0);
2062 UINT16 *buff16 = (UINT16 *)buff;
2063 int pitch16 = pitch/2;
2064 channels = bpp/16; ASSERT(channels >= m_header.channels);
2065
2066 for (i=0; i < h; i++) {
2067 UINT32 uPos = uOffset;
2068 UINT32 yPos = yOffset;
2069 cnt = 0;
2070 for (j=0; j < w; j++) {
2071 uAvg = u[uPos];
2072 vAvg = v[uPos];
2073 // Yuv
2074 g = y[yPos] + yuvOffset16 - ((uAvg + vAvg ) >> 2); // must be logical shift operator
2075 buff16[cnt + channelMap[1]] = Clamp16(g << shift);
2076 buff16[cnt + channelMap[2]] = Clamp16((uAvg + g) << shift);
2077 buff16[cnt + channelMap[0]] = Clamp16((vAvg + g) << shift);
2078 cnt += channels;
2079 if (!m_downsample || (j & 1)) uPos++;
2080 yPos++;
2081 }
2082 if (!m_downsample || (i & 1)) uOffset += uw;
2083 yOffset += yw;
2084 buff16 += pitch16;
2085
2086 if (cb) {
2087 percent += dP;
2088 if ((*cb)(percent, true, data)) ReturnWithError(EscapePressed);
2089 }
2090 }
2091 } else {
2092 ASSERT(bpp%8 == 0);
2093 const int shift = __max(0, UsedBitsPerChannel() - 8);
2094 channels = bpp/8; ASSERT(channels >= m_header.channels);
2095
2096 for (i=0; i < h; i++) {
2097 UINT32 uPos = uOffset;
2098 UINT32 yPos = yOffset;
2099 cnt = 0;
2100 for (j=0; j < w; j++) {
2101 uAvg = u[uPos];
2102 vAvg = v[uPos];
2103 // Yuv
2104 g = y[yPos] + yuvOffset16 - ((uAvg + vAvg ) >> 2); // must be logical shift operator
2105 buff[cnt + channelMap[1]] = Clamp8(g >> shift);
2106 buff[cnt + channelMap[2]] = Clamp8((uAvg + g) >> shift);
2107 buff[cnt + channelMap[0]] = Clamp8((vAvg + g) >> shift);
2108 cnt += channels;
2109 if (!m_downsample || (j & 1)) uPos++;
2110 yPos++;
2111 }
2112 if (!m_downsample || (i & 1)) uOffset += uw;
2113 yOffset += yw;
2114 buff += pitch;
2115
2116 if (cb) {
2117 percent += dP;
2118 if ((*cb)(percent, true, data)) ReturnWithError(EscapePressed);
2119 }
2120 }
2121 }
2122 break;
2123 }
2124 case ImageModeLabColor:
2125 {
2126 ASSERT(m_header.channels == 3);
2127 ASSERT(m_header.bpp == m_header.channels*8);
2128 ASSERT(bpp%8 == 0);
2129
2130 DataT* l = m_channel[0]; ASSERT(l);
2131 DataT* a = m_channel[1]; ASSERT(a);
2132 DataT* b = m_channel[2]; ASSERT(b);
2133 UINT32 cnt, channels = bpp/8; ASSERT(channels >= m_header.channels);
2134
2135 for (i=0; i < h; i++) {
2136 UINT32 uPos = uOffset;
2137 UINT32 yPos = yOffset;
2138 cnt = 0;
2139 for (j=0; j < w; j++) {
2140 uAvg = a[uPos];
2141 vAvg = b[uPos];
2142 buff[cnt + channelMap[0]] = Clamp8(l[yPos] + YUVoffset8);
2143 buff[cnt + channelMap[1]] = Clamp8(uAvg + YUVoffset8);
2144 buff[cnt + channelMap[2]] = Clamp8(vAvg + YUVoffset8);
2145 cnt += channels;
2146 if (!m_downsample || (j & 1)) uPos++;
2147 yPos++;
2148 }
2149 if (!m_downsample || (i & 1)) uOffset += uw;
2150 yOffset += yw;
2151 buff += pitch;
2152
2153 if (cb) {
2154 percent += dP;
2155 if ((*cb)(percent, true, data)) ReturnWithError(EscapePressed);
2156 }
2157 }
2158 break;
2159 }
2160 case ImageModeLab48:
2161 {
2162 ASSERT(m_header.channels == 3);
2163 ASSERT(m_header.bpp == m_header.channels*16);
2164
2165 const DataT yuvOffset16 = 1 << (UsedBitsPerChannel() - 1);
2166
2167 DataT* l = m_channel[0]; ASSERT(l);
2168 DataT* a = m_channel[1]; ASSERT(a);
2169 DataT* b = m_channel[2]; ASSERT(b);
2170 UINT32 cnt, channels;
2171
2172 if (bpp%16 == 0) {
2173 const int shift = 16 - UsedBitsPerChannel(); ASSERT(shift >= 0);
2174 UINT16 *buff16 = (UINT16 *)buff;
2175 int pitch16 = pitch/2;
2176 channels = bpp/16; ASSERT(channels >= m_header.channels);
2177
2178 for (i=0; i < h; i++) {
2179 UINT32 uPos = uOffset;
2180 UINT32 yPos = yOffset;
2181 cnt = 0;
2182 for (j=0; j < w; j++) {
2183 uAvg = a[uPos];
2184 vAvg = b[uPos];
2185 buff16[cnt + channelMap[0]] = Clamp16((l[yPos] + yuvOffset16) << shift);
2186 buff16[cnt + channelMap[1]] = Clamp16((uAvg + yuvOffset16) << shift);
2187 buff16[cnt + channelMap[2]] = Clamp16((vAvg + yuvOffset16) << shift);
2188 cnt += channels;
2189 if (!m_downsample || (j & 1)) uPos++;
2190 yPos++;
2191 }
2192 if (!m_downsample || (i & 1)) uOffset += uw;
2193 yOffset += yw;
2194 buff16 += pitch16;
2195
2196 if (cb) {
2197 percent += dP;
2198 if ((*cb)(percent, true, data)) ReturnWithError(EscapePressed);
2199 }
2200 }
2201 } else {
2202 ASSERT(bpp%8 == 0);
2203 const int shift = __max(0, UsedBitsPerChannel() - 8);
2204 channels = bpp/8; ASSERT(channels >= m_header.channels);
2205
2206 for (i=0; i < h; i++) {
2207 UINT32 uPos = uOffset;
2208 UINT32 yPos = yOffset;
2209 cnt = 0;
2210 for (j=0; j < w; j++) {
2211 uAvg = a[uPos];
2212 vAvg = b[uPos];
2213 buff[cnt + channelMap[0]] = Clamp8((l[yPos] + yuvOffset16) >> shift);
2214 buff[cnt + channelMap[1]] = Clamp8((uAvg + yuvOffset16) >> shift);
2215 buff[cnt + channelMap[2]] = Clamp8((vAvg + yuvOffset16) >> shift);
2216 cnt += channels;
2217 if (!m_downsample || (j & 1)) uPos++;
2218 yPos++;
2219 }
2220 if (!m_downsample || (i & 1)) uOffset += uw;
2221 yOffset += yw;
2222 buff += pitch;
2223
2224 if (cb) {
2225 percent += dP;
2226 if ((*cb)(percent, true, data)) ReturnWithError(EscapePressed);
2227 }
2228 }
2229 }
2230 break;
2231 }
2232 case ImageModeRGBA:
2233 case ImageModeCMYKColor:
2234 {
2235 ASSERT(m_header.channels == 4);
2236 ASSERT(m_header.bpp == m_header.channels*8);
2237 ASSERT(bpp%8 == 0);
2238
2239 DataT* y = m_channel[0]; ASSERT(y);
2240 DataT* u = m_channel[1]; ASSERT(u);
2241 DataT* v = m_channel[2]; ASSERT(v);
2242 DataT* a = m_channel[3]; ASSERT(a);
2243 UINT8 g, aAvg;
2244 UINT32 cnt, channels = bpp/8; ASSERT(channels >= m_header.channels);
2245
2246 for (i=0; i < h; i++) {
2247 UINT32 uPos = uOffset;
2248 UINT32 yPos = yOffset;
2249 cnt = 0;
2250 for (j=0; j < w; j++) {
2251 uAvg = u[uPos];
2252 vAvg = v[uPos];
2253 aAvg = Clamp8(a[uPos] + YUVoffset8);
2254 // Yuv
2255 buff[cnt + channelMap[1]] = g = Clamp8(y[yPos] + YUVoffset8 - ((uAvg + vAvg ) >> 2)); // must be logical shift operator
2256 buff[cnt + channelMap[2]] = Clamp8(uAvg + g);
2257 buff[cnt + channelMap[0]] = Clamp8(vAvg + g);
2258 buff[cnt + channelMap[3]] = aAvg;
2259 cnt += channels;
2260 if (!m_downsample || (j & 1)) uPos++;
2261 yPos++;
2262 }
2263 if (!m_downsample || (i & 1)) uOffset += uw;
2264 yOffset += yw;
2265 buff += pitch;
2266
2267 if (cb) {
2268 percent += dP;
2269 if ((*cb)(percent, true, data)) ReturnWithError(EscapePressed);
2270 }
2271 }
2272 break;
2273 }
2274 case ImageModeCMYK64:
2275 {
2276 ASSERT(m_header.channels == 4);
2277 ASSERT(m_header.bpp == 64);
2278
2279 const DataT yuvOffset16 = 1 << (UsedBitsPerChannel() - 1);
2280
2281 DataT* y = m_channel[0]; ASSERT(y);
2282 DataT* u = m_channel[1]; ASSERT(u);
2283 DataT* v = m_channel[2]; ASSERT(v);
2284 DataT* a = m_channel[3]; ASSERT(a);
2285 DataT g, aAvg;
2286 UINT32 cnt, channels;
2287
2288 if (bpp%16 == 0) {
2289 const int shift = 16 - UsedBitsPerChannel(); ASSERT(shift >= 0);
2290 UINT16 *buff16 = (UINT16 *)buff;
2291 int pitch16 = pitch/2;
2292 channels = bpp/16; ASSERT(channels >= m_header.channels);
2293
2294 for (i=0; i < h; i++) {
2295 UINT32 uPos = uOffset;
2296 UINT32 yPos = yOffset;
2297 cnt = 0;
2298 for (j=0; j < w; j++) {
2299 uAvg = u[uPos];
2300 vAvg = v[uPos];
2301 aAvg = a[uPos] + yuvOffset16;
2302 // Yuv
2303 g = y[yPos] + yuvOffset16 - ((uAvg + vAvg ) >> 2); // must be logical shift operator
2304 buff16[cnt + channelMap[1]] = Clamp16(g << shift);
2305 buff16[cnt + channelMap[2]] = Clamp16((uAvg + g) << shift);
2306 buff16[cnt + channelMap[0]] = Clamp16((vAvg + g) << shift);
2307 buff16[cnt + channelMap[3]] = Clamp16(aAvg << shift);
2308 cnt += channels;
2309 if (!m_downsample || (j & 1)) uPos++;
2310 yPos++;
2311 }
2312 if (!m_downsample || (i & 1)) uOffset += uw;
2313 yOffset += yw;
2314 buff16 += pitch16;
2315
2316 if (cb) {
2317 percent += dP;
2318 if ((*cb)(percent, true, data)) ReturnWithError(EscapePressed);
2319 }
2320 }
2321 } else {
2322 ASSERT(bpp%8 == 0);
2323 const int shift = __max(0, UsedBitsPerChannel() - 8);
2324 channels = bpp/8; ASSERT(channels >= m_header.channels);
2325
2326 for (i=0; i < h; i++) {
2327 UINT32 uPos = uOffset;
2328 UINT32 yPos = yOffset;
2329 cnt = 0;
2330 for (j=0; j < w; j++) {
2331 uAvg = u[uPos];
2332 vAvg = v[uPos];
2333 aAvg = a[uPos] + yuvOffset16;
2334 // Yuv
2335 g = y[yPos] + yuvOffset16 - ((uAvg + vAvg ) >> 2); // must be logical shift operator
2336 buff[cnt + channelMap[1]] = Clamp8(g >> shift);
2337 buff[cnt + channelMap[2]] = Clamp8((uAvg + g) >> shift);
2338 buff[cnt + channelMap[0]] = Clamp8((vAvg + g) >> shift);
2339 buff[cnt + channelMap[3]] = Clamp8(aAvg >> shift);
2340 cnt += channels;
2341 if (!m_downsample || (j & 1)) uPos++;
2342 yPos++;
2343 }
2344 if (!m_downsample || (i & 1)) uOffset += uw;
2345 yOffset += yw;
2346 buff += pitch;
2347
2348 if (cb) {
2349 percent += dP;
2350 if ((*cb)(percent, true, data)) ReturnWithError(EscapePressed);
2351 }
2352 }
2353 }
2354 break;
2355 }
2356 #ifdef __PGF32SUPPORT__
2357 case ImageModeGray32:
2358 {
2359 ASSERT(m_header.channels == 1);
2360 ASSERT(m_header.bpp == 32);
2361
2362 const int yuvOffset31 = 1 << (UsedBitsPerChannel() - 1);
2363 DataT* y = m_channel[0]; ASSERT(y);
2364
2365 if (bpp == 32) {
2366 const int shift = 31 - UsedBitsPerChannel(); ASSERT(shift >= 0);
2367 UINT32 *buff32 = (UINT32 *)buff;
2368 int pitch32 = pitch/4;
2369
2370 for (i=0; i < h; i++) {
2371 UINT32 yPos = yOffset;
2372 for (j = 0; j < w; j++) {
2373 buff32[j] = Clamp31((y[yPos++] + yuvOffset31) << shift);
2374 }
2375 yOffset += yw;
2376 buff32 += pitch32;
2377
2378 if (cb) {
2379 percent += dP;
2380 if ((*cb)(percent, true, data)) ReturnWithError(EscapePressed);
2381 }
2382 }
2383 } else if (bpp == 16) {
2384 const int usedBits = UsedBitsPerChannel();
2385 UINT16 *buff16 = (UINT16 *)buff;
2386 int pitch16 = pitch/2;
2387
2388 if (usedBits < 16) {
2389 const int shift = 16 - usedBits;
2390 for (i=0; i < h; i++) {
2391 UINT32 yPos = yOffset;
2392 for (j = 0; j < w; j++) {
2393 buff16[j] = Clamp16((y[yPos++] + yuvOffset31) << shift);
2394 }
2395 yOffset += yw;
2396 buff16 += pitch16;
2397
2398 if (cb) {
2399 percent += dP;
2400 if ((*cb)(percent, true, data)) ReturnWithError(EscapePressed);
2401 }
2402 }
2403 } else {
2404 const int shift = __max(0, usedBits - 16);
2405 for (i=0; i < h; i++) {
2406 UINT32 yPos = yOffset;
2407 for (j = 0; j < w; j++) {
2408 buff16[j] = Clamp16((y[yPos++] + yuvOffset31) >> shift);
2409 }
2410 yOffset += yw;
2411 buff16 += pitch16;
2412
2413 if (cb) {
2414 percent += dP;
2415 if ((*cb)(percent, true, data)) ReturnWithError(EscapePressed);
2416 }
2417 }
2418 }
2419 } else {
2420 ASSERT(bpp == 8);
2421 const int shift = __max(0, UsedBitsPerChannel() - 8);
2422
2423 for (i=0; i < h; i++) {
2424 UINT32 yPos = yOffset;
2425 for (j = 0; j < w; j++) {
2426 buff[j] = Clamp8((y[yPos++] + yuvOffset31) >> shift);
2427 }
2428 yOffset += yw;
2429 buff += pitch;
2430
2431 if (cb) {
2432 percent += dP;
2433 if ((*cb)(percent, true, data)) ReturnWithError(EscapePressed);
2434 }
2435 }
2436 }
2437 break;
2438 }
2439 #endif
2440 case ImageModeRGB12:
2441 {
2442 ASSERT(m_header.channels == 3);
2443 ASSERT(m_header.bpp == m_header.channels*4);
2444 ASSERT(bpp == m_header.channels*4);
2445 ASSERT(!m_downsample);
2446
2447 DataT* y = m_channel[0]; ASSERT(y);
2448 DataT* u = m_channel[1]; ASSERT(u);
2449 DataT* v = m_channel[2]; ASSERT(v);
2450 UINT16 yval;
2451 UINT32 cnt;
2452
2453 for (i=0; i < h; i++) {
2454 UINT32 yPos = yOffset;
2455 cnt = 0;
2456 for (j=0; j < w; j++) {
2457 // Yuv
2458 uAvg = u[yPos];
2459 vAvg = v[yPos];
2460 yval = Clamp4(y[yPos] + YUVoffset4 - ((uAvg + vAvg ) >> 2)); // must be logical shift operator
2461 if (j%2 == 0) {
2462 buff[cnt] = UINT8(Clamp4(vAvg + yval) | (yval << 4));
2463 cnt++;
2464 buff[cnt] = Clamp4(uAvg + yval);
2465 } else {
2466 buff[cnt] |= Clamp4(vAvg + yval) << 4;
2467 cnt++;
2468 buff[cnt] = UINT8(yval | (Clamp4(uAvg + yval) << 4));
2469 cnt++;
2470 }
2471 yPos++;
2472 }
2473 yOffset += yw;
2474 buff += pitch;
2475
2476 if (cb) {
2477 percent += dP;
2478 if ((*cb)(percent, true, data)) ReturnWithError(EscapePressed);
2479 }
2480 }
2481 break;
2482 }
2483 case ImageModeRGB16:
2484 {
2485 ASSERT(m_header.channels == 3);
2486 ASSERT(m_header.bpp == 16);
2487 ASSERT(bpp == 16);
2488 ASSERT(!m_downsample);
2489
2490 DataT* y = m_channel[0]; ASSERT(y);
2491 DataT* u = m_channel[1]; ASSERT(u);
2492 DataT* v = m_channel[2]; ASSERT(v);
2493 UINT16 yval;
2494 UINT16 *buff16 = (UINT16 *)buff;
2495 int pitch16 = pitch/2;
2496
2497 for (i=0; i < h; i++) {
2498 UINT32 yPos = yOffset;
2499 for (j = 0; j < w; j++) {
2500 // Yuv
2501 uAvg = u[yPos];
2502 vAvg = v[yPos];
2503 yval = Clamp6(y[yPos++] + YUVoffset6 - ((uAvg + vAvg ) >> 2)); // must be logical shift operator
2504 buff16[j] = (yval << 5) | ((Clamp6(uAvg + yval) >> 1) << 11) | (Clamp6(vAvg + yval) >> 1);
2505 }
2506 yOffset += yw;
2507 buff16 += pitch16;
2508
2509 if (cb) {
2510 percent += dP;
2511 if ((*cb)(percent, true, data)) ReturnWithError(EscapePressed);
2512 }
2513 }
2514 break;
2515 }
2516 default:
2517 ASSERT(false);
2518 }
2519
2520 #ifdef _DEBUG
2521 // display ROI (RGB) in debugger
2522 roiimage.width = w;
2523 roiimage.height = h;
2524 if (pitch > 0) {
2525 roiimage.pitch = pitch;
2526 roiimage.data = buff;
2527 } else {
2528 roiimage.pitch = -pitch;
2529 roiimage.data = buff + (h - 1)*pitch;
2530 }
2531 #endif
2532
2533 }
ImageModeIndexedColor
#define ImageModeIndexedColor
Definition: PGFplatform.h:100
PGFMagicVersion::version
UINT8 version
PGF version.
Definition: PGFtypes.h:115
ImageModeRGB12
#define ImageModeRGB12
Definition: PGFplatform.h:117
PGFHeader::mode
UINT8 mode
image mode according to Adobe's image modes
Definition: PGFtypes.h:158
ImageModeHSBColor
#define ImageModeHSBColor
Definition: PGFplatform.h:104
MaxChannels
#define MaxChannels
maximum number of (color) channels
Definition: PGFtypes.h:64
CPGFImage::UsedBitsPerChannel
BYTE UsedBitsPerChannel() const
Definition: PGFimage.cpp:755
DataT
INT32 DataT
Definition: PGFtypes.h:268
ImageModeRGBA
#define ImageModeRGBA
Definition: PGFplatform.h:115
CPGFImage::m_header
PGFHeader m_header
PGF file header.
Definition: PGFimage.h:529
ImageModeLabColor
#define ImageModeLabColor
Definition: PGFplatform.h:107
CPGFImage::m_channel
DataT * m_channel[MaxChannels]
untransformed channels in YUV format
Definition: PGFimage.h:522
CPGFImage::m_preHeader
PGFPreHeader m_preHeader
PGF pre-header.
Definition: PGFimage.h:528
ImageModeGray16
#define ImageModeGray16
Definition: PGFplatform.h:108
PGFRect::right
UINT32 right
Definition: PGFtypes.h:225
CPGFImage::GetAlignedROI
PGFRect GetAlignedROI(int c=0) const
ImageModeLab48
#define ImageModeLab48
Definition: PGFplatform.h:110
CPGFImage::Clamp6
UINT16 Clamp6(DataT v) const
Definition: PGFimage.h:566
ImageModeCMYKColor
#define ImageModeCMYKColor
Definition: PGFplatform.h:102
ImageModeGrayScale
#define ImageModeGrayScale
Definition: PGFplatform.h:99
PGFHeader::bpp
UINT8 bpp
bits per pixel
Definition: PGFtypes.h:156
YUVoffset6
#define YUVoffset6
Definition: PGFimage.cpp:37
CPGFImage::Clamp31
UINT32 Clamp31(DataT v) const
Definition: PGFimage.h:576
CPGFImage::Clamp16
UINT16 Clamp16(DataT v) const
Definition: PGFimage.h:573
PGFRect::Height
UINT32 Height() const
Definition: PGFtypes.h:258
CPGFImage::m_downsample
bool m_downsample
chrominance channels are downsampled
Definition: PGFimage.h:535
__max
#define __max(x, y)
Definition: PGFplatform.h:92
CPGFImage::m_width
UINT32 m_width[MaxChannels]
width of each channel at current level
Definition: PGFimage.h:526
ImageModeGray32
#define ImageModeGray32
Definition: PGFplatform.h:116
PGFRect::top
UINT32 top
Definition: PGFtypes.h:225
CPGFImage::ROIisSupported
bool ROIisSupported() const
Definition: PGFimage.h:466
PGFRect::left
UINT32 left
Definition: PGFtypes.h:225
CPGFImage::Clamp8
UINT8 Clamp8(DataT v) const
Definition: PGFimage.h:569
CPGFImage::Clamp4
UINT8 Clamp4(DataT v) const
Definition: PGFimage.h:563
ImageModeRGBColor
#define ImageModeRGBColor
Definition: PGFplatform.h:101
ImageModeHSLColor
#define ImageModeHSLColor
Definition: PGFplatform.h:103
ImageModeBitmap
#define ImageModeBitmap
Definition: PGFplatform.h:98
Version7
#define Version7
Codec major and minor version number stored in PGFHeader.
Definition: PGFtypes.h:73
PGFHeader::channels
UINT8 channels
number of channels
Definition: PGFtypes.h:157
PGFRect
Rectangle.
Definition: PGFtypes.h:224
PGFRect::Width
UINT32 Width() const
Definition: PGFtypes.h:255
ImageModeCMYK64
#define ImageModeCMYK64
Definition: PGFplatform.h:111
YUVoffset4
#define YUVoffset4
Definition: PGFimage.cpp:36
ImageModeRGB16
#define ImageModeRGB16
Definition: PGFplatform.h:118
YUVoffset8
#define YUVoffset8
Definition: PGFimage.cpp:38
CPGFImage::ComputeLevelROI
PGFRect ComputeLevelROI() const
ImageModeRGB48
#define ImageModeRGB48
Definition: PGFplatform.h:109
PGFRect::bottom
UINT32 bottom
Definition: PGFtypes.h:225
Version5
#define Version5
new coding scheme since major version 5
Definition: PGFtypes.h:71
CPGFImage::m_height
UINT32 m_height[MaxChannels]
height of each channel at current level
Definition: PGFimage.h:527

## ◆ GetChannel()

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

Return an internal YUV image channel.

Parameters

  c | A channel index

Returns
  An internal YUV image channel

Definition at line 317 of file PGFimage.h.

317 { ASSERT(c >= 0 && c < MaxChannels); return m_channel[c]; }
MaxChannels
#define MaxChannels
maximum number of (color) channels
Definition: PGFtypes.h:64
CPGFImage::m_channel
DataT * m_channel[MaxChannels]
untransformed channels in YUV format
Definition: PGFimage.h:522

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

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

Definition at line 1349 of file PGFimage.cpp.

1349 {
1350 if (iFirstColor + nColors > ColorTableLen) ReturnWithError(ColorTableError);
1351
1352 for (UINT32 i=iFirstColor, j=0; j < nColors; i++, j++) {
1353 prgbColors[j] = m_postHeader.clut[i];
1354 }
1355 }
ColorTableLen
#define ColorTableLen
size of color lookup table (clut)
Definition: PGFtypes.h:66
CPGFImage::m_postHeader
PGFPostHeader m_postHeader
PGF post-header.
Definition: PGFimage.h:530
PGFPostHeader::clut
RGBQUAD clut[ColorTableLen]
color table for indexed color images (optional part of file header)
Definition: PGFtypes.h:169

## ◆ GetColorTable() [2/2]

const RGBQUAD* CPGFImage::GetColorTable | ( |  | ) | const
| inline

Returns
  Address of color table

Definition at line 330 of file PGFimage.h.

330 { return m_postHeader.clut; }
CPGFImage::m_postHeader
PGFPostHeader m_postHeader
PGF post-header.
Definition: PGFimage.h:530
PGFPostHeader::clut
RGBQUAD clut[ColorTableLen]
color table for indexed color images (optional part of file header)
Definition: PGFtypes.h:169

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

648 {
649 ASSERT(m_decoder);
650 return m_decoder->GetEncodedHeaderLength();
651 }
CPGFImage::m_decoder
CDecoder * m_decoder
PGF decoder.
Definition: PGFimage.h:523
CDecoder::GetEncodedHeaderLength
UINT32 GetEncodedHeaderLength() const
Definition: Decoder.h:136

## ◆ GetEncodedLevelLength()

UINT32 CPGFImage::GetEncodedLevelLength | ( | int | level | ) | const
| inline

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

Parameters

  level | The image level

Returns
  The length of a PGF level in bytes

Definition at line 367 of file PGFimage.h.

367 { ASSERT(level >= 0 && level < m_header.nLevels); return m_levelLength[m_header.nLevels - level - 1]; }
CPGFImage::m_header
PGFHeader m_header
PGF file header.
Definition: PGFimage.h:529
PGFHeader::nLevels
UINT8 nLevels
number of FWT transforms
Definition: PGFtypes.h:154
CPGFImage::m_levelLength
UINT32 * m_levelLength
length of each level in bytes; first level starts immediately after this array
Definition: PGFimage.h:525

## ◆ GetHeader()

const PGFHeader* CPGFImage::GetHeader | ( |  | ) | const
| inline

Return the PGF header structure.

Returns
  A PGF header structure

Definition at line 335 of file PGFimage.h.

335 { return &m_header; }
CPGFImage::m_header
PGFHeader m_header
PGF file header.
Definition: PGFimage.h:529

## ◆ 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 341 of file PGFimage.h.

341 { return (1 << m_header.usedBitsPerChannel) - 1; }
CPGFImage::m_header
PGFHeader m_header
PGF file header.
Definition: PGFimage.h:529
PGFHeader::usedBitsPerChannel
UINT8 usedBitsPerChannel
number of used bits per channel in 16- and 32-bit per channel modes
Definition: PGFtypes.h:159

## ◆ GetUserData()

const UINT8 * CPGFImage::GetUserData | ( | UINT32 & | cachedSize,
|  | UINT32 * | pTotalSize = `nullptr`
| ) |  | const

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

Parameters

  cachedSize | [out] Size of returned user data in bytes.
  pTotalSize | [optional out] Pointer to return the size of user data stored in image header in bytes.

Returns
  A pointer to user data or nullptr if there is no user data available.

Return user data and size of user data. Precondition: The PGF image has been opened with a call of Open(...). In an encoder scenario don't call this method before WriteHeader().

Parameters

  cachedSize | [out] Size of returned user data in bytes.
  pTotalSize | [optional out] Pointer to return the size of user data stored in image header in bytes.

Returns
  A pointer to user data or nullptr if there is no user data available.

Definition at line 337 of file PGFimage.cpp.

337 {
338 cachedSize = m_postHeader.cachedUserDataLen;
339 if (pTotalSize) *pTotalSize = m_postHeader.userDataLen;
340 return m_postHeader.userData;
341 }
PGFPostHeader::userDataLen
UINT32 userDataLen
user data size in bytes (not part of file header)
Definition: PGFtypes.h:171
PGFPostHeader::userData
UINT8 * userData
user data of size userDataLen (optional part of file header)
Definition: PGFtypes.h:170
PGFPostHeader::cachedUserDataLen
UINT32 cachedUserDataLen
cached user data size in bytes (not part of file header)
Definition: PGFtypes.h:172
CPGFImage::m_postHeader
PGFPostHeader m_postHeader
PGF post-header.
Definition: PGFimage.h:530

## ◆ 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 346 of file PGFimage.h.

346 { return m_userDataPos; }
CPGFImage::m_userDataPos
UINT64 m_userDataPos
stream position of user data
Definition: PGFimage.h:531

## ◆ GetYUV()

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

Get YUV image data in interleaved format: (ordering is YUV[A]) The absolute value of pitch is the number of bytes of an image row of the given image buffer. If pitch is negative, then the image buffer must point to the last row of a bottom-up image (first byte on last row). if pitch is positive, then the image buffer must point to the first row of a top-down image (first byte). The sequence of output channels in the output image buffer does not need to be the same as provided by PGF. In case of different sequences you have to provide a channelMap of size of expected channels (depending on image mode). For example, PGF provides a channel sequence BGR in RGB color mode. If your provided image buffer expects a channel sequence VUY, then the channelMap looks like { 2, 1, 0 }. It might throw an IOException.

Parameters

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

Get YUV image data in interleaved format: (ordering is YUV[A]) The absolute value of pitch is the number of bytes of an image row of the given image buffer. If pitch is negative, then the image buffer must point to the last row of a bottom-up image (first byte on last row). if pitch is positive, then the image buffer must point to the first row of a top-down image (first byte). The sequence of output channels in the output image buffer does not need to be the same as provided by PGF. In case of different sequences you have to provide a channelMap of size of expected channels (depending on image mode). For example, PGF provides a channel sequence BGR in RGB color mode. If your provided image buffer expects a channel sequence VUY, then the channelMap looks like { 2, 1, 0 }. It might throw an IOException.

Parameters

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

Definition at line 2549 of file PGFimage.cpp.

2549 {
2550 ASSERT(buff);
2551 const UINT32 w = m_width[0];
2552 const UINT32 h = m_height[0];
2553 const bool wOdd = (1 == w%2);
2554 const int dataBits = DataTSize*8; ASSERT(dataBits == 16 || dataBits == 32);
2555 const int pitch2 = pitch/DataTSize;
2556 const int yuvOffset = (dataBits == 16) ? YUVoffset8 : YUVoffset16;
2557 const double dP = 1.0/h;
2558
2559 int defMap[] = { 0, 1, 2, 3, 4, 5, 6, 7 }; ASSERT(sizeof(defMap)/sizeof(defMap[0]) == MaxChannels);
2560 if (channelMap == nullptr) channelMap = defMap;
2561 int sampledPos = 0, yPos = 0;
2562 DataT uAvg, vAvg;
2563 double percent = 0;
2564 UINT32 i, j;
2565
2566 if (m_header.channels == 3) {
2567 ASSERT(bpp%dataBits == 0);
2568
2569 DataT* y = m_channel[0]; ASSERT(y);
2570 DataT* u = m_channel[1]; ASSERT(u);
2571 DataT* v = m_channel[2]; ASSERT(v);
2572 int cnt, channels = bpp/dataBits; ASSERT(channels >= m_header.channels);
2573
2574 for (i=0; i < h; i++) {
2575 if (i%2) sampledPos -= (w + 1)/2;
2576 cnt = 0;
2577 for (j=0; j < w; j++) {
2578 if (m_downsample) {
2579 // image was downsampled
2580 uAvg = u[sampledPos];
2581 vAvg = v[sampledPos];
2582 } else {
2583 uAvg = u[yPos];
2584 vAvg = v[yPos];
2585 }
2586 buff[cnt + channelMap[0]] = y[yPos];
2587 buff[cnt + channelMap[1]] = uAvg;
2588 buff[cnt + channelMap[2]] = vAvg;
2589 yPos++;
2590 cnt += channels;
2591 if (j%2) sampledPos++;
2592 }
2593 buff += pitch2;
2594 if (wOdd) sampledPos++;
2595
2596 if (cb) {
2597 percent += dP;
2598 if ((*cb)(percent, true, data)) ReturnWithError(EscapePressed);
2599 }
2600 }
2601 } else if (m_header.channels == 4) {
2602 ASSERT(m_header.bpp == m_header.channels*8);
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 DataT* a = m_channel[3]; ASSERT(a);
2609 UINT8 aAvg;
2610 int cnt, channels = bpp/dataBits; ASSERT(channels >= m_header.channels);
2611
2612 for (i=0; i < h; i++) {
2613 if (i%2) sampledPos -= (w + 1)/2;
2614 cnt = 0;
2615 for (j=0; j < w; j++) {
2616 if (m_downsample) {
2617 // image was downsampled
2618 uAvg = u[sampledPos];
2619 vAvg = v[sampledPos];
2620 aAvg = Clamp8(a[sampledPos] + yuvOffset);
2621 } else {
2622 uAvg = u[yPos];
2623 vAvg = v[yPos];
2624 aAvg = Clamp8(a[yPos] + yuvOffset);
2625 }
2626 // Yuv
2627 buff[cnt + channelMap[0]] = y[yPos];
2628 buff[cnt + channelMap[1]] = uAvg;
2629 buff[cnt + channelMap[2]] = vAvg;
2630 buff[cnt + channelMap[3]] = aAvg;
2631 yPos++;
2632 cnt += channels;
2633 if (j%2) sampledPos++;
2634 }
2635 buff += pitch2;
2636 if (wOdd) sampledPos++;
2637
2638 if (cb) {
2639 percent += dP;
2640 if ((*cb)(percent, true, data)) ReturnWithError(EscapePressed);
2641 }
2642 }
2643 }
2644 }
YUVoffset16
#define YUVoffset16
Definition: PGFimage.cpp:39
MaxChannels
#define MaxChannels
maximum number of (color) channels
Definition: PGFtypes.h:64
DataT
INT32 DataT
Definition: PGFtypes.h:268
CPGFImage::m_header
PGFHeader m_header
PGF file header.
Definition: PGFimage.h:529
DataTSize
#define DataTSize
Definition: PGFtypes.h:282
CPGFImage::m_channel
DataT * m_channel[MaxChannels]
untransformed channels in YUV format
Definition: PGFimage.h:522
PGFHeader::bpp
UINT8 bpp
bits per pixel
Definition: PGFtypes.h:156
CPGFImage::m_downsample
bool m_downsample
chrominance channels are downsampled
Definition: PGFimage.h:535
CPGFImage::m_width
UINT32 m_width[MaxChannels]
width of each channel at current level
Definition: PGFimage.h:526
CPGFImage::Clamp8
UINT8 Clamp8(DataT v) const
Definition: PGFimage.h:569
PGFHeader::channels
UINT8 channels
number of channels
Definition: PGFtypes.h:157
YUVoffset8
#define YUVoffset8
Definition: PGFimage.cpp:38
CPGFImage::m_height
UINT32 m_height[MaxChannels]
height of each channel at current level
Definition: PGFimage.h:527

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

  level | A level

Returns
  Image level height in pixels

Definition at line 420 of file PGFimage.h.

420 { ASSERT(level >= 0); return LevelSizeL(m_header.height, level); }
CPGFImage::m_header
PGFHeader m_header
PGF file header.
Definition: PGFimage.h:529
CPGFImage::LevelSizeL
static UINT32 LevelSizeL(UINT32 size, int level)
Definition: PGFimage.h:499
PGFHeader::height
UINT32 height
image height in pixels
Definition: PGFtypes.h:153

## ◆ ImportBitmap()

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

Import an image from a specified image buffer. This method is usually called before Write(...) and after SetHeader(...). The absolute value of pitch is the number of bytes of an image row. If pitch is negative, then buff points to the last row of a bottom-up image (first byte on last row). If pitch is positive, then buff points to the first row of a top-down image (first byte). The sequence of input channels in the input image buffer does not need to be the same as expected from PGF. In case of different sequences you have to provide a channelMap of size of expected channels (depending on image mode). For example, PGF expects in RGB color mode a channel sequence BGR. If your provided image buffer contains a channel sequence ARGB, then the channelMap looks like { 3, 2, 1, 0 }. It might throw an IOException.

Parameters

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

Definition at line 791 of file PGFimage.cpp.

791 {
792 ASSERT(buff);
793 ASSERT(m_channel[0]);
794
795 // color transform
796 RgbToYuv(pitch, buff, bpp, channelMap, cb, data);
797
798 if (m_downsample) {
799 // Subsampling of the chrominance and alpha channels
800 for (int i=1; i < m_header.channels; i++) {
801 Downsample(i);
802 }
803 }
804 }
CPGFImage::m_header
PGFHeader m_header
PGF file header.
Definition: PGFimage.h:529
CPGFImage::m_channel
DataT * m_channel[MaxChannels]
untransformed channels in YUV format
Definition: PGFimage.h:522
CPGFImage::m_downsample
bool m_downsample
chrominance channels are downsampled
Definition: PGFimage.h:535
PGFHeader::channels
UINT8 channels
number of channels
Definition: PGFtypes.h:157
CPGFImage::RgbToYuv
void RgbToYuv(int pitch, UINT8 *rgbBuff, BYTE bpp, int channelMap[], CallbackPtr cb, void *data)
Definition: PGFimage.cpp:1388
CPGFImage::Downsample
void Downsample(int nChannel)
Definition: PGFimage.cpp:809

## ◆ ImportIsSupported()

bool CPGFImage::ImportIsSupported | ( | BYTE | mode | ) |
| static

Check for valid import image mode.

Parameters

  mode | Image mode

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

Definition at line 1304 of file PGFimage.cpp.

1304 {
1305 size_t size = DataTSize;
1306
1307 if (size >= 2) {
1308 switch(mode) {
1309 case ImageModeBitmap:
1310 case ImageModeIndexedColor:
1311 case ImageModeGrayScale:
1312 case ImageModeRGBColor:
1313 case ImageModeCMYKColor:
1314 case ImageModeHSLColor:
1315 case ImageModeHSBColor:
1316 //case ImageModeDuotone:
1317 case ImageModeLabColor:
1318 case ImageModeRGB12:
1319 case ImageModeRGB16:
1320 case ImageModeRGBA:
1321 return true;
1322 }
1323 }
1324 if (size >= 3) {
1325 switch(mode) {
1326 case ImageModeGray16:
1327 case ImageModeRGB48:
1328 case ImageModeLab48:
1329 case ImageModeCMYK64:
1330 //case ImageModeDuotone16:
1331 return true;
1332 }
1333 }
1334 if (size >=4) {
1335 switch(mode) {
1336 case ImageModeGray32:
1337 return true;
1338 }
1339 }
1340 return false;
1341 }
ImageModeIndexedColor
#define ImageModeIndexedColor
Definition: PGFplatform.h:100
ImageModeRGB12
#define ImageModeRGB12
Definition: PGFplatform.h:117
ImageModeHSBColor
#define ImageModeHSBColor
Definition: PGFplatform.h:104
ImageModeRGBA
#define ImageModeRGBA
Definition: PGFplatform.h:115
DataTSize
#define DataTSize
Definition: PGFtypes.h:282
ImageModeLabColor
#define ImageModeLabColor
Definition: PGFplatform.h:107
ImageModeGray16
#define ImageModeGray16
Definition: PGFplatform.h:108
ImageModeLab48
#define ImageModeLab48
Definition: PGFplatform.h:110
ImageModeCMYKColor
#define ImageModeCMYKColor
Definition: PGFplatform.h:102
ImageModeGrayScale
#define ImageModeGrayScale
Definition: PGFplatform.h:99
ImageModeGray32
#define ImageModeGray32
Definition: PGFplatform.h:116
ImageModeRGBColor
#define ImageModeRGBColor
Definition: PGFplatform.h:101
ImageModeHSLColor
#define ImageModeHSLColor
Definition: PGFplatform.h:103
ImageModeBitmap
#define ImageModeBitmap
Definition: PGFplatform.h:98
ImageModeCMYK64
#define ImageModeCMYK64
Definition: PGFplatform.h:111
ImageModeRGB16
#define ImageModeRGB16
Definition: PGFplatform.h:118
ImageModeRGB48
#define ImageModeRGB48
Definition: PGFplatform.h:109

## ◆ ImportYUV()

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

Import a YUV image from a specified image buffer. The absolute value of pitch is the number of bytes of an image row. If pitch is negative, then buff points to the last row of a bottom-up image (first byte on last row). If pitch is positive, then buff points to the first row of a top-down image (first byte). The sequence of input channels in the input image buffer does not need to be the same as expected from PGF. In case of different sequences you have to provide a channelMap of size of expected channels (depending on image mode). For example, PGF expects in RGB color mode a channel sequence BGR. If your provided image buffer contains a channel sequence VUY, then the channelMap looks like { 2, 1, 0 }. It might throw an IOException.

Parameters

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

Import a YUV image from a specified image buffer. The absolute value of pitch is the number of bytes of an image row. If pitch is negative, then buff points to the last row of a bottom-up image (first byte on last row). If pitch is positive, then buff points to the first row of a top-down image (first byte). The sequence of input channels in the input image buffer does not need to be the same as expected from PGF. In case of different sequences you have to provide a channelMap of size of expected channels (depending on image mode). For example, PGF expects in RGB color mode a channel sequence BGR. If your provided image buffer contains a channel sequence VUY, then the channelMap looks like { 2, 1, 0 }. It might throw an IOException.

Parameters

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

Definition at line 2660 of file PGFimage.cpp.

2660 {
2661 ASSERT(buff);
2662 const double dP = 1.0/m_header.height;
2663 const int dataBits = DataTSize*8; ASSERT(dataBits == 16 || dataBits == 32);
2664 const int pitch2 = pitch/DataTSize;
2665 const int yuvOffset = (dataBits == 16) ? YUVoffset8 : YUVoffset16;
2666
2667 int yPos = 0, cnt = 0;
2668 double percent = 0;
2669 int defMap[] = { 0, 1, 2, 3, 4, 5, 6, 7 }; ASSERT(sizeof(defMap)/sizeof(defMap[0]) == MaxChannels);
2670
2671 if (channelMap == nullptr) channelMap = defMap;
2672
2673 if (m_header.channels == 3) {
2674 ASSERT(bpp%dataBits == 0);
2675
2676 DataT* y = m_channel[0]; ASSERT(y);
2677 DataT* u = m_channel[1]; ASSERT(u);
2678 DataT* v = m_channel[2]; ASSERT(v);
2679 const int channels = bpp/dataBits; ASSERT(channels >= m_header.channels);
2680
2681 for (UINT32 h=0; h < m_header.height; h++) {
2682 if (cb) {
2683 if ((*cb)(percent, true, data)) ReturnWithError(EscapePressed);
2684 percent += dP;
2685 }
2686
2687 cnt = 0;
2688 for (UINT32 w=0; w < m_header.width; w++) {
2689 y[yPos] = buff[cnt + channelMap[0]];
2690 u[yPos] = buff[cnt + channelMap[1]];
2691 v[yPos] = buff[cnt + channelMap[2]];
2692 yPos++;
2693 cnt += channels;
2694 }
2695 buff += pitch2;
2696 }
2697 } else if (m_header.channels == 4) {
2698 ASSERT(bpp%dataBits == 0);
2699
2700 DataT* y = m_channel[0]; ASSERT(y);
2701 DataT* u = m_channel[1]; ASSERT(u);
2702 DataT* v = m_channel[2]; ASSERT(v);
2703 DataT* a = m_channel[3]; ASSERT(a);
2704 const int channels = bpp/dataBits; ASSERT(channels >= m_header.channels);
2705
2706 for (UINT32 h=0; h < m_header.height; h++) {
2707 if (cb) {
2708 if ((*cb)(percent, true, data)) ReturnWithError(EscapePressed);
2709 percent += dP;
2710 }
2711
2712 cnt = 0;
2713 for (UINT32 w=0; w < m_header.width; w++) {
2714 y[yPos] = buff[cnt + channelMap[0]];
2715 u[yPos] = buff[cnt + channelMap[1]];
2716 v[yPos] = buff[cnt + channelMap[2]];
2717 a[yPos] = buff[cnt + channelMap[3]] - yuvOffset;
2718 yPos++;
2719 cnt += channels;
2720 }
2721 buff += pitch2;
2722 }
2723 }
2724
2725 if (m_downsample) {
2726 // Subsampling of the chrominance and alpha channels
2727 for (int i=1; i < m_header.channels; i++) {
2728 Downsample(i);
2729 }
2730 }
2731 }
YUVoffset16
#define YUVoffset16
Definition: PGFimage.cpp:39
MaxChannels
#define MaxChannels
maximum number of (color) channels
Definition: PGFtypes.h:64
PGFHeader::width
UINT32 width
image width in pixels
Definition: PGFtypes.h:152
DataT
INT32 DataT
Definition: PGFtypes.h:268
CPGFImage::m_header
PGFHeader m_header
PGF file header.
Definition: PGFimage.h:529
DataTSize
#define DataTSize
Definition: PGFtypes.h:282
CPGFImage::m_channel
DataT * m_channel[MaxChannels]
untransformed channels in YUV format
Definition: PGFimage.h:522
CPGFImage::m_downsample
bool m_downsample
chrominance channels are downsampled
Definition: PGFimage.h:535
PGFHeader::channels
UINT8 channels
number of channels
Definition: PGFtypes.h:157
CPGFImage::Downsample
void Downsample(int nChannel)
Definition: PGFimage.cpp:809
YUVoffset8
#define YUVoffset8
Definition: PGFimage.cpp:38
PGFHeader::height
UINT32 height
image height in pixels
Definition: PGFtypes.h:153

## ◆ Init()

void CPGFImage::Init | ( |  | ) |
| private

Definition at line 69 of file PGFimage.cpp.

69 {
70 // init pointers
71 m_decoder = nullptr;
72 m_encoder = nullptr;
73 m_levelLength = nullptr;
74
75 // init members
76 #ifdef __PGFROISUPPORT__
77 m_streamReinitialized = false;
78 #endif
79 m_currentLevel = 0;
80 m_quant = 0;
81 m_userDataPos = 0;
82 m_downsample = false;
83 m_favorSpeedOverSize = false;
84 m_useOMPinEncoder = true;
85 m_useOMPinDecoder = true;
86 m_cb = nullptr;
87 m_cbArg = nullptr;
88 m_progressMode = PM_Relative;
89 m_percent = 0;
90 m_userDataPolicy = UP_CacheAll;
91
92 // init preHeader
93 memcpy(m_preHeader.magic, PGFMagic, 3);
94 m_preHeader.version = PGFVersion;
95 m_preHeader.hSize = 0;
96
97 // init postHeader
98 m_postHeader.userData = nullptr;
99 m_postHeader.userDataLen = 0;
100 m_postHeader.cachedUserDataLen = 0;
101
102 // init channels
103 for (int i = 0; i < MaxChannels; i++) {
104 m_channel[i] = nullptr;
105 m_wtChannel[i] = nullptr;
106 }
107
108 // set image width and height
109 for (int i = 0; i < MaxChannels; i++) {
110 m_width[0] = 0;
111 m_height[0] = 0;
112 }
113 }
CPGFImage::m_favorSpeedOverSize
bool m_favorSpeedOverSize
favor encoding speed over compression ratio
Definition: PGFimage.h:536
CPGFImage::m_userDataPos
UINT64 m_userDataPos
stream position of user data
Definition: PGFimage.h:531
CPGFImage::m_useOMPinDecoder
bool m_useOMPinDecoder
use Open MP in decoder
Definition: PGFimage.h:538
PGFMagicVersion::version
UINT8 version
PGF version.
Definition: PGFtypes.h:115
PGFVersion
#define PGFVersion
current standard version
Definition: PGFtypes.h:76
MaxChannels
#define MaxChannels
maximum number of (color) channels
Definition: PGFtypes.h:64
PM_Relative
Definition: PGFtypes.h:100
PGFPostHeader::userDataLen
UINT32 userDataLen
user data size in bytes (not part of file header)
Definition: PGFtypes.h:171
CPGFImage::m_decoder
CDecoder * m_decoder
PGF decoder.
Definition: PGFimage.h:523
PGFPostHeader::userData
UINT8 * userData
user data of size userDataLen (optional part of file header)
Definition: PGFtypes.h:170
CPGFImage::m_streamReinitialized
bool m_streamReinitialized
stream has been reinitialized
Definition: PGFimage.h:540
CPGFImage::m_quant
BYTE m_quant
quantization parameter
Definition: PGFimage.h:534
CPGFImage::m_cbArg
void * m_cbArg
refresh callback argument
Definition: PGFimage.h:546
CPGFImage::m_channel
DataT * m_channel[MaxChannels]
untransformed channels in YUV format
Definition: PGFimage.h:522
CPGFImage::m_preHeader
PGFPreHeader m_preHeader
PGF pre-header.
Definition: PGFimage.h:528
PGFMagic
#define PGFMagic
PGF identification.
Definition: PGFtypes.h:61
UP_CacheAll
Definition: PGFtypes.h:101
PGFPostHeader::cachedUserDataLen
UINT32 cachedUserDataLen
cached user data size in bytes (not part of file header)
Definition: PGFtypes.h:172
CPGFImage::m_progressMode
ProgressMode m_progressMode
progress mode used in Read and Write; PM_Relative is default mode
Definition: PGFimage.h:548
CPGFImage::m_wtChannel
CWaveletTransform * m_wtChannel[MaxChannels]
wavelet transformed color channels
Definition: PGFimage.h:521
PGFMagicVersion::magic
char magic[3]
PGF identification = "PGF".
Definition: PGFtypes.h:114
CPGFImage::m_postHeader
PGFPostHeader m_postHeader
PGF post-header.
Definition: PGFimage.h:530
CPGFImage::m_downsample
bool m_downsample
chrominance channels are downsampled
Definition: PGFimage.h:535
CPGFImage::m_levelLength
UINT32 * m_levelLength
length of each level in bytes; first level starts immediately after this array
Definition: PGFimage.h:525
PGFPreHeader::hSize
UINT32 hSize
total size of PGFHeader, [ColorTable], and [UserData] in bytes (since Version 6: 4 Bytes)
Definition: PGFtypes.h:124
CPGFImage::m_width
UINT32 m_width[MaxChannels]
width of each channel at current level
Definition: PGFimage.h:526
CPGFImage::m_useOMPinEncoder
bool m_useOMPinEncoder
use Open MP in encoder
Definition: PGFimage.h:537
CPGFImage::m_userDataPolicy
UINT32 m_userDataPolicy
user data (metadata) policy during open
Definition: PGFimage.h:533
CPGFImage::m_percent
double m_percent
progress [0..1]
Definition: PGFimage.h:547
CPGFImage::m_cb
RefreshCB m_cb
pointer to refresh callback procedure
Definition: PGFimage.h:545
CPGFImage::m_encoder
CEncoder * m_encoder
PGF encoder.
Definition: PGFimage.h:524
CPGFImage::m_currentLevel
int m_currentLevel
transform level of current image
Definition: PGFimage.h:532
CPGFImage::m_height
UINT32 m_height[MaxChannels]
height of each channel at current level
Definition: PGFimage.h:527

## ◆ IsFullyRead()

bool CPGFImage::IsFullyRead | ( |  | ) | const
| inline

Return true if all levels have been read.

Definition at line 436 of file PGFimage.h.

436 { return m_currentLevel == 0; }
CPGFImage::m_currentLevel
int m_currentLevel
transform level of current image
Definition: PGFimage.h:532

## ◆ IsOpen()

bool CPGFImage::IsOpen | ( |  | ) | const
| inline

Returns true if the PGF has been opened for reading.

Definition at line 77 of file PGFimage.h.

77 { return m_decoder != nullptr; }
CPGFImage::m_decoder
CDecoder * m_decoder
PGF decoder.
Definition: PGFimage.h:523

## ◆ 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 427 of file PGFimage.h.

427 { return (BYTE)m_currentLevel; }
CPGFImage::m_currentLevel
int m_currentLevel
transform level of current image
Definition: PGFimage.h:532

## ◆ Levels()

BYTE CPGFImage::Levels | ( |  | ) | const
| inline

Return the number of image levels.

Returns
  Number of image levels

Definition at line 432 of file PGFimage.h.

432 { return m_header.nLevels; }
CPGFImage::m_header
PGFHeader m_header
PGF file header.
Definition: PGFimage.h:529
PGFHeader::nLevels
UINT8 nLevels
number of FWT transforms
Definition: PGFtypes.h:154

## ◆ LevelSizeH()

static UINT32 CPGFImage::LevelSizeH | ( | UINT32 | size,
|  | int | level
| ) |  |
| inline static

Compute and return image width/height of HH subband at given level.

Parameters

  size | Original image size (e.g. width or height at level 0)
  level | An image level

Returns
  high pass size at given level in pixels

Definition at line 506 of file PGFimage.h.

506 { ASSERT(level >= 0); UINT32 d = 1 << (level - 1); return (size + d - 1) >> level; }

## ◆ LevelSizeL()

static UINT32 CPGFImage::LevelSizeL | ( | UINT32 | size,
|  | int | level
| ) |  |
| inline static

Compute and return image width/height of LL subband at given level.

Parameters

  size | Original image size (e.g. width or height at level 0)
  level | An image level

Returns
  Image width/height at given level in pixels

Definition at line 499 of file PGFimage.h.

499 { ASSERT(level >= 0); UINT32 d = 1 << level; return (size + d - 1) >> level; }

## ◆ MaxChannelDepth()

static BYTE CPGFImage::MaxChannelDepth | ( | BYTE | version = `PGFVersion` | ) |
| inline static

Return maximum channel depth.

Parameters

  version | pgf pre-header version number

Returns
  maximum channel depth in bit of given version (16 or 32 bit)

Definition at line 518 of file PGFimage.h.

518 { return (version & PGF32) ? 32 : 16; }
PGF32
#define PGF32
32 bit values are used -> allows at maximum 30 input bits, otherwise 16 bit values are used -> allows...
Definition: PGFtypes.h:69

## ◆ 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 455 of file PGFimage.h.

455 { return m_header.mode; }
PGFHeader::mode
UINT8 mode
image mode according to Adobe's image modes
Definition: PGFtypes.h:158
CPGFImage::m_header
PGFHeader m_header
PGF file header.
Definition: PGFimage.h:529

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

  stream | A PGF stream

Definition at line 141 of file PGFimage.cpp.

141 {
142 ASSERT(stream);
143
144 // create decoder and read PGFPreHeader PGFHeader PGFPostHeader LevelLengths
145 m_decoder = new CDecoder(stream, m_preHeader, m_header, m_postHeader, m_levelLength,
146 m_userDataPos, m_useOMPinDecoder, m_userDataPolicy);
147
148 if (m_header.nLevels > MaxLevel) ReturnWithError(FormatCannotRead);
149
150 // set current level
151 m_currentLevel = m_header.nLevels;
152
153 // set image width and height
154 m_width[0] = m_header.width;
155 m_height[0] = m_header.height;
156
157 // complete header
158 if (!CompleteHeader()) ReturnWithError(FormatCannotRead);
159
160 // interpret quant parameter
161 if (m_header.quality > DownsampleThreshold &&
162 (m_header.mode == ImageModeRGBColor ||
163 m_header.mode == ImageModeRGBA ||
164 m_header.mode == ImageModeRGB48 ||
165 m_header.mode == ImageModeCMYKColor ||
166 m_header.mode == ImageModeCMYK64 ||
167 m_header.mode == ImageModeLabColor ||
168 m_header.mode == ImageModeLab48)) {
169 m_downsample = true;
170 m_quant = m_header.quality - 1;
171 } else {
172 m_downsample = false;
173 m_quant = m_header.quality;
174 }
175
176 // set channel dimensions (chrominance is subsampled by factor 2)
177 if (m_downsample) {
178 for (int i=1; i < m_header.channels; i++) {
179 m_width[i] = (m_width[0] + 1) >> 1;
180 m_height[i] = (m_height[0] + 1) >> 1;
181 }
182 } else {
183 for (int i=1; i < m_header.channels; i++) {
184 m_width[i] = m_width[0];
185 m_height[i] = m_height[0];
186 }
187 }
188
189 if (m_header.nLevels > 0) {
190 // init wavelet subbands
191 for (int i=0; i < m_header.channels; i++) {
192 m_wtChannel[i] = new CWaveletTransform(m_width[i], m_height[i], m_header.nLevels);
193 }
194
195 // used in Read when PM_Absolute
196 m_percent = pow(0.25, m_header.nLevels);
197
198 } else {
199 // very small image: we don't use DWT and encoding
200
201 // read channels
202 for (int c=0; c < m_header.channels; c++) {
203 const UINT32 size = m_width[c]*m_height[c];
204 m_channel[c] = new(std::nothrow) DataT[size];
205 if (!m_channel[c]) ReturnWithError(InsufficientMemory);
206
207 // read channel data from stream
208 for (UINT32 i=0; i < size; i++) {
209 int count = DataTSize;
210 stream->Read(&count, &m_channel[c][i]);
211 if (count != DataTSize) ReturnWithError(MissingData);
212 }
213 }
214 }
215 }
CPGFStream::Read
virtual void Read(int *count, void *buffer)=0
CPGFImage::m_userDataPos
UINT64 m_userDataPos
stream position of user data
Definition: PGFimage.h:531
CPGFImage::m_useOMPinDecoder
bool m_useOMPinDecoder
use Open MP in decoder
Definition: PGFimage.h:538
PGFHeader::mode
UINT8 mode
image mode according to Adobe's image modes
Definition: PGFtypes.h:158
PGFHeader::width
UINT32 width
image width in pixels
Definition: PGFtypes.h:152
DataT
INT32 DataT
Definition: PGFtypes.h:268
ImageModeRGBA
#define ImageModeRGBA
Definition: PGFplatform.h:115
CPGFImage::m_decoder
CDecoder * m_decoder
PGF decoder.
Definition: PGFimage.h:523
CPGFImage::m_header
PGFHeader m_header
PGF file header.
Definition: PGFimage.h:529
CPGFImage::CompleteHeader
bool CompleteHeader()
Definition: PGFimage.cpp:218
CPGFImage::m_quant
BYTE m_quant
quantization parameter
Definition: PGFimage.h:534
DataTSize
#define DataTSize
Definition: PGFtypes.h:282
ImageModeLabColor
#define ImageModeLabColor
Definition: PGFplatform.h:107
CPGFImage::m_channel
DataT * m_channel[MaxChannels]
untransformed channels in YUV format
Definition: PGFimage.h:522
CPGFImage::m_preHeader
PGFPreHeader m_preHeader
PGF pre-header.
Definition: PGFimage.h:528
PGFHeader::nLevels
UINT8 nLevels
number of FWT transforms
Definition: PGFtypes.h:154
ImageModeLab48
#define ImageModeLab48
Definition: PGFplatform.h:110
ImageModeCMYKColor
#define ImageModeCMYKColor
Definition: PGFplatform.h:102
MaxLevel
#define MaxLevel
maximum number of transform levels
Definition: PGFtypes.h:62
CPGFImage::m_wtChannel
CWaveletTransform * m_wtChannel[MaxChannels]
wavelet transformed color channels
Definition: PGFimage.h:521
CPGFImage::m_postHeader
PGFPostHeader m_postHeader
PGF post-header.
Definition: PGFimage.h:530
CPGFImage::m_downsample
bool m_downsample
chrominance channels are downsampled
Definition: PGFimage.h:535
CDecoder
PGF decoder.
Definition: Decoder.h:46
DownsampleThreshold
#define DownsampleThreshold
if quality is larger than this threshold than downsampling is used
Definition: PGFtypes.h:65
CSubband::CWaveletTransform
friend class CWaveletTransform
Definition: Subband.h:43
CPGFImage::m_levelLength
UINT32 * m_levelLength
length of each level in bytes; first level starts immediately after this array
Definition: PGFimage.h:525
CPGFImage::m_width
UINT32 m_width[MaxChannels]
width of each channel at current level
Definition: PGFimage.h:526
ImageModeRGBColor
#define ImageModeRGBColor
Definition: PGFplatform.h:101
CPGFImage::m_userDataPolicy
UINT32 m_userDataPolicy
user data (metadata) policy during open
Definition: PGFimage.h:533
CPGFImage::m_percent
double m_percent
progress [0..1]
Definition: PGFimage.h:547
PGFHeader::channels
UINT8 channels
number of channels
Definition: PGFtypes.h:157
ImageModeCMYK64
#define ImageModeCMYK64
Definition: PGFplatform.h:111
CPGFImage::m_currentLevel
int m_currentLevel
transform level of current image
Definition: PGFimage.h:532
PGFHeader::quality
UINT8 quality
quantization parameter: 0=lossless, 4=standard, 6=poor quality
Definition: PGFtypes.h:155
PGFHeader::height
UINT32 height
image height in pixels
Definition: PGFtypes.h:153
ImageModeRGB48
#define ImageModeRGB48
Definition: PGFplatform.h:109
CPGFImage::m_height
UINT32 m_height[MaxChannels]
height of each channel at current level
Definition: PGFimage.h:527

## ◆ 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 442 of file PGFimage.h.

442 { return m_header.quality; }
CPGFImage::m_header
PGFHeader m_header
PGF file header.
Definition: PGFimage.h:529
PGFHeader::quality
UINT8 quality
quantization parameter: 0=lossless, 4=standard, 6=poor quality
Definition: PGFtypes.h:155

## ◆ Read() [1/2]

void CPGFImage::Read | ( | int | level = `0`,
|  | CallbackPtr | cb = `nullptr`,
|  | void * | data = `nullptr`
| ) |  |

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

Parameters

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

Definition at line 402 of file PGFimage.cpp.

402 {
403 ASSERT((level >= 0 && level < m_header.nLevels) || m_header.nLevels == 0); // m_header.nLevels == 0: image didn't use wavelet transform
404 ASSERT(m_decoder);
405
406 #ifdef __PGFROISUPPORT__
407 if (ROIisSupported() && m_header.nLevels > 0) {
408 // new encoding scheme supporting ROI
409 PGFRect rect(0, 0, m_header.width, m_header.height);
410 Read(rect, level, cb, data);
411 return;
412 }
413 #endif
414
415 if (m_header.nLevels == 0) {
416 if (level == 0) {
417 // the data has already been read during open
418 // now update progress
419 if (cb) {
420 if ((*cb)(1.0, true, data)) ReturnWithError(EscapePressed);
421 }
422 }
423 } else {
424 const int levelDiff = m_currentLevel - level;
425 double percent = (m_progressMode == PM_Relative) ? pow(0.25, levelDiff) : m_percent;
426
427 // encoding scheme without ROI
428 while (m_currentLevel > level) {
429 for (int i=0; i < m_header.channels; i++) {
430 CWaveletTransform* wtChannel = m_wtChannel[i];
431 ASSERT(wtChannel);
432
433 // decode file and write stream to m_wtChannel
434 if (m_currentLevel == m_header.nLevels) {
435 // last level also has LL band
436 wtChannel->GetSubband(m_currentLevel, LL)->PlaceTile(*m_decoder, m_quant);
437 }
438 if (m_preHeader.version & Version5) {
439 // since version 5
440 wtChannel->GetSubband(m_currentLevel, HL)->PlaceTile(*m_decoder, m_quant);
441 wtChannel->GetSubband(m_currentLevel, LH)->PlaceTile(*m_decoder, m_quant);
442 } else {
443 // until version 4
444 m_decoder->DecodeInterleaved(wtChannel, m_currentLevel, m_quant);
445 }
446 wtChannel->GetSubband(m_currentLevel, HH)->PlaceTile(*m_decoder, m_quant);
447 }
448
449 volatile OSError error = NoError; // volatile prevents optimizations
450 #ifdef LIBPGF_USE_OPENMP
451 #pragma omp parallel for default(shared)
452 #endif
453 for (int i=0; i < m_header.channels; i++) {
454 // inverse transform from m_wtChannel to m_channel
455 if (error == NoError) {
456 OSError err = m_wtChannel[i]->InverseTransform(m_currentLevel, &m_width[i], &m_height[i], &m_channel[i]);
457 if (err != NoError) error = err;
458 }
459 ASSERT(m_channel[i]);
460 }
461 if (error != NoError) ReturnWithError(error);
462
463 // set new level: must be done before refresh callback
464 m_currentLevel--;
465
466 // now we have to refresh the display
467 if (m_cb) m_cb(m_cbArg);
468
469 // now update progress
470 if (cb) {
471 percent *= 4;
472 if (m_progressMode == PM_Absolute) m_percent = percent;
473 if ((*cb)(percent, true, data)) ReturnWithError(EscapePressed);
474 }
475 }
476 }
477 }
CWaveletTransform::InverseTransform
OSError InverseTransform(int level, UINT32 *width, UINT32 *height, DataT **data)
Definition: WaveletTransform.cpp:245
CPGFImage::Read
void Read(int level=0, CallbackPtr cb=nullptr, void *data=nullptr)
Definition: PGFimage.cpp:402
PGFMagicVersion::version
UINT8 version
PGF version.
Definition: PGFtypes.h:115
HH
Definition: PGFtypes.h:99
PGFHeader::width
UINT32 width
image width in pixels
Definition: PGFtypes.h:152
PM_Relative
Definition: PGFtypes.h:100
CPGFImage::m_decoder
CDecoder * m_decoder
PGF decoder.
Definition: PGFimage.h:523
CPGFImage::m_header
PGFHeader m_header
PGF file header.
Definition: PGFimage.h:529
CDecoder::DecodeInterleaved
void DecodeInterleaved(CWaveletTransform *wtChannel, int level, int quantParam)
Definition: Decoder.cpp:333
CPGFImage::m_quant
BYTE m_quant
quantization parameter
Definition: PGFimage.h:534
CPGFImage::m_cbArg
void * m_cbArg
refresh callback argument
Definition: PGFimage.h:546
CPGFImage::m_channel
DataT * m_channel[MaxChannels]
untransformed channels in YUV format
Definition: PGFimage.h:522
CPGFImage::m_preHeader
PGFPreHeader m_preHeader
PGF pre-header.
Definition: PGFimage.h:528
PGFHeader::nLevels
UINT8 nLevels
number of FWT transforms
Definition: PGFtypes.h:154
CWaveletTransform
PGF wavelet transform.
Definition: WaveletTransform.h:55
PM_Absolute
Definition: PGFtypes.h:100
CPGFImage::m_progressMode
ProgressMode m_progressMode
progress mode used in Read and Write; PM_Relative is default mode
Definition: PGFimage.h:548
CPGFImage::m_wtChannel
CWaveletTransform * m_wtChannel[MaxChannels]
wavelet transformed color channels
Definition: PGFimage.h:521
CSubband::PlaceTile
void PlaceTile(CDecoder &decoder, int quantParam, bool tile=false, UINT32 tileX=0, UINT32 tileY=0)
Definition: Subband.cpp:203
LH
Definition: PGFtypes.h:99
CPGFImage::m_width
UINT32 m_width[MaxChannels]
width of each channel at current level
Definition: PGFimage.h:526
HL
Definition: PGFtypes.h:99
CWaveletTransform::GetSubband
CSubband * GetSubband(int level, Orientation orientation)
Definition: WaveletTransform.h:93
CPGFImage::ROIisSupported
bool ROIisSupported() const
Definition: PGFimage.h:466
LL
Definition: PGFtypes.h:99
CPGFImage::m_percent
double m_percent
progress [0..1]
Definition: PGFimage.h:547
PGFHeader::channels
UINT8 channels
number of channels
Definition: PGFtypes.h:157
PGFRect
Rectangle.
Definition: PGFtypes.h:224
CPGFImage::m_cb
RefreshCB m_cb
pointer to refresh callback procedure
Definition: PGFimage.h:545
CPGFImage::m_currentLevel
int m_currentLevel
transform level of current image
Definition: PGFimage.h:532
PGFHeader::height
UINT32 height
image height in pixels
Definition: PGFtypes.h:153
Version5
#define Version5
new coding scheme since major version 5
Definition: PGFtypes.h:71
CPGFImage::m_height
UINT32 m_height[MaxChannels]
height of each channel at current level
Definition: PGFimage.h:527

## ◆ Read() [2/2]

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

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) at level 0. The rect might be cropped.
  level | [0, nLevels) The image level of the resulting image in the internal image buffer.
  cb | A pointer to a callback procedure. The procedure is called after reading a single level. If cb returns true, then it stops proceeding.
  data | Data Pointer to C++ class container to host callback procedure.

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

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

Returns
  The number of bytes copied to the target buffer

Definition at line 706 of file PGFimage.cpp.

706 {
707 ASSERT(level >= 0 && level < m_header.nLevels);
708 ASSERT(target);
709 ASSERT(targetLen > 0);
710 ASSERT(m_decoder);
711
712 // reset stream position
713 m_decoder->SetStreamPosToData();
714
715 // position stream
716 UINT64 offset = 0;
717
718 for (int i=m_header.nLevels - 1; i > level; i--) {
719 offset += m_levelLength[m_header.nLevels - 1 - i];
720 }
721 m_decoder->Skip(offset);
722
723 // compute number of bytes to read
724 UINT32 len = __min(targetLen, GetEncodedLevelLength(level));
725
726 // read data
727 len = m_decoder->ReadEncodedData(target, len);
728 ASSERT(len >= 0 && len <= targetLen);
729
730 return len;
731 }
CPGFImage::m_decoder
CDecoder * m_decoder
PGF decoder.
Definition: PGFimage.h:523
CPGFImage::GetEncodedLevelLength
UINT32 GetEncodedLevelLength(int level) const
Definition: PGFimage.h:367
CPGFImage::m_header
PGFHeader m_header
PGF file header.
Definition: PGFimage.h:529
CDecoder::SetStreamPosToData
void SetStreamPosToData()
Resets stream position to beginning of data block.
Definition: Decoder.h:144
PGFHeader::nLevels
UINT8 nLevels
number of FWT transforms
Definition: PGFtypes.h:154
CPGFImage::m_levelLength
UINT32 * m_levelLength
length of each level in bytes; first level starts immediately after this array
Definition: PGFimage.h:525
__min
#define __min(x, y)
Definition: PGFplatform.h:91
CDecoder::Skip
void Skip(UINT64 offset)
Definition: Decoder.cpp:449
CDecoder::ReadEncodedData
UINT32 ReadEncodedData(UINT8 *target, UINT32 len) const
Definition: Decoder.cpp:246

## ◆ ReadEncodedHeader()

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

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

Parameters

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

Returns
  The number of bytes copied to the target buffer

Definition at line 660 of file PGFimage.cpp.

660 {
661 ASSERT(target);
662 ASSERT(targetLen > 0);
663 ASSERT(m_decoder);
664
665 // reset stream position
666 m_decoder->SetStreamPosToStart();
667
668 // compute number of bytes to read
669 UINT32 len = __min(targetLen, GetEncodedHeaderLength());
670
671 // read data
672 len = m_decoder->ReadEncodedData(target, len);
673 ASSERT(len >= 0 && len <= targetLen);
674
675 return len;
676 }
CPGFImage::m_decoder
CDecoder * m_decoder
PGF decoder.
Definition: PGFimage.h:523
__min
#define __min(x, y)
Definition: PGFplatform.h:91
CDecoder::ReadEncodedData
UINT32 ReadEncodedData(UINT8 *target, UINT32 len) const
Definition: Decoder.cpp:246
CPGFImage::GetEncodedHeaderLength
UINT32 GetEncodedHeaderLength() const
Definition: PGFimage.cpp:648
CDecoder::SetStreamPosToStart
void SetStreamPosToStart()
Resets stream position to beginning of PGF pre-header.
Definition: Decoder.h:140

## ◆ ReadPreview()

void CPGFImage::ReadPreview | ( |  | ) |
| inline

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

Definition at line 111 of file PGFimage.h.

111 { Read(Levels() - 1); }
CPGFImage::Read
void Read(int level=0, CallbackPtr cb=nullptr, void *data=nullptr)
Definition: PGFimage.cpp:402
CPGFImage::Levels
BYTE Levels() const
Definition: PGFimage.h:432

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

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

Definition at line 348 of file PGFimage.cpp.

348 {
349 if (m_header.nLevels == 0) {
350 // image didn't use wavelet transform
351 if (level == 0) {
352 for (int i=0; i < m_header.channels; i++) {
353 ASSERT(m_wtChannel[i]);
354 m_channel[i] = m_wtChannel[i]->GetSubband(0, LL)->GetBuffer();
355 }
356 }
357 } else {
358 int currentLevel = m_header.nLevels;
359
360 #ifdef __PGFROISUPPORT__
361 if (ROIisSupported()) {
362 // enable ROI reading
363 SetROI(PGFRect(0, 0, m_header.width, m_header.height));
364 }
365 #endif
366
367 while (currentLevel > level) {
368 for (int i=0; i < m_header.channels; i++) {
369 ASSERT(m_wtChannel[i]);
370 // dequantize subbands
371 if (currentLevel == m_header.nLevels) {
372 // last level also has LL band
373 m_wtChannel[i]->GetSubband(currentLevel, LL)->Dequantize(m_quant);
374 }
375 m_wtChannel[i]->GetSubband(currentLevel, HL)->Dequantize(m_quant);
376 m_wtChannel[i]->GetSubband(currentLevel, LH)->Dequantize(m_quant);
377 m_wtChannel[i]->GetSubband(currentLevel, HH)->Dequantize(m_quant);
378
379 // inverse transform from m_wtChannel to m_channel
380 OSError err = m_wtChannel[i]->InverseTransform(currentLevel, &m_width[i], &m_height[i], &m_channel[i]);
381 if (err != NoError) ReturnWithError(err);
382 ASSERT(m_channel[i]);
383 }
384
385 currentLevel--;
386 }
387 }
388 }
CWaveletTransform::InverseTransform
OSError InverseTransform(int level, UINT32 *width, UINT32 *height, DataT **data)
Definition: WaveletTransform.cpp:245
HH
Definition: PGFtypes.h:99
CSubband::Dequantize
void Dequantize(int quantParam)
Definition: Subband.cpp:154
CSubband::GetBuffer
DataT * GetBuffer()
Definition: Subband.h:107
PGFHeader::width
UINT32 width
image width in pixels
Definition: PGFtypes.h:152
CPGFImage::m_header
PGFHeader m_header
PGF file header.
Definition: PGFimage.h:529
CPGFImage::m_quant
BYTE m_quant
quantization parameter
Definition: PGFimage.h:534
CPGFImage::m_channel
DataT * m_channel[MaxChannels]
untransformed channels in YUV format
Definition: PGFimage.h:522
PGFHeader::nLevels
UINT8 nLevels
number of FWT transforms
Definition: PGFtypes.h:154
CPGFImage::SetROI
void SetROI(PGFRect rect)
CPGFImage::m_wtChannel
CWaveletTransform * m_wtChannel[MaxChannels]
wavelet transformed color channels
Definition: PGFimage.h:521
LH
Definition: PGFtypes.h:99
CPGFImage::m_width
UINT32 m_width[MaxChannels]
width of each channel at current level
Definition: PGFimage.h:526
HL
Definition: PGFtypes.h:99
CWaveletTransform::GetSubband
CSubband * GetSubband(int level, Orientation orientation)
Definition: WaveletTransform.h:93
CPGFImage::ROIisSupported
bool ROIisSupported() const
Definition: PGFimage.h:466
LL
Definition: PGFtypes.h:99
PGFHeader::channels
UINT8 channels
number of channels
Definition: PGFtypes.h:157
PGFRect
Rectangle.
Definition: PGFtypes.h:224
PGFHeader::height
UINT32 height
image height in pixels
Definition: PGFtypes.h:153
CPGFImage::m_height
UINT32 m_height[MaxChannels]
height of each channel at current level
Definition: PGFimage.h:527

## ◆ ResetStreamPos()

void CPGFImage::ResetStreamPos | ( | bool | startOfData | ) |

Reset stream position to start of PGF pre-header or start of data. Must not be called before Open() or before Write(). Use this method after Read() if you want to read the same image several times, e.g. reading different ROIs.

Parameters

  startOfData | true: you want to read the same image several times. false: resets stream position to the initial position

Definition at line 682 of file PGFimage.cpp.

682 {
683 if (startOfData) {
684 ASSERT(m_decoder);
685 m_decoder->SetStreamPosToData();
686 } else {
687 if (m_decoder) {
688 m_decoder->SetStreamPosToStart();
689 } else if (m_encoder) {
690 m_encoder->SetStreamPosToStart();
691 } else {
692 ASSERT(false);
693 }
694 }
695 }
CPGFImage::m_decoder
CDecoder * m_decoder
PGF decoder.
Definition: PGFimage.h:523
CDecoder::SetStreamPosToData
void SetStreamPosToData()
Resets stream position to beginning of data block.
Definition: Decoder.h:144
CEncoder::SetStreamPosToStart
void SetStreamPosToStart()
Resets stream position to beginning of PGF pre-header.
Definition: Encoder.h:188
CPGFImage::m_encoder
CEncoder * m_encoder
PGF encoder.
Definition: PGFimage.h:524
CDecoder::SetStreamPosToStart
void SetStreamPosToStart()
Resets stream position to beginning of PGF pre-header.
Definition: Decoder.h:140

## ◆ RgbToYuv()

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

Definition at line 1388 of file PGFimage.cpp.

1388 {
1389 ASSERT(buff);
1390 UINT32 yPos = 0, cnt = 0;
1391 double percent = 0;
1392 const double dP = 1.0/m_header.height;
1393 int defMap[] = { 0, 1, 2, 3, 4, 5, 6, 7 }; ASSERT(sizeof(defMap)/sizeof(defMap[0]) == MaxChannels);
1394
1395 if (channelMap == nullptr) channelMap = defMap;
1396
1397 switch(m_header.mode) {
1398 case ImageModeBitmap:
1399 {
1400 ASSERT(m_header.channels == 1);
1401 ASSERT(m_header.bpp == 1);
1402 ASSERT(bpp == 1);
1403
1404 const UINT32 w = m_header.width;
1405 const UINT32 w2 = (m_header.width + 7)/8;
1406 DataT* y = m_channel[0]; ASSERT(y);
1407
1408 // new unpacked version since version 7
1409 for (UINT32 h = 0; h < m_header.height; h++) {
1410 if (cb) {
1411 if ((*cb)(percent, true, data)) ReturnWithError(EscapePressed);
1412 percent += dP;
1413 }
1414 cnt = 0;
1415 for (UINT32 j = 0; j < w2; j++) {
1416 UINT8 byte = buff[j];
1417 for (int k = 0; k < 8; k++) {
1418 UINT8 bit = (byte & 0x80) >> 7;
1419 if (cnt < w) y[yPos++] = bit;
1420 byte <<= 1;
1421 cnt++;
1422 }
1423 }
1424 buff += pitch;
1425 }
1426 /* old version: packed values: 8 pixels in 1 byte
1427 for (UINT32 h = 0; h < m_header.height; h++) {
1428 if (cb) {
1429 if ((*cb)(percent, true, data)) ReturnWithError(EscapePressed);
1430 percent += dP;
1431 }
1432
1433 for (UINT32 j = 0; j < w2; j++) {
1434 y[yPos++] = buff[j] - YUVoffset8;
1435 }
1436 // version 5 and 6
1437 // for (UINT32 j = w2; j < w; j++) {
1438 // y[yPos++] = YUVoffset8;
1439 //}
1440 buff += pitch;
1441 }
1442 */
1443 }
1444 break;
1445 case ImageModeIndexedColor:
1446 case ImageModeGrayScale:
1447 case ImageModeHSLColor:
1448 case ImageModeHSBColor:
1449 case ImageModeLabColor:
1450 {
1451 ASSERT(m_header.channels >= 1);
1452 ASSERT(m_header.bpp == m_header.channels*8);
1453 ASSERT(bpp%8 == 0);
1454 const int channels = bpp/8; ASSERT(channels >= m_header.channels);
1455
1456 for (UINT32 h=0; h < m_header.height; h++) {
1457 if (cb) {
1458 if ((*cb)(percent, true, data)) ReturnWithError(EscapePressed);
1459 percent += dP;
1460 }
1461
1462 cnt = 0;
1463 for (UINT32 w=0; w < m_header.width; w++) {
1464 for (int c=0; c < m_header.channels; c++) {
1465 m_channel[c][yPos] = buff[cnt + channelMap[c]] - YUVoffset8;
1466 }
1467 cnt += channels;
1468 yPos++;
1469 }
1470 buff += pitch;
1471 }
1472 }
1473 break;
1474 case ImageModeGray16:
1475 case ImageModeLab48:
1476 {
1477 ASSERT(m_header.channels >= 1);
1478 ASSERT(m_header.bpp == m_header.channels*16);
1479 ASSERT(bpp%16 == 0);
1480
1481 UINT16 *buff16 = (UINT16 *)buff;
1482 const int pitch16 = pitch/2;
1483 const int channels = bpp/16; ASSERT(channels >= m_header.channels);
1484 const int shift = 16 - UsedBitsPerChannel(); ASSERT(shift >= 0);
1485 const DataT yuvOffset16 = 1 << (UsedBitsPerChannel() - 1);
1486
1487 for (UINT32 h=0; h < m_header.height; h++) {
1488 if (cb) {
1489 if ((*cb)(percent, true, data)) ReturnWithError(EscapePressed);
1490 percent += dP;
1491 }
1492
1493 cnt = 0;
1494 for (UINT32 w=0; w < m_header.width; w++) {
1495 for (int c=0; c < m_header.channels; c++) {
1496 m_channel[c][yPos] = (buff16[cnt + channelMap[c]] >> shift) - yuvOffset16;
1497 }
1498 cnt += channels;
1499 yPos++;
1500 }
1501 buff16 += pitch16;
1502 }
1503 }
1504 break;
1505 case ImageModeRGBColor:
1506 {
1507 ASSERT(m_header.channels == 3);
1508 ASSERT(m_header.bpp == m_header.channels*8);
1509 ASSERT(bpp%8 == 0);
1510
1511 DataT* y = m_channel[0]; ASSERT(y);
1512 DataT* u = m_channel[1]; ASSERT(u);
1513 DataT* v = m_channel[2]; ASSERT(v);
1514 const int channels = bpp/8; ASSERT(channels >= m_header.channels);
1515 UINT8 b, g, r;
1516
1517 for (UINT32 h=0; h < m_header.height; h++) {
1518 if (cb) {
1519 if ((*cb)(percent, true, data)) ReturnWithError(EscapePressed);
1520 percent += dP;
1521 }
1522
1523 cnt = 0;
1524 for (UINT32 w=0; w < m_header.width; w++) {
1525 b = buff[cnt + channelMap[0]];
1526 g = buff[cnt + channelMap[1]];
1527 r = buff[cnt + channelMap[2]];
1528 // Yuv
1529 y[yPos] = ((b + (g << 1) + r) >> 2) - YUVoffset8;
1530 u[yPos] = r - g;
1531 v[yPos] = b - g;
1532 yPos++;
1533 cnt += channels;
1534 }
1535 buff += pitch;
1536 }
1537 }
1538 break;
1539 case ImageModeRGB48:
1540 {
1541 ASSERT(m_header.channels == 3);
1542 ASSERT(m_header.bpp == m_header.channels*16);
1543 ASSERT(bpp%16 == 0);
1544
1545 UINT16 *buff16 = (UINT16 *)buff;
1546 const int pitch16 = pitch/2;
1547 const int channels = bpp/16; ASSERT(channels >= m_header.channels);
1548 const int shift = 16 - UsedBitsPerChannel(); ASSERT(shift >= 0);
1549 const DataT yuvOffset16 = 1 << (UsedBitsPerChannel() - 1);
1550
1551 DataT* y = m_channel[0]; ASSERT(y);
1552 DataT* u = m_channel[1]; ASSERT(u);
1553 DataT* v = m_channel[2]; ASSERT(v);
1554 UINT16 b, g, r;
1555
1556 for (UINT32 h=0; h < m_header.height; h++) {
1557 if (cb) {
1558 if ((*cb)(percent, true, data)) ReturnWithError(EscapePressed);
1559 percent += dP;
1560 }
1561
1562 cnt = 0;
1563 for (UINT32 w=0; w < m_header.width; w++) {
1564 b = buff16[cnt + channelMap[0]] >> shift;
1565 g = buff16[cnt + channelMap[1]] >> shift;
1566 r = buff16[cnt + channelMap[2]] >> shift;
1567 // Yuv
1568 y[yPos] = ((b + (g << 1) + r) >> 2) - yuvOffset16;
1569 u[yPos] = r - g;
1570 v[yPos] = b - g;
1571 yPos++;
1572 cnt += channels;
1573 }
1574 buff16 += pitch16;
1575 }
1576 }
1577 break;
1578 case ImageModeRGBA:
1579 case ImageModeCMYKColor:
1580 {
1581 ASSERT(m_header.channels == 4);
1582 ASSERT(m_header.bpp == m_header.channels*8);
1583 ASSERT(bpp%8 == 0);
1584 const int channels = bpp/8; ASSERT(channels >= m_header.channels);
1585
1586 DataT* y = m_channel[0]; ASSERT(y);
1587 DataT* u = m_channel[1]; ASSERT(u);
1588 DataT* v = m_channel[2]; ASSERT(v);
1589 DataT* a = m_channel[3]; ASSERT(a);
1590 UINT8 b, g, r;
1591
1592 for (UINT32 h=0; h < m_header.height; h++) {
1593 if (cb) {
1594 if ((*cb)(percent, true, data)) ReturnWithError(EscapePressed);
1595 percent += dP;
1596 }
1597
1598 cnt = 0;
1599 for (UINT32 w=0; w < m_header.width; w++) {
1600 b = buff[cnt + channelMap[0]];
1601 g = buff[cnt + channelMap[1]];
1602 r = buff[cnt + channelMap[2]];
1603 // Yuv
1604 y[yPos] = ((b + (g << 1) + r) >> 2) - YUVoffset8;
1605 u[yPos] = r - g;
1606 v[yPos] = b - g;
1607 a[yPos++] = buff[cnt + channelMap[3]] - YUVoffset8;
1608 cnt += channels;
1609 }
1610 buff += pitch;
1611 }
1612 }
1613 break;
1614 case ImageModeCMYK64:
1615 {
1616 ASSERT(m_header.channels == 4);
1617 ASSERT(m_header.bpp == m_header.channels*16);
1618 ASSERT(bpp%16 == 0);
1619
1620 UINT16 *buff16 = (UINT16 *)buff;
1621 const int pitch16 = pitch/2;
1622 const int channels = bpp/16; ASSERT(channels >= m_header.channels);
1623 const int shift = 16 - UsedBitsPerChannel(); ASSERT(shift >= 0);
1624 const DataT yuvOffset16 = 1 << (UsedBitsPerChannel() - 1);
1625
1626 DataT* y = m_channel[0]; ASSERT(y);
1627 DataT* u = m_channel[1]; ASSERT(u);
1628 DataT* v = m_channel[2]; ASSERT(v);
1629 DataT* a = m_channel[3]; ASSERT(a);
1630 UINT16 b, g, r;
1631
1632 for (UINT32 h=0; h < m_header.height; h++) {
1633 if (cb) {
1634 if ((*cb)(percent, true, data)) ReturnWithError(EscapePressed);
1635 percent += dP;
1636 }
1637
1638 cnt = 0;
1639 for (UINT32 w=0; w < m_header.width; w++) {
1640 b = buff16[cnt + channelMap[0]] >> shift;
1641 g = buff16[cnt + channelMap[1]] >> shift;
1642 r = buff16[cnt + channelMap[2]] >> shift;
1643 // Yuv
1644 y[yPos] = ((b + (g << 1) + r) >> 2) - yuvOffset16;
1645 u[yPos] = r - g;
1646 v[yPos] = b - g;
1647 a[yPos++] = (buff16[cnt + channelMap[3]] >> shift) - yuvOffset16;
1648 cnt += channels;
1649 }
1650 buff16 += pitch16;
1651 }
1652 }
1653 break;
1654 #ifdef __PGF32SUPPORT__
1655 case ImageModeGray32:
1656 {
1657 ASSERT(m_header.channels == 1);
1658 ASSERT(m_header.bpp == 32);
1659 ASSERT(bpp == 32);
1660 ASSERT(DataTSize == sizeof(UINT32));
1661
1662 DataT* y = m_channel[0]; ASSERT(y);
1663
1664 UINT32 *buff32 = (UINT32 *)buff;
1665 const int pitch32 = pitch/4;
1666 const int shift = 31 - UsedBitsPerChannel(); ASSERT(shift >= 0);
1667 const DataT yuvOffset31 = 1 << (UsedBitsPerChannel() - 1);
1668
1669 for (UINT32 h=0; h < m_header.height; h++) {
1670 if (cb) {
1671 if ((*cb)(percent, true, data)) ReturnWithError(EscapePressed);
1672 percent += dP;
1673 }
1674
1675 for (UINT32 w=0; w < m_header.width; w++) {
1676 y[yPos++] = (buff32[w] >> shift) - yuvOffset31;
1677 }
1678 buff32 += pitch32;
1679 }
1680 }
1681 break;
1682 #endif
1683 case ImageModeRGB12:
1684 {
1685 ASSERT(m_header.channels == 3);
1686 ASSERT(m_header.bpp == m_header.channels*4);
1687 ASSERT(bpp == m_header.channels*4);
1688
1689 DataT* y = m_channel[0]; ASSERT(y);
1690 DataT* u = m_channel[1]; ASSERT(u);
1691 DataT* v = m_channel[2]; ASSERT(v);
1692
1693 UINT8 rgb = 0, b, g, r;
1694
1695 for (UINT32 h=0; h < m_header.height; h++) {
1696 if (cb) {
1697 if ((*cb)(percent, true, data)) ReturnWithError(EscapePressed);
1698 percent += dP;
1699 }
1700
1701 cnt = 0;
1702 for (UINT32 w=0; w < m_header.width; w++) {
1703 if (w%2 == 0) {
1704 // even pixel position
1705 rgb = buff[cnt];
1706 b = rgb & 0x0F;
1707 g = (rgb & 0xF0) >> 4;
1708 cnt++;
1709 rgb = buff[cnt];
1710 r = rgb & 0x0F;
1711 } else {
1712 // odd pixel position
1713 b = (rgb & 0xF0) >> 4;
1714 cnt++;
1715 rgb = buff[cnt];
1716 g = rgb & 0x0F;
1717 r = (rgb & 0xF0) >> 4;
1718 cnt++;
1719 }
1720
1721 // Yuv
1722 y[yPos] = ((b + (g << 1) + r) >> 2) - YUVoffset4;
1723 u[yPos] = r - g;
1724 v[yPos] = b - g;
1725 yPos++;
1726 }
1727 buff += pitch;
1728 }
1729 }
1730 break;
1731 case ImageModeRGB16:
1732 {
1733 ASSERT(m_header.channels == 3);
1734 ASSERT(m_header.bpp == 16);
1735 ASSERT(bpp == 16);
1736
1737 DataT* y = m_channel[0]; ASSERT(y);
1738 DataT* u = m_channel[1]; ASSERT(u);
1739 DataT* v = m_channel[2]; ASSERT(v);
1740
1741 UINT16 *buff16 = (UINT16 *)buff;
1742 UINT16 rgb, b, g, r;
1743 const int pitch16 = pitch/2;
1744
1745 for (UINT32 h=0; h < m_header.height; h++) {
1746 if (cb) {
1747 if ((*cb)(percent, true, data)) ReturnWithError(EscapePressed);
1748 percent += dP;
1749 }
1750 for (UINT32 w=0; w < m_header.width; w++) {
1751 rgb = buff16[w];
1752 r = (rgb & 0xF800) >> 10; // highest 5 bits
1753 g = (rgb & 0x07E0) >> 5; // middle 6 bits
1754 b = (rgb & 0x001F) << 1; // lowest 5 bits
1755 // Yuv
1756 y[yPos] = ((b + (g << 1) + r) >> 2) - YUVoffset6;
1757 u[yPos] = r - g;
1758 v[yPos] = b - g;
1759 yPos++;
1760 }
1761
1762 buff16 += pitch16;
1763 }
1764 }
1765 break;
1766 default:
1767 ASSERT(false);
1768 }
1769 }
ImageModeIndexedColor
#define ImageModeIndexedColor
Definition: PGFplatform.h:100
ImageModeRGB12
#define ImageModeRGB12
Definition: PGFplatform.h:117
PGFHeader::mode
UINT8 mode
image mode according to Adobe's image modes
Definition: PGFtypes.h:158
ImageModeHSBColor
#define ImageModeHSBColor
Definition: PGFplatform.h:104
MaxChannels
#define MaxChannels
maximum number of (color) channels
Definition: PGFtypes.h:64
CPGFImage::UsedBitsPerChannel
BYTE UsedBitsPerChannel() const
Definition: PGFimage.cpp:755
PGFHeader::width
UINT32 width
image width in pixels
Definition: PGFtypes.h:152
DataT
INT32 DataT
Definition: PGFtypes.h:268
ImageModeRGBA
#define ImageModeRGBA
Definition: PGFplatform.h:115
CPGFImage::m_header
PGFHeader m_header
PGF file header.
Definition: PGFimage.h:529
DataTSize
#define DataTSize
Definition: PGFtypes.h:282
ImageModeLabColor
#define ImageModeLabColor
Definition: PGFplatform.h:107
CPGFImage::m_channel
DataT * m_channel[MaxChannels]
untransformed channels in YUV format
Definition: PGFimage.h:522
ImageModeGray16
#define ImageModeGray16
Definition: PGFplatform.h:108
ImageModeLab48
#define ImageModeLab48
Definition: PGFplatform.h:110
ImageModeCMYKColor
#define ImageModeCMYKColor
Definition: PGFplatform.h:102
ImageModeGrayScale
#define ImageModeGrayScale
Definition: PGFplatform.h:99
PGFHeader::bpp
UINT8 bpp
bits per pixel
Definition: PGFtypes.h:156
YUVoffset6
#define YUVoffset6
Definition: PGFimage.cpp:37
ImageModeGray32
#define ImageModeGray32
Definition: PGFplatform.h:116
ImageModeRGBColor
#define ImageModeRGBColor
Definition: PGFplatform.h:101
ImageModeHSLColor
#define ImageModeHSLColor
Definition: PGFplatform.h:103
ImageModeBitmap
#define ImageModeBitmap
Definition: PGFplatform.h:98
PGFHeader::channels
UINT8 channels
number of channels
Definition: PGFtypes.h:157
ImageModeCMYK64
#define ImageModeCMYK64
Definition: PGFplatform.h:111
YUVoffset4
#define YUVoffset4
Definition: PGFimage.cpp:36
ImageModeRGB16
#define ImageModeRGB16
Definition: PGFplatform.h:118
YUVoffset8
#define YUVoffset8
Definition: PGFimage.cpp:38
PGFHeader::height
UINT32 height
image height in pixels
Definition: PGFtypes.h:153
ImageModeRGB48
#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 466 of file PGFimage.h.

466 { return (m_preHeader.version & PGFROI) == PGFROI; }
PGFMagicVersion::version
UINT8 version
PGF version.
Definition: PGFtypes.h:115
CPGFImage::m_preHeader
PGFPreHeader m_preHeader
PGF pre-header.
Definition: PGFimage.h:528
PGFROI
#define PGFROI
supports Regions Of Interest
Definition: PGFtypes.h:70

## ◆ SetChannel()

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

Set internal PGF image buffer channel.

Parameters

  channel | A YUV data channel
  c | A channel index

Definition at line 272 of file PGFimage.h.

272 { ASSERT(c >= 0 && c < MaxChannels); m_channel[c] = channel; }
MaxChannels
#define MaxChannels
maximum number of (color) channels
Definition: PGFtypes.h:64
CPGFImage::m_channel
DataT * m_channel[MaxChannels]
untransformed channels in YUV format
Definition: PGFimage.h:522

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

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

Definition at line 1363 of file PGFimage.cpp.

1363 {
1364 if (iFirstColor + nColors > ColorTableLen) ReturnWithError(ColorTableError);
1365
1366 for (UINT32 i=iFirstColor, j=0; j < nColors; i++, j++) {
1367 m_postHeader.clut[i] = prgbColors[j];
1368 }
1369 }
ColorTableLen
#define ColorTableLen
size of color lookup table (clut)
Definition: PGFtypes.h:66
CPGFImage::m_postHeader
PGFPostHeader m_postHeader
PGF post-header.
Definition: PGFimage.h:530
PGFPostHeader::clut
RGBQUAD clut[ColorTableLen]
color table for indexed color images (optional part of file header)
Definition: PGFtypes.h:169

## ◆ SetHeader()

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

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

Parameters

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

Definition at line 893 of file PGFimage.cpp.

893 {
894 ASSERT(!m_decoder); // current image must be closed
895 ASSERT(header.quality <= MaxQuality);
896 ASSERT(userDataLength <= MaxUserDataSize);
897
898 // init state
899 #ifdef __PGFROISUPPORT__
900 m_streamReinitialized = false;
901 #endif
902
903 // init preHeader
904 memcpy(m_preHeader.magic, PGFMagic, 3);
905 m_preHeader.version = PGFVersion | flags;
906 m_preHeader.hSize = HeaderSize;
907
908 // copy header
909 memcpy(&m_header, &header, HeaderSize);
910
911 // check quality
912 if (m_header.quality > MaxQuality) m_header.quality = MaxQuality;
913
914 // complete header
915 CompleteHeader();
916
917 // check and set number of levels
918 ComputeLevels();
919
920 // check for downsample
921 if (m_header.quality > DownsampleThreshold && (m_header.mode == ImageModeRGBColor ||
922 m_header.mode == ImageModeRGBA ||
923 m_header.mode == ImageModeRGB48 ||
924 m_header.mode == ImageModeCMYKColor ||
925 m_header.mode == ImageModeCMYK64 ||
926 m_header.mode == ImageModeLabColor ||
927 m_header.mode == ImageModeLab48)) {
928 m_downsample = true;
929 m_quant = m_header.quality - 1;
930 } else {
931 m_downsample = false;
932 m_quant = m_header.quality;
933 }
934
935 // update header size and copy user data
936 if (m_header.mode == ImageModeIndexedColor) {
937 // update header size
938 m_preHeader.hSize += ColorTableSize;
939 }
940 if (userDataLength && userData) {
941 if (userDataLength > MaxUserDataSize) userDataLength = MaxUserDataSize;
942 m_postHeader.userData = new(std::nothrow) UINT8[userDataLength];
943 if (!m_postHeader.userData) ReturnWithError(InsufficientMemory);
944 m_postHeader.userDataLen = m_postHeader.cachedUserDataLen = userDataLength;
945 memcpy(m_postHeader.userData, userData, userDataLength);
946 // update header size
947 m_preHeader.hSize += userDataLength;
948 }
949
950 // allocate channels
951 for (int i=0; i < m_header.channels; i++) {
952 // set current width and height
953 m_width[i] = m_header.width;
954 m_height[i] = m_header.height;
955
956 // allocate channels
957 ASSERT(!m_channel[i]);
958 m_channel[i] = new(std::nothrow) DataT[m_header.width*m_header.height];
959 if (!m_channel[i]) {
960 if (i) i--;
961 while(i) {
962 delete[] m_channel[i]; m_channel[i] = 0;
963 i--;
964 }
965 ReturnWithError(InsufficientMemory);
966 }
967 }
968 }
ImageModeIndexedColor
#define ImageModeIndexedColor
Definition: PGFplatform.h:100
PGFMagicVersion::version
UINT8 version
PGF version.
Definition: PGFtypes.h:115
PGFHeader::mode
UINT8 mode
image mode according to Adobe's image modes
Definition: PGFtypes.h:158
PGFVersion
#define PGFVersion
current standard version
Definition: PGFtypes.h:76
PGFHeader::width
UINT32 width
image width in pixels
Definition: PGFtypes.h:152
ColorTableSize
#define ColorTableSize
Definition: PGFtypes.h:281
DataT
INT32 DataT
Definition: PGFtypes.h:268
PGFPostHeader::userDataLen
UINT32 userDataLen
user data size in bytes (not part of file header)
Definition: PGFtypes.h:171
ImageModeRGBA
#define ImageModeRGBA
Definition: PGFplatform.h:115
CPGFImage::m_decoder
CDecoder * m_decoder
PGF decoder.
Definition: PGFimage.h:523
PGFPostHeader::userData
UINT8 * userData
user data of size userDataLen (optional part of file header)
Definition: PGFtypes.h:170
CPGFImage::m_header
PGFHeader m_header
PGF file header.
Definition: PGFimage.h:529
CPGFImage::m_streamReinitialized
bool m_streamReinitialized
stream has been reinitialized
Definition: PGFimage.h:540
CPGFImage::CompleteHeader
bool CompleteHeader()
Definition: PGFimage.cpp:218
CPGFImage::m_quant
BYTE m_quant
quantization parameter
Definition: PGFimage.h:534
HeaderSize
#define HeaderSize
Definition: PGFtypes.h:280
ImageModeLabColor
#define ImageModeLabColor
Definition: PGFplatform.h:107
CPGFImage::m_channel
DataT * m_channel[MaxChannels]
untransformed channels in YUV format
Definition: PGFimage.h:522
CPGFImage::m_preHeader
PGFPreHeader m_preHeader
PGF pre-header.
Definition: PGFimage.h:528
PGFMagic
#define PGFMagic
PGF identification.
Definition: PGFtypes.h:61
ImageModeLab48
#define ImageModeLab48
Definition: PGFplatform.h:110
PGFPostHeader::cachedUserDataLen
UINT32 cachedUserDataLen
cached user data size in bytes (not part of file header)
Definition: PGFtypes.h:172
ImageModeCMYKColor
#define ImageModeCMYKColor
Definition: PGFplatform.h:102
PGFMagicVersion::magic
char magic[3]
PGF identification = "PGF".
Definition: PGFtypes.h:114
CPGFImage::m_postHeader
PGFPostHeader m_postHeader
PGF post-header.
Definition: PGFimage.h:530
CPGFImage::ComputeLevels
void ComputeLevels()
Definition: PGFimage.cpp:853
CPGFImage::m_downsample
bool m_downsample
chrominance channels are downsampled
Definition: PGFimage.h:535
DownsampleThreshold
#define DownsampleThreshold
if quality is larger than this threshold than downsampling is used
Definition: PGFtypes.h:65
PGFPreHeader::hSize
UINT32 hSize
total size of PGFHeader, [ColorTable], and [UserData] in bytes (since Version 6: 4 Bytes)
Definition: PGFtypes.h:124
CPGFImage::m_width
UINT32 m_width[MaxChannels]
width of each channel at current level
Definition: PGFimage.h:526
MaxQuality
#define MaxQuality
maximum quality
Definition: PGFtypes.h:94
ImageModeRGBColor
#define ImageModeRGBColor
Definition: PGFplatform.h:101
PGFHeader::channels
UINT8 channels
number of channels
Definition: PGFtypes.h:157
MaxUserDataSize
#define MaxUserDataSize
Definition: PGFtypes.h:283
ImageModeCMYK64
#define ImageModeCMYK64
Definition: PGFplatform.h:111
PGFHeader::quality
UINT8 quality
quantization parameter: 0=lossless, 4=standard, 6=poor quality
Definition: PGFtypes.h:155
PGFHeader::height
UINT32 height
image height in pixels
Definition: PGFtypes.h:153
ImageModeRGB48
#define ImageModeRGB48
Definition: PGFplatform.h:109
CPGFImage::m_height
UINT32 m_height[MaxChannels]
height of each channel at current level
Definition: PGFimage.h:527

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

  maxValue | The maximum intensity value.

Definition at line 737 of file PGFimage.cpp.

737 {
738 const BYTE bpc = m_header.bpp/m_header.channels;
739 BYTE pot = 0;
740
741 while(maxValue > 0) {
742 pot++;
743 maxValue >>= 1;
744 }
745 // store bits per channel
746 if (pot > bpc) pot = bpc;
747 if (pot > 31) pot = 31;
748 m_header.usedBitsPerChannel = pot;
749 }
CPGFImage::m_header
PGFHeader m_header
PGF file header.
Definition: PGFimage.h:529
PGFHeader::usedBitsPerChannel
UINT8 usedBitsPerChannel
number of used bits per channel in 16- and 32-bit per channel modes
Definition: PGFtypes.h:159
PGFHeader::bpp
UINT8 bpp
bits per pixel
Definition: PGFtypes.h:156
PGFHeader::channels
UINT8 channels
number of channels
Definition: PGFtypes.h:157

## ◆ 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 296 of file PGFimage.h.

296 { m_progressMode = pm; }
CPGFImage::m_progressMode
ProgressMode m_progressMode
progress mode used in Read and Write; PM_Relative is default mode
Definition: PGFimage.h:548

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

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

Definition at line 303 of file PGFimage.h.

303 { m_cb = callback; m_cbArg = arg; }
CPGFImage::m_cbArg
void * m_cbArg
refresh callback argument
Definition: PGFimage.h:546
CPGFImage::m_cb
RefreshCB m_cb
pointer to refresh callback procedure
Definition: PGFimage.h:545

## ◆ SetROI()

void CPGFImage::SetROI | ( | PGFRect | rect | ) |
| private

## ◆ UpdatePostHeaderSize()

UINT32 CPGFImage::UpdatePostHeaderSize | ( |  | ) |
| private

Definition at line 1123 of file PGFimage.cpp.

1123 {
1124 ASSERT(m_encoder);
1125
1126 INT64 offset = m_encoder->ComputeOffset(); ASSERT(offset >= 0);
1127
1128 if (offset > 0) {
1129 // update post-header size and rewrite pre-header
1130 m_preHeader.hSize += (UINT32)offset;
1131 m_encoder->UpdatePostHeaderSize(m_preHeader);
1132 }
1133
1134 // write dummy levelLength into stream
1135 return m_encoder->WriteLevelLength(m_levelLength);
1136 }
CPGFImage::m_preHeader
PGFPreHeader m_preHeader
PGF pre-header.
Definition: PGFimage.h:528
CEncoder::WriteLevelLength
UINT32 WriteLevelLength(UINT32 *&levelLength)
Definition: Encoder.cpp:177
CEncoder::UpdatePostHeaderSize
void UpdatePostHeaderSize(PGFPreHeader preHeader)
Definition: Encoder.cpp:160
CPGFImage::m_levelLength
UINT32 * m_levelLength
length of each level in bytes; first level starts immediately after this array
Definition: PGFimage.h:525
PGFPreHeader::hSize
UINT32 hSize
total size of PGFHeader, [ColorTable], and [UserData] in bytes (since Version 6: 4 Bytes)
Definition: PGFtypes.h:124
CPGFImage::m_encoder
CEncoder * m_encoder
PGF encoder.
Definition: PGFimage.h:524
CEncoder::ComputeOffset
INT64 ComputeOffset() const
Definition: Encoder.h:184

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

755 {
756 const BYTE bpc = m_header.bpp/m_header.channels;
757
758 if (bpc > 8) {
759 return m_header.usedBitsPerChannel;
760 } else {
761 return bpc;
762 }
763 }
CPGFImage::m_header
PGFHeader m_header
PGF file header.
Definition: PGFimage.h:529
PGFHeader::usedBitsPerChannel
UINT8 usedBitsPerChannel
number of used bits per channel in 16- and 32-bit per channel modes
Definition: PGFtypes.h:159
PGFHeader::bpp
UINT8 bpp
bits per pixel
Definition: PGFtypes.h:156
PGFHeader::channels
UINT8 channels
number of channels
Definition: PGFtypes.h:157

## ◆ Version()

BYTE CPGFImage::Version | ( |  | ) | const
| inline

Returns the used codec major version of a pgf image

Returns
  PGF codec major version of this image

Definition at line 484 of file PGFimage.h.

484 { BYTE ver = CodecMajorVersion(m_preHeader.version); return (ver <= 7) ? ver : (BYTE)m_header.version.major; }
PGFMagicVersion::version
UINT8 version
PGF version.
Definition: PGFtypes.h:115
CPGFImage::m_header
PGFHeader m_header
PGF file header.
Definition: PGFimage.h:529
CPGFImage::m_preHeader
PGFPreHeader m_preHeader
PGF pre-header.
Definition: PGFimage.h:528
CPGFImage::CodecMajorVersion
static BYTE CodecMajorVersion(BYTE version=PGFVersion)
Return major version.
Definition: PGFimage.cpp:767
PGFVersionNumber::major
UINT16 major
major version number
Definition: PGFtypes.h:140
PGFHeader::version
PGFVersionNumber version
codec version number: (since Version 7)
Definition: PGFtypes.h:160

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

  level | A level

Returns
  Image level width in pixels

Definition at line 413 of file PGFimage.h.

413 { ASSERT(level >= 0); return LevelSizeL(m_header.width, level); }
PGFHeader::width
UINT32 width
image width in pixels
Definition: PGFtypes.h:152
CPGFImage::m_header
PGFHeader m_header
PGF file header.
Definition: PGFimage.h:529
CPGFImage::LevelSizeL
static UINT32 LevelSizeL(UINT32 size, int level)
Definition: PGFimage.h:499

## ◆ Write() [1/2]

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

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

Parameters

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

Definition at line 1220 of file PGFimage.cpp.

1220 {
1221 ASSERT(stream);
1222 ASSERT(m_preHeader.hSize);
1223
1224 // create wavelet transform channels and encoder
1225 UINT32 nBytes = WriteHeader(stream);
1226
1227 // write image
1228 nBytes += WriteImage(stream, cb, data);
1229
1230 // return written bytes
1231 if (nWrittenBytes) *nWrittenBytes += nBytes;
1232 }
CPGFImage::m_preHeader
PGFPreHeader m_preHeader
PGF pre-header.
Definition: PGFimage.h:528
CPGFImage::WriteImage
UINT32 WriteImage(CPGFStream *stream, CallbackPtr cb=nullptr, void *data=nullptr)
Definition: PGFimage.cpp:1149
CPGFImage::WriteHeader
UINT32 WriteHeader(CPGFStream *stream)
Definition: PGFimage.cpp:978
PGFPreHeader::hSize
UINT32 hSize
total size of PGFHeader, [ColorTable], and [UserData] in bytes (since Version 6: 4 Bytes)
Definition: PGFtypes.h:124

## ◆ Write() [2/2]

UINT32 CPGFImage::Write | ( | int | level,
|  | CallbackPtr | cb = `nullptr`,
|  | void * | data = `nullptr`
| ) |  |

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

Parameters

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

Returns
  The number of bytes written into stream.

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

  stream | A PGF stream

Returns
  The number of bytes written into stream.

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

Parameters

  stream | A PGF stream

Returns
  The number of bytes written into stream.

Definition at line 978 of file PGFimage.cpp.

978 {
979 ASSERT(m_header.nLevels <= MaxLevel);
980 ASSERT(m_header.quality <= MaxQuality); // quality is already initialized
981
982 if (m_header.nLevels > 0) {
983 volatile OSError error = NoError; // volatile prevents optimizations
984 // create new wt channels
985 #ifdef LIBPGF_USE_OPENMP
986 #pragma omp parallel for default(shared)
987 #endif
988 for (int i=0; i < m_header.channels; i++) {
989 DataT *temp = nullptr;
990 if (error == NoError) {
991 if (m_wtChannel[i]) {
992 ASSERT(m_channel[i]);
993 // copy m_channel to temp
994 int size = m_height[i]*m_width[i];
995 temp = new(std::nothrow) DataT[size];
996 if (temp) {
997 memcpy(temp, m_channel[i], size*DataTSize);
998 delete m_wtChannel[i]; // also deletes m_channel
999 m_channel[i] = nullptr;
1000 } else {
1001 error = InsufficientMemory;
1002 }
1003 }
1004 if (error == NoError) {
1005 if (temp) {
1006 ASSERT(!m_channel[i]);
1007 m_channel[i] = temp;
1008 }
1009 m_wtChannel[i] = new CWaveletTransform(m_width[i], m_height[i], m_header.nLevels, m_channel[i]);
1010 if (m_wtChannel[i]) {
1011 #ifdef __PGFROISUPPORT__
1012 m_wtChannel[i]->SetROI(PGFRect(0, 0, m_width[i], m_height[i]));
1013 #endif
1014
1015 // wavelet subband decomposition
1016 for (int l=0; error == NoError && l < m_header.nLevels; l++) {
1017 OSError err = m_wtChannel[i]->ForwardTransform(l, m_quant);
1018 if (err != NoError) error = err;
1019 }
1020 } else {
1021 delete[] m_channel[i];
1022 error = InsufficientMemory;
1023 }
1024 }
1025 }
1026 }
1027 if (error != NoError) {
1028 // free already allocated memory
1029 for (int i=0; i < m_header.channels; i++) {
1030 delete m_wtChannel[i];
1031 }
1032 ReturnWithError(error);
1033 }
1034
1035 m_currentLevel = m_header.nLevels;
1036
1037 // create encoder, write headers and user data, but not level-length area
1038 m_encoder = new CEncoder(stream, m_preHeader, m_header, m_postHeader, m_userDataPos, m_useOMPinEncoder);
1039 if (m_favorSpeedOverSize) m_encoder->FavorSpeedOverSize();
1040
1041 #ifdef __PGFROISUPPORT__
1042 if (ROIisSupported()) {
1043 // new encoding scheme supporting ROI
1044 m_encoder->SetROI();
1045 }
1046 #endif
1047
1048 } else {
1049 // very small image: we don't use DWT and encoding
1050
1051 // create encoder, write headers and user data, but not level-length area
1052 m_encoder = new CEncoder(stream, m_preHeader, m_header, m_postHeader, m_userDataPos, m_useOMPinEncoder);
1053 }
1054
1055 INT64 nBytes = m_encoder->ComputeHeaderLength();
1056 return (nBytes > 0) ? (UINT32)nBytes : 0;
1057 }
CPGFImage::m_favorSpeedOverSize
bool m_favorSpeedOverSize
favor encoding speed over compression ratio
Definition: PGFimage.h:536
CPGFImage::m_userDataPos
UINT64 m_userDataPos
stream position of user data
Definition: PGFimage.h:531
DataT
INT32 DataT
Definition: PGFtypes.h:268
CPGFImage::m_header
PGFHeader m_header
PGF file header.
Definition: PGFimage.h:529
CPGFImage::m_quant
BYTE m_quant
quantization parameter
Definition: PGFimage.h:534
DataTSize
#define DataTSize
Definition: PGFtypes.h:282
CPGFImage::m_channel
DataT * m_channel[MaxChannels]
untransformed channels in YUV format
Definition: PGFimage.h:522
CPGFImage::m_preHeader
PGFPreHeader m_preHeader
PGF pre-header.
Definition: PGFimage.h:528
PGFHeader::nLevels
UINT8 nLevels
number of FWT transforms
Definition: PGFtypes.h:154
CWaveletTransform::ForwardTransform
OSError ForwardTransform(int level, int quant)
Definition: WaveletTransform.cpp:88
MaxLevel
#define MaxLevel
maximum number of transform levels
Definition: PGFtypes.h:62
CPGFImage::m_wtChannel
CWaveletTransform * m_wtChannel[MaxChannels]
wavelet transformed color channels
Definition: PGFimage.h:521
CPGFImage::m_postHeader
PGFPostHeader m_postHeader
PGF post-header.
Definition: PGFimage.h:530
CSubband::CWaveletTransform
friend class CWaveletTransform
Definition: Subband.h:43
CPGFImage::m_width
UINT32 m_width[MaxChannels]
width of each channel at current level
Definition: PGFimage.h:526
CPGFImage::ROIisSupported
bool ROIisSupported() const
Definition: PGFimage.h:466
MaxQuality
#define MaxQuality
maximum quality
Definition: PGFtypes.h:94
CPGFImage::m_useOMPinEncoder
bool m_useOMPinEncoder
use Open MP in encoder
Definition: PGFimage.h:537
CEncoder::ComputeHeaderLength
INT64 ComputeHeaderLength() const
Definition: Encoder.h:174
CEncoder::FavorSpeedOverSize
void FavorSpeedOverSize()
Encoder favors speed over compression size.
Definition: Encoder.h:121
PGFHeader::channels
UINT8 channels
number of channels
Definition: PGFtypes.h:157
PGFRect
Rectangle.
Definition: PGFtypes.h:224
CPGFImage::m_encoder
CEncoder * m_encoder
PGF encoder.
Definition: PGFimage.h:524
CPGFImage::m_currentLevel
int m_currentLevel
transform level of current image
Definition: PGFimage.h:532
PGFHeader::quality
UINT8 quality
quantization parameter: 0=lossless, 4=standard, 6=poor quality
Definition: PGFtypes.h:155
CPGFImage::m_height
UINT32 m_height[MaxChannels]
height of each channel at current level
Definition: PGFimage.h:527
CEncoder
PGF encoder.
Definition: Encoder.h:46

## ◆ WriteImage()

UINT32 CPGFImage::WriteImage | ( | CPGFStream * | stream,
|  | CallbackPtr | cb = `nullptr`,
|  | void * | data = `nullptr`
| ) |  |

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

Parameters

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

Returns
  The number of bytes written into stream.

Definition at line 1149 of file PGFimage.cpp.

1149 {
1150 ASSERT(stream);
1151 ASSERT(m_preHeader.hSize);
1152
1153 int levels = m_header.nLevels;
1154 double percent = pow(0.25, levels);
1155
1156 // update post-header size, rewrite pre-header, and write dummy levelLength
1157 UINT32 nWrittenBytes = UpdatePostHeaderSize();
1158
1159 if (levels == 0) {
1160 // for very small images: write channels uncoded
1161 for (int c=0; c < m_header.channels; c++) {
1162 const UINT32 size = m_width[c]*m_height[c];
1163
1164 // write channel data into stream
1165 for (UINT32 i=0; i < size; i++) {
1166 int count = DataTSize;
1167 stream->Write(&count, &m_channel[c][i]);
1168 }
1169 }
1170
1171 // now update progress
1172 if (cb) {
1173 if ((*cb)(1, true, data)) ReturnWithError(EscapePressed);
1174 }
1175
1176 } else {
1177 // encode quantized wavelet coefficients and write to PGF file
1178 // encode subbands, higher levels first
1179 // color channels are interleaved
1180
1181 // encode all levels
1182 for (m_currentLevel = levels; m_currentLevel > 0; ) {
1183 WriteLevel(); // decrements m_currentLevel
1184
1185 // now update progress
1186 if (cb) {
1187 percent *= 4;
1188 if ((*cb)(percent, true, data)) ReturnWithError(EscapePressed);
1189 }
1190 }
1191
1192 // flush encoder and write level lengths
1193 m_encoder->Flush();
1194 }
1195
1196 // update level lengths
1197 nWrittenBytes += m_encoder->UpdateLevelLength(); // return written image bytes
1198
1199 // delete encoder
1200 delete m_encoder; m_encoder = nullptr;
1201
1202 ASSERT(!m_encoder);
1203
1204 return nWrittenBytes;
1205 }
CPGFStream::Write
virtual void Write(int *count, void *buffer)=0
CPGFImage::m_header
PGFHeader m_header
PGF file header.
Definition: PGFimage.h:529
CPGFImage::WriteLevel
void WriteLevel()
Definition: PGFimage.cpp:1067
DataTSize
#define DataTSize
Definition: PGFtypes.h:282
CPGFImage::m_channel
DataT * m_channel[MaxChannels]
untransformed channels in YUV format
Definition: PGFimage.h:522
CPGFImage::m_preHeader
PGFPreHeader m_preHeader
PGF pre-header.
Definition: PGFimage.h:528
PGFHeader::nLevels
UINT8 nLevels
number of FWT transforms
Definition: PGFtypes.h:154
PGFPreHeader::hSize
UINT32 hSize
total size of PGFHeader, [ColorTable], and [UserData] in bytes (since Version 6: 4 Bytes)
Definition: PGFtypes.h:124
CPGFImage::m_width
UINT32 m_width[MaxChannels]
width of each channel at current level
Definition: PGFimage.h:526
CEncoder::Flush
void Flush()
Definition: Encoder.cpp:310
CEncoder::UpdateLevelLength
UINT32 UpdateLevelLength()
Definition: Encoder.cpp:202
PGFHeader::channels
UINT8 channels
number of channels
Definition: PGFtypes.h:157
CPGFImage::m_encoder
CEncoder * m_encoder
PGF encoder.
Definition: PGFimage.h:524
CPGFImage::m_currentLevel
int m_currentLevel
transform level of current image
Definition: PGFimage.h:532
CPGFImage::m_height
UINT32 m_height[MaxChannels]
height of each channel at current level
Definition: PGFimage.h:527
CPGFImage::UpdatePostHeaderSize
UINT32 UpdatePostHeaderSize()
Definition: PGFimage.cpp:1123

## ◆ WriteLevel()

void CPGFImage::WriteLevel | ( |  | ) |
| private

Definition at line 1067 of file PGFimage.cpp.

1067 {
1068 ASSERT(m_encoder);
1069 ASSERT(m_currentLevel > 0);
1070 ASSERT(m_header.nLevels > 0);
1071
1072 #ifdef __PGFROISUPPORT__
1073 if (ROIisSupported()) {
1074 const int lastChannel = m_header.channels - 1;
1075
1076 for (int i=0; i < m_header.channels; i++) {
1077 // get number of tiles and tile indices
1078 const UINT32 nTiles = m_wtChannel[i]->GetNofTiles(m_currentLevel);
1079 const UINT32 lastTile = nTiles - 1;
1080
1081 if (m_currentLevel == m_header.nLevels) {
1082 // last level also has LL band
1083 ASSERT(nTiles == 1);
1084 m_wtChannel[i]->GetSubband(m_currentLevel, LL)->ExtractTile(*m_encoder);
1085 m_encoder->EncodeTileBuffer(); // encode macro block with tile-end = true
1086 }
1087 for (UINT32 tileY=0; tileY < nTiles; tileY++) {
1088 for (UINT32 tileX=0; tileX < nTiles; tileX++) {
1089 // extract tile to macro block and encode already filled macro blocks with tile-end = false
1090 m_wtChannel[i]->GetSubband(m_currentLevel, HL)->ExtractTile(*m_encoder, true, tileX, tileY);
1091 m_wtChannel[i]->GetSubband(m_currentLevel, LH)->ExtractTile(*m_encoder, true, tileX, tileY);
1092 m_wtChannel[i]->GetSubband(m_currentLevel, HH)->ExtractTile(*m_encoder, true, tileX, tileY);
1093 if (i == lastChannel && tileY == lastTile && tileX == lastTile) {
1094 // all necessary data are buffered. next call of EncodeTileBuffer will write the last piece of data of the current level.
1095 m_encoder->SetEncodedLevel(--m_currentLevel);
1096 }
1097 m_encoder->EncodeTileBuffer(); // encode last macro block with tile-end = true
1098 }
1099 }
1100 }
1101 } else
1102 #endif
1103 {
1104 for (int i=0; i < m_header.channels; i++) {
1105 ASSERT(m_wtChannel[i]);
1106 if (m_currentLevel == m_header.nLevels) {
1107 // last level also has LL band
1108 m_wtChannel[i]->GetSubband(m_currentLevel, LL)->ExtractTile(*m_encoder);
1109 }
1110 //encoder.EncodeInterleaved(m_wtChannel[i], m_currentLevel, m_quant); // until version 4
1111 m_wtChannel[i]->GetSubband(m_currentLevel, HL)->ExtractTile(*m_encoder); // since version 5
1112 m_wtChannel[i]->GetSubband(m_currentLevel, LH)->ExtractTile(*m_encoder); // since version 5
1113 m_wtChannel[i]->GetSubband(m_currentLevel, HH)->ExtractTile(*m_encoder);
1114 }
1115
1116 // all necessary data are buffered. next call of EncodeBuffer will write the last piece of data of the current level.
1117 m_encoder->SetEncodedLevel(--m_currentLevel);
1118 }
1119 }
HH
Definition: PGFtypes.h:99
CSubband::ExtractTile
void ExtractTile(CEncoder &encoder, bool tile=false, UINT32 tileX=0, UINT32 tileY=0)
Definition: Subband.cpp:177
CPGFImage::m_header
PGFHeader m_header
PGF file header.
Definition: PGFimage.h:529
PGFHeader::nLevels
UINT8 nLevels
number of FWT transforms
Definition: PGFtypes.h:154
CPGFImage::m_wtChannel
CWaveletTransform * m_wtChannel[MaxChannels]
wavelet transformed color channels
Definition: PGFimage.h:521
LH
Definition: PGFtypes.h:99
HL
Definition: PGFtypes.h:99
CWaveletTransform::GetSubband
CSubband * GetSubband(int level, Orientation orientation)
Definition: WaveletTransform.h:93
CPGFImage::ROIisSupported
bool ROIisSupported() const
Definition: PGFimage.h:466
LL
Definition: PGFtypes.h:99
PGFHeader::channels
UINT8 channels
number of channels
Definition: PGFtypes.h:157
CPGFImage::m_encoder
CEncoder * m_encoder
PGF encoder.
Definition: PGFimage.h:524
CPGFImage::m_currentLevel
int m_currentLevel
transform level of current image
Definition: PGFimage.h:532
CEncoder::SetEncodedLevel
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 545 of file PGFimage.h.

## ◆ m_cbArg

void* CPGFImage::m_cbArg
| private

refresh callback argument

Definition at line 546 of file PGFimage.h.

## ◆ m_channel

DataT* CPGFImage::m_channel[MaxChannels]
| protected

untransformed channels in YUV format

Definition at line 522 of file PGFimage.h.

## ◆ m_currentLevel

int CPGFImage::m_currentLevel
| protected

transform level of current image

Definition at line 532 of file PGFimage.h.

## ◆ m_decoder

CDecoder* CPGFImage::m_decoder
| protected

PGF decoder.

Definition at line 523 of file PGFimage.h.

## ◆ m_downsample

bool CPGFImage::m_downsample
| protected

chrominance channels are downsampled

Definition at line 535 of file PGFimage.h.

## ◆ m_encoder

CEncoder* CPGFImage::m_encoder
| protected

PGF encoder.

Definition at line 524 of file PGFimage.h.

## ◆ m_favorSpeedOverSize

bool CPGFImage::m_favorSpeedOverSize
| protected

favor encoding speed over compression ratio

Definition at line 536 of file PGFimage.h.

## ◆ m_header

PGFHeader CPGFImage::m_header
| protected

PGF file header.

Definition at line 529 of file PGFimage.h.

## ◆ m_height

UINT32 CPGFImage::m_height[MaxChannels]
| protected

height of each channel at current level

Definition at line 527 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 525 of file PGFimage.h.

## ◆ m_percent

double CPGFImage::m_percent
| private

progress [0..1]

Definition at line 547 of file PGFimage.h.

## ◆ m_postHeader

PGFPostHeader CPGFImage::m_postHeader
| protected

PGF post-header.

Definition at line 530 of file PGFimage.h.

## ◆ m_preHeader

PGFPreHeader CPGFImage::m_preHeader
| protected

PGF pre-header.

Definition at line 528 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 548 of file PGFimage.h.

## ◆ m_quant

BYTE CPGFImage::m_quant
| protected

quantization parameter

Definition at line 534 of file PGFimage.h.

## ◆ m_roi

PGFRect CPGFImage::m_roi
| protected

region of interest

Definition at line 541 of file PGFimage.h.

## ◆ m_streamReinitialized

bool CPGFImage::m_streamReinitialized
| protected

stream has been reinitialized

Definition at line 540 of file PGFimage.h.

## ◆ m_useOMPinDecoder

bool CPGFImage::m_useOMPinDecoder
| protected

use Open MP in decoder

Definition at line 538 of file PGFimage.h.

## ◆ m_useOMPinEncoder

bool CPGFImage::m_useOMPinEncoder
| protected

use Open MP in encoder

Definition at line 537 of file PGFimage.h.

## ◆ m_userDataPolicy

UINT32 CPGFImage::m_userDataPolicy
| protected

user data (metadata) policy during open

Definition at line 533 of file PGFimage.h.

## ◆ m_userDataPos

UINT64 CPGFImage::m_userDataPos
| protected

stream position of user data

Definition at line 531 of file PGFimage.h.

## ◆ m_width

UINT32 CPGFImage::m_width[MaxChannels]
| protected

width of each channel at current level

Definition at line 526 of file PGFimage.h.

## ◆ m_wtChannel

CWaveletTransform* CPGFImage::m_wtChannel[MaxChannels]
| protected

wavelet transformed color channels

Definition at line 521 of file PGFimage.h.

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

- PGFimage.h
- PGFimage.cpp