Created by the British Broadcasting Corporation.
00001 /* ***** BEGIN LICENSE BLOCK ***** 00002 * 00003 * $Id: wavelet_utils.h,v 1.28 2007/12/12 14:01:51 tjdwave Exp $ $Name: Dirac_0_9_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 bool Skipped() const { return m_skipped; } 00104 00106 void SetQIndex( const int qindex ){ m_qindex = qindex; } 00107 00109 void SetSkip( bool skip ){ m_skipped = skip; } 00110 00111 private: 00112 00114 /* 00115 Initialise the code block 00116 \param xstart the x-coord of the first coefficient in the block 00117 \param xend one past the last coefficient, horizontally 00118 \param ystart the y-coord of the first coefficient in the block 00119 \param yend one past the last coefficient, vertically 00120 */ 00121 void Init( const int xstart , const int ystart , const int xend , const int yend ); 00122 00123 private: 00124 00125 int m_xstart; 00126 int m_ystart; 00127 int m_xend; 00128 int m_yend; 00129 int m_xl; 00130 int m_yl; 00131 00132 int m_qindex; 00133 00134 bool m_skipped; 00135 }; 00136 00137 00139 class Subband 00140 { 00141 public: 00142 00144 Subband(); 00145 00147 00155 Subband(int xpos, int ypos, int xlen, int ylen); 00156 00158 00167 Subband(int xpos, int ypos, int xlen, int ylen, int d); 00168 00170 ~Subband(); 00171 00172 //Default (shallow) copy constructor and operator= used 00173 00175 int Xl() const {return m_xl;} 00176 00178 int Xp() const {return m_xp;} 00179 00181 int Yl() const {return m_yl;} 00182 00184 int Yp() const {return m_yp;} 00185 00187 int Max() const {return m_max_bit;} 00188 00190 double Wt() const {return m_wt;} 00191 00193 int Depth() const {return m_depth;} 00194 00196 int Scale() const {return ( 1<<m_depth );} 00197 00199 int QIndex() const {return m_qindex;} 00200 00202 bool UsingMultiQuants() const {return m_multi_quants; } 00203 00205 int Parent() const {return m_parent;} 00206 00208 const std::vector<int>& Children() const {return m_children;} 00209 00211 int Child(const int n) const {return m_children[n];} 00212 00214 TwoDArray<CodeBlock>& GetCodeBlocks(){ return m_code_block_array; } 00215 00217 const TwoDArray<CodeBlock>& GetCodeBlocks() const { return m_code_block_array; } 00218 00220 bool Skipped() const { return m_skipped; } 00221 00223 void SetWt( const float w ); 00224 00226 void SetParent( const int p ){ m_parent=p; } 00227 00229 void SetDepth( const int d ){ m_depth=d;} 00230 00232 void SetMax( const int m ){ m_max_bit=m; }; 00233 00235 void SetChildren( const std::vector<int>& clist ){ m_children = clist; } 00236 00238 void AddChild( const int c ){ m_children.push_back(c); } 00239 00241 void SetNumBlocks( const int ynum , const int xnum ); 00242 00244 void SetQIndex( const int idx){ m_qindex = idx; } 00245 00247 void SetUsingMultiQuants( const bool multi){ m_multi_quants = multi; } 00248 00250 void SetSkip(const bool skip ){ m_skipped = skip; } 00251 00252 private: 00253 // subband bounds 00254 int m_xp , m_yp , m_xl , m_yl; 00255 00256 // perceptual weight for quantisation 00257 double m_wt; 00258 00259 // depth in the transform 00260 int m_depth; 00261 00262 // quantiser index 00263 int m_qindex; 00264 00265 // position of parent in a subband list 00266 int m_parent; 00267 00268 // positions of children in the subband list 00269 std::vector<int> m_children; 00270 00271 // position of the MSB of the largest absolute value 00272 int m_max_bit; 00273 00274 // The code blocks 00275 TwoDArray<CodeBlock> m_code_block_array; 00276 00277 // A flag indicating whether we're using one qf for each code block 00278 bool m_multi_quants; 00279 00280 // Whether the subband is skipped or not 00281 bool m_skipped; 00282 }; 00283 00285 class SubbandList 00286 { 00287 public: 00289 SubbandList(){} 00290 00292 ~SubbandList(){} 00293 00294 //Default (shallow) copy constructor and operator= used 00296 void Init(const int depth,const int xlen,const int ylen); 00297 00299 int Length() const {return bands.size();} 00300 00302 Subband& operator()(const int n){return bands[n-1];} 00303 00305 const Subband& operator()(const int n) const {return bands[n-1];} 00306 00308 void AddBand(const Subband& b){bands.push_back(b);} 00309 00311 void Clear(){bands.clear();} 00312 00313 private: 00314 00316 float PerceptualWeight( const float xf , const float yf , const CompSort cs); 00317 00318 private: 00319 std::vector<Subband> bands; 00320 }; 00321 00323 00327 class WaveletTransform 00328 { 00329 public: 00331 WaveletTransform(int d = 4, WltFilter f = DAUB9_7); 00332 00334 virtual ~WaveletTransform(); 00335 00337 00343 void Transform(const Direction d, PicArray& pic_data, CoeffArray& coeff_data); 00344 00346 SubbandList& BandList(){return m_band_list;} 00347 00349 const SubbandList& BandList() const {return m_band_list;} 00350 00352 00363 void SetBandWeights (const float cpd, 00364 const FrameSort& fsort, 00365 const ChromaFormat& cformat, 00366 const CompSort csort, 00367 const bool field_coding); 00368 00369 00370 private: 00371 // Classes used within wavelet transform 00372 00374 class VHFilter 00375 { 00376 00377 public: 00378 00379 VHFilter(){} 00380 00381 virtual ~VHFilter(){} 00382 00384 virtual void Split(const int xp, const int yp, const int xl, const int yl, CoeffArray& coeff_data)=0; 00385 00387 virtual void Synth(const int xp, const int yp, const int xl, const int yl, CoeffArray& coeff_data)=0; 00388 00390 virtual double GetLowFactor() const=0; 00391 00393 virtual double GetHighFactor() const =0; 00394 00396 virtual int GetShift() const =0; 00397 00398 protected: 00399 00401 inline void Interleave( const int xp, const int yp, const int xl, const int yl, CoeffArray& coeff_data ); 00402 00403 00405 inline void DeInterleave( const int xp, const int yp, const int xl, const int yl, CoeffArray& coeff_data ); 00406 00408 void ShiftRowLeft(CoeffType *row, int length, int shift); 00409 00411 void ShiftRowRight(CoeffType *row, int length, int shift); 00412 }; 00413 00415 class VHFilterDAUB9_7 : public VHFilter 00416 { 00417 00418 public: 00419 00421 void Split(const int xp, const int yp, const int xl, const int yl, CoeffArray& coeff_data); 00422 00424 void Synth(const int xp, const int yp, const int xl, const int yl, CoeffArray& coeff_data); 00425 00427 double GetLowFactor() const { return 1.149604398;} 00428 00430 double GetHighFactor() const { return 0.869864452;} 00431 00433 int GetShift() const {return 1;} 00434 00435 00436 }; 00437 00439 class VHFilterLEGALL5_3 : public VHFilter 00440 { 00441 00442 public: 00443 00445 void Split(const int xp, const int yp, const int xl, const int yl, CoeffArray& coeff_data); 00446 00448 void Synth(const int xp, const int yp, const int xl, const int yl, CoeffArray& coeff_data); 00449 00451 double GetLowFactor() const { return 1.179535649;} 00452 00454 double GetHighFactor() const { return 0.81649658;} 00455 00457 int GetShift() const {return 1;} 00458 00459 00460 #ifdef HAVE_MMX 00461 inline void HorizSynth (int xp, int xl, int ystart, int yend, CoeffArray &coeff_data); 00462 #endif 00463 00464 }; 00465 00467 class VHFilterDD9_7 : public VHFilter 00468 { 00469 00470 public: 00471 00473 void Split(const int xp, const int yp, const int xl, const int yl, CoeffArray& coeff_data); 00474 00476 void Synth(const int xp, const int yp, const int xl, const int yl, CoeffArray& coeff_data); 00477 00479 double GetLowFactor() const { return 1.218660804;} 00480 00482 double GetHighFactor() const { return 0.780720058;} 00483 00485 int GetShift() const {return 1;} 00486 00487 }; 00488 00489 00491 class VHFilterDD13_7 : public VHFilter 00492 { 00493 00494 public: 00495 00497 void Split(const int xp, const int yp, const int xl, const int yl, CoeffArray& coeff_data); 00498 00500 void Synth(const int xp, const int yp, const int xl, const int yl, CoeffArray& coeff_data); 00501 00503 double GetLowFactor() const { return 1.235705971;} 00504 00506 double GetHighFactor() const { return 0.780719354;} 00507 00509 int GetShift() const {return 1;} 00510 00511 }; 00512 00514 class VHFilterHAAR0 : public VHFilter 00515 { 00516 00517 public: 00518 00520 void Split(const int xp, const int yp, const int xl, const int yl, CoeffArray& coeff_data); 00521 00523 void Synth(const int xp, const int yp, const int xl, const int yl, CoeffArray& coeff_data); 00524 00526 double GetLowFactor() const { return 1.414213562;} 00527 00529 double GetHighFactor() const { return 0.707106781;} 00530 00532 int GetShift() const {return 0;} 00533 00534 00535 }; 00536 00538 class VHFilterHAAR1 : public VHFilter 00539 { 00540 00541 public: 00542 00544 void Split(const int xp, const int yp, const int xl, const int yl, CoeffArray& coeff_data); 00545 00547 void Synth(const int xp, const int yp, const int xl, const int yl, CoeffArray& coeff_data); 00548 00550 double GetLowFactor() const { return 1.414213562;} 00551 00553 double GetHighFactor() const { return 0.707106781;} 00554 00556 int GetShift() const {return 1;} 00557 00558 00559 }; 00560 00561 00563 class VHFilterHAAR2 : public VHFilter 00564 { 00565 00566 public: 00567 00569 void Split(const int xp, const int yp, const int xl, const int yl, CoeffArray& coeff_data); 00570 00572 void Synth(const int xp, const int yp, const int xl, const int yl, CoeffArray& coeff_data); 00573 00575 double GetLowFactor() const { return 1.414213562;} 00576 00578 double GetHighFactor() const { return 0.707106781;} 00579 00581 int GetShift() const {return 2;} 00582 00583 }; 00584 00585 00586 00587 // Lifting steps used in the filters 00588 00590 template<int shift> 00591 class PredictStepShift 00592 { 00593 00594 public: 00595 00597 PredictStepShift(){} 00598 00599 // Assume default copy constructor, assignment= and destructor // 00600 00602 /* 00603 Do the filtering. 00604 \param in_val the value being predicted 00605 \param val1 the first value being used for prediction 00606 \param val2 the second value being used for prediction 00607 */ 00608 inline void Filter(CoeffType& in_val, const CoeffType& val1, const CoeffType& val2) const 00609 { 00610 in_val -= (( val1 + val2 + (1<<(shift-1)) ) >>shift ); 00611 } 00612 00613 }; 00614 00616 template<int shift> 00617 class UpdateStepShift 00618 { 00619 00620 public: 00622 UpdateStepShift(){} 00623 00625 /* 00626 Do the filtering. 00627 \param in_val the value being updated 00628 \param val1 the first value being used for updating 00629 \param val2 the second value being used for updating 00630 */ 00631 inline void Filter(CoeffType& in_val, const CoeffType& val1, const CoeffType& val2) const 00632 { 00633 in_val += ( ( val1 + val2 + (1<<(shift-1)) ) >>shift ); 00634 } 00635 00636 }; 00637 00639 template <int shift , int tap1, int tap2> 00640 class PredictStepFourTap 00641 { 00642 public: 00643 00645 PredictStepFourTap(){} 00646 00647 // Assume default copy constructor, assignment= and destructor // 00648 00650 inline void Filter(CoeffType& in_val, const CoeffType& val1, const CoeffType& val2 , 00651 const CoeffType& val3, const CoeffType& val4 ) const 00652 { 00653 in_val -= ( tap1*( val1 + val2 ) + tap2*( val3 + val4 ) + (1<<(shift-1)))>>shift; 00654 } 00655 }; 00656 00658 template <int shift , int tap1 , int tap2> 00659 class UpdateStepFourTap 00660 { 00661 00662 public: 00664 UpdateStepFourTap(){} 00665 00667 inline void Filter(CoeffType& in_val, const CoeffType& val1, const CoeffType& val2 , 00668 const CoeffType& val3, const CoeffType& val4 ) const 00669 { 00670 in_val += ( tap1*( val1 + val2 ) + tap2*( val3 + val4 ) + (1<<(shift-1)) )>>shift; 00671 } 00672 }; 00673 00675 template <int gain> class PredictStep97 00676 { 00677 public: 00678 00680 PredictStep97(){} 00681 00682 // Assume default copy constructor, assignment= and destructor // 00683 00685 /* 00686 Do the filtering. 00687 \param in_val the value being predicted 00688 \param val1 the first value being used for prediction 00689 \param val2 the second value being used for prediction 00690 */ 00691 inline void Filter(CoeffType& in_val, const CoeffType& val1, const CoeffType& val2) const 00692 { 00693 in_val -= static_cast< CoeffType >( (gain * static_cast< int >( val1 + val2 )) >>12 ); 00694 } 00695 }; 00696 00698 template <int gain> class UpdateStep97 00699 { 00700 00701 public: 00703 UpdateStep97(){} 00704 00706 /* 00707 Do the filtering. 00708 \param in_val the value being updated 00709 \param val1 the first value being used for updating 00710 \param val2 the second value being used for updating 00711 */ 00712 inline void Filter(CoeffType& in_val, const CoeffType& val1, const CoeffType& val2) const 00713 { 00714 in_val += static_cast< CoeffType >( (gain * static_cast< int >( val1 + val2 )) >>12 ); 00715 } 00716 }; 00717 00718 private: 00719 00720 // Private variables 00721 00722 SubbandList m_band_list; 00723 00725 int m_depth; 00726 00728 WltFilter m_filt_sort; 00729 00731 VHFilter* m_vhfilter; 00732 00733 private: 00734 // Private functions 00736 WaveletTransform(const WaveletTransform& cpy); 00737 00739 WaveletTransform& operator=(const WaveletTransform& rhs); 00740 00742 float PerceptualWeight(float xf,float yf,CompSort cs); 00743 }; 00744 00745 }// end namespace dirac 00746 00747 #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.