Created by the British Broadcasting Corporation.
00001 /* ***** BEGIN LICENSE BLOCK ***** 00002 * 00003 * $Id: wavelet_utils.h,v 1.26 2007/09/28 15:46:08 asuraparaju Exp $ $Name: Dirac_0_8_0 $ 00004 * 00005 * Version: MPL 1.1/GPL 2.0/LGPL 2.1 00006 * 00007 * The contents of this file are subject to the Mozilla Public License 00008 * Version 1.1 (the "License"); you may not use this file except in compliance 00009 * with the License. You may obtain a copy of the License at 00010 * http://www.mozilla.org/MPL/ 00011 * 00012 * Software distributed under the License is distributed on an "AS IS" basis, 00013 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for 00014 * the specific language governing rights and limitations under the License. 00015 * 00016 * The Original Code is BBC Research and Development code. 00017 * 00018 * The Initial Developer of the Original Code is the British Broadcasting 00019 * Corporation. 00020 * Portions created by the Initial Developer are Copyright (C) 2004. 00021 * All Rights Reserved. 00022 * 00023 * Contributor(s): Thomas Davies (Original Author), 00024 * Scott R Ladd 00025 * Anuradha Suraparaju 00026 * 00027 * Alternatively, the contents of this file may be used under the terms of 00028 * the GNU General Public License Version 2 (the "GPL"), or the GNU Lesser 00029 * Public License Version 2.1 (the "LGPL"), in which case the provisions of 00030 * the GPL or the LGPL are applicable instead of those above. If you wish to 00031 * allow use of your version of this file only under the terms of the either 00032 * the GPL or LGPL and not to allow others to use your version of this file 00033 * under the MPL, indicate your decision by deleting the provisions above 00034 * and replace them with the notice and other provisions required by the GPL 00035 * or LGPL. If you do not delete the provisions above, a recipient may use 00036 * your version of this file under the terms of any one of the MPL, the GPL 00037 * or the LGPL. 00038 * ***** END LICENSE BLOCK ***** */ 00039 00040 #ifndef _WAVELET_UTILS_H_ 00041 #define _WAVELET_UTILS_H_ 00042 00043 #include <libdirac_common/arrays.h> 00044 #include <libdirac_common/common.h> 00045 #include <vector> 00046 #include <cmath> 00047 #include <iostream> 00048 00049 //utilities for subband and wavelet transforms 00050 //Includes fast transform using lifting 00051 00052 namespace dirac 00053 { 00054 00055 class PicArray; 00056 class Subband; 00057 00059 class CodeBlock 00060 { 00061 00062 friend class Subband; 00063 00064 public: 00066 /* 00067 Default constructor - sets all dimensions to zero 00068 */ 00069 CodeBlock(); 00070 00072 /* 00073 Initialise the code block 00074 \param xstart the x-coord of the first coefficient in the block 00075 \param xend one past the last coefficient, horizontally 00076 \param ystart the y-coord of the first coefficient in the block 00077 \param yend one past the last coefficient, vertically 00078 */ 00079 CodeBlock( const int xstart , const int ystart , const int xend , const int yend); 00080 00082 int Xstart() const { return m_xstart; } 00083 00085 int Ystart() const { return m_ystart; } 00086 00088 int Xend() const { return m_xend; } 00089 00091 int Yend() const { return m_yend; } 00092 00094 int Xl() const { return m_xl; } 00095 00097 int Yl() const { return m_yl; } 00098 00100 int QIndex() const{ return m_qindex; } 00101 00103 float Wt() const { return m_wt; } 00104 00106 bool Skipped() const { return m_skipped; } 00107 00109 void SetQIndex( const int qindex ){ m_qindex = qindex; } 00110 00112 void SetSkip( bool skip ){ m_skipped = skip; } 00113 00114 private: 00115 00117 /* 00118 Initialise the code block 00119 \param xstart the x-coord of the first coefficient in the block 00120 \param xend one past the last coefficient, horizontally 00121 \param ystart the y-coord of the first coefficient in the block 00122 \param yend one past the last coefficient, vertically 00123 */ 00124 void Init( const int xstart , const int ystart , const int xend , const int yend ); 00125 00127 void SetWt( const float w ){ m_wt = w; } 00128 00129 00130 private: 00131 00132 int m_xstart; 00133 int m_ystart; 00134 int m_xend; 00135 int m_yend; 00136 int m_xl; 00137 int m_yl; 00138 00139 int m_qindex; 00140 float m_wt; 00141 00142 bool m_skipped; 00143 }; 00144 00145 00147 class Subband 00148 { 00149 public: 00150 00152 Subband(); 00153 00155 00163 Subband(int xpos, int ypos, int xlen, int ylen); 00164 00166 00175 Subband(int xpos, int ypos, int xlen, int ylen, int d); 00176 00178 ~Subband(); 00179 00180 //Default (shallow) copy constructor and operator= used 00181 00183 int Xl() const {return m_xl;} 00184 00186 int Xp() const {return m_xp;} 00187 00189 int Yl() const {return m_yl;} 00190 00192 int Yp() const {return m_yp;} 00193 00195 int Max() const {return m_max_bit;} 00196 00198 double Wt() const {return m_wt;} 00199 00201 int Depth() const {return m_depth;} 00202 00204 int Scale() const {return ( 1<<m_depth );} 00205 00207 int QIndex() const {return m_qindex;} 00208 00210 bool UsingMultiQuants() const {return m_multi_quants; } 00211 00213 int Parent() const {return m_parent;} 00214 00216 const std::vector<int>& Children() const {return m_children;} 00217 00219 int Child(const int n) const {return m_children[n];} 00220 00222 TwoDArray<CodeBlock>& GetCodeBlocks(){ return m_code_block_array; } 00223 00225 const TwoDArray<CodeBlock>& GetCodeBlocks() const { return m_code_block_array; } 00226 00228 bool Skipped() const { return m_skipped; } 00229 00231 void SetWt( const float w ); 00232 00234 void SetParent( const int p ){ m_parent=p; } 00235 00237 void SetDepth( const int d ){ m_depth=d;} 00238 00240 void SetMax( const int m ){ m_max_bit=m; }; 00241 00243 void SetChildren( const std::vector<int>& clist ){ m_children = clist; } 00244 00246 void AddChild( const int c ){ m_children.push_back(c); } 00247 00249 void SetNumBlocks( const int ynum , const int xnum ); 00250 00252 void SetQIndex( const int idx){ m_qindex = idx; } 00253 00255 void SetUsingMultiQuants( const bool multi){ m_multi_quants = multi; } 00256 00258 void SetSkip(const bool skip ){ m_skipped = skip; } 00259 00260 private: 00261 // subband bounds 00262 int m_xp , m_yp , m_xl , m_yl; 00263 00264 // perceptual weight for quantisation 00265 double m_wt; 00266 00267 // depth in the transform 00268 int m_depth; 00269 00270 // quantiser index 00271 int m_qindex; 00272 00273 // position of parent in a subband list 00274 int m_parent; 00275 00276 // positions of children in the subband list 00277 std::vector<int> m_children; 00278 00279 // position of the MSB of the largest absolute value 00280 int m_max_bit; 00281 00282 // The code blocks 00283 TwoDArray<CodeBlock> m_code_block_array; 00284 00285 // A flag indicating whether we're using one qf for each code block 00286 bool m_multi_quants; 00287 00288 // Whether the subband is skipped or not 00289 bool m_skipped; 00290 }; 00291 00293 class SubbandList 00294 { 00295 public: 00297 SubbandList(){} 00298 00300 ~SubbandList(){} 00301 00302 //Default (shallow) copy constructor and operator= used 00304 void Init(const int depth,const int xlen,const int ylen); 00305 00307 int Length() const {return bands.size();} 00308 00310 Subband& operator()(const int n){return bands[n-1];} 00311 00313 const Subband& operator()(const int n) const {return bands[n-1];} 00314 00316 void AddBand(const Subband& b){bands.push_back(b);} 00317 00319 void Clear(){bands.clear();} 00320 00321 private: 00322 00324 float PerceptualWeight( const float xf , const float yf , const CompSort cs); 00325 00326 private: 00327 std::vector<Subband> bands; 00328 }; 00329 00331 00335 class WaveletTransform 00336 { 00337 public: 00339 WaveletTransform(int d = 4, WltFilter f = DAUB9_7); 00340 00342 virtual ~WaveletTransform(); 00343 00345 00351 void Transform(const Direction d, PicArray& pic_data, CoeffArray& coeff_data); 00352 00354 SubbandList& BandList(){return m_band_list;} 00355 00357 const SubbandList& BandList() const {return m_band_list;} 00358 00360 00371 void SetBandWeights (const float cpd, 00372 const FrameSort& fsort, 00373 const ChromaFormat& cformat, 00374 const CompSort csort, 00375 const bool interlace); 00376 00377 00378 private: 00379 // Classes used within wavelet transform 00380 00382 class VHFilter 00383 { 00384 00385 public: 00386 00387 VHFilter(){} 00388 00389 virtual ~VHFilter(){} 00390 00392 virtual void Split(const int xp, const int yp, const int xl, const int yl, CoeffArray& coeff_data)=0; 00393 00395 virtual void Synth(const int xp, const int yp, const int xl, const int yl, CoeffArray& coeff_data)=0; 00396 00398 virtual double GetLowFactor() const=0; 00399 00401 virtual double GetHighFactor() const =0; 00402 00404 virtual int GetShift() const =0; 00405 00406 protected: 00407 00409 inline void Interleave( const int xp, const int yp, const int xl, const int yl, CoeffArray& coeff_data ); 00410 00411 00413 inline void DeInterleave( const int xp, const int yp, const int xl, const int yl, CoeffArray& coeff_data ); 00414 00416 void ShiftRowLeft(CoeffType *row, int length, int shift); 00417 00419 void ShiftRowRight(CoeffType *row, int length, int shift); 00420 }; 00421 00423 class VHFilterDAUB9_7 : public VHFilter 00424 { 00425 00426 public: 00427 00429 void Split(const int xp, const int yp, const int xl, const int yl, CoeffArray& coeff_data); 00430 00432 void Synth(const int xp, const int yp, const int xl, const int yl, CoeffArray& coeff_data); 00433 00435 double GetLowFactor() const { return 1.149604398;} 00436 00438 double GetHighFactor() const { return 0.869864452;} 00439 00441 int GetShift() const {return 1;} 00442 00443 00444 }; 00445 00447 class VHFilterLEGALL5_3 : public VHFilter 00448 { 00449 00450 public: 00451 00453 void Split(const int xp, const int yp, const int xl, const int yl, CoeffArray& coeff_data); 00454 00456 void Synth(const int xp, const int yp, const int xl, const int yl, CoeffArray& coeff_data); 00457 00459 double GetLowFactor() const { return 1.179535649;} 00460 00462 double GetHighFactor() const { return 0.81649658;} 00463 00465 int GetShift() const {return 1;} 00466 00467 00468 #ifdef HAVE_MMX 00469 inline void HorizSynth (int xp, int xl, int ystart, int yend, CoeffArray &coeff_data); 00470 #endif 00471 00472 }; 00473 00475 class VHFilterDD9_7 : public VHFilter 00476 { 00477 00478 public: 00479 00481 void Split(const int xp, const int yp, const int xl, const int yl, CoeffArray& coeff_data); 00482 00484 void Synth(const int xp, const int yp, const int xl, const int yl, CoeffArray& coeff_data); 00485 00487 double GetLowFactor() const { return 1.218660804;} 00488 00490 double GetHighFactor() const { return 0.780720058;} 00491 00493 int GetShift() const {return 1;} 00494 00495 }; 00496 00497 00499 class VHFilterDD13_7 : public VHFilter 00500 { 00501 00502 public: 00503 00505 void Split(const int xp, const int yp, const int xl, const int yl, CoeffArray& coeff_data); 00506 00508 void Synth(const int xp, const int yp, const int xl, const int yl, CoeffArray& coeff_data); 00509 00511 double GetLowFactor() const { return 1.235705971;} 00512 00514 double GetHighFactor() const { return 0.780719354;} 00515 00517 int GetShift() const {return 1;} 00518 00519 }; 00520 00522 class VHFilterHAAR0 : public VHFilter 00523 { 00524 00525 public: 00526 00528 void Split(const int xp, const int yp, const int xl, const int yl, CoeffArray& coeff_data); 00529 00531 void Synth(const int xp, const int yp, const int xl, const int yl, CoeffArray& coeff_data); 00532 00534 double GetLowFactor() const { return 1.414213562;} 00535 00537 double GetHighFactor() const { return 0.707106781;} 00538 00540 int GetShift() const {return 0;} 00541 00542 00543 }; 00544 00546 class VHFilterHAAR1 : public VHFilter 00547 { 00548 00549 public: 00550 00552 void Split(const int xp, const int yp, const int xl, const int yl, CoeffArray& coeff_data); 00553 00555 void Synth(const int xp, const int yp, const int xl, const int yl, CoeffArray& coeff_data); 00556 00558 double GetLowFactor() const { return 1.414213562;} 00559 00561 double GetHighFactor() const { return 0.707106781;} 00562 00564 int GetShift() const {return 1;} 00565 00566 00567 }; 00568 00569 00571 class VHFilterHAAR2 : public VHFilter 00572 { 00573 00574 public: 00575 00577 void Split(const int xp, const int yp, const int xl, const int yl, CoeffArray& coeff_data); 00578 00580 void Synth(const int xp, const int yp, const int xl, const int yl, CoeffArray& coeff_data); 00581 00583 double GetLowFactor() const { return 1.414213562;} 00584 00586 double GetHighFactor() const { return 0.707106781;} 00587 00589 int GetShift() const {return 2;} 00590 00591 }; 00592 00593 00594 00595 // Lifting steps used in the filters 00596 00598 template<int shift> 00599 class PredictStepShift 00600 { 00601 00602 public: 00603 00605 PredictStepShift(){} 00606 00607 // Assume default copy constructor, assignment= and destructor // 00608 00610 /* 00611 Do the filtering. 00612 \param in_val the value being predicted 00613 \param val1 the first value being used for prediction 00614 \param val2 the second value being used for prediction 00615 */ 00616 inline void Filter(CoeffType& in_val, const CoeffType& val1, const CoeffType& val2) const 00617 { 00618 in_val -= (( val1 + val2 + (1<<(shift-1)) ) >>shift ); 00619 } 00620 00621 }; 00622 00624 template<int shift> 00625 class UpdateStepShift 00626 { 00627 00628 public: 00630 UpdateStepShift(){} 00631 00633 /* 00634 Do the filtering. 00635 \param in_val the value being updated 00636 \param val1 the first value being used for updating 00637 \param val2 the second value being used for updating 00638 */ 00639 inline void Filter(CoeffType& in_val, const CoeffType& val1, const CoeffType& val2) const 00640 { 00641 in_val += ( ( val1 + val2 + (1<<(shift-1)) ) >>shift ); 00642 } 00643 00644 }; 00645 00647 template <int shift , int tap1, int tap2> 00648 class PredictStepFourTap 00649 { 00650 public: 00651 00653 PredictStepFourTap(){} 00654 00655 // Assume default copy constructor, assignment= and destructor // 00656 00658 inline void Filter(CoeffType& in_val, const CoeffType& val1, const CoeffType& val2 , 00659 const CoeffType& val3, const CoeffType& val4 ) const 00660 { 00661 in_val -= ( tap1*( val1 + val2 ) + tap2*( val3 + val4 ) + (1<<(shift-1)))>>shift; 00662 } 00663 }; 00664 00666 template <int shift , int tap1 , int tap2> 00667 class UpdateStepFourTap 00668 { 00669 00670 public: 00672 UpdateStepFourTap(){} 00673 00675 inline void Filter(CoeffType& in_val, const CoeffType& val1, const CoeffType& val2 , 00676 const CoeffType& val3, const CoeffType& val4 ) const 00677 { 00678 in_val += ( tap1*( val1 + val2 ) + tap2*( val3 + val4 ) + (1<<(shift-1)) )>>shift; 00679 } 00680 }; 00681 00683 template <int gain> class PredictStep97 00684 { 00685 public: 00686 00688 PredictStep97(){} 00689 00690 // Assume default copy constructor, assignment= and destructor // 00691 00693 /* 00694 Do the filtering. 00695 \param in_val the value being predicted 00696 \param val1 the first value being used for prediction 00697 \param val2 the second value being used for prediction 00698 */ 00699 inline void Filter(CoeffType& in_val, const CoeffType& val1, const CoeffType& val2) const 00700 { 00701 in_val -= static_cast< CoeffType >( (gain * static_cast< int >( val1 + val2 )) >>12 ); 00702 } 00703 }; 00704 00706 template <int gain> class UpdateStep97 00707 { 00708 00709 public: 00711 UpdateStep97(){} 00712 00714 /* 00715 Do the filtering. 00716 \param in_val the value being updated 00717 \param val1 the first value being used for updating 00718 \param val2 the second value being used for updating 00719 */ 00720 inline void Filter(CoeffType& in_val, const CoeffType& val1, const CoeffType& val2) const 00721 { 00722 in_val += static_cast< CoeffType >( (gain * static_cast< int >( val1 + val2 )) >>12 ); 00723 } 00724 }; 00725 00726 private: 00727 00728 // Private variables 00729 00730 SubbandList m_band_list; 00731 00733 int m_depth; 00734 00736 WltFilter m_filt_sort; 00737 00739 VHFilter* m_vhfilter; 00740 00741 private: 00742 // Private functions 00744 WaveletTransform(const WaveletTransform& cpy); 00745 00747 WaveletTransform& operator=(const WaveletTransform& rhs); 00748 00750 float PerceptualWeight(float xf,float yf,CompSort cs); 00751 }; 00752 00753 }// end namespace dirac 00754 00755 #endif
© 2004 British Broadcasting Corporation.
Dirac code licensed under the Mozilla Public License (MPL) Version 1.1.
HTML documentation generated by Dimitri van Heesch's
excellent Doxygen tool.