CWaveletTransform(3)
| CWaveletTransform(3) | libpgf | CWaveletTransform(3) |
NAME
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
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
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
quant A quantization value (linear scalar quantization)
Returns
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
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
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
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 }
Friends And Related Function Documentation
friend class CSubband [friend]
Definition at line 85 of file WaveletTransform.h.
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.
| Sat Feb 27 2021 | Version 6.14.12 |
