CWaveletTransform - Man Page

PGF wavelet transform.

Synopsis

#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)
CSubband * GetSubband (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 (UINT32 width, UINT32 height, int levels, DataT * data = NULL)

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

Parameters

width The width of the original image (at level 0) in pixels
height The height of the original image (at level 0) in pixels
levels The number of levels (>= 0)
data Input 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 }

CWaveletTransform::~CWaveletTransform () [inline]

Destructor.

Definition at line 98 of file WaveletTransform.h.

98 { Destroy(); }

Member Function Documentation

void CWaveletTransform::Destroy () [inline], [private]

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         }

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 }

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

level A wavelet transform pyramid level (>= 0 && < Levels())
quant A 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 }

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

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

Parameters

level A wavelet transform pyramid level (>= 0 && <= Levels())
orientation A 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         }

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
57         m_subband = new CSubband[m_nLevels][NSubbands];
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 }

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 }

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

level A wavelet transform pyramid level (> 0 && <= Levels())
width A pointer to the returned width of subband LL (in pixels)
height A pointer to the returned height of subband LL (in pixels)
data A 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 }

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

Member Data Documentation

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.

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

quadtree of subbands: LL HL LH HH

Definition at line 168 of file WaveletTransform.h.

Author

Generated automatically by Doxygen for libpgf from the source code.

Info

Wed Jan 29 2020 Version 6.14.12 libpgf