libpgf
6.11.42
PGF - Progressive Graphics File
|
PGF wavelet transform. More...
#include <WaveletTransform.h>
Public Member Functions | |
CWaveletTransform (UINT32 width, UINT32 height, int levels, DataT *data=NULL) | |
~CWaveletTransform () | |
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 |
PGF wavelet transform.
PGF wavelet transform class.
Definition at line 92 of file WaveletTransform.h.
CWaveletTransform::CWaveletTransform | ( | UINT32 | width, |
UINT32 | height, | ||
int | levels, | ||
DataT * | data = NULL |
||
) |
Constructor: Constructs a wavelet transform pyramid of given size and levels.
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.
CWaveletTransform::~CWaveletTransform | ( | ) | [inline] |
void CWaveletTransform::Destroy | ( | ) | [inline, private] |
Definition at line 163 of file WaveletTransform.h.
void CWaveletTransform::ForwardRow | ( | DataT * | buff, |
UINT32 | width | ||
) | [private] |
Definition at line 182 of file WaveletTransform.cpp.
{ if (width >= FilterWidth) { UINT32 i = 3; // left border handling src[1] -= ((src[0] + src[2] + c1) >> 1); src[0] += ((src[1] + c1) >> 1); // middle part for (; i < width-1; i += 2) { src[i] -= ((src[i-1] + src[i+1] + c1) >> 1); src[i-1] += ((src[i-2] + src[i] + c2) >> 2); } // right border handling if (width & 1) { src[i-1] += ((src[i-2] + c1) >> 1); } else { src[i] -= src[i-1]; src[i-1] += ((src[i-2] + src[i] + c2) >> 2); } } }
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.
level | A wavelet transform pyramid level (>= 0 && < Levels()) |
quant | A quantization value (linear scalar quantization) |
Definition at line 86 of file WaveletTransform.cpp.
{ ASSERT(level >= 0 && level < m_nLevels - 1); const int destLevel = level + 1; ASSERT(m_subband[destLevel]); CSubband* srcBand = &m_subband[level][LL]; ASSERT(srcBand); const UINT32 width = srcBand->GetWidth(); const UINT32 height = srcBand->GetHeight(); DataT* src = srcBand->GetBuffer(); ASSERT(src); UINT32 row0, row1, row2, row3; UINT32 i, k; // Allocate memory for next transform level for (i=0; i < NSubbands; i++) { if (!m_subband[destLevel][i].AllocMemory()) return InsufficientMemory; } if (height >= FilterHeight) { // transform LL subband // top border handling row0 = 0; row1 = width; row2 = row1 + width; ForwardRow(&src[row0], width); ForwardRow(&src[row1], width); ForwardRow(&src[row2], width); for (k=0; k < width; k++) { src[row1] -= ((src[row0] + src[row2] + c1) >> 1); src[row0] += ((src[row1] + c1) >> 1); row0++; row1++; row2++; } LinearToMallat(destLevel, &src[0], &src[row0], width); // middle part row3 = row2 + width; for (i=3; i < height-1; i += 2) { ForwardRow(&src[row2], width); ForwardRow(&src[row3], width); for (k=0; k < width; k++) { src[row2] -= ((src[row1] + src[row3] + c1) >> 1); src[row1] += ((src[row0] + src[row2] + c2) >> 2); row0++; row1++; row2++; row3++; } LinearToMallat(destLevel, &src[row0], &src[row1], width); row0 = row1; row1 = row2; row2 = row3; row3 += width; } // bottom border handling if (height & 1) { for (k=0; k < width; k++) { src[row1] += ((src[row0] + c1) >> 1); row0++; row1++; } LinearToMallat(destLevel, &src[row0], NULL, width); } else { ForwardRow(&src[row2], width); for (k=0; k < width; k++) { src[row2] -= src[row1]; src[row1] += ((src[row0] + src[row2] + c2) >> 2); row0++; row1++; row2++; } LinearToMallat(destLevel, &src[row0], &src[row1], width); } } else { // if height to small row0 = 0; row1 = width; // first part for (k=0; k < height; k += 2) { ForwardRow(&src[row0], width); ForwardRow(&src[row1], width); LinearToMallat(destLevel, &src[row0], &src[row1], width); row0 += width << 1; row1 += width << 1; } // bottom if (height & 1) { LinearToMallat(destLevel, &src[row0], NULL, width); } } if (quant > 0) { // subband quantization (without LL) for (i=1; i < NSubbands; i++) { m_subband[destLevel][i].Quantize(quant); } // LL subband quantization if (destLevel == m_nLevels - 1) { m_subband[destLevel][LL].Quantize(quant); } } // free source band srcBand->FreeMemory(); return NoError; }
CSubband* CWaveletTransform::GetSubband | ( | int | level, |
Orientation | orientation | ||
) | [inline] |
Get pointer to one of the 4 subband at a given level.
level | A wavelet transform pyramid level (>= 0 && <= Levels()) |
orientation | A quarter of the subband (LL, LH, HL, HH) |
Definition at line 130 of file WaveletTransform.h.
void CWaveletTransform::InitSubbands | ( | UINT32 | width, |
UINT32 | height, | ||
DataT * | data | ||
) | [private] |
Definition at line 51 of file WaveletTransform.cpp.
{ if (m_subband) Destroy(); // create subbands m_subband = new CSubband[m_nLevels][NSubbands]; // init subbands UINT32 loWidth = width; UINT32 hiWidth = width; UINT32 loHeight = height; UINT32 hiHeight = height; for (int level = 0; level < m_nLevels; level++) { m_subband[level][LL].Initialize(loWidth, loHeight, level, LL); // LL m_subband[level][HL].Initialize(hiWidth, loHeight, level, HL); // HL m_subband[level][LH].Initialize(loWidth, hiHeight, level, LH); // LH m_subband[level][HH].Initialize(hiWidth, hiHeight, level, HH); // HH hiWidth = loWidth >> 1; hiHeight = loHeight >> 1; loWidth = (loWidth + 1) >> 1; loHeight = (loHeight + 1) >> 1; } if (data) { m_subband[0][LL].SetBuffer(data); } }
void CWaveletTransform::InverseRow | ( | DataT * | buff, |
UINT32 | width | ||
) | [private] |
Definition at line 387 of file WaveletTransform.cpp.
{ if (width >= FilterWidth) { UINT32 i = 2; // left border handling dest[0] -= ((dest[1] + c1) >> 1); // middle part for (; i < width - 1; i += 2) { dest[i] -= ((dest[i-1] + dest[i+1] + c2) >> 2); dest[i-1] += ((dest[i-2] + dest[i] + c1) >> 1); } // right border handling if (width & 1) { dest[i] -= ((dest[i-1] + c1) >> 1); dest[i-1] += ((dest[i-2] + dest[i] + c1) >> 1); } else { dest[i-1] += dest[i-2]; } } }
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.
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 |
Definition at line 247 of file WaveletTransform.cpp.
{ ASSERT(srcLevel > 0 && srcLevel < m_nLevels); const int destLevel = srcLevel - 1; ASSERT(m_subband[destLevel]); CSubband* destBand = &m_subband[destLevel][LL]; const UINT32 width = destBand->GetWidth(); const UINT32 height = destBand->GetHeight(); UINT32 row0, row1, row2, row3, i, k, origin = 0; // allocate memory for the results of the inverse transform if (!destBand->AllocMemory()) return InsufficientMemory; DataT* dest = destBand->GetBuffer(); #ifdef __PGFROISUPPORT__ const UINT32 srcLeft = (m_ROIs.ROIisSupported()) ? m_ROIs.Left(srcLevel) : 0; const UINT32 srcTop = (m_ROIs.ROIisSupported()) ? m_ROIs.Top(srcLevel) : 0; UINT32 destWidth = destBand->BufferWidth(); // destination buffer width; is valid only after AllocMemory PGFRect destROI = (m_ROIs.ROIisSupported()) ? m_ROIs.GetROI(destLevel) : PGFRect(0, 0, width, height); destROI.right = destROI.left + destWidth; destROI.bottom = __min(destROI.bottom, height); UINT32 destHeight = destROI.Height(); // destination buffer height // update destination ROI if (destROI.left & 1) { destROI.left++; origin++; destWidth--; } if (destROI.top & 1) { destROI.top++; origin += destWidth; destHeight--; } // init source buffer position UINT32 left = destROI.left >> 1; UINT32 top = destROI.top >> 1; left -= srcLeft; top -= srcTop; for (i=0; i < NSubbands; i++) { m_subband[srcLevel][i].InitBuffPos(left, top); } #else PGFRect destROI(0, 0, width, height); const UINT32 destWidth = width; // destination buffer width const UINT32 destHeight = height; // destination buffer height // init source buffer position for (i=0; i < NSubbands; i++) { m_subband[srcLevel][i].InitBuffPos(); } #endif if (destHeight >= FilterHeight) { // top border handling row0 = origin; row1 = row0 + destWidth; MallatToLinear(srcLevel, &dest[row0], &dest[row1], destWidth); for (k=0; k < destWidth; k++) { ASSERT(row0 < destBand->m_size); ASSERT(row1 < destBand->m_size); dest[row0] -= ((dest[row1] + c1) >> 1); row0++; row1++; } // middle part row2 = row1; row1 = row0; row0 = row0 - destWidth; row3 = row2 + destWidth; for (i=destROI.top + 2; i < destROI.bottom - 1; i += 2) { MallatToLinear(srcLevel, &dest[row2], &dest[row3], destWidth); for (k=0; k < destWidth; k++) { ASSERT(row0 < destBand->m_size); ASSERT(row1 < destBand->m_size); ASSERT(row2 < destBand->m_size); ASSERT(row3 < destBand->m_size); dest[row2] -= ((dest[row1] + dest[row3] + c2) >> 2); dest[row1] += ((dest[row0] + dest[row2] + c1) >> 1); row0++; row1++; row2++; row3++; } InverseRow(&dest[row0 - destWidth], destWidth); InverseRow(&dest[row1 - destWidth], destWidth); row0 = row1; row1 = row2; row2 = row3; row3 += destWidth; } // bottom border handling if (destHeight & 1) { MallatToLinear(srcLevel, &dest[row2], 0, destWidth); for (k=0; k < destWidth; k++) { ASSERT(row0 < destBand->m_size); ASSERT(row1 < destBand->m_size); ASSERT(row2 < destBand->m_size); dest[row2] -= ((dest[row1] + c1) >> 1); dest[row1] += ((dest[row0] + dest[row2] + c1) >> 1); row0++; row1++; row2++; } InverseRow(&dest[row0 - destWidth], destWidth); InverseRow(&dest[row1 - destWidth], destWidth); InverseRow(&dest[row2 - destWidth], destWidth); } else { for (k=0; k < destWidth; k++) { ASSERT(row0 < destBand->m_size); ASSERT(row1 < destBand->m_size); dest[row1] += dest[row0]; row0++; row1++; } InverseRow(&dest[row0 - destWidth], destWidth); InverseRow(&dest[row1 - destWidth], destWidth); } } else { // destHeight to small row0 = origin; row1 = row0 + destWidth; // first part for (k=0; k < destHeight; k += 2) { MallatToLinear(srcLevel, &dest[row0], &dest[row1], destWidth); InverseRow(&dest[row0], destWidth); InverseRow(&dest[row1], destWidth); row0 += destWidth << 1; row1 += destWidth << 1; } // bottom if (destHeight & 1) { MallatToLinear(srcLevel, &dest[row0], 0, destWidth); InverseRow(&dest[row0], destWidth); } } // free memory of the current srcLevel for (i=0; i < NSubbands; i++) { m_subband[srcLevel][i].FreeMemory(); } // return info *w = destWidth; *h = destHeight; *data = dest; return NoError; }
void CWaveletTransform::LinearToMallat | ( | int | destLevel, |
DataT * | loRow, | ||
DataT * | hiRow, | ||
UINT32 | width | ||
) | [private] |
Definition at line 208 of file WaveletTransform.cpp.
{ const UINT32 wquot = width >> 1; const bool wrem = width & 1; CSubband &ll = m_subband[destLevel][LL], &hl = m_subband[destLevel][HL]; CSubband &lh = m_subband[destLevel][LH], &hh = m_subband[destLevel][HH]; UINT32 i; if (hiRow) { for (i=0; i < wquot; i++) { ll.WriteBuffer(*loRow++); // first access, than increment hl.WriteBuffer(*loRow++); lh.WriteBuffer(*hiRow++); // first access, than increment hh.WriteBuffer(*hiRow++); } if (wrem) { ll.WriteBuffer(*loRow); lh.WriteBuffer(*hiRow); } } else { for (i=0; i < wquot; i++) { ll.WriteBuffer(*loRow++); // first access, than increment hl.WriteBuffer(*loRow++); } if (wrem) ll.WriteBuffer(*loRow); } }
void CWaveletTransform::MallatToLinear | ( | int | srcLevel, |
DataT * | loRow, | ||
DataT * | hiRow, | ||
UINT32 | width | ||
) | [private] |
Definition at line 412 of file WaveletTransform.cpp.
{ const UINT32 wquot = width >> 1; const bool wrem = width & 1; CSubband &ll = m_subband[srcLevel][LL], &hl = m_subband[srcLevel][HL]; CSubband &lh = m_subband[srcLevel][LH], &hh = m_subband[srcLevel][HH]; UINT32 i; if (hiRow) { #ifdef __PGFROISUPPORT__ const bool storePos = wquot < ll.BufferWidth(); UINT32 llPos = 0, hlPos = 0, lhPos = 0, hhPos = 0; if (storePos) { // save current src buffer positions llPos = ll.GetBuffPos(); hlPos = hl.GetBuffPos(); lhPos = lh.GetBuffPos(); hhPos = hh.GetBuffPos(); } #endif for (i=0; i < wquot; i++) { *loRow++ = ll.ReadBuffer();// first access, than increment *loRow++ = hl.ReadBuffer();// first access, than increment *hiRow++ = lh.ReadBuffer();// first access, than increment *hiRow++ = hh.ReadBuffer();// first access, than increment } if (wrem) { *loRow++ = ll.ReadBuffer();// first access, than increment *hiRow++ = lh.ReadBuffer();// first access, than increment } #ifdef __PGFROISUPPORT__ if (storePos) { // increment src buffer positions ll.IncBuffRow(llPos); hl.IncBuffRow(hlPos); lh.IncBuffRow(lhPos); hh.IncBuffRow(hhPos); } #endif } else { #ifdef __PGFROISUPPORT__ const bool storePos = wquot < ll.BufferWidth(); UINT32 llPos = 0, hlPos = 0; if (storePos) { // save current src buffer positions llPos = ll.GetBuffPos(); hlPos = hl.GetBuffPos(); } #endif for (i=0; i < wquot; i++) { *loRow++ = ll.ReadBuffer();// first access, than increment *loRow++ = hl.ReadBuffer();// first access, than increment } if (wrem) *loRow++ = ll.ReadBuffer(); #ifdef __PGFROISUPPORT__ if (storePos) { // increment src buffer positions ll.IncBuffRow(llPos); hl.IncBuffRow(hlPos); } #endif } }
friend class CSubband [friend] |
Definition at line 93 of file WaveletTransform.h.
int CWaveletTransform::m_nLevels [private] |
number of transform levels: one more than the number of level in PGFimage
Definition at line 178 of file WaveletTransform.h.
CSubband(* CWaveletTransform::m_subband)[NSubbands] [private] |
quadtree of subbands: LL HL LH HH
Definition at line 179 of file WaveletTransform.h.