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.16 2005/05/04 13:35:02 tjdwave Exp $ $Name: Dirac_0_5_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), 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         };
00409 
00411         class VHFilterDaub9_7 : public VHFilter
00412         {
00413 
00414         public:
00415 
00417             void Split(const int xp, const int yp, const int xl, const int yl, PicArray&pic_data); 
00418 
00420             void Synth(const int xp, const int yp, const int xl, const int yl, PicArray& pic_data);
00421 
00423             double GetLowFactor() const { return 1.149604398;}
00424 
00426             double GetHighFactor() const { return 0.869864452;}
00427 
00428         };
00429 
00431         class VHFilter5_3 : public VHFilter
00432         {
00433 
00434         public:
00435 
00437             void Split(const int xp, const int yp, const int xl, const int yl, PicArray&pic_data); 
00438 
00440             void Synth(const int xp, const int yp, const int xl, const int yl, PicArray& pic_data);
00441 
00443             double GetLowFactor() const { return 1.179535649;}    
00444 
00446             double GetHighFactor() const { return 0.81649658;}
00447 
00448         };
00449 
00451         class VHFilterApprox9_7 : public VHFilter
00452         {
00453 
00454         public:
00455 
00457             void Split(const int xp, const int yp, const int xl, const int yl, PicArray&pic_data); 
00458 
00460             void Synth(const int xp, const int yp, const int xl, const int yl, PicArray& pic_data);
00461 
00463             double GetLowFactor() const { return 1.218660804;}
00464 
00466             double GetHighFactor() const { return 0.780720058;}
00467 
00468         };
00469 
00470 
00472         class VHFilter13_5 : 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.28087;}
00485 
00487             double GetHighFactor() const { return 0.809254;}
00488         };
00489 
00490 
00491         // Lifting steps used in the filters
00492 
00494         template<int shift>
00495         class PredictStepShift
00496         {
00497 
00498         public:
00499 
00501             PredictStepShift(){}
00502 
00503             // Assume default copy constructor, assignment= and destructor //
00504 
00506             /*
00507                 Do the filtering.
00508                 \param   in_val   the value being predicted
00509                 \param   val1   the first value being used for prediction
00510                 \param   val2   the second value being used for prediction
00511             */
00512             inline void Filter(ValueType& in_val, const ValueType& val1, const ValueType& val2) const
00513             {
00514                 in_val -= (( val1 + val2 ) >>shift );
00515             }
00516 
00517         };
00518 
00520         template<int shift>
00521         class UpdateStepShift
00522         {
00523 
00524         public:
00526             UpdateStepShift(){}
00527 
00529             /*
00530                 Do the filtering.
00531                 \param   in_val   the value being updated
00532                 \param   val1   the first value being used for updating
00533                 \param   val2   the second value being used for updating
00534             */
00535             inline void Filter(ValueType& in_val, const ValueType& val1, const ValueType& val2) const
00536             {
00537                 in_val += ( ( val1 + val2 ) >>shift );
00538             }
00539 
00540         };  
00541 
00543         template <int shift , int tap1, int tap2>
00544         class PredictStepFourTap
00545         {
00546         public:
00547 
00549             PredictStepFourTap(){}
00550 
00551             // Assume default copy constructor, assignment= and destructor //
00552 
00554             inline void Filter(ValueType& in_val, const ValueType& val1, const ValueType& val2 ,
00555                                                   const ValueType& val3, const ValueType& val4 ) const
00556             {
00557                 in_val -= ( tap1*( val1 + val2 ) + tap2*( val3 + val4 ) )>>shift;
00558             }
00559         }; 
00560 
00562         template <int shift , int tap1 , int tap2>
00563         class UpdateStepFourTap
00564         {
00565  
00566         public:
00568             UpdateStepFourTap(){}
00569 
00571             inline void Filter(ValueType& in_val, const ValueType& val1, const ValueType& val2 ,
00572                                                   const ValueType& val3, const ValueType& val4 ) const
00573             {
00574                 in_val += ( tap1*( val1 + val2 ) + tap2*( val3 + val4 ) )>>shift;
00575             }
00576         };  
00577 
00579         template <int gain> class PredictStep97
00580         {
00581         public:
00582 
00584             PredictStep97(){}
00585 
00586             // Assume default copy constructor, assignment= and destructor //
00587 
00589             /*
00590                 Do the filtering.
00591                 \param   in_val   the value being predicted
00592                 \param   val1   the first value being used for prediction
00593                 \param   val2   the second value being used for prediction
00594             */
00595             inline void Filter(ValueType& in_val, const ValueType& val1, const ValueType& val2) const
00596             {
00597                 in_val -= static_cast< ValueType >( (gain * static_cast< int >( val1 + val2 )) >>12 );
00598             }
00599         }; 
00600 
00602         template <int gain> class UpdateStep97
00603         {
00604  
00605         public:
00607             UpdateStep97(){}
00608 
00610             /*
00611                 Do the filtering.
00612                 \param   in_val   the value being updated
00613                 \param   val1   the first value being used for updating
00614                 \param   val2   the second value being used for updating
00615             */
00616             inline void Filter(ValueType& in_val, const ValueType& val1, const ValueType& val2) const
00617             {
00618                 in_val += static_cast< ValueType >( (gain * static_cast< int >( val1 + val2 )) >>12 );
00619             }
00620         };  
00621 
00622     private:
00623 
00624         // Private variables    
00625 
00626         SubbandList m_band_list;
00627 
00629         int m_depth;
00630     
00632         WltFilter m_filt_sort; 
00633 
00635         VHFilter* m_vhfilter;
00636 
00637     private:
00638         // Private functions
00640         WaveletTransform(const WaveletTransform& cpy);
00641     
00643         WaveletTransform& operator=(const WaveletTransform& rhs);
00644     
00646         float PerceptualWeight(float xf,float yf,CompSort cs);
00647    };  
00648 
00649 }// end namespace dirac
00650 
00651 #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.