libpgf  6.12.24
PGF - Progressive Graphics File
CWaveletTransform Class Reference

PGF wavelet transform. More...

#include <WaveletTransform.h>

Public Member Functions

 CWaveletTransform (UINT32 width, UINT32 height, int levels, DataT *data=NULL)
 
 ~CWaveletTransform ()
 Destructor. More...
 
OSError ForwardTransform (int level, int quant)
 
OSError InverseTransform (int level, UINT32 *width, UINT32 *height, DataT **data)
 
CSubbandGetSubband (int level, Orientation orientation)
 

Private Member Functions

void Destroy ()
 
void InitSubbands (UINT32 width, UINT32 height, DataT *data)
 
void ForwardRow (DataT *buff, UINT32 width)
 
void InverseRow (DataT *buff, UINT32 width)
 
void LinearToMallat (int destLevel, DataT *loRow, DataT *hiRow, UINT32 width)
 
void MallatToLinear (int srcLevel, DataT *loRow, DataT *hiRow, UINT32 width)
 

Private Attributes

int m_nLevels
 number of transform levels: one more than the number of level in PGFimage More...
 
CSubband(* m_subband )[NSubbands]
 quadtree of subbands: LL HL LH HH More...
 

Friends

class CSubband
 

Detailed Description

PGF wavelet transform.

PGF wavelet transform class.

Author
C. Stamm, R. Spuler

Definition at line 84 of file WaveletTransform.h.

Constructor & Destructor Documentation

◆ CWaveletTransform()

CWaveletTransform::CWaveletTransform ( UINT32  width,
UINT32  height,
int  levels,
DataT data = NULL 
)

Constructor: Constructs a wavelet transform pyramid of given size and levels.

Parameters
widthThe width of the original image (at level 0) in pixels
heightThe height of the original image (at level 0) in pixels
levelsThe number of levels (>= 0)
dataInput data of subband LL at level 0

Definition at line 40 of file WaveletTransform.cpp.

41 : m_nLevels(levels + 1)
42 , m_subband(0)
43 {
44  ASSERT(m_nLevels > 0 && m_nLevels <= MaxLevel + 1);
45  InitSubbands(width, height, data);
46 #ifdef __PGFROISUPPORT__
47  m_ROIindices.SetLevels(levels + 1);
48 #endif
49 }
#define MaxLevel
maximum number of transform levels
Definition: PGFtypes.h:56
int m_nLevels
number of transform levels: one more than the number of level in PGFimage
CSubband(* m_subband)[NSubbands]
quadtree of subbands: LL HL LH HH
void InitSubbands(UINT32 width, UINT32 height, DataT *data)

◆ ~CWaveletTransform()

CWaveletTransform::~CWaveletTransform ( )
inline

Destructor.

Definition at line 98 of file WaveletTransform.h.

98 { Destroy(); }

Member Function Documentation

◆ Destroy()

void CWaveletTransform::Destroy ( )
inlineprivate

Definition at line 151 of file WaveletTransform.h.

151  {
152  delete[] m_subband; m_subband = 0;
153  #ifdef __PGFROISUPPORT__
154  m_ROIindices.Destroy();
155  #endif
156  }
CSubband(* m_subband)[NSubbands]
quadtree of subbands: LL HL LH HH

◆ ForwardRow()

void CWaveletTransform::ForwardRow ( DataT buff,
UINT32  width 
)
private

Definition at line 181 of file WaveletTransform.cpp.

181  {
182  if (width >= FilterWidth) {
183  UINT32 i = 3;
184 
185  // left border handling
186  src[1] -= ((src[0] + src[2] + c1) >> 1);
187  src[0] += ((src[1] + c1) >> 1);
188 
189  // middle part
190  for (; i < width-1; i += 2) {
191  src[i] -= ((src[i-1] + src[i+1] + c1) >> 1);
192  src[i-1] += ((src[i-2] + src[i] + c2) >> 2);
193  }
194 
195  // right border handling
196  if (width & 1) {
197  src[i-1] += ((src[i-2] + c1) >> 1);
198  } else {
199  src[i] -= src[i-1];
200  src[i-1] += ((src[i-2] + src[i] + c2) >> 2);
201  }
202  }
203 }
#define c1
#define c2
#define FilterWidth
number of coefficients of the row wavelet filter

