- Main Page
- Namespaces
- Classes
- Files
- Directories

- File List
- File Members

# upconvert.cpp

    00001 /* ***** BEGIN LICENSE BLOCK *****
    00002 *
    00003 * $Id: upconvert.cpp,v 1.2 2005/01/30 05:11:40 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), Thomas Davies
    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 #include <libdirac_common/upconvert.h>
    00039 using namespace dirac;
    00040
    00041 #include <iostream>
    00042
    00043 //Up-convert by a factor of two.
    00044 void UpConverter::DoUpConverter(const PicArray& pic_data, PicArray& up_data)
    00045 {
    00046
    00047     xOld = pic_data.LengthX();
    00048     yOld = pic_data.LengthY();
    00049     xNew = up_data.LengthX();
    00050     yNew = up_data.LengthY();    //assumes up_data has twice the x and y length of the pic_data.
    00051                                 //TBC: What to do if this is wrong?
    00052
    00053     //Variables that will be used by the filter calculations
    00054     int sum;
    00055     int ypos(0);
    00056
    00057     //There are three y loops to cope with the leading edge, middle
    00058     //and trailing edge of each column.
    00059
    00060     for(int y = 0 ; y < Stage_I_Size; ++y , ypos += 2)
    00061     {
    00062
    00063         //We are filtering each column but doing it bit by bit.
    00064         //This means our main loop is in the x direction and
    00065         //there is a much greater chance the data we need will
    00066         //be in the cache.
    00067         for(int x = 0 , xpos = 0; x < xOld; x++ , xpos+=2 )
    00068         {
    00069
    00070             // Copy a Pixel from the original image in each even position
    00071             up_data[ypos][xpos] = pic_data[y][x];
    00072
    00073             //Work out the next pixel from filtered values.
    00074             //Excuse the complicated ternary stuff but it sorts out the edge
    00075             sum =  (pic_data[y][x] + pic_data[y+1][x])*StageI_I;
    00076             sum += (pic_data[(y>=1)?(y-1):0][x] + pic_data[y+2][x])*StageI_II;
    00077             sum += (pic_data[(y>=2)?(y-2):0][x] + pic_data[y+3][x])*StageI_III;
    00078             sum += (pic_data[(y>=3)?(y-3):0][x] + pic_data[y+4][x])*StageI_IV;
    00079             sum += (pic_data[(y>=4)?(y-4):0][x] + pic_data[y+5][x])*StageI_V;
    00080             sum += (pic_data[(y>=5)?(y-5):0][x] + pic_data[y+6][x])*StageI_VI;
    00081
    00082             up_data[ypos+1][xpos] = sum >> Stage_I_Shift;
    00083
    00084         }// x, xpos
    00085
    00086         // The row loop.
    00087         RowLoop(up_data, ypos);
    00088     }// y, ypos
    00089     // This loop is like the last one but it deals with the centre
    00090     // section of the image and so the ternary operations are dropped
    00091     // from the filter section.
    00092     for(int y = Stage_I_Size; y < yOld - Stage_I_Size; ++y , ypos += 2)
    00093     {
    00094         for(int x = 0 , xpos=0; x < xOld; x++ , xpos+=2 )
    00095         {
    00096
    00097             up_data[ypos][xpos] = pic_data[y][x];
    00098
    00099             sum =  (pic_data[y][x]   + pic_data[y+1][x])*StageI_I;
    00100             sum += (pic_data[y-1][x] + pic_data[y+2][x])*StageI_II;
    00101             sum += (pic_data[y-2][x] + pic_data[y+3][x])*StageI_III;
    00102             sum += (pic_data[y-3][x] + pic_data[y+4][x])*StageI_IV;
    00103             sum += (pic_data[y-4][x] + pic_data[y+5][x])*StageI_V;
    00104             sum += (pic_data[y-5][x] + pic_data[y+6][x])*StageI_VI;
    00105
    00106             up_data[ypos+1][xpos] = sum >> Stage_I_Shift;
    00107
    00108         }// x,xpos
    00109         RowLoop(up_data, ypos);
    00110
    00111     }// y, ypos
    00112     // Another similar loop! - this time we are dealing with
    00113     // the trailing edge so the ternary stuff is back in the
    00114     // filter calcs but in the second parameter.
    00115     for(int y = yOld - Stage_I_Size; y < yOld; ++y , ypos+=2)
    00116     {
    00117         for(int x = 0 , xpos=0 ; x < xOld; x++ , xpos+=2)
    00118         {
    00119
    00120             up_data[ypos][xpos]=pic_data[y][x];
    00121
    00122             sum =  (pic_data[y][x]     + pic_data[((y+1)<yOld)?(y+1):(yOld-1)][x])*StageI_I;
    00123             sum += (pic_data[y - 1][x] + pic_data[((y+2)<yOld)?(y+2):(yOld-1)][x])*StageI_II;
    00124             sum += (pic_data[y - 2][x] + pic_data[((y+3)<yOld)?(y+3):(yOld-1)][x])*StageI_III;
    00125             sum += (pic_data[y - 3][x] + pic_data[((y+4)<yOld)?(y+4):(yOld-1)][x])*StageI_IV;
    00126             sum += (pic_data[y - 4][x] + pic_data[((y+5)<yOld)?(y+5):(yOld-1)][x])*StageI_V;
    00127             sum += (pic_data[y - 5][x] + pic_data[((y+6)<yOld)?(y+6):(yOld-1)][x])*StageI_VI;
    00128             up_data[ypos+1][xpos] = sum >> Stage_I_Shift;
    00129
    00130         }//x,xpos
    00131         RowLoop(up_data, ypos);
    00132
    00133     }//y,ypos
    00134 }
    00135
    00136
    00137 void UpConverter::RowLoop(PicArray&up_data, const int row_num)
    00138 {
    00139     //Calculation variable
    00140     int sum;
    00141     int ypos;
    00142
    00143     //Leading row Edge
    00144     //Note the factor of two difference as we only want to fill in every other
    00145     //line as the others have already been created
    00146     for(int i = 0; i < 2; ++i)
    00147     {
    00148         ypos = row_num + i;
    00149
    00150         for(int x = 0; x < (2*Stage_I_Size); x+=2)
    00151         {
    00152
    00153             sum =  (up_data[ypos][x]     + up_data[ypos][x+2])*StageI_I;
    00154             sum += (up_data[ypos][(x>=2)?(x-2):0] + up_data[ypos][x+4])*StageI_II;
    00155             sum += (up_data[ypos][(x>=4)?(x-4):0] + up_data[ypos][x+6])*StageI_III;
    00156             sum += (up_data[ypos][(x>=6)?(x-6):0] + up_data[ypos][x+8])*StageI_IV;
    00157             sum += (up_data[ypos][(x>=8)?(x-8):0] + up_data[ypos][x+10])*StageI_V;
    00158             sum += (up_data[ypos][(x>=10)?(x-10):0] + up_data[ypos][x+12])*StageI_VI;
    00159
    00160             up_data[ypos][x+1] = sum >> Stage_I_Shift;
    00161         }// x
    00162         //Middle of row
    00163         for(int x = (2*Stage_I_Size); x < xNew - (2*Stage_I_Size); x+=2)
    00164         {
    00165             sum =  (up_data[ypos][x]   + up_data[ypos][x+2])*StageI_I;
    00166             sum += (up_data[ypos][x-2] + up_data[ypos][x+4])*StageI_II;
    00167             sum += (up_data[ypos][x-4] + up_data[ypos][x+6])*StageI_III;
    00168             sum += (up_data[ypos][x-6] + up_data[ypos][x+8])*StageI_IV;
    00169             sum += (up_data[ypos][x-8] + up_data[ypos][x+10])*StageI_V;
    00170             sum += (up_data[ypos][x-10] + up_data[ypos][x+12])*StageI_VI;
    00171
    00172             up_data[ypos][x+1] = sum >> Stage_I_Shift;
    00173         }// x
    00174         //Trailing row edge
    00175         for(int x = xNew - (2*Stage_I_Size); x < xNew; x+=2)
    00176         {
    00177             sum =  (up_data[ypos][x]   + up_data[ypos][(((x+2)<xNew)?(x+2):(xNew-2))])*StageI_I;
    00178             sum += (up_data[ypos][x-2] + up_data[ypos][(((x+4)<xNew)?(x+4):(xNew-2))])*StageI_II;
    00179             sum += (up_data[ypos][x-4] + up_data[ypos][(((x+6)<xNew)?(x+6):(xNew-2))])*StageI_III;
    00180             sum += (up_data[ypos][x-6] + up_data[ypos][(((x+8)<xNew)?(x+8):(xNew-2))])*StageI_IV;
    00181             sum += (up_data[ypos][x-8] + up_data[ypos][(((x+10)<xNew)?(x+10):(xNew-2))])*StageI_V;
    00182             sum += (up_data[ypos][x-10] + up_data[ypos][(((x+12)<xNew)?(x+12):(xNew-2))])*StageI_VI;
    00183             up_data[ypos][x+1] = sum >> Stage_I_Shift;
    00184         }// x
    00185     }
    00186 }