# 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.32 2008/10/20 04:21:02 asuraparaju Exp $ $Name: Dirac_1_0_2 $
    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 QuantIndex() const{ return m_quantindex; }
    00101
    00103         bool Skipped() const { return m_skipped; }
    00104
    00106         void SetQuantIndex( const int quantindex ){ m_quantindex = quantindex; }
    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_quantindex;
    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 QuantIndex() 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 SetNumBlocks( const int ynum , const int xnum );
    00236
    00238         void SetQuantIndex( const int idx){ m_qindex = idx; }
    00239
    00241         void SetUsingMultiQuants( const bool multi){ m_multi_quants = multi; }
    00242
    00244         void SetSkip(const bool skip ){ m_skipped = skip; }
    00245
    00246     private:
    00247         // subband bounds
    00248         int m_xp , m_yp , m_xl , m_yl;
    00249
    00250         // perceptual weight for quantisation
    00251         double m_wt;
    00252
    00253         // depth in the transform
    00254         int m_depth;
    00255
    00256         // quantiser index
    00257         int m_qindex;
    00258
    00259         // position of parent in a subband list
    00260         int m_parent;
    00261
    00262         // positions of children in the subband list
    00263         std::vector<int> m_children;
    00264
    00265         // position of the MSB of the largest absolute value
    00266         int m_max_bit;
    00267
    00268         // The code blocks
    00269         TwoDArray<CodeBlock> m_code_block_array;
    00270
    00271         // A flag indicating whether we're using one qf for each code block
    00272         bool m_multi_quants;
    00273
    00274         // Whether the subband is skipped or not
    00275         bool m_skipped;
    00276     };
    00277
    00279     class SubbandList
    00280     {
    00281     public:
    00283         SubbandList(){}
    00284
    00286         ~SubbandList(){}
    00287
    00288         //Default (shallow) copy constructor and operator= used
    00290         void Init(const int depth,const int xlen,const int ylen);
    00291
    00293         int Length() const {return bands.size();}
    00294
    00296         Subband& operator()(const int n){return bands[n-1];}
    00297
    00299         const Subband& operator()(const int n) const {return bands[n-1];}
    00300
    00302         void AddBand(const Subband& b){bands.push_back(b);}
    00303
    00305         void Clear(){bands.clear();}
    00306
    00307     private:
    00308
    00310         float PerceptualWeight( const float xf , const float yf , const CompSort cs);
    00311
    00312     private:
    00313         std::vector<Subband> bands;
    00314     };
    00315
    00316     class CoeffArray;
    00318         class VHFilter
    00319         {
    00320
    00321         public:
    00322
    00323             VHFilter(){}
    00324
    00325             virtual ~VHFilter(){}
    00326
    00328             virtual void Split(const int xp, const int yp, const int xl, const int yl, CoeffArray& coeff_data)=0;
    00329
    00331             virtual void Synth(const int xp, const int yp, const int xl, const int yl, CoeffArray& coeff_data)=0;
    00332
    00334             virtual int GetShift() const =0;
    00335
    00336         protected:
    00337
    00339             inline void Interleave( const int xp, const int yp, const int xl, const int yl, CoeffArray& coeff_data );
    00340
    00341
    00343             inline void DeInterleave( const int xp, const int yp, const int xl, const int yl, CoeffArray& coeff_data );
    00344
    00346             void ShiftRowLeft(CoeffType *row, int length, int shift);
    00347
    00349             void ShiftRowRight(CoeffType *row, int length, int shift);
    00350         };
    00351
    00353         class VHFilterDAUB9_7 : public VHFilter
    00354         {
    00355
    00356         public:
    00357
    00359             void Split(const int xp, const int yp, const int xl, const int yl, CoeffArray& coeff_data);
    00360
    00362             void Synth(const int xp, const int yp, const int xl, const int yl, CoeffArray& coeff_data);
    00363
    00365             int GetShift() const {return 1;}
    00366
    00367
    00368         };
    00369
    00371         class VHFilterLEGALL5_3 : public VHFilter
    00372         {
    00373
    00374         public:
    00375
    00377             void Split(const int xp, const int yp, const int xl, const int yl, CoeffArray& coeff_data);
    00378
    00380             void Synth(const int xp, const int yp, const int xl, const int yl, CoeffArray& coeff_data);
    00381
    00383             int GetShift() const {return 1;}
    00384
    00385
    00386 #ifdef HAVE_MMX
    00387             inline void HorizSynth (int xp, int xl, int ystart, int yend, CoeffArray &coeff_data);
    00388 #endif
    00389
    00390         };
    00391
    00393         class VHFilterDD9_7 : public VHFilter
    00394         {
    00395
    00396         public:
    00397
    00399             void Split(const int xp, const int yp, const int xl, const int yl, CoeffArray& coeff_data);
    00400
    00402             void Synth(const int xp, const int yp, const int xl, const int yl, CoeffArray& coeff_data);
    00403
    00405             int GetShift() const {return 1;}
    00406         };
    00407
    00408
    00410         class VHFilterDD13_7 : public VHFilter
    00411         {
    00412
    00413         public:
    00414
    00416             void Split(const int xp, const int yp, const int xl, const int yl, CoeffArray& coeff_data);
    00417
    00419             void Synth(const int xp, const int yp, const int xl, const int yl, CoeffArray& coeff_data);
    00420
    00422             int GetShift() const {return 1;}
    00423
    00424         };
    00425
    00427         class VHFilterHAAR0 : public VHFilter
    00428         {
    00429
    00430         public:
    00431
    00433             void Split(const int xp, const int yp, const int xl, const int yl, CoeffArray& coeff_data);
    00434
    00436             void Synth(const int xp, const int yp, const int xl, const int yl, CoeffArray& coeff_data);
    00437
    00439             int GetShift() const {return 0;}
    00440
    00441
    00442         };
    00443
    00445         class VHFilterHAAR1 : public VHFilter
    00446         {
    00447
    00448         public:
    00449
    00451             void Split(const int xp, const int yp, const int xl, const int yl, CoeffArray& coeff_data);
    00452
    00454             void Synth(const int xp, const int yp, const int xl, const int yl, CoeffArray& coeff_data);
    00455
    00457             int GetShift() const {return 1;}
    00458
    00459         };
    00460
    00461
    00463         class VHFilterHAAR2 : public VHFilter
    00464         {
    00465
    00466         public:
    00467
    00469             void Split(const int xp, const int yp, const int xl, const int yl, CoeffArray& coeff_data);
    00470
    00472             void Synth(const int xp, const int yp, const int xl, const int yl, CoeffArray& coeff_data);
    00473
    00475             double GetLowFactor() const { return 1.414213562;}
    00476
    00478             double GetHighFactor() const { return 0.707106781;}
    00479
    00481             int GetShift() const {return 2;}
    00482
    00483         };
    00484
    00485
    00486
    00487         // Lifting steps used in the filters
    00488
    00490         template<int shift>
    00491         class PredictStepShift
    00492         {
    00493
    00494         public:
    00495
    00497             PredictStepShift(){}
    00498
    00499             // Assume default copy constructor, assignment= and destructor //
    00500
    00502             /*
    00503                 Do the filtering.
    00504                 \param   in_val   the value being predicted
    00505                 \param   val1   the first value being used for prediction
    00506                 \param   val2   the second value being used for prediction
    00507             */
    00508             inline void Filter(CoeffType& in_val, const CoeffType& val1, const CoeffType& val2) const
    00509             {
    00510                 in_val -= (( val1 + val2 + (1<<(shift-1)) ) >>shift );
    00511             }
    00512
    00513         };
    00514
    00516         template<int shift>
    00517         class UpdateStepShift
    00518         {
    00519
    00520         public:
    00522             UpdateStepShift(){}
    00523
    00525             /*
    00526                 Do the filtering.
    00527                 \param   in_val   the value being updated
    00528                 \param   val1   the first value being used for updating
    00529                 \param   val2   the second value being used for updating
    00530             */
    00531             inline void Filter(CoeffType& in_val, const CoeffType& val1, const CoeffType& val2) const
    00532             {
    00533                 in_val += ( ( val1 + val2 + (1<<(shift-1)) ) >>shift );
    00534             }
    00535
    00536         };
    00537
    00539         template <int shift , int tap1, int tap2>
    00540         class PredictStepFourTap
    00541         {
    00542         public:
    00543
    00545             PredictStepFourTap(){}
    00546
    00547             // Assume default copy constructor, assignment= and destructor //
    00548
    00550             inline void Filter(CoeffType& in_val, const CoeffType& val1, const CoeffType& val2 ,
    00551                                                   const CoeffType& val3, const CoeffType& val4 ) const
    00552             {
    00553                 in_val -= ( tap1*( val1 + val2 ) + tap2*( val3 + val4 ) + (1<<(shift-1)))>>shift;
    00554             }
    00555         };
    00556
    00558         template <int shift , int tap1 , int tap2>
    00559         class UpdateStepFourTap
    00560         {
    00561
    00562         public:
    00564             UpdateStepFourTap(){}
    00565
    00567             inline void Filter(CoeffType& in_val, const CoeffType& val1, const CoeffType& val2 ,
    00568                                                   const CoeffType& val3, const CoeffType& val4 ) const
    00569             {
    00570                 in_val += ( tap1*( val1 + val2 ) + tap2*( val3 + val4 ) + (1<<(shift-1)) )>>shift;
    00571             }
    00572         };
    00573
    00575         template <int gain> class PredictStep97
    00576         {
    00577         public:
    00578
    00580             PredictStep97(){}
    00581
    00582             // Assume default copy constructor, assignment= and destructor //
    00583
    00585             /*
    00586                 Do the filtering.
    00587                 \param   in_val   the value being predicted
    00588                 \param   val1   the first value being used for prediction
    00589                 \param   val2   the second value being used for prediction
    00590             */
    00591             inline void Filter(CoeffType& in_val, const CoeffType& val1, const CoeffType& val2) const
    00592             {
    00593                 in_val -= static_cast< CoeffType >( (gain * static_cast< int >( val1 + val2 )) >>12 );
    00594             }
    00595         };
    00596
    00598         template <int gain> class UpdateStep97
    00599         {
    00600
    00601         public:
    00603             UpdateStep97(){}
    00604
    00606             /*
    00607                 Do the filtering.
    00608                 \param   in_val   the value being updated
    00609                 \param   val1   the first value being used for updating
    00610                 \param   val2   the second value being used for updating
    00611             */
    00612             inline void Filter(CoeffType& in_val, const CoeffType& val1, const CoeffType& val2) const
    00613             {
    00614                 in_val += static_cast< CoeffType >( (gain * static_cast< int >( val1 + val2 )) >>12 );
    00615             }
    00616         };
    00617
    00619
    00622     class CoeffArray: public TwoDArray<CoeffType>
    00623     {
    00624     public:
    00626
    00629         CoeffArray(): TwoDArray<CoeffType>(){}
    00630
    00632
    00636         CoeffArray(int height, int width, CompSort cs=Y_COMP):
    00637             TwoDArray<CoeffType>(height, width), m_csort(cs){}
    00638
    00639         //copy constructor and assignment= derived by inheritance
    00640
    00642         ~CoeffArray(){}
    00643
    00645         const CompSort& CSort() const {return m_csort;}
    00646
    00648         void SetCSort(const CompSort cs){ m_csort = cs; }
    00649
    00651         SubbandList& BandList(){return m_band_list;}
    00652
    00654         const SubbandList& BandList() const {return m_band_list;}
    00655
    00657
    00662         void SetBandWeights (const EncoderParams& encparams,
    00663                                  const PictureParams& pparams,
    00664                                  const CompSort csort,
    00665                  const float cpd_scale_factor);
    00666
    00667         private:
    00668
    00669         CompSort m_csort;
    00670
    00671         // The subband list to be used for conventional transform apps
    00672         SubbandList m_band_list;
    00673
    00674         private:
    00675
    00677         float PerceptualWeight(float xf,float yf,CompSort cs);
    00678
    00679     };
    00680
    00682
    00686     class WaveletTransform
    00687     {
    00688     public:
    00690         WaveletTransform(int d = 4, WltFilter f = DAUB9_7);
    00691
    00693         virtual ~WaveletTransform();
    00694
    00696
    00702         void Transform(const Direction d, PicArray& pic_data, CoeffArray& coeff_data);
    00703
    00704     private:
    00705
    00706
    00707     private:
    00708
    00709         // Private variables
    00710
    00712         int m_depth;
    00713
    00715         WltFilter m_filt_sort;
    00716
    00718         VHFilter* m_vhfilter;
    00719
    00720     private:
    00721         // Private functions
    00723         WaveletTransform(const WaveletTransform& cpy);
    00724
    00726         WaveletTransform& operator=(const WaveletTransform& rhs);
    00727
    00728    };
    00729 }// end namespace dirac
    00730
    00731 #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.