libpgf  7.15.32
PGF - Progressive Graphics File
Subband.cpp
Go to the documentation of this file.
1 /*
2  * The Progressive Graphics File; http://www.libpgf.org
3  *
4  * $Date: 2006-06-04 22:05:59 +0200 (So, 04 Jun 2006) $
5  * $Revision: 229 $
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 "Subband.h"
30 #include "Encoder.h"
31 #include "Decoder.h"
32 
34 // Default constructor
36 : m_width(0)
37 , m_height(0)
38 , m_size(0)
39 , m_level(0)
40 , m_orientation(LL)
41 , m_data(0)
42 , m_dataPos(0)
43 #ifdef __PGFROISUPPORT__
44 , m_nTiles(0)
45 #endif
46 {
47 }
48 
50 // Destructor
52  FreeMemory();
53 }
54 
56 // Initialize subband parameters
57 void CSubband::Initialize(UINT32 width, UINT32 height, int level, Orientation orient) {
58  m_width = width;
59  m_height = height;
61  m_level = level;
62  m_orientation = orient;
63  m_data = 0;
64  m_dataPos = 0;
65 #ifdef __PGFROISUPPORT__
66  m_ROI.left = 0;
67  m_ROI.top = 0;
68  m_ROI.right = m_width;
69  m_ROI.bottom = m_height;
70  m_nTiles = 0;
71 #endif
72 }
73 
75 // Allocate a memory buffer to store all wavelet coefficients of this subband.
76 // @return True if the allocation works without any problems
78  UINT32 oldSize = m_size;
79 
80 #ifdef __PGFROISUPPORT__
81  m_size = BufferWidth()*m_ROI.Height();
82 #endif
83  ASSERT(m_size > 0);
84 
85  if (m_data) {
86  if (oldSize >= m_size) {
87  return true;
88  } else {
89  delete[] m_data;
90  m_data = new(std::nothrow) DataT[m_size];
91  return (m_data != 0);
92  }
93  } else {
94  m_data = new(std::nothrow) DataT[m_size];
95  return (m_data != 0);
96  }
97 }
98 
100 // Delete the memory buffer of this subband.
102  if (m_data) {
103  delete[] m_data; m_data = 0;
104  }
105 }
106 
108 // Perform subband quantization with given quantization parameter.
109 // A scalar quantization (with dead-zone) is used. A large quantization value
110 // results in strong quantization and therefore in big quality loss.
111 // @param quantParam A quantization parameter (larger or equal to 0)
112 void CSubband::Quantize(int quantParam) {
113  if (m_orientation == LL) {
114  quantParam -= (m_level + 1);
115  // uniform rounding quantization
116  if (quantParam > 0) {
117  quantParam--;
118  for (UINT32 i=0; i < m_size; i++) {
119  if (m_data[i] < 0) {
120  m_data[i] = -(((-m_data[i] >> quantParam) + 1) >> 1);
121  } else {
122  m_data[i] = ((m_data[i] >> quantParam) + 1) >> 1;
123  }
124  }
125  }
126  } else {
127  if (m_orientation == HH) {
128  quantParam -= (m_level - 1);
129  } else {
130  quantParam -= m_level;
131  }
132  // uniform deadzone quantization
133  if (quantParam > 0) {
134  int threshold = ((1 << quantParam) * 7)/5; // good value
135  quantParam--;
136  for (UINT32 i=0; i < m_size; i++) {
137  if (m_data[i] < -threshold) {
138  m_data[i] = -(((-m_data[i] >> quantParam) + 1) >> 1);
139  } else if (m_data[i] > threshold) {
140  m_data[i] = ((m_data[i] >> quantParam) + 1) >> 1;
141  } else {
142  m_data[i] = 0;
143  }
144  }
145  }
146  }
147 }
148 
154 void CSubband::Dequantize(int quantParam) {
155  if (m_orientation == LL) {
156  quantParam -= m_level + 1;
157  } else if (m_orientation == HH) {
158  quantParam -= m_level - 1;
159  } else {
160  quantParam -= m_level;
161  }
162  if (quantParam > 0) {
163  for (UINT32 i=0; i < m_size; i++) {
164  m_data[i] <<= quantParam;
165  }
166  }
167 }
168 
177 void CSubband::ExtractTile(CEncoder& encoder, bool tile /*= false*/, UINT32 tileX /*= 0*/, UINT32 tileY /*= 0*/) {
178 #ifdef __PGFROISUPPORT__
179  if (tile) {
180  // compute tile position and size
181  UINT32 xPos, yPos, w, h;
182  TilePosition(tileX, tileY, xPos, yPos, w, h);
183 
184  // write values into buffer using partitiong scheme
185  encoder.Partition(this, w, h, xPos + yPos*m_width, m_width);
186  } else
187 #endif
188  {
189  tileX; tileY; tile; // prevents from unreferenced formal parameter warning
190  // write values into buffer using partitiong scheme
191  encoder.Partition(this, m_width, m_height, 0, m_width);
192  }
193 }
194 
203 void CSubband::PlaceTile(CDecoder& decoder, int quantParam, bool tile /*= false*/, UINT32 tileX /*= 0*/, UINT32 tileY /*= 0*/) {
204  // allocate memory
205  if (!AllocMemory()) ReturnWithError(InsufficientMemory);
206 
207  // correct quantParam with normalization factor
208  if (m_orientation == LL) {
209  quantParam -= m_level + 1;
210  } else if (m_orientation == HH) {
211  quantParam -= m_level - 1;
212  } else {
213  quantParam -= m_level;
214  }
215  if (quantParam < 0) quantParam = 0;
216 
217 #ifdef __PGFROISUPPORT__
218  if (tile) {
219  UINT32 xPos, yPos, w, h;
220 
221  // compute tile position and size
222  TilePosition(tileX, tileY, xPos, yPos, w, h);
223 
224  ASSERT(xPos >= m_ROI.left && yPos >= m_ROI.top);
225  decoder.Partition(this, quantParam, w, h, (xPos - m_ROI.left) + (yPos - m_ROI.top)*BufferWidth(), BufferWidth());
226  } else
227 #endif
228  {
229  tileX; tileY; tile; // prevents from unreferenced formal parameter warning
230  // read values into buffer using partitiong scheme
231  decoder.Partition(this, quantParam, m_width, m_height, 0, m_width);
232  }
233 }
234 
235 
236 
237 #ifdef __PGFROISUPPORT__
238 void CSubband::SetAlignedROI(const PGFRect& roi) {
241  ASSERT(roi.left <= m_width);
242  ASSERT(roi.top <= m_height);
243 
244  m_ROI = roi;
245  if (m_ROI.right > m_width) m_ROI.right = m_width;
246  if (m_ROI.bottom > m_height) m_ROI.bottom = m_height;
247 }
248 
257 void CSubband::TilePosition(UINT32 tileX, UINT32 tileY, UINT32& xPos, UINT32& yPos, UINT32& w, UINT32& h) const {
258  ASSERT(tileX < m_nTiles); ASSERT(tileY < m_nTiles);
259  // example
260  // band = HH, w = 30, ldTiles = 2 -> 4 tiles in a row/column
261  // --> tile widths
262  // 8 7 8 7
263  //
264  // tile partitioning scheme
265  // 0 1 2 3
266  // 4 5 6 7
267  // 8 9 A B
268  // C D E F
269 
270  UINT32 nTiles = m_nTiles;
271  UINT32 m;
272  UINT32 left = 0, right = nTiles;
273  UINT32 top = 0, bottom = nTiles;
274 
275  xPos = 0;
276  yPos = 0;
277  w = m_width;
278  h = m_height;
279 
280  while (nTiles > 1) {
281  // compute xPos and w with binary search
282  m = left + ((right - left) >> 1);
283  if (tileX >= m) {
284  xPos += (w + 1) >> 1;
285  w >>= 1;
286  left = m;
287  } else {
288  w = (w + 1) >> 1;
289  right = m;
290  }
291  // compute yPos and h with binary search
292  m = top + ((bottom - top) >> 1);
293  if (tileY >= m) {
294  yPos += (h + 1) >> 1;
295  h >>= 1;
296  top = m;
297  } else {
298  h = (h + 1) >> 1;
299  bottom = m;
300  }
301  nTiles >>= 1;
302  }
303  ASSERT(xPos < m_width && (xPos + w <= m_width));
304  ASSERT(yPos < m_height && (yPos + h <= m_height));
305 }
306 
309 void CSubband::TileIndex(bool topLeft, UINT32 xPos, UINT32 yPos, UINT32& tileX, UINT32& tileY, UINT32& x, UINT32& y) const {
310  UINT32 m;
311  UINT32 left = 0, right = m_width;
312  UINT32 top = 0, bottom = m_height;
313  UINT32 nTiles = m_nTiles;
314 
315  if (xPos > m_width) xPos = m_width;
316  if (yPos > m_height) yPos = m_height;
317 
318  if (topLeft) {
319  // compute tileX with binary search
320  tileX = 0;
321  while (nTiles > 1) {
322  nTiles >>= 1;
323  m = left + ((right - left + 1) >> 1);
324  if (xPos < m) {
325  // exclusive m
326  right = m;
327  } else {
328  tileX += nTiles;
329  left = m;
330  }
331  }
332  x = left;
333  ASSERT(tileX >= 0 && tileX < m_nTiles);
334 
335  // compute tileY with binary search
336  nTiles = m_nTiles;
337  tileY = 0;
338  while (nTiles > 1) {
339  nTiles >>= 1;
340  m = top + ((bottom - top + 1) >> 1);
341  if (yPos < m) {
342  // exclusive m
343  bottom = m;
344  } else {
345  tileY += nTiles;
346  top = m;
347  }
348  }
349  y = top;
350  ASSERT(tileY >= 0 && tileY < m_nTiles);
351 
352  } else {
353  // compute tileX with binary search
354  tileX = 1;
355  while (nTiles > 1) {
356  nTiles >>= 1;
357  m = left + ((right - left + 1) >> 1);
358  if (xPos <= m) {
359  // inclusive m
360  right = m;
361  } else {
362  tileX += nTiles;
363  left = m;
364  }
365  }
366  x = right;
367  ASSERT(tileX > 0 && tileX <= m_nTiles);
368 
369  // compute tileY with binary search
370  nTiles = m_nTiles;
371  tileY = 1;
372  while (nTiles > 1) {
373  nTiles >>= 1;
374  m = top + ((bottom - top + 1) >> 1);
375  if (yPos <= m) {
376  // inclusive m
377  bottom = m;
378  } else {
379  tileY += nTiles;
380  top = m;
381  }
382  }
383  y = bottom;
384  ASSERT(tileY > 0 && tileY <= m_nTiles);
385  }
386 }
387 
388 #endif
Definition: PGFtypes.h:99
DataT * m_data
buffer
Definition: Subband.h:172
void Dequantize(int quantParam)
Definition: Subband.cpp:154
UINT32 m_width
width in pixels
Definition: Subband.h:166
void ExtractTile(CEncoder &encoder, bool tile=false, UINT32 tileX=0, UINT32 tileY=0)
Definition: Subband.cpp:177
INT32 DataT
Definition: PGFtypes.h:262
UINT32 m_height
height in pixels
Definition: Subband.h:167
~CSubband()
Destructor.
Definition: Subband.cpp:51
bool AllocMemory()
Definition: Subband.cpp:77
void Initialize(UINT32 width, UINT32 height, int level, Orientation orient)
Definition: Subband.cpp:57
CSubband()
Standard constructor.
Definition: Subband.cpp:35
PGF wavelet subband class.
UINT32 right
Definition: PGFtypes.h:258
Orientation
Definition: PGFtypes.h:99
void Partition(CSubband *band, int quantParam, int width, int height, int startPos, int pitch)
Definition: Decoder.cpp:266
void PlaceTile(CDecoder &decoder, int quantParam, bool tile=false, UINT32 tileX=0, UINT32 tileY=0)
Definition: Subband.cpp:203
#define __PGFROISUPPORT__
Definition: PGFplatform.h:60
PGF decoder.
Definition: Decoder.h:46
PGF decoder class.
UINT32 m_size
size of data buffer m_data
Definition: Subband.h:168
PGF encoder class.
UINT32 top
Definition: PGFtypes.h:258
void Partition(CSubband *band, int width, int height, int startPos, int pitch)
Definition: Encoder.cpp:246
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
Definition: PGFtypes.h:99
int m_level
recursion level
Definition: Subband.h:169
Rectangle.
Definition: PGFtypes.h:222
UINT32 m_dataPos
current position in m_data
Definition: Subband.h:171
Orientation m_orientation
0=LL, 1=HL, 2=LH, 3=HH L=lowpass filtered, H=highpass filterd
Definition: Subband.h:170
PGF encoder.
Definition: Encoder.h:46