CWaveletTransform man page

CWaveletTransform — 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

Thu Feb 4 2016 Version 6.14.12 libpgf