libpgf  6.12.24
PGF - Progressive Graphics File
 All Classes Files Functions Variables Typedefs Enumerations Enumerator Friends Defines
Subband.cpp
Go to the documentation of this file.
00001 /*
00002  * The Progressive Graphics File; http://www.libpgf.org
00003  * 
00004  * $Date: 2006-06-04 22:05:59 +0200 (So, 04 Jun 2006) $
00005  * $Revision: 229 $
00006  * 
00007  * This file Copyright (C) 2006 xeraina GmbH, Switzerland
00008  * 
00009  * This program is free software; you can redistribute it and/or
00010  * modify it under the terms of the GNU LESSER GENERAL PUBLIC LICENSE
00011  * as published by the Free Software Foundation; either version 2.1
00012  * of the License, or (at your option) any later version.
00013  * 
00014  * This program is distributed in the hope that it will be useful,
00015  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00016  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00017  * GNU General Public License for more details.
00018  * 
00019  * You should have received a copy of the GNU General Public License
00020  * along with this program; if not, write to the Free Software
00021  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
00022  */
00023 
00028 
00029 #include "Subband.h"
00030 #include "Encoder.h"
00031 #include "Decoder.h"
00032 
00034 // Default constructor
00035 CSubband::CSubband() 
00036 : m_size(0)
00037 , m_data(0)
00038 #ifdef __PGFROISUPPORT__
00039 , m_nTiles(0)
00040 #endif
00041 {
00042 }
00043 
00045 // Destructor
00046 CSubband::~CSubband() {
00047         FreeMemory();
00048 }
00049 
00051 // Initialize subband parameters
00052 void CSubband::Initialize(UINT32 width, UINT32 height, int level, Orientation orient) {
00053         m_width = width;
00054         m_height = height;
00055         m_size = m_width*m_height;
00056         m_level = level;
00057         m_orientation = orient;
00058         m_data = 0;
00059         m_dataPos = 0;
00060 #ifdef __PGFROISUPPORT__
00061         m_ROI.left = 0;
00062         m_ROI.top = 0;
00063         m_ROI.right = m_width;
00064         m_ROI.bottom = m_height;
00065         m_nTiles = 0;
00066 #endif
00067 }
00068 
00070 // Allocate a memory buffer to store all wavelet coefficients of this subband.
00071 // @return True if the allocation works without any problems
00072 bool CSubband::AllocMemory() {
00073         UINT32 oldSize = m_size;
00074 
00075 #ifdef __PGFROISUPPORT__
00076         m_size = BufferWidth()*m_ROI.Height();
00077 #endif
00078         ASSERT(m_size > 0);
00079 
00080         if (m_data) {
00081                 if (oldSize >= m_size) {
00082                         return true;
00083                 } else {
00084                         delete[] m_data;
00085                         m_data = new(std::nothrow) DataT[m_size];
00086                         return (m_data != 0);
00087                 }
00088         } else {
00089                 m_data = new(std::nothrow) DataT[m_size];
00090                 return (m_data != 0);
00091         }
00092 }
00093 
00095 // Delete the memory buffer of this subband.
00096 void CSubband::FreeMemory() {
00097         if (m_data) {
00098                 delete[] m_data; m_data = 0;
00099         }
00100 }
00101 
00103 // Perform subband quantization with given quantization parameter.
00104 // A scalar quantization (with dead-zone) is used. A large quantization value
00105 // results in strong quantization and therefore in big quality loss.
00106 // @param quantParam A quantization parameter (larger or equal to 0)
00107 void CSubband::Quantize(int quantParam) {
00108         if (m_orientation == LL) {
00109                 quantParam -= (m_level + 1);
00110                 // uniform rounding quantization
00111                 if (quantParam > 0) {
00112                         quantParam--;
00113                         for (UINT32 i=0; i < m_size; i++) {
00114                                 if (m_data[i] < 0) {
00115                                         m_data[i] = -(((-m_data[i] >> quantParam) + 1) >> 1);
00116                                 } else {
00117                                         m_data[i] = ((m_data[i] >> quantParam) + 1) >> 1;
00118                                 }
00119                         }
00120                 }
00121         } else {
00122                 if (m_orientation == HH) {
00123                         quantParam -= (m_level - 1);
00124                 } else {
00125                         quantParam -= m_level;
00126                 }
00127                 // uniform deadzone quantization
00128                 if (quantParam > 0) {
00129                         int threshold = ((1 << quantParam) * 7)/5;      // good value
00130                         quantParam--;
00131                         for (UINT32 i=0; i < m_size; i++) {
00132                                 if (m_data[i] < -threshold) {
00133                                         m_data[i] = -(((-m_data[i] >> quantParam) + 1) >> 1);
00134                                 } else if (m_data[i] > threshold) {
00135                                         m_data[i] = ((m_data[i] >> quantParam) + 1) >> 1;
00136                                 } else {
00137                                         m_data[i] = 0;
00138                                 }
00139                         }
00140                 }
00141         }
00142 }
00143 
00149 void CSubband::Dequantize(int quantParam) {
00150         if (m_orientation == LL) {
00151                 quantParam -= m_level + 1;
00152         } else if (m_orientation == HH) {
00153                 quantParam -= m_level - 1;
00154         } else {
00155                 quantParam -= m_level;
00156         }
00157         if (quantParam > 0) {
00158                 for (UINT32 i=0; i < m_size; i++) {
00159                         m_data[i] <<= quantParam;
00160                 }
00161         }
00162 }
00163 
00172 void CSubband::ExtractTile(CEncoder& encoder, bool tile /*= false*/, UINT32 tileX /*= 0*/, UINT32 tileY /*= 0*/) THROW_ {
00173 #ifdef __PGFROISUPPORT__
00174         if (tile) {
00175                 // compute tile position and size
00176                 UINT32 xPos, yPos, w, h;
00177                 TilePosition(tileX, tileY, xPos, yPos, w, h);
00178 
00179                 // write values into buffer using partitiong scheme
00180                 encoder.Partition(this, w, h, xPos + yPos*m_width, m_width);
00181         } else 
00182 #endif
00183         {
00184                 // write values into buffer using partitiong scheme
00185                 encoder.Partition(this, m_width, m_height, 0, m_width);
00186         }
00187 }
00188 
00197 void CSubband::PlaceTile(CDecoder& decoder, int quantParam, bool tile /*= false*/, UINT32 tileX /*= 0*/, UINT32 tileY /*= 0*/) THROW_ {
00198         // allocate memory
00199         if (!AllocMemory()) ReturnWithError(InsufficientMemory);
00200 
00201         // correct quantParam with normalization factor
00202         if (m_orientation == LL) {
00203                 quantParam -= m_level + 1;
00204         } else if (m_orientation == HH) {
00205                 quantParam -= m_level - 1;
00206         } else {
00207                 quantParam -= m_level;
00208         }
00209         if (quantParam < 0) quantParam = 0;
00210 
00211 #ifdef __PGFROISUPPORT__
00212         if (tile) {
00213                 UINT32 xPos, yPos, w, h;
00214 
00215                 // compute tile position and size
00216                 TilePosition(tileX, tileY, xPos, yPos, w, h);
00217                 
00218                 ASSERT(xPos >= m_ROI.left && yPos >= m_ROI.top);
00219                 decoder.Partition(this, quantParam, w, h, (xPos - m_ROI.left) + (yPos - m_ROI.top)*BufferWidth(), BufferWidth());
00220         } else 
00221 #endif
00222         {
00223                 // read values into buffer using partitiong scheme
00224                 decoder.Partition(this, quantParam, m_width, m_height, 0, m_width);
00225         }
00226 }
00227 
00228 
00229 
00230 #ifdef __PGFROISUPPORT__
00231 
00232 
00233 
00234 
00235 
00236 
00237 
00238 
00239 void CSubband::TilePosition(UINT32 tileX, UINT32 tileY, UINT32& xPos, UINT32& yPos, UINT32& w, UINT32& h) const {
00240         // example
00241         // band = HH, w = 30, ldTiles = 2 -> 4 tiles in a row/column
00242         // --> tile widths
00243         // 8 7 8 7
00244         // 
00245         // tile partitioning scheme
00246         // 0 1 2 3
00247         // 4 5 6 7
00248         // 8 9 A B
00249         // C D E F
00250 
00251         UINT32 nTiles = m_nTiles;
00252         ASSERT(tileX < nTiles); ASSERT(tileY < nTiles);
00253         UINT32 m;
00254         UINT32 left = 0, right = nTiles;
00255         UINT32 top = 0, bottom = nTiles;
00256 
00257         xPos = 0;
00258         yPos = 0;
00259         w = m_width;
00260         h = m_height;
00261 
00262         while (nTiles > 1) {
00263                 // compute xPos and w with binary search
00264                 m = (left + right) >> 1;
00265                 if (tileX >= m) {
00266                         xPos += (w + 1) >> 1;
00267                         w >>= 1;
00268                         left = m;
00269                 } else {
00270                         w = (w + 1) >> 1;
00271                         right = m;
00272                 }
00273                 // compute yPos and h with binary search
00274                 m = (top + bottom) >> 1;
00275                 if (tileY >= m) {
00276                         yPos += (h + 1) >> 1;
00277                         h >>= 1;
00278                         top = m;
00279                 } else {
00280                         h = (h + 1) >> 1;
00281                         bottom = m;
00282                 }
00283                 nTiles >>= 1;
00284         }
00285         ASSERT(xPos < m_width && (xPos + w <= m_width));
00286         ASSERT(yPos < m_height && (yPos + h <= m_height));
00287 }
00288 
00289 #endif