libpgf: Subband.cpp Source File

| libpgf 7.21.2 PGF - Progressive Graphics File

Loading...
Searching...
No Matches
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
35CSubband::CSubband()
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
51CSubband::~CSubband() {
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;
60 m_size = m_width*m_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
77 bool CSubband::AllocMemory() {
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.
101 void CSubband::FreeMemory() {
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__
240void 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
257void 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
309void 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
Decoder.h
PGF decoder class.
Encoder.h
PGF encoder class.
__PGFROISUPPORT__
#define __PGFROISUPPORT__
Definition PGFplatform.h:60
Orientation
Orientation
Definition PGFtypes.h:99
LL
@ LL
Definition PGFtypes.h:99
HH
@ HH
Definition PGFtypes.h:99
DataT
INT32 DataT
Definition PGFtypes.h:269
Subband.h
PGF wavelet subband class.
CDecoder
PGF decoder.
Definition Decoder.h:46
CDecoder::Partition
void Partition(CSubband *band, int quantParam, int width, int height, int startPos, int pitch)
Definition Decoder.cpp:266
CEncoder
PGF encoder.
Definition Encoder.h:46
CEncoder::Partition
void Partition(CSubband *band, int width, int height, int startPos, int pitch)
Definition Encoder.cpp:246
CSubband::m_size
UINT32 m_size
size of data buffer m_data
Definition Subband.h:168
CSubband::m_dataPos
UINT32 m_dataPos
current position in m_data
Definition Subband.h:171
CSubband::AllocMemory
bool AllocMemory()
Definition Subband.cpp:77
CSubband::Dequantize
void Dequantize(int quantParam)
Definition Subband.cpp:154
CSubband::Initialize
void Initialize(UINT32 width, UINT32 height, int level, Orientation orient)
Definition Subband.cpp:57
CSubband::Quantize
void Quantize(int quantParam)
Definition Subband.cpp:112
CSubband::FreeMemory
void FreeMemory()
Delete the memory buffer of this subband.
Definition Subband.cpp:101
CSubband::m_height
UINT32 m_height
height in pixels
Definition Subband.h:167
CSubband::m_orientation
Orientation m_orientation
0=LL, 1=HL, 2=LH, 3=HH L=lowpass filtered, H=highpass filterd
Definition Subband.h:170
CSubband::m_data
DataT * m_data
buffer
Definition Subband.h:172
CSubband::ExtractTile
void ExtractTile(CEncoder &encoder, bool tile=false, UINT32 tileX=0, UINT32 tileY=0)
Definition Subband.cpp:177
CSubband::m_level
int m_level
recursion level
Definition Subband.h:169
CSubband::~CSubband
~CSubband()
Destructor.
Definition Subband.cpp:51
CSubband::PlaceTile
void PlaceTile(CDecoder &decoder, int quantParam, bool tile=false, UINT32 tileX=0, UINT32 tileY=0)
Definition Subband.cpp:203
CSubband::m_width
UINT32 m_width
width in pixels
Definition Subband.h:166
CSubband::CSubband
CSubband()
Standard constructor.
Definition Subband.cpp:35
PGFRect
Rectangle.
Definition PGFtypes.h:225
PGFRect::top
UINT32 top
Definition PGFtypes.h:226
PGFRect::right
UINT32 right
Definition PGFtypes.h:226
PGFRect::left
UINT32 left
Definition PGFtypes.h:226