libpgf 6.14.12
PGF - Progressive Graphics File
Loading...
Searching...
No Matches
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.
 
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
 
CSubband(* m_subband )[NSubbands]
 quadtree of subbands: LL HL LH HH
 

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
CSubband(* m_subband)[NSubbands]
quadtree of subbands: LL HL LH HH
void InitSubbands(UINT32 width, UINT32 height, DataT *data)
int m_nLevels
number of transform levels: one more than the number of level in PGFimage

◆ ~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 }

◆ 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 c2
#define c1
#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}
#define NSubbands
number of subbands per level
Definition PGFtypes.h:57
@ LL
Definition PGFtypes.h:92
INT32 DataT
Definition PGFtypes.h:219
#define FilterHeight
number of coefficients of the column wavelet filter
Wavelet channel class.
Definition Subband.h:42
DataT * GetBuffer()
Definition Subband.h:106
int GetWidth() const
Definition Subband.h:127
void Quantize(int quantParam)
Definition Subband.cpp:112
void FreeMemory()
Delete the memory buffer of this subband.
Definition Subband.cpp:101
int GetHeight() const
Definition Subband.h:122
void ForwardRow(DataT *buff, UINT32 width)
void LinearToMallat(int destLevel, DataT *loRow, DataT *hiRow, UINT32 width)

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

◆ 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}
@ HL
Definition PGFtypes.h:92
@ LH
Definition PGFtypes.h:92
@ HH
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:57

◆ InverseRow()

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

Definition at line 418 of file WaveletTransform.cpp.

418 {
419 if (width >= FilterWidth) {
420 UINT32 i = 2;
421
422 // left border handling
423 dest[0] -= ((dest[1] + c1) >> 1);
424
425 // middle part
426 for (; i < width - 1; i += 2) {
427 dest[i] -= ((dest[i-1] + dest[i+1] + c2) >> 2);
428 dest[i-1] += ((dest[i-2] + dest[i] + c1) >> 1);
429 }
430
431 // right border handling
432 if (width & 1) {
433 dest[i] -= ((dest[i-1] + c1) >> 1);
434 dest[i-1] += ((dest[i-2] + dest[i] + c1) >> 1);
435 } else {
436 dest[i-1] += dest[i-2];
437 }
438 }
439}

◆ 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 const UINT32 leftD = destROI.left >> 1;
277 const UINT32 left0 = m_subband[srcLevel][LL].GetROI().left;
278 const UINT32 left1 = m_subband[srcLevel][HL].GetROI().left;
279 const UINT32 topD = destROI.top >> 1;
280 const UINT32 top0 = m_subband[srcLevel][LL].GetROI().top;
281 const UINT32 top1 = m_subband[srcLevel][LH].GetROI().top;
282 ASSERT(m_subband[srcLevel][LH].GetROI().left == left0);
283 ASSERT(m_subband[srcLevel][HH].GetROI().left == left1);
284 ASSERT(m_subband[srcLevel][HL].GetROI().top == top0);
285 ASSERT(m_subband[srcLevel][HH].GetROI().top == top1);
286
287 UINT32 srcOffsetX[2] = { 0, 0 };
288 UINT32 srcOffsetY[2] = { 0, 0 };
289
290 if (leftD >= __max(left0, left1)) {
291 srcOffsetX[0] = leftD - left0;
292 srcOffsetX[1] = leftD - left1;
293 } else {
294 if (left0 <= left1) {
295 const UINT32 dx = (left1 - leftD) << 1;
296 destROI.left += dx;
297 origin += dx;
298 width -= dx;
299 srcOffsetX[0] = left1 - left0;
300 } else {
301 const UINT32 dx = (left0 - leftD) << 1;
302 destROI.left += dx;
303 origin += dx;
304 width -= dx;
305 srcOffsetX[1] = left0 - left1;
306 }
307 }
308 if (topD >= __max(top0, top1)) {
309 srcOffsetY[0] = topD - top0;
310 srcOffsetY[1] = topD - top1;
311 } else {
312 if (top0 <= top1) {
313 const UINT32 dy = (top1 - topD) << 1;
314 destROI.top += dy;
315 origin += dy*destWidth;
316 height -= dy;
317 srcOffsetY[0] = top1 - top0;
318 } else {
319 const UINT32 dy = (top0 - topD) << 1;
320 destROI.top += dy;
321 origin += dy*destWidth;
322 height -= dy;
323 srcOffsetY[1] = top0 - top1;
324 }
325 }
326
327 m_subband[srcLevel][LL].InitBuffPos(srcOffsetX[0], srcOffsetY[0]);
328 m_subband[srcLevel][HL].InitBuffPos(srcOffsetX[1], srcOffsetY[0]);
329 m_subband[srcLevel][LH].InitBuffPos(srcOffsetX[0], srcOffsetY[1]);
330 m_subband[srcLevel][HH].InitBuffPos(srcOffsetX[1], srcOffsetY[1]);
331
332#else
333 width = destBand->GetWidth();
334 height = destBand->GetHeight();
335 PGFRect destROI(0, 0, width, height);
336 const UINT32 destWidth = width; // destination buffer width
337 const UINT32 destHeight = height; // destination buffer height
338
339 // init source buffer position
340 for (int i=0; i < NSubbands; i++) {
341 m_subband[srcLevel][i].InitBuffPos();
342 }
343#endif
344
345 if (destHeight >= FilterHeight) {
346 // top border handling
347 row0 = origin; row1 = row0 + destWidth;
348 MallatToLinear(srcLevel, row0, row1, width);
349 for (UINT32 k=0; k < width; k++) {
350 row0[k] -= ((row1[k] + c1) >> 1);
351 }
352
353 // middle part
354 row2 = row1 + destWidth; row3 = row2 + destWidth;
355 for (UINT32 i=destROI.top + 2; i < destROI.bottom - 1; i += 2) {
356 MallatToLinear(srcLevel, row2, row3, width);
357 for (UINT32 k=0; k < width; k++) {
358 row2[k] -= ((row1[k] + row3[k] + c2) >> 2);
359 row1[k] += ((row0[k] + row2[k] + c1) >> 1);
360 }
361 InverseRow(row0, width);
362 InverseRow(row1, width);
363 row0 = row2; row1 = row3; row2 = row1 + destWidth; row3 = row2 + destWidth;
364 }
365
366 // bottom border handling
367 if (height & 1) {
368 MallatToLinear(srcLevel, row2, NULL, width);
369 for (UINT32 k=0; k < width; k++) {
370 row2[k] -= ((row1[k] + c1) >> 1);
371 row1[k] += ((row0[k] + row2[k] + c1) >> 1);
372 }
373 InverseRow(row0, width);
374 InverseRow(row1, width);
375 InverseRow(row2, width);
376 row0 = row1; row1 = row2; row2 += destWidth;
377 } else {
378 for (UINT32 k=0; k < width; k++) {
379 row1[k] += row0[k];
380 }
381 InverseRow(row0, width);
382 InverseRow(row1, width);
383 row0 = row1; row1 += destWidth;
384 }
385 } else {
386 // height is too small
387 row0 = origin; row1 = row0 + destWidth;
388 // first part
389 for (UINT32 k=0; k < height; k += 2) {
390 MallatToLinear(srcLevel, row0, row1, width);
391 InverseRow(row0, width);
392 InverseRow(row1, width);
393 row0 += destWidth << 1; row1 += destWidth << 1;
394 }
395 // bottom
396 if (height & 1) {
397 MallatToLinear(srcLevel, row0, NULL, width);
398 InverseRow(row0, width);
399 }
400 }
401
402 // free memory of the current srcLevel
403 for (int i=0; i < NSubbands; i++) {
404 m_subband[srcLevel][i].FreeMemory();
405 }
406
407 // return info
408 *w = destWidth;
409 *h = height;
410 *data = dest;
411 return NoError;
412}
#define __max(x, y)
Definition PGFplatform.h:92
void InitBuffPos()
Definition Subband.h:160
bool AllocMemory()
Definition Subband.cpp:77
void InverseRow(DataT *buff, UINT32 width)
void MallatToLinear(int srcLevel, DataT *loRow, DataT *hiRow, UINT32 width)
Rectangle.
Definition PGFtypes.h:194
UINT32 Height() const
Definition PGFtypes.h:207
UINT32 Width() const
Definition PGFtypes.h:205
UINT32 top
Definition PGFtypes.h:215
UINT32 bottom
Definition PGFtypes.h:215
UINT32 left
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}
void WriteBuffer(DataT val)
Definition Subband.h:146