◆ ForwardTransform()

OSError CWaveletTransform::ForwardTransform ( int  level,
int  quant 
)

Compute fast forward wavelet transform of LL subband at given level and stores result on all 4 subbands of level + 1.

Parameters
levelA wavelet transform pyramid level (>= 0 && < Levels())
quantA quantization value (linear scalar quantization)
Returns
error in case of a memory allocation problem

Definition at line 88 of file WaveletTransform.cpp.

88  {
89  ASSERT(level >= 0 && level < m_nLevels - 1);
90  const int destLevel = level + 1;
91  ASSERT(m_subband[destLevel]);
92  CSubband* srcBand = &m_subband[level][LL]; ASSERT(srcBand);
93  const UINT32 width = srcBand->GetWidth();
94  const UINT32 height = srcBand->GetHeight();
95  DataT* src = srcBand->GetBuffer(); ASSERT(src);
96  DataT *row0, *row1, *row2, *row3;
97 
98  // Allocate memory for next transform level
99  for (int i=0; i < NSubbands; i++) {
100  if (!m_subband[destLevel][i].AllocMemory()) return InsufficientMemory;
101  }
102 
103  if (height >= FilterHeight) {
104  // transform LL subband
105  // top border handling
106  row0 = src; row1 = row0 + width; row2 = row1 + width;
107  ForwardRow(row0, width);
108  ForwardRow(row1, width);
109  ForwardRow(row2, width);
110  for (UINT32 k=0; k < width; k++) {
111  row1[k] -= ((row0[k] + row2[k] + c1) >> 1);
112  row0[k] += ((row1[k] + c1) >> 1);
113  }
114  LinearToMallat(destLevel, row0, row1, width);
115  row0 = row1; row1 = row2; row2 += width; row3 = row2 + width;
116 
117  // middle part
118  for (UINT32 i=3; i < height-1; i += 2) {
119  ForwardRow(row2, width);
120  ForwardRow(row3, width);
121  for (UINT32 k=0; k < width; k++) {
122  row2[k] -= ((row1[k] + row3[k] + c1) >> 1);
123  row1[k] += ((row0[k] + row2[k] + c2) >> 2);
124  }
125  LinearToMallat(destLevel, row1, row2, width);
126  row0 = row2; row1 = row3; row2 = row3 + width; row3 = row2 + width;
127  }
128 
129  // bottom border handling
130  if (height & 1) {
131  for (UINT32 k=0; k < width; k++) {
132  row1[k] += ((row0[k] + c1) >> 1);
133  }
134  LinearToMallat(destLevel, row1, NULL, width);
135  row0 = row1; row1 += width;
136  } else {
137  ForwardRow(row2, width);
138  for (UINT32 k=0; k < width; k++) {
139  row2[k] -= row1[k];
140  row1[k] += ((row0[k] + row2[k] + c2) >> 2);
141  }
142  LinearToMallat(destLevel, row1, row2, width);
143  row0 = row1; row1 = row2; row2 += width;
144  }
145  } else {
146  // if height is too small
147  row0 = src; row1 = row0 + width;
148  // first part
149  for (UINT32 k=0; k < height; k += 2) {
150  ForwardRow(row0, width);
151  ForwardRow(row1, width);
152  LinearToMallat(destLevel, row0, row1, width);
153  row0 += width << 1; row1 += width << 1;
154  }
155  // bottom
156  if (height & 1) {
157  LinearToMallat(destLevel, row0, NULL, width);
158  }
159  }
160 
161  if (quant > 0) {
162  // subband quantization (without LL)
163  for (int i=1; i < NSubbands; i++) {
164  m_subband[destLevel][i].Quantize(quant);
165  }
166  // LL subband quantization
167  if (destLevel == m_nLevels - 1) {
168  m_subband[destLevel][LL].Quantize(quant);
169  }
170  }
171 
172  // free source band
173  srcBand->FreeMemory();
174  return NoError;
175 }
DataT * GetBuffer()
Definition: Subband.h:106
INT32 DataT
Definition: PGFtypes.h:219
bool AllocMemory()
Definition: Subband.cpp:72
void ForwardRow(DataT *buff, UINT32 width)
Wavelet channel class.
Definition: Subband.h:42
#define c1
int GetHeight() const
Definition: Subband.h:122
int m_nLevels
number of transform levels: one more than the number of level in PGFimage
CSubband(* m_subband)[NSubbands]
quadtree of subbands: LL HL LH HH
void FreeMemory()
Delete the memory buffer of this subband.
Definition: Subband.cpp:96
void Quantize(int quantParam)
Definition: Subband.cpp:107
void LinearToMallat(int destLevel, DataT *loRow, DataT *hiRow, UINT32 width)
Definition: PGFtypes.h:92
#define FilterHeight
number of coefficients of the column wavelet filter
#define c2
int GetWidth() const
Definition: Subband.h:127
#define NSubbands
number of subbands per level
Definition: PGFtypes.h:57

