libpgf  7.15.32
PGF - Progressive Graphics File
WaveletTransform.cpp
Go to the documentation of this file.
1 /*
2  * The Progressive Graphics File; http://www.libpgf.org
3  *
4  * $Date: 2006-05-18 16:03:32 +0200 (Do, 18 Mai 2006) $
5  * $Revision: 194 $
6  *
7  * This file Copyright (C) 2006 xeraina GmbH, Switzerland
8  *
9  * This program is free software; you can redistribute it and/or
10  * modify it under the terms of the GNU LESSER GENERAL PUBLIC LICENSE
11  * as published by the Free Software Foundation; either version 2.1
12  * of the License, or (at your option) any later version.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program; if not, write to the Free Software
21  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
22  */
23 
28 
29 #include "WaveletTransform.h"
30 
31 #define c1 1 // best value 1
32 #define c2 2 // best value 2
33 
35 // Constructor: Constructs a wavelet transform pyramid of given size and levels.
36 // @param width The width of the original image (at level 0) in pixels
37 // @param height The height of the original image (at level 0) in pixels
38 // @param levels The number of levels (>= 0)
39 // @param data Input data of subband LL at level 0
40 CWaveletTransform::CWaveletTransform(UINT32 width, UINT32 height, int levels, DataT* data)
41 : m_nLevels(levels + 1) // m_nLevels in CPGFImage determines the number of FWT steps; this.m_nLevels determines the number subband-planes
42 , m_subband(nullptr)
43 , m_indices(nullptr)
44 {
45  ASSERT(m_nLevels > 0 && m_nLevels <= MaxLevel + 1);
46  InitSubbands(width, height, data);
47 }
48 
50 // Initialize size subbands on all levels
51 void CWaveletTransform::InitSubbands(UINT32 width, UINT32 height, DataT* data) {
52  if (m_subband) Destroy();
53 
54  // create subbands
56 
57  // init subbands
58  UINT32 loWidth = width;
59  UINT32 hiWidth = width;
60  UINT32 loHeight = height;
61  UINT32 hiHeight = height;
62 
63  for (int level = 0; level < m_nLevels; level++) {
64  m_subband[level][LL].Initialize(loWidth, loHeight, level, LL); // LL
65  m_subband[level][HL].Initialize(hiWidth, loHeight, level, HL); // HL
66  m_subband[level][LH].Initialize(loWidth, hiHeight, level, LH); // LH
67  m_subband[level][HH].Initialize(hiWidth, hiHeight, level, HH); // HH
68  hiWidth = loWidth >> 1; hiHeight = loHeight >> 1;
69  loWidth = (loWidth + 1) >> 1; loHeight = (loHeight + 1) >> 1;
70  }
71  if (data) {
72  m_subband[0][LL].SetBuffer(data);
73  }
74 }
75 
77 // Compute fast forward wavelet transform of LL subband at given level and
78 // stores result in all 4 subbands of level + 1.
79 // Wavelet transform used in writing a PGF file
80 // Forward Transform of srcBand and split and store it into subbands on destLevel
81 // low pass filter at even positions: 1/8[-1, 2, (6), 2, -1]
82 // high pass filter at odd positions: 1/4[-2, (4), -2]
83 // @param level A wavelet transform pyramid level (>= 0 && < Levels())
84 // @param quant A quantization value (linear scalar quantization)
85 // @return error in case of a memory allocation problem
86 OSError CWaveletTransform::ForwardTransform(int level, int quant) {
87  ASSERT(level >= 0 && level < m_nLevels - 1);
88  const int destLevel = level + 1;
89  ASSERT(m_subband[destLevel]);
90  CSubband* srcBand = &m_subband[level][LL]; ASSERT(srcBand);
91  const UINT32 width = srcBand->GetWidth();
92  const UINT32 height = srcBand->GetHeight();
93  DataT* src = srcBand->GetBuffer(); ASSERT(src);
94  DataT *row0, *row1, *row2, *row3;
95 
96  // Allocate memory for next transform level
97  for (int i=0; i < NSubbands; i++) {
98  if (!m_subband[destLevel][i].AllocMemory()) return InsufficientMemory;
99  }
100 
101  if (height >= FilterSize) { // changed from FilterSizeH to FilterSize
102  // top border handling
103  row0 = src; row1 = row0 + width; row2 = row1 + width;
104  ForwardRow(row0, width);
105  ForwardRow(row1, width);
106  ForwardRow(row2, width);
107  for (UINT32 k=0; k < width; k++) {
108  row1[k] -= ((row0[k] + row2[k] + c1) >> 1); // high pass
109  row0[k] += ((row1[k] + c1) >> 1); // low pass
110  }
111  InterleavedToSubbands(destLevel, row0, row1, width);
112  row0 = row1; row1 = row2; row2 += width; row3 = row2 + width;
113 
114  // middle part
115  for (UINT32 i=3; i < height-1; i += 2) {
116  ForwardRow(row2, width);
117  ForwardRow(row3, width);
118  for (UINT32 k=0; k < width; k++) {
119  row2[k] -= ((row1[k] + row3[k] + c1) >> 1); // high pass filter
120  row1[k] += ((row0[k] + row2[k] + c2) >> 2); // low pass filter
121  }
122  InterleavedToSubbands(destLevel, row1, row2, width);
123  row0 = row2; row1 = row3; row2 = row3 + width; row3 = row2 + width;
124  }
125 
126  // bottom border handling
127  if (height & 1) {
128  for (UINT32 k=0; k < width; k++) {
129  row1[k] += ((row0[k] + c1) >> 1); // low pass
130  }
131  InterleavedToSubbands(destLevel, row1, nullptr, width);
132  row0 = row1; row1 += width;
133  } else {
134  ForwardRow(row2, width);
135  for (UINT32 k=0; k < width; k++) {
136  row2[k] -= row1[k]; // high pass
137  row1[k] += ((row0[k] + row2[k] + c2) >> 2); // low pass
138  }
139  InterleavedToSubbands(destLevel, row1, row2, width);
140  row0 = row1; row1 = row2; row2 += width;
141  }
142  } else {
143  // if height is too small
144  row0 = src; row1 = row0 + width;
145  // first part
146  for (UINT32 k=0; k < height; k += 2) {
147  ForwardRow(row0, width);
148  ForwardRow(row1, width);
149  InterleavedToSubbands(destLevel, row0, row1, width);
150  row0 += width << 1; row1 += width << 1;
151  }
152  // bottom
153  if (height & 1) {
154  InterleavedToSubbands(destLevel, row0, nullptr, width);
155  }
156  }
157 
158  if (quant > 0) {
159  // subband quantization (without LL)
160  for (int i=1; i < NSubbands; i++) {
161  m_subband[destLevel][i].Quantize(quant);
162  }
163  // LL subband quantization
164  if (destLevel == m_nLevels - 1) {
165  m_subband[destLevel][LL].Quantize(quant);
166  }
167  }
168 
169  // free source band
170  srcBand->FreeMemory();
171  return NoError;
172 }
173 
175 // Forward transform one row
176 // low pass filter at even positions: 1/8[-1, 2, (6), 2, -1]
177 // high pass filter at odd positions: 1/4[-2, (4), -2]
178 void CWaveletTransform::ForwardRow(DataT* src, UINT32 width) {
179  if (width >= FilterSize) {
180  UINT32 i = 3;
181 
182  // left border handling
183  src[1] -= ((src[0] + src[2] + c1) >> 1); // high pass
184  src[0] += ((src[1] + c1) >> 1); // low pass
185 
186  // middle part
187  for (; i < width-1; i += 2) {
188  src[i] -= ((src[i-1] + src[i+1] + c1) >> 1); // high pass
189  src[i-1] += ((src[i-2] + src[i] + c2) >> 2); // low pass
190  }
191 
192  // right border handling
193  if (width & 1) {
194  src[i-1] += ((src[i-2] + c1) >> 1); // low pass
195  } else {
196  src[i] -= src[i-1]; // high pass
197  src[i-1] += ((src[i-2] + src[i] + c2) >> 2); // low pass
198  }
199  }
200 }
201 
203 // Copy transformed and interleaved (L,H,L,H,...) rows loRow and hiRow to subbands LL,HL,LH,HH
204 void CWaveletTransform::InterleavedToSubbands(int destLevel, DataT* loRow, DataT* hiRow, UINT32 width) {
205  const UINT32 wquot = width >> 1;
206  const bool wrem = (width & 1);
207  CSubband &ll = m_subband[destLevel][LL], &hl = m_subband[destLevel][HL];
208  CSubband &lh = m_subband[destLevel][LH], &hh = m_subband[destLevel][HH];
209 
210  if (hiRow) {
211  for (UINT32 i=0; i < wquot; i++) {
212  ll.WriteBuffer(*loRow++); // first access, than increment
213  hl.WriteBuffer(*loRow++);
214  lh.WriteBuffer(*hiRow++); // first access, than increment
215  hh.WriteBuffer(*hiRow++);
216  }
217  if (wrem) {
218  ll.WriteBuffer(*loRow);
219  lh.WriteBuffer(*hiRow);
220  }
221  } else {
222  for (UINT32 i=0; i < wquot; i++) {
223  ll.WriteBuffer(*loRow++); // first access, than increment
224  hl.WriteBuffer(*loRow++);
225  }
226  if (wrem) ll.WriteBuffer(*loRow);
227  }
228 }
229 
231 // Compute fast inverse wavelet transform of all 4 subbands of given level and
232 // stores result in LL subband of level - 1.
233 // Inverse wavelet transform used in reading a PGF file
234 // Inverse Transform srcLevel and combine to destBand
235 // low-pass coefficients at even positions, high-pass coefficients at odd positions
236 // inverse filter for even positions: 1/4[-1, (4), -1]
237 // inverse filter for odd positions: 1/8[-1, 4, (6), 4, -1]
238 // @param srcLevel A wavelet transform pyramid level (> 0 && <= Levels())
239 // @param w [out] A pointer to the returned width of subband LL (in pixels)
240 // @param h [out] A pointer to the returned height of subband LL (in pixels)
241 // @param data [out] A pointer to the returned array of image data
242 // @return error in case of a memory allocation problem
243 OSError CWaveletTransform::InverseTransform(int srcLevel, UINT32* w, UINT32* h, DataT** data) {
244  ASSERT(srcLevel > 0 && srcLevel < m_nLevels);
245  const int destLevel = srcLevel - 1;
246  ASSERT(m_subband[destLevel]);
247  CSubband* destBand = &m_subband[destLevel][LL];
248  UINT32 width, height;
249 
250  // allocate memory for the results of the inverse transform
251  if (!destBand->AllocMemory()) return InsufficientMemory;
252  DataT *origin = destBand->GetBuffer(), *row0, *row1, *row2, *row3;
253 
254 #ifdef __PGFROISUPPORT__
255  PGFRect destROI = destBand->GetAlignedROI();
256  const UINT32 destWidth = destROI.Width(); // destination buffer width
257  const UINT32 destHeight = destROI.Height(); // destination buffer height
258  width = destWidth; // destination working width
259  height = destHeight; // destination working height
260 
261  // update destination ROI
262  if (destROI.top & 1) {
263  destROI.top++;
264  origin += destWidth;
265  height--;
266  }
267  if (destROI.left & 1) {
268  destROI.left++;
269  origin++;
270  width--;
271  }
272 
273  // init source buffer position
274  const UINT32 leftD = destROI.left >> 1;
275  const UINT32 left0 = m_subband[srcLevel][LL].GetAlignedROI().left;
276  const UINT32 left1 = m_subband[srcLevel][HL].GetAlignedROI().left;
277  const UINT32 topD = destROI.top >> 1;
278  const UINT32 top0 = m_subband[srcLevel][LL].GetAlignedROI().top;
279  const UINT32 top1 = m_subband[srcLevel][LH].GetAlignedROI().top;
280  ASSERT(m_subband[srcLevel][LH].GetAlignedROI().left == left0);
281  ASSERT(m_subband[srcLevel][HH].GetAlignedROI().left == left1);
282  ASSERT(m_subband[srcLevel][HL].GetAlignedROI().top == top0);
283  ASSERT(m_subband[srcLevel][HH].GetAlignedROI().top == top1);
284 
285  UINT32 srcOffsetX[2] = { 0, 0 };
286  UINT32 srcOffsetY[2] = { 0, 0 };
287 
288  if (leftD >= __max(left0, left1)) {
289  srcOffsetX[0] = leftD - left0;
290  srcOffsetX[1] = leftD - left1;
291  } else {
292  if (left0 <= left1) {
293  const UINT32 dx = (left1 - leftD) << 1;
294  destROI.left += dx;
295  origin += dx;
296  width -= dx;
297  srcOffsetX[0] = left1 - left0;
298  } else {
299  const UINT32 dx = (left0 - leftD) << 1;
300  destROI.left += dx;
301  origin += dx;
302  width -= dx;
303  srcOffsetX[1] = left0 - left1;
304  }
305  }
306  if (topD >= __max(top0, top1)) {
307  srcOffsetY[0] = topD - top0;
308  srcOffsetY[1] = topD - top1;
309  } else {
310  if (top0 <= top1) {
311  const UINT32 dy = (top1 - topD) << 1;
312  destROI.top += dy;
313  origin += dy*destWidth;
314  height -= dy;
315  srcOffsetY[0] = top1 - top0;
316  } else {
317  const UINT32 dy = (top0 - topD) << 1;
318  destROI.top += dy;
319  origin += dy*destWidth;
320  height -= dy;
321  srcOffsetY[1] = top0 - top1;
322  }
323  }
324 
325  m_subband[srcLevel][LL].InitBuffPos(srcOffsetX[0], srcOffsetY[0]);
326  m_subband[srcLevel][HL].InitBuffPos(srcOffsetX[1], srcOffsetY[0]);
327  m_subband[srcLevel][LH].InitBuffPos(srcOffsetX[0], srcOffsetY[1]);
328  m_subband[srcLevel][HH].InitBuffPos(srcOffsetX[1], srcOffsetY[1]);
329 
330 #else
331  width = destBand->GetWidth();
332  height = destBand->GetHeight();
333  PGFRect destROI(0, 0, width, height);
334  const UINT32 destWidth = width; // destination buffer width
335  const UINT32 destHeight = height; // destination buffer height
336 
337  // init source buffer position
338  for (int i = 0; i < NSubbands; i++) {
339  m_subband[srcLevel][i].InitBuffPos();
340  }
341 #endif
342 
343  if (destHeight >= FilterSize) { // changed from FilterSizeH to FilterSize
344  // top border handling
345  row0 = origin; row1 = row0 + destWidth;
346  SubbandsToInterleaved(srcLevel, row0, row1, width);
347  for (UINT32 k = 0; k < width; k++) {
348  row0[k] -= ((row1[k] + c1) >> 1); // even
349  }
350 
351  // middle part
352  row2 = row1 + destWidth; row3 = row2 + destWidth;
353  for (UINT32 i = destROI.top + 2; i < destROI.bottom - 1; i += 2) {
354  SubbandsToInterleaved(srcLevel, row2, row3, width);
355  for (UINT32 k = 0; k < width; k++) {
356  row2[k] -= ((row1[k] + row3[k] + c2) >> 2); // even
357  row1[k] += ((row0[k] + row2[k] + c1) >> 1); // odd
358  }
359  InverseRow(row0, width);
360  InverseRow(row1, width);
361  row0 = row2; row1 = row3; row2 = row1 + destWidth; row3 = row2 + destWidth;
362  }
363 
364  // bottom border handling
365  if (height & 1) {
366  SubbandsToInterleaved(srcLevel, row2, nullptr, width);
367  for (UINT32 k = 0; k < width; k++) {
368  row2[k] -= ((row1[k] + c1) >> 1); // even
369  row1[k] += ((row0[k] + row2[k] + c1) >> 1); // odd
370  }
371  InverseRow(row0, width);
372  InverseRow(row1, width);
373  InverseRow(row2, width);
374  row0 = row1; row1 = row2; row2 += destWidth;
375  } else {
376  for (UINT32 k = 0; k < width; k++) {
377  row1[k] += row0[k];
378  }
379  InverseRow(row0, width);
380  InverseRow(row1, width);
381  row0 = row1; row1 += destWidth;
382  }
383  } else {
384  // height is too small
385  row0 = origin; row1 = row0 + destWidth;
386  // first part
387  for (UINT32 k = 0; k < height; k += 2) {
388  SubbandsToInterleaved(srcLevel, row0, row1, width);
389  InverseRow(row0, width);
390  InverseRow(row1, width);
391  row0 += destWidth << 1; row1 += destWidth << 1;
392  }
393  // bottom
394  if (height & 1) {
395  SubbandsToInterleaved(srcLevel, row0, nullptr, width);
396  InverseRow(row0, width);
397  }
398  }
399 
400  // free memory of the current srcLevel
401  for (int i = 0; i < NSubbands; i++) {
402  m_subband[srcLevel][i].FreeMemory();
403  }
404 
405  // return info
406  *w = destWidth;
407  *h = destHeight;
408  *data = destBand->GetBuffer();
409  return NoError;
410 }
411 
413 // Inverse Wavelet Transform of one row
414 // low-pass coefficients at even positions, high-pass coefficients at odd positions
415 // inverse filter for even positions: 1/4[-1, (4), -1]
416 // inverse filter for odd positions: 1/8[-1, 4, (6), 4, -1]
417 void CWaveletTransform::InverseRow(DataT* dest, UINT32 width) {
418  if (width >= FilterSize) {
419  UINT32 i = 2;
420 
421  // left border handling
422  dest[0] -= ((dest[1] + c1) >> 1); // even
423 
424  // middle part
425  for (; i < width - 1; i += 2) {
426  dest[i] -= ((dest[i-1] + dest[i+1] + c2) >> 2); // even
427  dest[i-1] += ((dest[i-2] + dest[i] + c1) >> 1); // odd
428  }
429 
430  // right border handling
431  if (width & 1) {
432  dest[i] -= ((dest[i-1] + c1) >> 1); // even
433  dest[i-1] += ((dest[i-2] + dest[i] + c1) >> 1); // odd
434  } else {
435  dest[i-1] += dest[i-2]; // odd
436  }
437  }
438 }
439 
441 // Copy transformed coefficients from subbands LL,HL,LH,HH to interleaved format (L,H,L,H,...)
442 void CWaveletTransform::SubbandsToInterleaved(int srcLevel, DataT* loRow, DataT* hiRow, UINT32 width) {
443  const UINT32 wquot = width >> 1;
444  const bool wrem = (width & 1);
445  CSubband &ll = m_subband[srcLevel][LL], &hl = m_subband[srcLevel][HL];
446  CSubband &lh = m_subband[srcLevel][LH], &hh = m_subband[srcLevel][HH];
447 
448  if (hiRow) {
449  #ifdef __PGFROISUPPORT__
450  const bool storePos = wquot < ll.BufferWidth();
451  UINT32 llPos = 0, hlPos = 0, lhPos = 0, hhPos = 0;
452 
453  if (storePos) {
454  // save current src buffer positions
455  llPos = ll.GetBuffPos();
456  hlPos = hl.GetBuffPos();
457  lhPos = lh.GetBuffPos();
458  hhPos = hh.GetBuffPos();
459  }
460  #endif
461 
462  for (UINT32 i=0; i < wquot; i++) {
463  *loRow++ = ll.ReadBuffer();// first access, than increment
464  *loRow++ = hl.ReadBuffer();// first access, than increment
465  *hiRow++ = lh.ReadBuffer();// first access, than increment
466  *hiRow++ = hh.ReadBuffer();// first access, than increment
467  }
468 
469  if (wrem) {
470  *loRow++ = ll.ReadBuffer();// first access, than increment
471  *hiRow++ = lh.ReadBuffer();// first access, than increment
472  }
473 
474  #ifdef __PGFROISUPPORT__
475  if (storePos) {
476  // increment src buffer positions
477  ll.IncBuffRow(llPos);
478  hl.IncBuffRow(hlPos);
479  lh.IncBuffRow(lhPos);
480  hh.IncBuffRow(hhPos);
481  }
482  #endif
483 
484  } else {
485  #ifdef __PGFROISUPPORT__
486  const bool storePos = wquot < ll.BufferWidth();
487  UINT32 llPos = 0, hlPos = 0;
488 
489  if (storePos) {
490  // save current src buffer positions
491  llPos = ll.GetBuffPos();
492  hlPos = hl.GetBuffPos();
493  }
494  #endif
495 
496  for (UINT32 i=0; i < wquot; i++) {
497  *loRow++ = ll.ReadBuffer();// first access, than increment
498  *loRow++ = hl.ReadBuffer();// first access, than increment
499  }
500  if (wrem) *loRow++ = ll.ReadBuffer();
501 
502  #ifdef __PGFROISUPPORT__
503  if (storePos) {
504  // increment src buffer positions
505  ll.IncBuffRow(llPos);
506  hl.IncBuffRow(hlPos);
507  }
508  #endif
509  }
510 }
511 
512 #ifdef __PGFROISUPPORT__
513 void CWaveletTransform::SetROI(PGFRect roi) {
517  const UINT32 delta = (FilterSize >> 1) << m_nLevels;
518 
519  // create tile indices
520  delete[] m_indices;
521  m_indices = new PGFRect[m_nLevels];
522 
523  // enlarge rect: add margin
524  roi.left = (roi.left > delta) ? roi.left - delta : 0;
525  roi.top = (roi.top > delta) ? roi.top - delta : 0;
526  roi.right += delta;
527  roi.bottom += delta;
528 
529  for (int l = 0; l < m_nLevels; l++) {
530  PGFRect alignedROI;
531  PGFRect& indices = m_indices[l];
532  UINT32 nTiles = GetNofTiles(l);
533  CSubband& subband = m_subband[l][LL];
534 
535  // use roi to determine the necessary tile indices (for all subbands the same) and aligned ROI for LL subband
536  subband.SetNTiles(nTiles); // must be called before TileIndex()
537  subband.TileIndex(true, roi.left, roi.top, indices.left, indices.top, alignedROI.left, alignedROI.top);
538  subband.TileIndex(false, roi.right, roi.bottom, indices.right, indices.bottom, alignedROI.right, alignedROI.bottom);
539  subband.SetAlignedROI(alignedROI);
540  ASSERT(l == 0 ||
541  (m_indices[l-1].left >= 2*m_indices[l].left &&
542  m_indices[l-1].top >= 2*m_indices[l].top &&
543  m_indices[l-1].right <= 2*m_indices[l].right &&
544  m_indices[l-1].bottom <= 2*m_indices[l].bottom));
545 
546  // determine aligned ROI of other three subbands
547  PGFRect aroi;
548  UINT32 w, h;
549  for (int b = 1; b < NSubbands; b++) {
550  CSubband& sb = m_subband[l][b];
551  sb.SetNTiles(nTiles); // must be called before TilePosition()
552  sb.TilePosition(indices.left, indices.top, aroi.left, aroi.top, w, h);
553  sb.TilePosition(indices.right - 1, indices.bottom - 1, aroi.right, aroi.bottom, w, h);
554  aroi.right += w;
555  aroi.bottom += h;
556  sb.SetAlignedROI(aroi);
557  }
558 
559  // use aligned ROI of LL subband for next level
560  roi.left = alignedROI.left >> 1;
561  roi.top = alignedROI.top >> 1;
562  roi.right = (alignedROI.right + 1) >> 1;
563  roi.bottom = (alignedROI.bottom + 1) >> 1;
564  }
565 }
566 
567 #endif // __PGFROISUPPORT__
OSError InverseTransform(int level, UINT32 *width, UINT32 *height, DataT **data)
Definition: PGFtypes.h:99
DataT * GetBuffer()
Definition: Subband.h:107
INT32 DataT
Definition: PGFtypes.h:262
void SetBuffer(DataT *b)
Definition: Subband.h:148
bool AllocMemory()
Definition: Subband.cpp:77
void Initialize(UINT32 width, UINT32 height, int level, Orientation orient)
Definition: Subband.cpp:57
void ForwardRow(DataT *buff, UINT32 width)
const UINT32 FilterSize
UINT32 GetBuffPos() const
Definition: Subband.h:151
UINT32 right
Definition: PGFtypes.h:258
Wavelet channel class.
Definition: Subband.h:42
void InitBuffPos()
Definition: Subband.h:162
#define c1
int GetHeight() const
Definition: Subband.h:123
void InverseRow(DataT *buff, UINT32 width)
OSError ForwardTransform(int level, int quant)
#define MaxLevel
maximum number of transform levels
Definition: PGFtypes.h:62
DataT ReadBuffer()
Definition: Subband.h:149
UINT32 Height() const
Definition: PGFtypes.h:250
Definition: PGFtypes.h:99
#define __max(x, y)
Definition: PGFplatform.h:92
int m_nLevels
number of LL levels: one more than header.nLevels in PGFimage
Definition: PGFtypes.h:99
UINT32 top
Definition: PGFtypes.h:258
void SubbandsToInterleaved(int srcLevel, DataT *loRow, DataT *hiRow, UINT32 width)
PGF wavelet transform class.
CSubband(* m_subband)[NSubbands]
quadtree of subbands: LL HL LH HH
void FreeMemory()
Delete the memory buffer of this subband.
Definition: Subband.cpp:101
void Quantize(int quantParam)
Definition: Subband.cpp:112
UINT32 left
Definition: PGFtypes.h:258
void InterleavedToSubbands(int destLevel, DataT *loRow, DataT *hiRow, UINT32 width)
Definition: PGFtypes.h:99
CWaveletTransform(UINT32 width, UINT32 height, int levels, DataT *data=nullptr)
void InitSubbands(UINT32 width, UINT32 height, DataT *data)
#define c2
void WriteBuffer(DataT val)
Definition: Subband.h:147
Rectangle.
Definition: PGFtypes.h:222
int GetWidth() const
Definition: Subband.h:128
#define NSubbands
number of subbands per level
Definition: PGFtypes.h:63
UINT32 Width() const
Definition: PGFtypes.h:248
UINT32 bottom
Definition: PGFtypes.h:258