Dirac - A Video Codec

Created by the British Broadcasting Corporation.


wavelet_utils.h

Go to the documentation of this file.
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.