◆ GetSubband()

CSubband* CWaveletTransform::GetSubband ( int  level,
Orientation  orientation 
)
inline

Get pointer to one of the 4 subband at a given level.

Parameters
levelA wavelet transform pyramid level (>= 0 && <= Levels())
orientationA quarter of the subband (LL, LH, HL, HH)

Definition at line 122 of file WaveletTransform.h.

122  {
123  ASSERT(level >= 0 && level < m_nLevels);
124  return &m_subband[level][orientation];
125  }
int m_nLevels
number of transform levels: one more than the number of level in PGFimage
CSubband(* m_subband)[NSubbands]
quadtree of subbands: LL HL LH HH

◆ InitSubbands()

void CWaveletTransform::InitSubbands ( UINT32  width,
UINT32  height,
DataT data 
)
private

Definition at line 53 of file WaveletTransform.cpp.

53  {
54  if (m_subband) Destroy();
55 
56  // create subbands
58 
59  // init subbands
60  UINT32 loWidth = width;
61  UINT32 hiWidth = width;
62  UINT32 loHeight = height;
63  UINT32 hiHeight = height;
64 
65  for (int level = 0; level < m_nLevels; level++) {
66  m_subband[level][LL].Initialize(loWidth, loHeight, level, LL); // LL
67  m_subband[level][HL].Initialize(hiWidth, loHeight, level, HL); // HL
68  m_subband[level][LH].Initialize(loWidth, hiHeight, level, LH); // LH
69  m_subband[level][HH].Initialize(hiWidth, hiHeight, level, HH); // HH
70  hiWidth = loWidth >> 1; hiHeight = loHeight >> 1;
71  loWidth = (loWidth + 1) >> 1; loHeight = (loHeight + 1) >> 1;
72  }
73  if (data) {
74  m_subband[0][LL].SetBuffer(data);
75  }
76 }
Definition: PGFtypes.h:92
void SetBuffer(DataT *b)
Definition: Subband.h:147
void Initialize(UINT32 width, UINT32 height, int level, Orientation orient)
Definition: Subband.cpp:52
Wavelet channel class.
Definition: Subband.h:42
Definition: PGFtypes.h:92
int m_nLevels
number of transform levels: one more than the number of level in PGFimage
Definition: PGFtypes.h:92
CSubband(* m_subband)[NSubbands]
quadtree of subbands: LL HL LH HH
Definition: PGFtypes.h:92
#define NSubbands
number of subbands per level
Definition: PGFtypes.h:57

◆ InverseRow()

void CWaveletTransform::InverseRow ( DataT buff,
UINT32  width 
)
private

Definition at line 367 of file WaveletTransform.cpp.

367  {
368  if (width >= FilterWidth) {
369  UINT32 i = 2;
370 
371  // left border handling
372  dest[0] -= ((dest[1] + c1) >> 1);
373 
374  // middle part
375  for (; i < width - 1; i += 2) {
376  dest[i] -= ((dest[i-1] + dest[i+1] + c2) >> 2);
377  dest[i-1] += ((dest[i-2] + dest[i] + c1) >> 1);
378  }
379 
380  // right border handling
381  if (width & 1) {
382  dest[i] -= ((dest[i-1] + c1) >> 1);
383  dest[i-1] += ((dest[i-2] + dest[i] + c1) >> 1);
384  } else {
385  dest[i-1] += dest[i-2];
386  }
387  }
388 }
#define c1
#define c2
#define FilterWidth
number of coefficients of the row wavelet filter

