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.28 2007/12/12 14:01:51 tjdwave Exp $ $Name: Dirac_0_9_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         bool Skipped() const { return m_skipped; }
00104 
00106         void SetQIndex( const int qindex ){ m_qindex = qindex; }
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_qindex;
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 QIndex() 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 SetChildren( const std::vector<int>& clist ){ m_children = clist; }
00236 
00238         void AddChild( const int c ){ m_children.push_back(c); }
00239 
00241         void SetNumBlocks( const int ynum , const int xnum );
00242 
00244         void SetQIndex( const int idx){ m_qindex = idx; }
00245 
00247         void SetUsingMultiQuants( const bool multi){ m_multi_quants = multi; }
00248 
00250         void SetSkip(const bool skip ){ m_skipped = skip; }
00251 
00252     private:
00253         // subband bounds
00254         int m_xp , m_yp , m_xl , m_yl;
00255 
00256         // perceptual weight for quantisation
00257         double m_wt;
00258 
00259         // depth in the transform
00260         int m_depth;
00261 
00262         // quantiser index
00263         int m_qindex;
00264 
00265         // position of parent in a subband list
00266         int m_parent;
00267 
00268         // positions of children in the subband list
00269         std::vector<int> m_children;
00270 
00271         // position of the MSB of the largest absolute value
00272         int m_max_bit;
00273 
00274         // The code blocks
00275         TwoDArray<CodeBlock> m_code_block_array;
00276 
00277         // A flag indicating whether we're using one qf for each code block
00278         bool m_multi_quants;
00279 
00280         // Whether the subband is skipped or not
00281         bool m_skipped;
00282     };
00283 
00285     class SubbandList
00286     {
00287     public:
00289         SubbandList(){}
00290 
00292         ~SubbandList(){}
00293 
00294         //Default (shallow) copy constructor and operator= used
00296         void Init(const int depth,const int xlen,const int ylen);
00297 
00299         int Length() const {return bands.size();}
00300 
00302         Subband& operator()(const int n){return bands[n-1];}
00303 
00305         const Subband& operator()(const int n) const {return bands[n-1];}
00306 
00308         void AddBand(const Subband& b){bands.push_back(b);}
00309 
00311         void Clear(){bands.clear();}
00312 
00313     private:
00314 
00316         float PerceptualWeight( const float xf , const float yf , const CompSort cs);
00317 
00318     private:
00319         std::vector<Subband> bands;
00320     };
00321 
00323 
00327     class WaveletTransform
00328     {
00329     public:
00331         WaveletTransform(int d = 4, WltFilter f = DAUB9_7);
00332 
00334         virtual ~WaveletTransform();
00335 
00337 
00343         void Transform(const Direction d, PicArray& pic_data, CoeffArray& coeff_data);
00344 
00346         SubbandList& BandList(){return m_band_list;}
00347 
00349         const SubbandList& BandList() const {return m_band_list;}
00350 
00352 
00363         void SetBandWeights (const float cpd,
00364                              const FrameSort& fsort,
00365                              const ChromaFormat& cformat,
00366                              const CompSort csort,
00367                              const bool field_coding);
00368 
00369 
00370     private:
00371         // Classes used within wavelet transform
00372 
00374         class VHFilter
00375         {
00376 
00377         public:
00378 
00379             VHFilter(){}
00380 
00381             virtual ~VHFilter(){}
00382 
00384             virtual void Split(const int xp, const int yp, const int xl, const int yl, CoeffArray& coeff_data)=0;
00385 
00387             virtual void Synth(const int xp, const int yp, const int xl, const int yl, CoeffArray& coeff_data)=0;
00388 
00390             virtual double GetLowFactor() const=0;
00391 
00393             virtual double GetHighFactor() const =0;
00394 
00396             virtual int GetShift() const =0;
00397 
00398         protected:
00399 
00401             inline void Interleave( const int xp, const int yp, const int xl, const int yl, CoeffArray& coeff_data );
00402 
00403 
00405             inline void DeInterleave( const int xp, const int yp, const int xl, const int yl, CoeffArray& coeff_data );
00406 
00408             void ShiftRowLeft(CoeffType *row, int length, int shift);
00409 
00411             void ShiftRowRight(CoeffType *row, int length, int shift);
00412         };
00413 
00415         class VHFilterDAUB9_7 : public VHFilter
00416         {
00417 
00418         public:
00419 
00421             void Split(const int xp, const int yp, const int xl, const int yl, CoeffArray& coeff_data);
00422 
00424             void Synth(const int xp, const int yp, const int xl, const int yl, CoeffArray& coeff_data);
00425 
00427             double GetLowFactor() const { return 1.149604398;}
00428 
00430             double GetHighFactor() const { return 0.869864452;}
00431 
00433             int GetShift() const {return 1;}
00434 
00435 
00436         };
00437 
00439         class VHFilterLEGALL5_3 : public VHFilter
00440         {
00441 
00442         public:
00443 
00445             void Split(const int xp, const int yp, const int xl, const int yl, CoeffArray& coeff_data);
00446 
00448             void Synth(const int xp, const int yp, const int xl, const int yl, CoeffArray& coeff_data);
00449 
00451             double GetLowFactor() const { return 1.179535649;}
00452 
00454             double GetHighFactor() const { return 0.81649658;}
00455 
00457             int GetShift() const {return 1;}
00458 
00459 
00460 #ifdef HAVE_MMX
00461             inline void HorizSynth (int xp, int xl, int ystart, int yend, CoeffArray &coeff_data);
00462 #endif
00463 
00464         };
00465 
00467         class VHFilterDD9_7 : public VHFilter
00468         {
00469 
00470         public:
00471 
00473             void Split(const int xp, const int yp, const int xl, const int yl, CoeffArray& coeff_data);
00474 
00476             void Synth(const int xp, const int yp, const int xl, const int yl, CoeffArray& coeff_data);
00477 
00479             double GetLowFactor() const { return 1.218660804;}
00480 
00482             double GetHighFactor() const { return 0.780720058;}
00483 
00485             int GetShift() const {return 1;}
00486 
00487         };
00488 
00489 
00491         class VHFilterDD13_7 : public VHFilter
00492         {
00493 
00494         public:
00495 
00497             void Split(const int xp, const int yp, const int xl, const int yl, CoeffArray& coeff_data);
00498 
00500             void Synth(const int xp, const int yp, const int xl, const int yl, CoeffArray& coeff_data);
00501 
00503             double GetLowFactor() const { return 1.235705971;}
00504 
00506             double GetHighFactor() const { return 0.780719354;}
00507 
00509             int GetShift() const {return 1;}
00510 
00511         };
00512 
00514         class VHFilterHAAR0 : public VHFilter
00515         {
00516 
00517         public:
00518 
00520             void Split(const int xp, const int yp, const int xl, const int yl, CoeffArray& coeff_data);
00521 
00523             void Synth(const int xp, const int yp, const int xl, const int yl, CoeffArray& coeff_data);
00524 
00526             double GetLowFactor() const { return 1.414213562;}
00527 
00529             double GetHighFactor() const { return 0.707106781;}
00530 
00532             int GetShift() const {return 0;}
00533 
00534 
00535         };
00536 
00538         class VHFilterHAAR1 : public VHFilter
00539         {
00540 
00541         public:
00542 
00544             void Split(const int xp, const int yp, const int xl, const int yl, CoeffArray& coeff_data);
00545 
00547             void Synth(const int xp, const int yp, const int xl, const int yl, CoeffArray& coeff_data);
00548 
00550             double GetLowFactor() const { return 1.414213562;}
00551 
00553             double GetHighFactor() const { return 0.707106781;}
00554 
00556             int GetShift() const {return 1;}
00557 
00558 
00559         };
00560 
00561 
00563         class VHFilterHAAR2 : public VHFilter
00564         {
00565 
00566         public:
00567 
00569             void Split(const int xp, const int yp, const int xl, const int yl, CoeffArray& coeff_data);
00570 
00572             void Synth(const int xp, const int yp, const int xl, const int yl, CoeffArray& coeff_data);
00573 
00575             double GetLowFactor() const { return 1.414213562;}
00576 
00578             double GetHighFactor() const { return 0.707106781;}
00579 
00581             int GetShift() const {return 2;}
00582 
00583         };
00584 
00585 
00586 
00587         // Lifting steps used in the filters
00588 
00590         template<int shift>
00591         class PredictStepShift
00592         {
00593 
00594         public:
00595 
00597             PredictStepShift(){}
00598 
00599             // Assume default copy constructor, assignment= and destructor //
00600 
00602             /*
00603                 Do the filtering.
00604                 \param   in_val   the value being predicted
00605                 \param   val1   the first value being used for prediction
00606                 \param   val2   the second value being used for prediction
00607             */
00608             inline void Filter(CoeffType& in_val, const CoeffType& val1, const CoeffType& val2) const
00609             {
00610                 in_val -= (( val1 + val2 + (1<<(shift-1)) ) >>shift );
00611             }
00612 
00613         };
00614 
00616         template<int shift>
00617         class UpdateStepShift
00618         {
00619 
00620         public:
00622             UpdateStepShift(){}
00623 
00625             /*
00626                 Do the filtering.
00627                 \param   in_val   the value being updated
00628                 \param   val1   the first value being used for updating
00629                 \param   val2   the second value being used for updating
00630             */
00631             inline void Filter(CoeffType& in_val, const CoeffType& val1, const CoeffType& val2) const
00632             {
00633                 in_val += ( ( val1 + val2 + (1<<(shift-1)) ) >>shift );
00634             }
00635 
00636         };
00637 
00639         template <int shift , int tap1, int tap2>
00640         class PredictStepFourTap
00641         {
00642         public:
00643 
00645             PredictStepFourTap(){}
00646 
00647             // Assume default copy constructor, assignment= and destructor //
00648 
00650             inline void Filter(CoeffType& in_val, const CoeffType& val1, const CoeffType& val2 ,
00651                                                   const CoeffType& val3, const CoeffType& val4 ) const
00652             {
00653                 in_val -= ( tap1*( val1 + val2 ) + tap2*( val3 + val4 ) + (1<<(shift-1)))>>shift;
00654             }
00655         };
00656 
00658         template <int shift , int tap1 , int tap2>
00659         class UpdateStepFourTap
00660         {
00661 
00662         public:
00664             UpdateStepFourTap(){}
00665 
00667             inline void Filter(CoeffType& in_val, const CoeffType& val1, const CoeffType& val2 ,
00668                                                   const CoeffType& val3, const CoeffType& val4 ) const
00669             {
00670                 in_val += ( tap1*( val1 + val2 ) + tap2*( val3 + val4 ) + (1<<(shift-1)) )>>shift;
00671             }
00672         };
00673 
00675         template <int gain> class PredictStep97
00676         {
00677         public:
00678 
00680             PredictStep97(){}
00681 
00682             // Assume default copy constructor, assignment= and destructor //
00683 
00685             /*
00686                 Do the filtering.
00687                 \param   in_val   the value being predicted
00688                 \param   val1   the first value being used for prediction
00689                 \param   val2   the second value being used for prediction
00690             */
00691             inline void Filter(CoeffType& in_val, const CoeffType& val1, const CoeffType& val2) const
00692             {
00693                 in_val -= static_cast< CoeffType >( (gain * static_cast< int >( val1 + val2 )) >>12 );
00694             }
00695         };
00696 
00698         template <int gain> class UpdateStep97
00699         {
00700 
00701         public:
00703             UpdateStep97(){}
00704 
00706             /*
00707                 Do the filtering.
00708                 \param   in_val   the value being updated
00709                 \param   val1   the first value being used for updating
00710                 \param   val2   the second value being used for updating
00711             */
00712             inline void Filter(CoeffType& in_val, const CoeffType& val1, const CoeffType& val2) const
00713             {
00714                 in_val += static_cast< CoeffType >( (gain * static_cast< int >( val1 + val2 )) >>12 );
00715             }
00716         };
00717 
00718     private:
00719 
00720         // Private variables
00721 
00722         SubbandList m_band_list;
00723 
00725         int m_depth;
00726 
00728         WltFilter m_filt_sort;
00729 
00731         VHFilter* m_vhfilter;
00732 
00733     private:
00734         // Private functions
00736         WaveletTransform(const WaveletTransform& cpy);
00737 
00739         WaveletTransform& operator=(const WaveletTransform& rhs);
00740 
00742         float PerceptualWeight(float xf,float yf,CompSort cs);
00743    };
00744 
00745 }// end namespace dirac
00746 
00747 #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.