00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00028
00029 #include "Subband.h"
00030 #include "Encoder.h"
00031 #include "Decoder.h"
00032
00034
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
00051 CSubband::~CSubband() {
00052 FreeMemory();
00053 }
00054
00056
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
00076
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
00101 void CSubband::FreeMemory() {
00102 if (m_data) {
00103 delete[] m_data; m_data = 0;
00104 }
00105 }
00106
00108
00109
00110
00111
00112 void CSubband::Quantize(int quantParam) {
00113 if (m_orientation == LL) {
00114 quantParam -= (m_level + 1);
00115
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
00133 if (quantParam > 0) {
00134 int threshold = ((1 << quantParam) * 7)/5;
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 , UINT32 tileX , UINT32 tileY ) THROW_ {
00178 #ifdef __PGFROISUPPORT__
00179 if (tile) {
00180
00181 UINT32 xPos, yPos, w, h;
00182 TilePosition(tileX, tileY, xPos, yPos, w, h);
00183
00184
00185 encoder.Partition(this, w, h, xPos + yPos*m_width, m_width);
00186 } else
00187 #endif
00188 {
00189
00190 encoder.Partition(this, m_width, m_height, 0, m_width);
00191 }
00192 }
00193
00202 void CSubband::PlaceTile(CDecoder& decoder, int quantParam, bool tile , UINT32 tileX , UINT32 tileY ) THROW_ {
00203
00204 if (!AllocMemory()) ReturnWithError(InsufficientMemory);
00205
00206
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
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
00229 decoder.Partition(this, quantParam, m_width, m_height, 0, m_width);
00230 }
00231 }
00232
00233
00234
00235 #ifdef __PGFROISUPPORT__
00244 void CSubband::TilePosition(UINT32 tileX, UINT32 tileY, UINT32& xPos, UINT32& yPos, UINT32& w, UINT32& h) const {
00245
00246
00247
00248
00249
00250
00251
00252
00253
00254
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
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
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