libpgf  6.11.42
PGF - Progressive Graphics File
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() : m_size(0), m_data(0)
00036 #ifdef __PGFROISUPPORT__
00037 , m_ROIs(0), m_dataWidth(0) 
00038 #endif
00039 {
00040 }
00041 
00043 // Destructor
00044 CSubband::~CSubband() {
00045         FreeMemory();
00046 }
00047 
00049 // Initialize subband parameters
00050 void CSubband::Initialize(UINT32 width, UINT32 height, int level, Orientation orient) {
00051         m_width = width;
00052         m_height = height;
00053         m_size = m_width*m_height;
00054         m_level = level;
00055         m_orientation = orient;
00056         m_data = 0;
00057         m_dataPos = 0;
00058 #ifdef __PGFROISUPPORT__
00059         m_ROIs = 0;
00060         m_dataWidth = width;
00061 #endif
00062 }
00063 
00064 
00066 // Allocate a memory buffer to store all wavelet coefficients of this subband.
00067 // @return True if the allocation did work without any problems
00068 bool CSubband::AllocMemory() {
00069         UINT32 oldSize = m_size;
00070 
00071 #ifdef __PGFROISUPPORT__
00072         if (m_ROIs) {
00073                 // reset dataWidth and size
00074                 const PGFRect& roi = m_ROIs->GetROI(m_level);
00075                 m_dataWidth = __min(m_width, roi.right) - roi.left;
00076                 ASSERT(m_dataWidth > 0);
00077                 m_size = m_dataWidth*(__min(m_height, roi.bottom) - roi.top);
00078         }
00079 #endif
00080         ASSERT(m_size > 0);
00081 
00082         if (m_data) {
00083                 if (oldSize >= m_size) {
00084                         return true;
00085                 } else {
00086                         delete[] m_data;
00087                         m_data = new(std::nothrow) DataT[m_size];
00088                         return (m_data != 0);
00089                 }
00090         } else {
00091                 m_data = new(std::nothrow) DataT[m_size];
00092                 return (m_data != 0);
00093         }
00094 }
00095 
00097 // Delete the memory buffer of this subband.
00098 void CSubband::FreeMemory() {
00099         if (m_data) {
00100                 delete[] m_data; m_data = 0;
00101         }
00102 }
00103 
00105 // Perform subband quantization with given quantization parameter.
00106 // A scalar quantization (with dead-zone) is used. A large quantization value
00107 // results in strong quantization and therefore in big quality loss.
00108 // @param quantParam A quantization parameter (larger or equal to 0)
00109 void CSubband::Quantize(int quantParam) {
00110         if (m_orientation == LL) {
00111                 quantParam -= (m_level + 1);
00112                 // uniform rounding quantization
00113                 if (quantParam > 0) {
00114                         quantParam--;
00115                         for (UINT32 i=0; i < m_size; i++) {
00116                                 if (m_data[i] < 0) {
00117                                         m_data[i] = -(((-m_data[i] >> quantParam) + 1) >> 1);
00118                                 } else {
00119                                         m_data[i] = ((m_data[i] >> quantParam) + 1) >> 1;
00120                                 }
00121                         }
00122                 }
00123         } else {
00124                 if (m_orientation == HH) {
00125                         quantParam -= (m_level - 1);
00126                 } else {
00127                         quantParam -= m_level;
00128                 }
00129                 // uniform deadzone quantization
00130                 if (quantParam > 0) {
00131                         int threshold = ((1 << quantParam) * 7)/5;      // good value
00132                         quantParam--;
00133                         for (UINT32 i=0; i < m_size; i++) {
00134                                 if (m_data[i] < -threshold) {
00135                                         m_data[i] = -(((-m_data[i] >> quantParam) + 1) >> 1);
00136                                 } else if (m_data[i] > threshold) {
00137                                         m_data[i] = ((m_data[i] >> quantParam) + 1) >> 1;
00138                                 } else {
00139                                         m_data[i] = 0;
00140                                 }
00141                         }
00142                 }
00143         }
00144 }
00145 
00151 void CSubband::Dequantize(int quantParam) {
00152         if (m_orientation == LL) {
00153                 quantParam -= m_level + 1;
00154         } else if (m_orientation == HH) {
00155                 quantParam -= m_level - 1;
00156         } else {
00157                 quantParam -= m_level;
00158         }
00159         if (quantParam > 0) {
00160                 for (UINT32 i=0; i < m_size; i++) {
00161                         m_data[i] <<= quantParam;
00162                 }
00163         }
00164 }
00165 
00174 void CSubband::ExtractTile(CEncoder& encoder, bool tile /*= false*/, UINT32 tileX /*= 0*/, UINT32 tileY /*= 0*/) THROW_ {
00175 #ifdef __PGFROISUPPORT__
00176         if (tile) {
00177                 // compute tile position and size
00178                 UINT32 xPos, yPos, w, h;
00179                 TilePosition(tileX, tileY, xPos, yPos, w, h);
00180 
00181                 // write values into buffer using partitiong scheme
00182                 encoder.Partition(this, w, h, xPos + yPos*m_width, m_width);
00183         } else 
00184 #endif
00185         {
00186                 // write values into buffer using partitiong scheme
00187                 encoder.Partition(this, m_width, m_height, 0, m_width);
00188         }
00189 }
00190 
00199 void CSubband::PlaceTile(CDecoder& decoder, int quantParam, bool tile /*= false*/, UINT32 tileX /*= 0*/, UINT32 tileY /*= 0*/) THROW_ {
00200         // allocate memory
00201         if (!AllocMemory()) ReturnWithError(InsufficientMemory);
00202 
00203         // correct quantParam with normalization factor
00204         if (m_orientation == LL) {
00205                 quantParam -= m_level + 1;
00206         } else if (m_orientation == HH) {
00207                 quantParam -= m_level - 1;
00208         } else {
00209                 quantParam -= m_level;
00210         }
00211         if (quantParam < 0) quantParam = 0;
00212 
00213 #ifdef __PGFROISUPPORT__
00214         if (tile) {
00215                 // compute tile position and size
00216                 const PGFRect& roi = m_ROIs->GetROI(m_level);
00217                 UINT32 xPos, yPos, w, h;
00218                 TilePosition(tileX, tileY, xPos, yPos, w, h);
00219 
00220                 // read values into buffer using partitiong scheme
00221                 decoder.Partition(this, quantParam, w, h, (xPos - roi.left) + (yPos - roi.top)*m_dataWidth, m_dataWidth);
00222         } else 
00223 #endif
00224         {
00225                 // read values into buffer using partitiong scheme
00226                 decoder.Partition(this, quantParam, m_width, m_height, 0, m_width);
00227         }
00228 }
00229 
00230 
00231 
00232 #ifdef __PGFROISUPPORT__
00233 
00234 
00235 
00236 
00237 
00238 
00239 
00240 
00241 void CSubband::TilePosition(UINT32 tileX, UINT32 tileY, UINT32& xPos, UINT32& yPos, UINT32& w, UINT32& h) const {
00242         // example
00243         // band = HH, w = 30, ldTiles = 2 -> 4 tiles in a row/column
00244         // --> tile widths
00245         // 8 7 8 7
00246         // 
00247         // tile partitioning scheme
00248         // 0 1 2 3
00249         // 4 5 6 7
00250         // 8 9 A B
00251         // C D E F
00252 
00253         UINT32 nTiles = m_ROIs->GetNofTiles(m_level);
00254         ASSERT(tileX < nTiles); ASSERT(tileY < nTiles);
00255         UINT32 m;
00256         UINT32 left = 0, right = nTiles;
00257         UINT32 top = 0, bottom = nTiles;
00258 
00259         xPos = 0;
00260         yPos = 0;
00261         w = m_width;
00262         h = m_height;
00263 
00264         while (nTiles > 1) {
00265                 // compute xPos and w with binary search
00266                 m = (left + right) >> 1;
00267                 if (tileX >= m) {
00268                         xPos += (w + 1) >> 1;
00269                         w >>= 1;
00270                         left = m;
00271                 } else {
00272                         w = (w + 1) >> 1;
00273                         right = m;
00274                 }
00275                 // compute yPos and h with binary search
00276                 m = (top + bottom) >> 1;
00277                 if (tileY >= m) {
00278                         yPos += (h + 1) >> 1;
00279                         h >>= 1;
00280                         top = m;
00281                 } else {
00282                         h = (h + 1) >> 1;
00283                         bottom = m;
00284                 }
00285                 nTiles >>= 1;
00286         }
00287         ASSERT(xPos < m_width && (xPos + w <= m_width));
00288         ASSERT(yPos < m_height && (yPos + h <= m_height));
00289 }
00290 
00291 #endif
 All Classes Files Functions Variables Typedefs Enumerations Enumerator Friends Defines