# 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.21 2006/10/05 15:22:52 tjdwave Exp $ $Name: Dirac_0_7_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
    00350         void Transform(const Direction d, PicArray& pic_data);
    00351
    00353         SubbandList& BandList(){return m_band_list;}
    00354
    00356         const SubbandList& BandList() const {return m_band_list;}
    00357
    00359
    00369         void SetBandWeights (const float cpd,
    00370                              const FrameSort& fsort,
    00371                              const ChromaFormat& cformat,
    00372                              const CompSort csort);
    00373
    00374
    00375     private:
    00376         // Classes used within wavelet transform
    00377
    00379         class VHFilter
    00380         {
    00381
    00382         public:
    00383
    00384             VHFilter(){}
    00385
    00386             virtual ~VHFilter(){}
    00387
    00389             virtual void Split(const int xp, const int yp, const int xl, const int yl, PicArray&pic_data)=0;
    00390
    00392             virtual void Synth(const int xp, const int yp, const int xl, const int yl, PicArray& pic_data)=0;
    00393
    00395             virtual double GetLowFactor() const=0;
    00396
    00398             virtual double GetHighFactor() const =0;
    00399
    00401             virtual int GetShift() const =0;
    00402
    00403         protected:
    00404
    00406             inline void Interleave( const int xp, const int yp, const int xl, const int yl, PicArray&pic_data );
    00407
    00408
    00410             inline void DeInterleave( const int xp, const int yp, const int xl, const int yl, PicArray&pic_data );
    00411
    00413             void ShiftRowLeft(ValueType *row, int length, int shift);
    00414
    00416             void ShiftRowRight(ValueType *row, int length, int shift);
    00417         };
    00418
    00420         class VHFilterDAUB9_7 : public VHFilter
    00421         {
    00422
    00423         public:
    00424
    00426             void Split(const int xp, const int yp, const int xl, const int yl, PicArray&pic_data);
    00427
    00429             void Synth(const int xp, const int yp, const int xl, const int yl, PicArray& pic_data);
    00430
    00432             double GetLowFactor() const { return 1.149604398;}
    00433
    00435             double GetHighFactor() const { return 0.869864452;}
    00436
    00438             int GetShift() const {return 1;}
    00439
    00440
    00441         };
    00442
    00444         class VHFilterLEGALL5_3 : public VHFilter
    00445         {
    00446
    00447         public:
    00448
    00450             void Split(const int xp, const int yp, const int xl, const int yl, PicArray&pic_data);
    00451
    00453             void Synth(const int xp, const int yp, const int xl, const int yl, PicArray& pic_data);
    00454
    00456             double GetLowFactor() const { return 1.179535649;}
    00457
    00459             double GetHighFactor() const { return 0.81649658;}
    00460
    00462             int GetShift() const {return 1;}
    00463
    00464
    00465 #ifdef HAVE_MMX
    00466             inline void HorizSynth (int xp, int xl, int ystart, int yend, PicArray &pic_data);
    00467 #endif
    00468
    00469         };
    00470
    00472         class VHFilterDD9_3 : public VHFilter
    00473         {
    00474
    00475         public:
    00476
    00478             void Split(const int xp, const int yp, const int xl, const int yl, PicArray&pic_data);
    00479
    00481             void Synth(const int xp, const int yp, const int xl, const int yl, PicArray& pic_data);
    00482
    00484             double GetLowFactor() const { return 1.218660804;}
    00485
    00487             double GetHighFactor() const { return 0.780720058;}
    00488
    00490             int GetShift() const {return 1;}
    00491
    00492         };
    00493
    00494
    00496         class VHFilterDD13_5 : public VHFilter
    00497         {
    00498
    00499         public:
    00500
    00502             void Split(const int xp, const int yp, const int xl, const int yl, PicArray&pic_data);
    00503
    00505             void Synth(const int xp, const int yp, const int xl, const int yl, PicArray& pic_data);
    00506
    00508             double GetLowFactor() const { return 1.28087;}
    00509
    00511             double GetHighFactor() const { return 0.809254;}
    00512
    00514             int GetShift() const {return 1;}
    00515
    00516         };
    00517
    00519         class VHFilterHAAR0 : public VHFilter
    00520         {
    00521
    00522         public:
    00523
    00525             void Split(const int xp, const int yp, const int xl, const int yl, PicArray&pic_data);
    00526
    00528             void Synth(const int xp, const int yp, const int xl, const int yl, PicArray& pic_data);
    00529
    00531             double GetLowFactor() const { return 1.414213562;}
    00532
    00534             double GetHighFactor() const { return 0.707106781;}
    00535
    00537             int GetShift() const {return 0;}
    00538
    00539
    00540         };
    00541
    00543         class VHFilterHAAR1 : public VHFilter
    00544         {
    00545
    00546         public:
    00547
    00549             void Split(const int xp, const int yp, const int xl, const int yl, PicArray&pic_data);
    00550
    00552             void Synth(const int xp, const int yp, const int xl, const int yl, PicArray& pic_data);
    00553
    00555             double GetLowFactor() const { return 1.414213562;}
    00556
    00558             double GetHighFactor() const { return 0.707106781;}
    00559
    00561             int GetShift() const {return 1;}
    00562
    00563
    00564         };
    00565
    00566
    00568         class VHFilterHAAR2 : public VHFilter
    00569         {
    00570
    00571         public:
    00572
    00574             void Split(const int xp, const int yp, const int xl, const int yl, PicArray&pic_data);
    00575
    00577             void Synth(const int xp, const int yp, const int xl, const int yl, PicArray& pic_data);
    00578
    00580             double GetLowFactor() const { return 1.414213562;}
    00581
    00583             double GetHighFactor() const { return 0.707106781;}
    00584
    00586             int GetShift() const {return 2;}
    00587
    00588         };
    00589
    00590
    00591
    00592         // Lifting steps used in the filters
    00593
    00595         template<int shift>
    00596         class PredictStepShift
    00597         {
    00598
    00599         public:
    00600
    00602             PredictStepShift(){}
    00603
    00604             // Assume default copy constructor, assignment= and destructor //
    00605
    00607             /*
    00608                 Do the filtering.
    00609                 \param   in_val   the value being predicted
    00610                 \param   val1   the first value being used for prediction
    00611                 \param   val2   the second value being used for prediction
    00612             */
    00613             inline void Filter(ValueType& in_val, const ValueType& val1, const ValueType& val2) const
    00614             {
    00615                 in_val -= (( val1 + val2 + (1<<(shift-1)) ) >>shift );
    00616             }
    00617
    00618         };
    00619
    00621         template<int shift>
    00622         class UpdateStepShift
    00623         {
    00624
    00625         public:
    00627             UpdateStepShift(){}
    00628
    00630             /*
    00631                 Do the filtering.
    00632                 \param   in_val   the value being updated
    00633                 \param   val1   the first value being used for updating
    00634                 \param   val2   the second value being used for updating
    00635             */
    00636             inline void Filter(ValueType& in_val, const ValueType& val1, const ValueType& val2) const
    00637             {
    00638                 in_val += ( ( val1 + val2 + (1<<(shift-1)) ) >>shift );
    00639             }
    00640
    00641         };
    00642
    00644         template <int shift , int tap1, int tap2>
    00645         class PredictStepFourTap
    00646         {
    00647         public:
    00648
    00650             PredictStepFourTap(){}
    00651
    00652             // Assume default copy constructor, assignment= and destructor //
    00653
    00655             inline void Filter(ValueType& in_val, const ValueType& val1, const ValueType& val2 ,
    00656                                                   const ValueType& val3, const ValueType& val4 ) const
    00657             {
    00658                 in_val -= ( tap1*( val1 + val2 ) + tap2*( val3 + val4 ) + (1<<(shift-1)))>>shift;
    00659             }
    00660         };
    00661
    00663         template <int shift , int tap1 , int tap2>
    00664         class UpdateStepFourTap
    00665         {
    00666
    00667         public:
    00669             UpdateStepFourTap(){}
    00670
    00672             inline void Filter(ValueType& in_val, const ValueType& val1, const ValueType& val2 ,
    00673                                                   const ValueType& val3, const ValueType& val4 ) const
    00674             {
    00675                 in_val += ( tap1*( val1 + val2 ) + tap2*( val3 + val4 ) + (1<<(shift-1)) )>>shift;
    00676             }
    00677         };
    00678
    00680         template <int gain> class PredictStep97
    00681         {
    00682         public:
    00683
    00685             PredictStep97(){}
    00686
    00687             // Assume default copy constructor, assignment= and destructor //
    00688
    00690             /*
    00691                 Do the filtering.
    00692                 \param   in_val   the value being predicted
    00693                 \param   val1   the first value being used for prediction
    00694                 \param   val2   the second value being used for prediction
    00695             */
    00696             inline void Filter(ValueType& in_val, const ValueType& val1, const ValueType& val2) const
    00697             {
    00698                 in_val -= static_cast< ValueType >( (gain * static_cast< int >( val1 + val2 )) >>12 );
    00699             }
    00700         };
    00701
    00703         template <int gain> class UpdateStep97
    00704         {
    00705
    00706         public:
    00708             UpdateStep97(){}
    00709
    00711             /*
    00712                 Do the filtering.
    00713                 \param   in_val   the value being updated
    00714                 \param   val1   the first value being used for updating
    00715                 \param   val2   the second value being used for updating
    00716             */
    00717             inline void Filter(ValueType& in_val, const ValueType& val1, const ValueType& val2) const
    00718             {
    00719                 in_val += static_cast< ValueType >( (gain * static_cast< int >( val1 + val2 )) >>12 );
    00720             }
    00721         };
    00722
    00723     private:
    00724
    00725         // Private variables
    00726
    00727         SubbandList m_band_list;
    00728
    00730         int m_depth;
    00731
    00733         WltFilter m_filt_sort;
    00734
    00736         VHFilter* m_vhfilter;
    00737
    00738     private:
    00739         // Private functions
    00741         WaveletTransform(const WaveletTransform& cpy);
    00742
    00744         WaveletTransform& operator=(const WaveletTransform& rhs);
    00745
    00747         float PerceptualWeight(float xf,float yf,CompSort cs);
    00748    };
    00749
    00750 }// end namespace dirac
    00751
    00752 #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.