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