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