- Main Page
- Namespaces
- Classes
- Files
- Directories

- File List
- File Members

# downconvert.cpp

    00001 /* ***** BEGIN LICENSE BLOCK *****
    00002 *
    00003 * $Id: downconvert.cpp,v 1.2 2005/01/30 05:11:42 gabest Exp $ $Name:  $
    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): Richard Felton (Original Author),
    00024 *                 Thomas Davies
    00025 *
    00026 * Alternatively, the contents of this file may be used under the terms of
    00027 * the GNU General Public License Version 2 (the "GPL"), or the GNU Lesser
    00028 * Public License Version 2.1 (the "LGPL"), in which case the provisions of
    00029 * the GPL or the LGPL are applicable instead of those above. If you wish to
    00030 * allow use of your version of this file only under the terms of the either
    00031 * the GPL or LGPL and not to allow others to use your version of this file
    00032 * under the MPL, indicate your decision by deleting the provisions above
    00033 * and replace them with the notice and other provisions required by the GPL
    00034 * or LGPL. If you do not delete the provisions above, a recipient may use
    00035 * your version of this file under the terms of any one of the MPL, the GPL
    00036 * or the LGPL.
    00037 * ***** END LICENSE BLOCK ***** */
    00038
    00039 #include <libdirac_motionest/downconvert.h>
    00040 using namespace dirac;
    00041
    00042 DownConverter::DownConverter()
    00043 {}
    00044
    00045
    00046 //General function - does some admin and calls the correct function
    00047 void DownConverter::DoDownConvert(const PicArray& old_data, PicArray& new_data)
    00048 {
    00049     //Down-convert by a factor of two.
    00050     m_row_buffer= new ValueType[old_data.LengthX()];
    00051     //Variables that will be used by the filter calculations
    00052     int sum;
    00053     int colpos;
    00054
    00055     // The area of the picture that will be downconverted
    00056     const int xlen = 2*new_data.LengthX();
    00057     const int ylen = 2*new_data.LengthY();
    00058
    00059
    00060     //There are three y loops to cope with the leading edge, middle
    00061     //and trailing edge of each column.
    00062     colpos=0;
    00063     for( int y=0; y<Stage_I_Size*2 ; y+=2 , colpos++ )
    00064     {
    00065         // We are filtering each column but doing it bit by bit.
    00066         // This means our main loop is in the x direction and
    00067         // there is a much greater chance the data we need will
    00068         // be in the cache.
    00069
    00070         for( int x=0 ; x<xlen ; x++ )
    00071         {
    00072             // In down conversion we interpolate every pixel
    00073             // so there is no copying.
    00074             // Excuse the complicated ternary stuff but it sorts out the edge
    00075             sum =  (old_data[y][x] + old_data[y+1][x])*StageI_I;
    00076             sum += (old_data[((y-1)>=0)?(y-1):0][x] + old_data[y+2][x])*StageI_II;
    00077             sum += (old_data[((y-2)>=0)?(y-2):0][x] + old_data[y+3][x])*StageI_III;
    00078             sum += (old_data[((y-3)>=0)?(y-3):0][x] + old_data[y+4][x])*StageI_IV;
    00079             sum += (old_data[((y-4)>=0)?(y-4):0][x] + old_data[y+5][x])*StageI_V;
    00080             sum += (old_data[((y-5)>=0)?(y-5):0][x] + old_data[y+6][x])*StageI_VI;
    00081             sum += 1<<(StageI_Shift-1);//do rounding right
    00082             m_row_buffer[x] = sum >> StageI_Shift;
    00083         }// x
    00084         //Speaking of which - the row loop.
    00085
    00086         RowLoop(colpos,old_data,new_data);
    00087     }// y
    00088
    00089     // This loop is like the last one but it deals with the center
    00090     // section of the image and so the ternary operations are dropped
    00091     // from the filter section.
    00092     for( int y=Stage_I_Size*2 ; y<ylen-Stage_I_Size*2 ; y+=2 , colpos++ )
    00093     {
    00094         for( int x=0 ; x<xlen ; x++ )
    00095         {
    00096
    00097             sum =  (old_data[y][x]   + old_data[y+1][x])*StageI_I;
    00098             sum += (old_data[y-1][x] + old_data[y+2][x])*StageI_II;
    00099             sum += (old_data[y-2][x] + old_data[y+3][x])*StageI_III;
    00100             sum += (old_data[y-3][x] + old_data[y+4][x])*StageI_IV;
    00101             sum += (old_data[y-4][x] + old_data[y+5][x])*StageI_V;
    00102             sum += (old_data[y-5][x] + old_data[y+6][x])*StageI_VI;
    00103             sum += 1<<(StageI_Shift-1);//do rounding right
    00104             m_row_buffer[x] = sum >> StageI_Shift;
    00105         }// x
    00106
    00107         RowLoop( colpos , old_data , new_data );
    00108     }// y
    00109
    00110     // Another similar loop! - this time we are dealing with
    00111     // the trailing edge so the ternary stuff is back in the
    00112     // filter calcs but in the second parameter.
    00113
    00114     for( int y=ylen-(Stage_I_Size*2) ; y<ylen-1 ; y+=2 , colpos++ )
    00115     {
    00116         for( int x=0; x<xlen ; x++ )
    00117         {
    00118
    00119             sum =  (old_data[y][x]   + old_data[((y+1)<ylen)?(y+1):(ylen-1)][x])*StageI_I;
    00120             sum += (old_data[y-1][x] + old_data[((y+2)<ylen)?(y+2):(ylen-1)][x])*StageI_II;
    00121             sum += (old_data[y-2][x] + old_data[((y+3)<ylen)?(y+3):(ylen-1)][x])*StageI_III;
    00122             sum += (old_data[y-3][x] + old_data[((y+4)<ylen)?(y+4):(ylen-1)][x])*StageI_IV;
    00123             sum += (old_data[y-4][x] + old_data[((y+5)<ylen)?(y+5):(ylen-1)][x])*StageI_V;
    00124             sum += (old_data[y-5][x] + old_data[((y+6)<ylen)?(y+6):(ylen-1)][x])*StageI_VI;
    00125
    00126             // Do rounding right
    00127             sum += 1<<(StageI_Shift-1);
    00128             m_row_buffer[x] = sum >> StageI_Shift;
    00129
    00130         }// x
    00131
    00132         RowLoop( colpos , old_data , new_data );
    00133
    00134     }//  y
    00135
    00136     // Tidy up the data
    00137     delete[] m_row_buffer;
    00138
    00139 }
    00140
    00141
    00142 // The loop over the columns is the same every time so lends itself to isolation
    00143 // as an individual function.
    00144 void DownConverter::RowLoop( const int colpos , const PicArray& old_data , PicArray& new_data)
    00145 {
    00146
    00147      //Calculation variables
    00148     int sum;
    00149     const int xlen = 2*new_data.LengthX();
    00150     int linepos=0;
    00151
    00152      // Leading Column Edge
    00153      // Similar loops to the x case in ByHalf_opto, for explanation look there.
    00154      // Note the factor of two difference as we only want to fill in every other
    00155      // line as the others have already been created by the line loops.
    00156
    00157     for( int x=0; x<(2*Stage_I_Size) ; x+=2 , linepos++ )
    00158     {
    00159         sum =  (m_row_buffer[((x)>=0)?(x):0]     + m_row_buffer[x+1])*StageI_I;
    00160         sum += (m_row_buffer[((x-1)>=0)?(x-1):0] + m_row_buffer[x+2])*StageI_II;
    00161         sum += (m_row_buffer[((x-2)>=0)?(x-2):0] + m_row_buffer[x+3])*StageI_III;
    00162         sum += (m_row_buffer[((x-3)>=0)?(x-3):0] + m_row_buffer[x+4])*StageI_IV;
    00163         sum += (m_row_buffer[((x-4)>=0)?(x-4):0] + m_row_buffer[x+5])*StageI_V;
    00164         sum += (m_row_buffer[((x-5)>=0)?(x-5):0] + m_row_buffer[x+6])*StageI_VI;
    00165         sum += 1<<(StageI_Shift-1);//do rounding right
    00166
    00167         new_data[colpos][linepos] = sum >> StageI_Shift;
    00168
    00169     }
    00170      //Middle of column
    00171     for( int x=(2*Stage_I_Size) ; x<xlen-(2*Stage_I_Size) ; x+=2 , linepos++)
    00172     {
    00173         sum =  (m_row_buffer[x]   + m_row_buffer[x+1])*StageI_I;
    00174         sum += (m_row_buffer[x-1] + m_row_buffer[x+2])*StageI_II;
    00175         sum += (m_row_buffer[x-2] + m_row_buffer[x+3])*StageI_III;
    00176         sum += (m_row_buffer[x-3] + m_row_buffer[x+4])*StageI_IV;
    00177         sum += (m_row_buffer[x-4] + m_row_buffer[x+5])*StageI_V;
    00178         sum += (m_row_buffer[x-5] + m_row_buffer[x+6])*StageI_VI;
    00179         sum += 1<<(StageI_Shift-1);//do rounding right
    00180
    00181         new_data[colpos][linepos] = sum >> StageI_Shift;
    00182
    00183     }
    00184      //Trailing column edge
    00185     for( int x=xlen-(2*Stage_I_Size) ; x< xlen-1 ; x+=2 , linepos++ )
    00186     {
    00187         sum =  (m_row_buffer[x]   + m_row_buffer[((x+1)<xlen)?(x+1):(xlen-1)])*StageI_I;
    00188         sum += (m_row_buffer[x-1] + m_row_buffer[((x+2)<xlen)?(x+2):(xlen-1)])*StageI_II;
    00189         sum += (m_row_buffer[x-2] + m_row_buffer[((x+3)<xlen)?(x+3):(xlen-1)])*StageI_III;
    00190         sum += (m_row_buffer[x-3] + m_row_buffer[((x+4)<xlen)?(x+4):(xlen-1)])*StageI_IV;
    00191         sum += (m_row_buffer[x-4] + m_row_buffer[((x+5)<xlen)?(x+5):(xlen-1)])*StageI_V;
    00192         sum += (m_row_buffer[x-5] + m_row_buffer[((x+6)<xlen)?(x+6):(xlen-1)])*StageI_VI;
    00193         sum += 1<<(StageI_Shift-1);//do rounding right
    00194
    00195         new_data[colpos][linepos] = sum >> StageI_Shift;
    00196
    00197     }
    00198
    00199 }