◆ InverseTransform()

OSError CWaveletTransform::InverseTransform ( int  level,
UINT32 *  width,
UINT32 *  height,
DataT **  data 
)

Compute fast inverse wavelet transform of all 4 subbands of given level and stores result in LL subband of level - 1.

Parameters
levelA wavelet transform pyramid level (> 0 && <= Levels())
widthA pointer to the returned width of subband LL (in pixels)
heightA pointer to the returned height of subband LL (in pixels)
dataA pointer to the returned array of image data
Returns
error in case of a memory allocation problem

Definition at line 245 of file WaveletTransform.cpp.

245  {
246  ASSERT(srcLevel > 0 && srcLevel < m_nLevels);
247  const int destLevel = srcLevel - 1;
248  ASSERT(m_subband[destLevel]);
249  CSubband* destBand = &m_subband[destLevel][LL];
250  UINT32 width, height;
251 
252  // allocate memory for the results of the inverse transform
253  if (!destBand->AllocMemory()) return InsufficientMemory;
254  DataT *dest = destBand->GetBuffer(), *origin = dest, *row0, *row1, *row2, *row3;
255 
256 #ifdef __PGFROISUPPORT__
257  PGFRect destROI = destBand->GetROI(); // is valid only after AllocMemory
258  width = destROI.Width();
259  height = destROI.Height();
260  const UINT32 destWidth = width; // destination buffer width
261  const UINT32 destHeight = height; // destination buffer height
262 
263  // update destination ROI
264  if (destROI.top & 1) {
265  destROI.top++;
266  origin += destWidth;
267  height--;
268  }
269  if (destROI.left & 1) {
270  destROI.left++;
271  origin++;
272  width--;
273  }
274 
275  // init source buffer position
276  for (int i=0; i < NSubbands; i++) {
277  UINT32 left = (destROI.left >> 1) - m_subband[srcLevel][i].GetROI().left;
278  UINT32 top = (destROI.top >> 1) - m_subband[srcLevel][i].GetROI().top;
279  m_subband[srcLevel][i].InitBuffPos(left, top);
280  }
281 #else
282  width = destBand->GetWidth();
283  height = destBand->GetHeight();
284  PGFRect destROI(0, 0, width, height);
285  const UINT32 destWidth = width; // destination buffer width
286  const UINT32 destHeight = height; // destination buffer height
287 
288  // init source buffer position
289  for (int i=0; i < NSubbands; i++) {
290  m_subband[srcLevel][i].InitBuffPos();
291  }
292 #endif
293 
294  if (destHeight >= FilterHeight) {
295  // top border handling
296  row0 = origin; row1 = row0 + destWidth;
297  MallatToLinear(srcLevel, row0, row1, width);
298  for (UINT32 k=0; k < width; k++) {
299  row0[k] -= ((row1[k] + c1) >> 1);
300  }
301 
302  // middle part
303  row2 = row1 + destWidth; row3 = row2 + destWidth;
304  for (UINT32 i=destROI.top + 2; i < destROI.bottom - 1; i += 2) {
305  MallatToLinear(srcLevel, row2, row3, width);
306  for (UINT32 k=0; k < width; k++) {
307  row2[k] -= ((row1[k] + row3[k] + c2) >> 2);
308  row1[k] += ((row0[k] + row2[k] + c1) >> 1);
309  }
310  InverseRow(row0, width);
311  InverseRow(row1, width);
312  row0 = row2; row1 = row3; row2 = row1 + destWidth; row3 = row2 + destWidth;
313  }
314 
315  // bottom border handling
316  if (height & 1) {
317  MallatToLinear(srcLevel, row2, NULL, width);
318  for (UINT32 k=0; k < width; k++) {
319  row2[k] -= ((row1[k] + c1) >> 1);
320  row1[k] += ((row0[k] + row2[k] + c1) >> 1);
321  }
322  InverseRow(row0, width);
323  InverseRow(row1, width);
324  InverseRow(row2, width);
325  row0 = row1; row1 = row2; row2 += destWidth;
326  } else {
327  for (UINT32 k=0; k < width; k++) {
328  row1[k] += row0[k];
329  }
330  InverseRow(row0, width);
331  InverseRow(row1, width);
332  row0 = row1; row1 += destWidth;
333  }
334  } else {
335  // height is too small
336  row0 = origin; row1 = row0 + destWidth;
337  // first part
338  for (UINT32 k=0; k < height; k += 2) {
339  MallatToLinear(srcLevel, row0, row1, width);
340  InverseRow(row0, width);
341  InverseRow(row1, width);
342  row0 += destWidth << 1; row1 += destWidth << 1;
343  }
344  // bottom
345  if (height & 1) {
346  MallatToLinear(srcLevel, row0, NULL, width);
347  InverseRow(row0, width);
348  }
349  }
350 
351  // free memory of the current srcLevel
352  for (int i=0; i < NSubbands; i++) {
353  m_subband[srcLevel][i].FreeMemory();
354  }
355 
356  // return info
357  *w = destWidth;
358  *h = height;
359  *data = dest;
360  return NoError;
361 }
DataT * GetBuffer()
Definition: Subband.h:106
void MallatToLinear(int srcLevel, DataT *loRow, DataT *hiRow, UINT32 width)
INT32 DataT
Definition: PGFtypes.h:219
bool AllocMemory()
Definition: Subband.cpp:72
Wavelet channel class.
Definition: Subband.h:42
void InitBuffPos()
Definition: Subband.h:160
#define c1
int GetHeight() const
Definition: Subband.h:122
void InverseRow(DataT *buff, UINT32 width)
UINT32 Height() const
Definition: PGFtypes.h:207
int m_nLevels
number of transform levels: one more than the number of level in PGFimage
UINT32 top
Definition: PGFtypes.h:215
CSubband(* m_subband)[NSubbands]
quadtree of subbands: LL HL LH HH
void FreeMemory()
Delete the memory buffer of this subband.
Definition: Subband.cpp:96
UINT32 left
Definition: PGFtypes.h:215
Definition: PGFtypes.h:92
#define FilterHeight
number of coefficients of the column wavelet filter
#define c2
Rectangle.
Definition: PGFtypes.h:194
int GetWidth() const
Definition: Subband.h:127
#define NSubbands
number of subbands per level
Definition: PGFtypes.h:57
UINT32 Width() const
Definition: PGFtypes.h:205
UINT32 bottom
Definition: PGFtypes.h:215

