Home | History | Annotate | Download | only in common
      1 /*
      2  *  Copyright (c) 2010 The WebM project authors. All Rights Reserved.
      3  *
      4  *  Use of this source code is governed by a BSD-style license
      5  *  that can be found in the LICENSE file in the root of the source
      6  *  tree. An additional intellectual property rights grant can be found
      7  *  in the file PATENTS.  All contributing project authors may
      8  *  be found in the AUTHORS file in the root of the source tree.
      9  */
     10 
     11 
     12 /****************************************************************************
     13  * Notes:
     14  *
     15  * This implementation makes use of 16 bit fixed point verio of two multiply
     16  * constants:
     17  *         1.   sqrt(2) * cos (pi/8)
     18  *         2.   sqrt(2) * sin (pi/8)
     19  * Becuase the first constant is bigger than 1, to maintain the same 16 bit
     20  * fixed point precision as the second one, we use a trick of
     21  *         x * a = x + x*(a-1)
     22  * so
     23  *         x * sqrt(2) * cos (pi/8) = x + x * (sqrt(2) *cos(pi/8)-1).
     24  **************************************************************************/
     25 static const int cospi8sqrt2minus1 = 20091;
     26 static const int sinpi8sqrt2      = 35468;
     27 static const int rounding = 0;
     28 void vp8_short_idct4x4llm_c(short *input, short *output, int pitch)
     29 {
     30     int i;
     31     int a1, b1, c1, d1;
     32 
     33     short *ip = input;
     34     short *op = output;
     35     int temp1, temp2;
     36     int shortpitch = pitch >> 1;
     37 
     38     for (i = 0; i < 4; i++)
     39     {
     40         a1 = ip[0] + ip[8];
     41         b1 = ip[0] - ip[8];
     42 
     43         temp1 = (ip[4] * sinpi8sqrt2 + rounding) >> 16;
     44         temp2 = ip[12] + ((ip[12] * cospi8sqrt2minus1 + rounding) >> 16);
     45         c1 = temp1 - temp2;
     46 
     47         temp1 = ip[4] + ((ip[4] * cospi8sqrt2minus1 + rounding) >> 16);
     48         temp2 = (ip[12] * sinpi8sqrt2 + rounding) >> 16;
     49         d1 = temp1 + temp2;
     50 
     51         op[shortpitch*0] = a1 + d1;
     52         op[shortpitch*3] = a1 - d1;
     53 
     54         op[shortpitch*1] = b1 + c1;
     55         op[shortpitch*2] = b1 - c1;
     56 
     57         ip++;
     58         op++;
     59     }
     60 
     61     ip = output;
     62     op = output;
     63 
     64     for (i = 0; i < 4; i++)
     65     {
     66         a1 = ip[0] + ip[2];
     67         b1 = ip[0] - ip[2];
     68 
     69         temp1 = (ip[1] * sinpi8sqrt2 + rounding) >> 16;
     70         temp2 = ip[3] + ((ip[3] * cospi8sqrt2minus1 + rounding) >> 16);
     71         c1 = temp1 - temp2;
     72 
     73         temp1 = ip[1] + ((ip[1] * cospi8sqrt2minus1 + rounding) >> 16);
     74         temp2 = (ip[3] * sinpi8sqrt2 + rounding) >> 16;
     75         d1 = temp1 + temp2;
     76 
     77 
     78         op[0] = (a1 + d1 + 4) >> 3;
     79         op[3] = (a1 - d1 + 4) >> 3;
     80 
     81         op[1] = (b1 + c1 + 4) >> 3;
     82         op[2] = (b1 - c1 + 4) >> 3;
     83 
     84         ip += shortpitch;
     85         op += shortpitch;
     86     }
     87 }
     88 
     89 void vp8_short_idct4x4llm_1_c(short *input, short *output, int pitch)
     90 {
     91     int i;
     92     int a1;
     93     short *op = output;
     94     int shortpitch = pitch >> 1;
     95     a1 = ((input[0] + 4) >> 3);
     96 
     97     for (i = 0; i < 4; i++)
     98     {
     99         op[0] = a1;
    100         op[1] = a1;
    101         op[2] = a1;
    102         op[3] = a1;
    103         op += shortpitch;
    104     }
    105 }
    106 
    107 void vp8_dc_only_idct_add_c(short input_dc, unsigned char *pred_ptr, unsigned char *dst_ptr, int pitch, int stride)
    108 {
    109     int a1 = ((input_dc + 4) >> 3);
    110     int r, c;
    111 
    112     for (r = 0; r < 4; r++)
    113     {
    114         for (c = 0; c < 4; c++)
    115         {
    116             int a = a1 + pred_ptr[c] ;
    117 
    118             if (a < 0)
    119                 a = 0;
    120 
    121             if (a > 255)
    122                 a = 255;
    123 
    124             dst_ptr[c] = (unsigned char) a ;
    125         }
    126 
    127         dst_ptr += stride;
    128         pred_ptr += pitch;
    129     }
    130 
    131 }
    132 
    133 void vp8_short_inv_walsh4x4_c(short *input, short *output)
    134 {
    135     int i;
    136     int a1, b1, c1, d1;
    137     int a2, b2, c2, d2;
    138     short *ip = input;
    139     short *op = output;
    140 
    141     for (i = 0; i < 4; i++)
    142     {
    143         a1 = ip[0] + ip[12];
    144         b1 = ip[4] + ip[8];
    145         c1 = ip[4] - ip[8];
    146         d1 = ip[0] - ip[12];
    147 
    148         op[0] = a1 + b1;
    149         op[4] = c1 + d1;
    150         op[8] = a1 - b1;
    151         op[12] = d1 - c1;
    152         ip++;
    153         op++;
    154     }
    155 
    156     ip = output;
    157     op = output;
    158 
    159     for (i = 0; i < 4; i++)
    160     {
    161         a1 = ip[0] + ip[3];
    162         b1 = ip[1] + ip[2];
    163         c1 = ip[1] - ip[2];
    164         d1 = ip[0] - ip[3];
    165 
    166         a2 = a1 + b1;
    167         b2 = c1 + d1;
    168         c2 = a1 - b1;
    169         d2 = d1 - c1;
    170 
    171         op[0] = (a2 + 3) >> 3;
    172         op[1] = (b2 + 3) >> 3;
    173         op[2] = (c2 + 3) >> 3;
    174         op[3] = (d2 + 3) >> 3;
    175 
    176         ip += 4;
    177         op += 4;
    178     }
    179 }
    180 
    181 void vp8_short_inv_walsh4x4_1_c(short *input, short *output)
    182 {
    183     int i;
    184     int a1;
    185     short *op = output;
    186 
    187     a1 = ((input[0] + 3) >> 3);
    188 
    189     for (i = 0; i < 4; i++)
    190     {
    191         op[0] = a1;
    192         op[1] = a1;
    193         op[2] = a1;
    194         op[3] = a1;
    195         op += 4;
    196     }
    197 }
    198