downconvert.cpp
上传用户:xjjlds
上传日期:2015-12-05
资源大小:22823k
文件大小:8k
源码类别:

多媒体编程

开发平台:

Visual C++

  1. /* ***** BEGIN LICENSE BLOCK *****
  2. *
  3. * $Id: downconvert.cpp,v 1.2 2005/01/30 05:11:42 gabest Exp $ $Name:  $
  4. *
  5. * Version: MPL 1.1/GPL 2.0/LGPL 2.1
  6. *
  7. * The contents of this file are subject to the Mozilla Public License
  8. * Version 1.1 (the "License"); you may not use this file except in compliance
  9. * with the License. You may obtain a copy of the License at
  10. * http://www.mozilla.org/MPL/
  11. *
  12. * Software distributed under the License is distributed on an "AS IS" basis,
  13. * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
  14. * the specific language governing rights and limitations under the License.
  15. *
  16. * The Original Code is BBC Research and Development code.
  17. *
  18. * The Initial Developer of the Original Code is the British Broadcasting
  19. * Corporation.
  20. * Portions created by the Initial Developer are Copyright (C) 2004.
  21. * All Rights Reserved.
  22. *
  23. * Contributor(s): Richard Felton (Original Author), 
  24. *                 Thomas Davies
  25. *
  26. * Alternatively, the contents of this file may be used under the terms of
  27. * the GNU General Public License Version 2 (the "GPL"), or the GNU Lesser
  28. * Public License Version 2.1 (the "LGPL"), in which case the provisions of
  29. * the GPL or the LGPL are applicable instead of those above. If you wish to
  30. * allow use of your version of this file only under the terms of the either
  31. * the GPL or LGPL and not to allow others to use your version of this file
  32. * under the MPL, indicate your decision by deleting the provisions above
  33. * and replace them with the notice and other provisions required by the GPL
  34. * or LGPL. If you do not delete the provisions above, a recipient may use
  35. * your version of this file under the terms of any one of the MPL, the GPL
  36. * or the LGPL.
  37. * ***** END LICENSE BLOCK ***** */
  38. #include <libdirac_motionest/downconvert.h>
  39. using namespace dirac;
  40. DownConverter::DownConverter()
  41. {}
  42. //General function - does some admin and calls the correct function
  43. void DownConverter::DoDownConvert(const PicArray& old_data, PicArray& new_data)
  44. {
  45.     //Down-convert by a factor of two.
  46.     m_row_buffer= new ValueType[old_data.LengthX()];    
  47.     //Variables that will be used by the filter calculations
  48.     int sum;
  49.     int colpos;
  50.     // The area of the picture that will be downconverted
  51.     const int xlen = 2*new_data.LengthX();    
  52.     const int ylen = 2*new_data.LengthY();    
  53.     //There are three y loops to cope with the leading edge, middle 
  54.     //and trailing edge of each column.
  55.     colpos=0;
  56.     for( int y=0; y<Stage_I_Size*2 ; y+=2 , colpos++ )
  57.     {
  58.         // We are filtering each column but doing it bit by bit.
  59.         // This means our main loop is in the x direction and
  60.         // there is a much greater chance the data we need will
  61.         // be in the cache.
  62.         for( int x=0 ; x<xlen ; x++ )
  63.         {            
  64.             // In down conversion we interpolate every pixel
  65.             // so there is no copying.
  66.             // Excuse the complicated ternary stuff but it sorts out the edge
  67.             sum =  (old_data[y][x] + old_data[y+1][x])*StageI_I;
  68.             sum += (old_data[((y-1)>=0)?(y-1):0][x] + old_data[y+2][x])*StageI_II;
  69.             sum += (old_data[((y-2)>=0)?(y-2):0][x] + old_data[y+3][x])*StageI_III;
  70.             sum += (old_data[((y-3)>=0)?(y-3):0][x] + old_data[y+4][x])*StageI_IV;
  71.             sum += (old_data[((y-4)>=0)?(y-4):0][x] + old_data[y+5][x])*StageI_V;
  72.             sum += (old_data[((y-5)>=0)?(y-5):0][x] + old_data[y+6][x])*StageI_VI;
  73.             sum += 1<<(StageI_Shift-1);//do rounding right
  74.             m_row_buffer[x] = sum >> StageI_Shift;
  75.         }// x
  76.         //Speaking of which - the row loop.
  77.         RowLoop(colpos,old_data,new_data);
  78.     }// y 
  79.     // This loop is like the last one but it deals with the center
  80.     // section of the image and so the ternary operations are dropped
  81.     // from the filter section.
  82.     for( int y=Stage_I_Size*2 ; y<ylen-Stage_I_Size*2 ; y+=2 , colpos++ )
  83.     {
  84.         for( int x=0 ; x<xlen ; x++ )
  85.         {
  86.             sum =  (old_data[y][x]   + old_data[y+1][x])*StageI_I;
  87.             sum += (old_data[y-1][x] + old_data[y+2][x])*StageI_II;
  88.             sum += (old_data[y-2][x] + old_data[y+3][x])*StageI_III;
  89.             sum += (old_data[y-3][x] + old_data[y+4][x])*StageI_IV;
  90.             sum += (old_data[y-4][x] + old_data[y+5][x])*StageI_V;
  91.             sum += (old_data[y-5][x] + old_data[y+6][x])*StageI_VI;
  92.             sum += 1<<(StageI_Shift-1);//do rounding right
  93.             m_row_buffer[x] = sum >> StageI_Shift;
  94.         }// x
  95.         RowLoop( colpos , old_data , new_data );
  96.     }// y
  97.     // Another similar loop! - this time we are dealing with
  98.     // the trailing edge so the ternary stuff is back in the
  99.     // filter calcs but in the second parameter.
  100.     for( int y=ylen-(Stage_I_Size*2) ; y<ylen-1 ; y+=2 , colpos++ )
  101.     {
  102.         for( int x=0; x<xlen ; x++ )
  103.         {
  104.             sum =  (old_data[y][x]   + old_data[((y+1)<ylen)?(y+1):(ylen-1)][x])*StageI_I;
  105.             sum += (old_data[y-1][x] + old_data[((y+2)<ylen)?(y+2):(ylen-1)][x])*StageI_II;
  106.             sum += (old_data[y-2][x] + old_data[((y+3)<ylen)?(y+3):(ylen-1)][x])*StageI_III;
  107.             sum += (old_data[y-3][x] + old_data[((y+4)<ylen)?(y+4):(ylen-1)][x])*StageI_IV;
  108.             sum += (old_data[y-4][x] + old_data[((y+5)<ylen)?(y+5):(ylen-1)][x])*StageI_V;
  109.             sum += (old_data[y-5][x] + old_data[((y+6)<ylen)?(y+6):(ylen-1)][x])*StageI_VI;
  110.             // Do rounding right
  111.             sum += 1<<(StageI_Shift-1);
  112.             m_row_buffer[x] = sum >> StageI_Shift;
  113.         }// x
  114.         RowLoop( colpos , old_data , new_data );
  115.     }//  y
  116.     // Tidy up the data
  117.     delete[] m_row_buffer;
  118. }
  119. // The loop over the columns is the same every time so lends itself to isolation
  120. // as an individual function.
  121. void DownConverter::RowLoop( const int colpos , const PicArray& old_data , PicArray& new_data)
  122. {
  123.      //Calculation variables
  124.     int sum;
  125.     const int xlen = 2*new_data.LengthX();
  126.     int linepos=0;    
  127.      // Leading Column Edge
  128.      // Similar loops to the x case in ByHalf_opto, for explanation look there.
  129.      // Note the factor of two difference as we only want to fill in every other
  130.      // line as the others have already been created by the line loops.
  131.     for( int x=0; x<(2*Stage_I_Size) ; x+=2 , linepos++ )
  132.     {
  133.         sum =  (m_row_buffer[((x)>=0)?(x):0]     + m_row_buffer[x+1])*StageI_I;
  134.         sum += (m_row_buffer[((x-1)>=0)?(x-1):0] + m_row_buffer[x+2])*StageI_II;
  135.         sum += (m_row_buffer[((x-2)>=0)?(x-2):0] + m_row_buffer[x+3])*StageI_III;
  136.         sum += (m_row_buffer[((x-3)>=0)?(x-3):0] + m_row_buffer[x+4])*StageI_IV;
  137.         sum += (m_row_buffer[((x-4)>=0)?(x-4):0] + m_row_buffer[x+5])*StageI_V;
  138.         sum += (m_row_buffer[((x-5)>=0)?(x-5):0] + m_row_buffer[x+6])*StageI_VI;
  139.         sum += 1<<(StageI_Shift-1);//do rounding right
  140.         new_data[colpos][linepos] = sum >> StageI_Shift;
  141.     }
  142.      //Middle of column
  143.     for( int x=(2*Stage_I_Size) ; x<xlen-(2*Stage_I_Size) ; x+=2 , linepos++) 
  144.     {
  145.         sum =  (m_row_buffer[x]   + m_row_buffer[x+1])*StageI_I;
  146.         sum += (m_row_buffer[x-1] + m_row_buffer[x+2])*StageI_II;
  147.         sum += (m_row_buffer[x-2] + m_row_buffer[x+3])*StageI_III;
  148.         sum += (m_row_buffer[x-3] + m_row_buffer[x+4])*StageI_IV;
  149.         sum += (m_row_buffer[x-4] + m_row_buffer[x+5])*StageI_V;
  150.         sum += (m_row_buffer[x-5] + m_row_buffer[x+6])*StageI_VI;
  151.         sum += 1<<(StageI_Shift-1);//do rounding right
  152.         new_data[colpos][linepos] = sum >> StageI_Shift;
  153.     }
  154.      //Trailing column edge
  155.     for( int x=xlen-(2*Stage_I_Size) ; x< xlen-1 ; x+=2 , linepos++ )
  156.     {
  157.         sum =  (m_row_buffer[x]   + m_row_buffer[((x+1)<xlen)?(x+1):(xlen-1)])*StageI_I;
  158.         sum += (m_row_buffer[x-1] + m_row_buffer[((x+2)<xlen)?(x+2):(xlen-1)])*StageI_II;
  159.         sum += (m_row_buffer[x-2] + m_row_buffer[((x+3)<xlen)?(x+3):(xlen-1)])*StageI_III;
  160.         sum += (m_row_buffer[x-3] + m_row_buffer[((x+4)<xlen)?(x+4):(xlen-1)])*StageI_IV;
  161.         sum += (m_row_buffer[x-4] + m_row_buffer[((x+5)<xlen)?(x+5):(xlen-1)])*StageI_V;
  162.         sum += (m_row_buffer[x-5] + m_row_buffer[((x+6)<xlen)?(x+6):(xlen-1)])*StageI_VI;
  163.         sum += 1<<(StageI_Shift-1);//do rounding right
  164.         new_data[colpos][linepos] = sum >> StageI_Shift;
  165.     }
  166. }