◆ MallatToLinear()

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

Definition at line 443 of file WaveletTransform.cpp.

443 {
444 const UINT32 wquot = width >> 1;
445 const bool wrem = width & 1;
446 CSubband &ll = m_subband[srcLevel][LL], &hl = m_subband[srcLevel][HL];
447 CSubband &lh = m_subband[srcLevel][LH], &hh = m_subband[srcLevel][HH];
448
449 if (hiRow) {
450 #ifdef __PGFROISUPPORT__
451 const bool storePos = wquot < ll.BufferWidth();
452 UINT32 llPos = 0, hlPos = 0, lhPos = 0, hhPos = 0;
453
454 if (storePos) {
455 // save current src buffer positions
456 llPos = ll.GetBuffPos();
457 hlPos = hl.GetBuffPos();
458 lhPos = lh.GetBuffPos();
459 hhPos = hh.GetBuffPos();
460 }
461 #endif
462
463 for (UINT32 i=0; i < wquot; i++) {
464 *loRow++ = ll.ReadBuffer();// first access, than increment
465 *loRow++ = hl.ReadBuffer();// first access, than increment
466 *hiRow++ = lh.ReadBuffer();// first access, than increment
467 *hiRow++ = hh.ReadBuffer();// first access, than increment
468 }
469
470 if (wrem) {
471 *loRow++ = ll.ReadBuffer();// first access, than increment
472 *hiRow++ = lh.ReadBuffer();// first access, than increment
473 }
474
475 #ifdef __PGFROISUPPORT__
476 if (storePos) {
477 // increment src buffer positions
478 ll.IncBuffRow(llPos);
479 hl.IncBuffRow(hlPos);
480 lh.IncBuffRow(lhPos);
481 hh.IncBuffRow(hhPos);
482 }
483 #endif
484
485 } else {
486 #ifdef __PGFROISUPPORT__
487 const bool storePos = wquot < ll.BufferWidth();
488 UINT32 llPos = 0, hlPos = 0;
489
490 if (storePos) {
491 // save current src buffer positions
492 llPos = ll.GetBuffPos();
493 hlPos = hl.GetBuffPos();
494 }
495 #endif
496
497 for (UINT32 i=0; i < wquot; i++) {
498 *loRow++ = ll.ReadBuffer();// first access, than increment
499 *loRow++ = hl.ReadBuffer();// first access, than increment
500 }
501 if (wrem) *loRow++ = ll.ReadBuffer();
502
503 #ifdef __PGFROISUPPORT__
504 if (storePos) {
505 // increment src buffer positions
506 ll.IncBuffRow(llPos);
507 hl.IncBuffRow(hlPos);
508 }
509 #endif
510 }
511}
UINT32 GetBuffPos() const
Definition Subband.h:150
DataT ReadBuffer()
Definition Subband.h:148

Friends And Related Symbol 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: