# 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.19 2006/06/05 14:54:42 asuraparaju Exp $ $Name: Dirac_0_6_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), Scott R Ladd
    00024 *
    00025 * Alternatively, the contents of this file may be used under the terms of
    00026 * the GNU General Public License Version 2 (the "GPL"), or the GNU Lesser
    00027 * Public License Version 2.1 (the "LGPL"), in which case the provisions of
    00028 * the GPL or the LGPL are applicable instead of those above. If you wish to
    00029 * allow use of your version of this file only under the terms of the either
    00030 * the GPL or LGPL and not to allow others to use your version of this file
    00031 * under the MPL, indicate your decision by deleting the provisions above
    00032 * and replace them with the notice and other provisions required by the GPL
    00033 * or LGPL. If you do not delete the provisions above, a recipient may use
    00034 * your version of this file under the terms of any one of the MPL, the GPL
    00035 * or the LGPL.
    00036 * ***** END LICENSE BLOCK ***** */
    00037
    00038 #ifndef _WAVELET_UTILS_H_
    00039 #define _WAVELET_UTILS_H_
    00040
    00041 #include <libdirac_common/arrays.h>
    00042 #include <libdirac_common/common.h>
    00043 #include <vector>
    00044 #include <cmath>
    00045 #include <iostream>
    00046
    00047 //utilities for subband and wavelet transforms
    00048 //Includes fast transform using lifting
    00049
    00050 namespace dirac
    00051 {
    00052
    00053     class PicArray;
    00054     class Subband;
    00055
    00057     class CodeBlock
    00058     {
    00059
    00060     friend class Subband;
    00061
    00062     public:
    00064         /*
    00065             Default constructor - sets all dimensions to zero
    00066         */
    00067         CodeBlock();
    00068
    00070         /*
    00071             Initialise the code block
    00072             \param    xstart  the x-coord of the first coefficient in the block
    00073             \param    xend    one past the last coefficient, horizontally
    00074             \param    ystart  the y-coord of the first coefficient in the block
    00075             \param    yend    one past the last coefficient, vertically
    00076         */
    00077         CodeBlock( const int xstart , const int ystart , const int xend , const int yend);
    00078
    00080         int Xstart() const { return m_xstart; }
    00081
    00083         int Ystart() const { return m_ystart; }
    00084
    00086         int Xend() const { return m_xend; }
    00087
    00089         int Yend() const { return m_yend; }
    00090
    00092         int Xl() const { return m_xl; }
    00093
    00095         int Yl() const { return m_yl; }
    00096
    00098         int QIndex() const{ return m_qindex; }
    00099
    00101         float Wt() const { return m_wt; }
    00102
    00104         bool Skipped() const { return m_skipped; }
    00105
    00107         void SetQIndex( const int qindex ){ m_qindex = qindex; }
    00108
    00110         void SetSkip( bool skip ){ m_skipped = skip; }
    00111
    00112     private:
    00113
    00115         /*
    00116             Initialise the code block
    00117             \param    xstart  the x-coord of the first coefficient in the block
    00118             \param    xend    one past the last coefficient, horizontally
    00119             \param    ystart  the y-coord of the first coefficient in the block
    00120             \param    yend    one past the last coefficient, vertically
    00121         */
    00122         void Init( const int xstart , const int ystart , const int xend , const int yend );
    00123
    00125         void SetWt( const float w ){ m_wt = w; }
    00126
    00127
    00128     private:
    00129
    00130         int m_xstart;
    00131         int m_ystart;
    00132         int m_xend;
    00133         int m_yend;
    00134         int m_xl;
    00135         int m_yl;
    00136
    00137         int m_qindex;
    00138         float m_wt;
    00139
    00140         bool m_skipped;
    00141     };
    00142
    00143
    00145     class Subband
    00146     {
    00147     public:
    00148
    00150         Subband();
    00151
    00153
    00161         Subband(int xpos, int ypos, int xlen, int ylen);
    00162
    00164
    00173         Subband(int xpos, int ypos, int xlen, int ylen, int d);
    00174
    00176         ~Subband();
    00177
    00178         //Default (shallow) copy constructor and operator= used
    00179
    00181         int Xl() const {return m_xl;}
    00182
    00184         int Xp() const {return m_xp;}
    00185
    00187         int Yl() const {return m_yl;}
    00188
    00190         int Yp() const {return m_yp;}
    00191
    00193         int Max() const {return m_max_bit;}
    00194
    00196         double Wt() const {return m_wt;}
    00197
    00199         int Depth() const {return m_depth;}
    00200
    00202         int Scale() const {return ( 1<<m_depth );}
    00203
    00205         int QIndex() const {return m_qindex;}
    00206
    00208         bool UsingMultiQuants() const {return m_multi_quants; }
    00209
    00211         int Parent() const {return m_parent;}
    00212
    00214         const std::vector<int>& Children() const {return m_children;}
    00215
    00217         int Child(const int n) const {return m_children[n];}
    00218
    00220         TwoDArray<CodeBlock>& GetCodeBlocks(){ return m_code_block_array; }
    00221
    00223         const TwoDArray<CodeBlock>& GetCodeBlocks() const { return m_code_block_array; }
    00224
    00226         bool Skipped() const { return m_skipped; }
    00227
    00229         void SetWt( const float w );
    00230
    00232         void SetParent( const int p ){ m_parent=p; }
    00233
    00235         void SetDepth( const int d ){ m_depth=d;}
    00236
    00238         void SetMax( const int m ){ m_max_bit=m; };
    00239
    00241         void SetChildren( const std::vector<int>& clist ){ m_children = clist; }
    00242
    00244         void AddChild( const int c ){ m_children.push_back(c); }
    00245
    00247         void SetNumBlocks( const int ynum , const int xnum );
    00248
    00250         void SetQIndex( const int idx){ m_qindex = idx; }
    00251
    00253         void SetUsingMultiQuants( const bool multi){ m_multi_quants = multi; }
    00254
    00256         void SetSkip(const bool skip ){ m_skipped = skip; }
    00257
    00258     private:
    00259         // subband bounds
    00260         int m_xp , m_yp , m_xl , m_yl;
    00261
    00262         // perceptual weight for quantisation
    00263         double m_wt;
    00264
    00265         // depth in the transform
    00266         int m_depth;
    00267
    00268         // quantiser index
    00269         int m_qindex;
    00270
    00271         // position of parent in a subband list
    00272         int m_parent;
    00273
    00274         // positions of children in the subband list
    00275         std::vector<int> m_children;
    00276
    00277         // position of the MSB of the largest absolute value
    00278         int m_max_bit;
    00279
    00280         // The code blocks
    00281         TwoDArray<CodeBlock> m_code_block_array;
    00282
    00283         // A flag indicating whether we're using one qf for each code block
    00284         bool m_multi_quants;
    00285
    00286         // Whether the subband is skipped or not
    00287         bool m_skipped;
    00288     };
    00289
    00291     class SubbandList
    00292     {
    00293     public:
    00295         SubbandList(){}
    00296
    00298         ~SubbandList(){}
    00299
    00300         //Default (shallow) copy constructor and operator= used
    00302         void Init(const int depth,const int xlen,const int ylen);
    00303
    00305         int Length() const {return bands.size();}
    00306
    00308         Subband& operator()(const int n){return bands[n-1];}
    00309
    00311         const Subband& operator()(const int n) const {return bands[n-1];}
    00312
    00314         void AddBand(const Subband& b){bands.push_back(b);}
    00315
    00317         void Clear(){bands.clear();}
    00318
    00319     private:
    00320
    00322         float PerceptualWeight( const float xf , const float yf , const CompSort cs);
    00323
    00324     private:
    00325         std::vector<Subband> bands;
    00326     };
    00327
    00329
    00333     class WaveletTransform
    00334     {
    00335     public:
    00337         WaveletTransform(int d = 4, WltFilter f = DAUB97);
    00338
    00340         virtual ~WaveletTransform();
    00341
    00343
    00348         void Transform(const Direction d, PicArray& pic_data);
    00349
    00351         SubbandList& BandList(){return m_band_list;}
    00352
    00354         const SubbandList& BandList() const {return m_band_list;}
    00355
    00357
    00367         void SetBandWeights (const float cpd,
    00368                              const FrameSort& fsort,
    00369                              const ChromaFormat& cformat,
    00370                              const CompSort csort);
    00371
    00373         ValueType GetMeanDCVal() const;
    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
    00400         protected:
    00401
    00403             inline void Interleave( const int xp, const int yp, const int xl, const int yl, PicArray&pic_data );
    00404
    00405
    00407             inline void DeInterleave( const int xp, const int yp, const int xl, const int yl, PicArray&pic_data );
    00408
    00410             void ShiftRowLeft(ValueType *row, int length, int shift);
    00411
    00413             void ShiftRowRight(ValueType *row, int length, int shift);
    00414         };
    00415
    00417         class VHFilterDaub9_7 : public VHFilter
    00418         {
    00419
    00420         public:
    00421
    00423             void Split(const int xp, const int yp, const int xl, const int yl, PicArray&pic_data);
    00424
    00426             void Synth(const int xp, const int yp, const int xl, const int yl, PicArray& pic_data);
    00427
    00429             double GetLowFactor() const { return 1.149604398;}
    00430
    00432             double GetHighFactor() const { return 0.869864452;}
    00433
    00434         };
    00435
    00437         class VHFilter5_3 : public VHFilter
    00438         {
    00439
    00440         public:
    00441
    00443             void Split(const int xp, const int yp, const int xl, const int yl, PicArray&pic_data);
    00444
    00446             void Synth(const int xp, const int yp, const int xl, const int yl, PicArray& pic_data);
    00447
    00449             double GetLowFactor() const { return 1.179535649;}
    00450
    00452             double GetHighFactor() const { return 0.81649658;}
    00453
    00454 #ifdef HAVE_MMX
    00455             inline void HorizSynth (int xp, int xl, int ystart, int yend, PicArray &pic_data);
    00456 #endif
    00457
    00458         };
    00459
    00461         class VHFilterApprox9_7 : public VHFilter
    00462         {
    00463
    00464         public:
    00465
    00467             void Split(const int xp, const int yp, const int xl, const int yl, PicArray&pic_data);
    00468
    00470             void Synth(const int xp, const int yp, const int xl, const int yl, PicArray& pic_data);
    00471
    00473             double GetLowFactor() const { return 1.218660804;}
    00474
    00476             double GetHighFactor() const { return 0.780720058;}
    00477
    00478         };
    00479
    00480
    00482         class VHFilter13_5 : public VHFilter
    00483         {
    00484
    00485         public:
    00486
    00488             void Split(const int xp, const int yp, const int xl, const int yl, PicArray&pic_data);
    00489
    00491             void Synth(const int xp, const int yp, const int xl, const int yl, PicArray& pic_data);
    00492
    00494             double GetLowFactor() const { return 1.28087;}
    00495
    00497             double GetHighFactor() const { return 0.809254;}
    00498         };
    00499
    00500
    00501         // Lifting steps used in the filters
    00502
    00504         template<int shift>
    00505         class PredictStepShift
    00506         {
    00507
    00508         public:
    00509
    00511             PredictStepShift(){}
    00512
    00513             // Assume default copy constructor, assignment= and destructor //
    00514
    00516             /*
    00517                 Do the filtering.
    00518                 \param   in_val   the value being predicted
    00519                 \param   val1   the first value being used for prediction
    00520                 \param   val2   the second value being used for prediction
    00521             */
    00522             inline void Filter(ValueType& in_val, const ValueType& val1, const ValueType& val2) const
    00523             {
    00524 //                in_val -= (( val1 + val2 ) >>shift );
    00525                 in_val -= (( val1 + val2 + (1<<(shift-1)) ) >>shift );
    00526             }
    00527
    00528         };
    00529
    00531         template<int shift>
    00532         class UpdateStepShift
    00533         {
    00534
    00535         public:
    00537             UpdateStepShift(){}
    00538
    00540             /*
    00541                 Do the filtering.
    00542                 \param   in_val   the value being updated
    00543                 \param   val1   the first value being used for updating
    00544                 \param   val2   the second value being used for updating
    00545             */
    00546             inline void Filter(ValueType& in_val, const ValueType& val1, const ValueType& val2) const
    00547             {
    00548                 in_val += ( ( val1 + val2 + (1<<(shift-1)) ) >>shift );
    00549             }
    00550
    00551         };
    00552
    00554         template <int shift , int tap1, int tap2>
    00555         class PredictStepFourTap
    00556         {
    00557         public:
    00558
    00560             PredictStepFourTap(){}
    00561
    00562             // Assume default copy constructor, assignment= and destructor //
    00563
    00565             inline void Filter(ValueType& in_val, const ValueType& val1, const ValueType& val2 ,
    00566                                                   const ValueType& val3, const ValueType& val4 ) const
    00567             {
    00568                 in_val -= ( tap1*( val1 + val2 ) + tap2*( val3 + val4 ) + (1<<(shift-1)))>>shift;
    00569             }
    00570         };
    00571
    00573         template <int shift , int tap1 , int tap2>
    00574         class UpdateStepFourTap
    00575         {
    00576
    00577         public:
    00579             UpdateStepFourTap(){}
    00580
    00582             inline void Filter(ValueType& in_val, const ValueType& val1, const ValueType& val2 ,
    00583                                                   const ValueType& val3, const ValueType& val4 ) const
    00584             {
    00585                 in_val += ( tap1*( val1 + val2 ) + tap2*( val3 + val4 ) + (1<<(shift-1)) )>>shift;
    00586             }
    00587         };
    00588
    00590         template <int gain> class PredictStep97
    00591         {
    00592         public:
    00593
    00595             PredictStep97(){}
    00596
    00597             // Assume default copy constructor, assignment= and destructor //
    00598
    00600             /*
    00601                 Do the filtering.
    00602                 \param   in_val   the value being predicted
    00603                 \param   val1   the first value being used for prediction
    00604                 \param   val2   the second value being used for prediction
    00605             */
    00606             inline void Filter(ValueType& in_val, const ValueType& val1, const ValueType& val2) const
    00607             {
    00608                 in_val -= static_cast< ValueType >( (gain * static_cast< int >( val1 + val2 )) >>12 );
    00609             }
    00610         };
    00611
    00613         template <int gain> class UpdateStep97
    00614         {
    00615
    00616         public:
    00618             UpdateStep97(){}
    00619
    00621             /*
    00622                 Do the filtering.
    00623                 \param   in_val   the value being updated
    00624                 \param   val1   the first value being used for updating
    00625                 \param   val2   the second value being used for updating
    00626             */
    00627             inline void Filter(ValueType& in_val, const ValueType& val1, const ValueType& val2) const
    00628             {
    00629                 in_val += static_cast< ValueType >( (gain * static_cast< int >( val1 + val2 )) >>12 );
    00630             }
    00631         };
    00632
    00633     private:
    00634
    00635         // Private variables
    00636
    00637         SubbandList m_band_list;
    00638
    00640         int m_depth;
    00641
    00643         WltFilter m_filt_sort;
    00644
    00646         VHFilter* m_vhfilter;
    00647
    00648     private:
    00649         // Private functions
    00651         WaveletTransform(const WaveletTransform& cpy);
    00652
    00654         WaveletTransform& operator=(const WaveletTransform& rhs);
    00655
    00657         float PerceptualWeight(float xf,float yf,CompSort cs);
    00658    };
    00659
    00660 }// end namespace dirac
    00661
    00662 #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.