◆ LinearToMallat()

void CWaveletTransform::LinearToMallat ( int  destLevel,
DataT loRow,
DataT hiRow,
UINT32  width 
)
private

Definition at line 207 of file WaveletTransform.cpp.

207  {
208  const UINT32 wquot = width >> 1;
209  const bool wrem = width & 1;
210  CSubband &ll = m_subband[destLevel][LL], &hl = m_subband[destLevel][HL];
211  CSubband &lh = m_subband[destLevel][LH], &hh = m_subband[destLevel][HH];
212 
213  if (hiRow) {
214  for (UINT32 i=0; i < wquot; i++) {
215  ll.WriteBuffer(*loRow++); // first access, than increment
216  hl.WriteBuffer(*loRow++);
217  lh.WriteBuffer(*hiRow++); // first access, than increment
218  hh.WriteBuffer(*hiRow++);
219  }
220  if (wrem) {
221  ll.WriteBuffer(*loRow);
222  lh.WriteBuffer(*hiRow);
223  }
224  } else {
225  for (UINT32 i=0; i < wquot; i++) {
226  ll.WriteBuffer(*loRow++); // first access, than increment
227  hl.WriteBuffer(*loRow++);
228  }
229  if (wrem) ll.WriteBuffer(*loRow);
230  }
231 }
Definition: PGFtypes.h:92
Wavelet channel class.
Definition: Subband.h:42
Definition: PGFtypes.h:92
Definition: PGFtypes.h:92
CSubband(* m_subband)[NSubbands]
quadtree of subbands: LL HL LH HH
Definition: PGFtypes.h:92
void WriteBuffer(DataT val)
Definition: Subband.h:146

◆ MallatToLinear()

void CWaveletTransform::MallatToLinear ( int  srcLevel,
DataT loRow,
DataT hiRow,
UINT32  width 
)
private

Definition at line 392 of file WaveletTransform.cpp.

392  {
393  const UINT32 wquot = width >> 1;
394  const bool wrem = width & 1;
395  CSubband &ll = m_subband[srcLevel][LL], &hl = m_subband[srcLevel][HL];
396  CSubband &lh = m_subband[srcLevel][LH], &hh = m_subband[srcLevel][HH];
397 
398  if (hiRow) {
399  #ifdef __PGFROISUPPORT__
400  const bool storePos = wquot < ll.BufferWidth();
401  UINT32 llPos = 0, hlPos = 0, lhPos = 0, hhPos = 0;
402 
403  if (storePos) {
404  // save current src buffer positions
405  llPos = ll.GetBuffPos();
406  hlPos = hl.GetBuffPos();
407  lhPos = lh.GetBuffPos();
408  hhPos = hh.GetBuffPos();
409  }
410  #endif
411 
412  for (UINT32 i=0; i < wquot; i++) {
413  *loRow++ = ll.ReadBuffer();// first access, than increment
414  *loRow++ = hl.ReadBuffer();// first access, than increment
415  *hiRow++ = lh.ReadBuffer();// first access, than increment
416  *hiRow++ = hh.ReadBuffer();// first access, than increment
417  }
418 
419  if (wrem) {
420  *loRow++ = ll.ReadBuffer();// first access, than increment
421  *hiRow++ = lh.ReadBuffer();// first access, than increment
422  }
423 
424  #ifdef __PGFROISUPPORT__
425  if (storePos) {
426  // increment src buffer positions
427  ll.IncBuffRow(llPos);
428  hl.IncBuffRow(hlPos);
429  lh.IncBuffRow(lhPos);
430  hh.IncBuffRow(hhPos);
431  }
432  #endif
433 
434  } else {
435  #ifdef __PGFROISUPPORT__
436  const bool storePos = wquot < ll.BufferWidth();
437  UINT32 llPos = 0, hlPos = 0;
438 
439  if (storePos) {
440  // save current src buffer positions
441  llPos = ll.GetBuffPos();
442  hlPos = hl.GetBuffPos();
443  }
444  #endif
445 
446  for (UINT32 i=0; i < wquot; i++) {
447  *loRow++ = ll.ReadBuffer();// first access, than increment
448  *loRow++ = hl.ReadBuffer();// first access, than increment
449  }
450  if (wrem) *loRow++ = ll.ReadBuffer();
451 
452  #ifdef __PGFROISUPPORT__
453  if (storePos) {
454  // increment src buffer positions
455  ll.IncBuffRow(llPos);
456  hl.IncBuffRow(hlPos);
457  }
458  #endif
459  }
460 }
Definition: PGFtypes.h:92
UINT32 GetBuffPos() const
Definition: Subband.h:150
Wavelet channel class.
Definition: Subband.h:42
DataT ReadBuffer()
Definition: Subband.h:148
Definition: PGFtypes.h:92
Definition: PGFtypes.h:92
CSubband(* m_subband)[NSubbands]
quadtree of subbands: LL HL LH HH
Definition: PGFtypes.h:92

Friends And Related Function Documentation

◆ CSubband

friend class CSubband
friend

Definition at line 85 of file WaveletTransform.h.

Member Data Documentation

◆ m_nLevels

int CWaveletTransform::m_nLevels
private

number of transform levels: one more than the number of level in PGFimage

Definition at line 167 of file WaveletTransform.h.

◆ m_subband

CSubband(* CWaveletTransform::m_subband)[NSubbands]
private

quadtree of subbands: LL HL LH HH

Definition at line 168 of file WaveletTransform.h.


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