Home | History | Annotate | Download | only in camera
      1 /*
      2  * Copyright (C) Texas Instruments - http://www.ti.com/
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 #include "NV12_resize.h"
     18 
     19 #ifdef LOG_TAG
     20 #undef LOG_TAG
     21 #endif
     22 #define LOG_TAG "NV12_resize"
     23 
     24 #define STRIDE 4096
     25 
     26 /*==========================================================================
     27 * Function Name  : VT_resizeFrame_Video_opt2_lp
     28 *
     29 * Description    : Resize a yuv frame.
     30 *
     31 * Input(s)       : input_img_ptr        -> Input Image Structure
     32 *                : output_img_ptr       -> Output Image Structure
     33 *                : cropout             -> crop structure
     34 *
     35 * Value Returned : mmBool               -> FALSE on error TRUE on success
     36 * NOTE:
     37 *            Not tested for crop funtionallity.
     38 *            faster version.
     39 ============================================================================*/
     40 mmBool
     41 VT_resizeFrame_Video_opt2_lp(
     42         structConvImage* i_img_ptr,      /* Points to the input image            */
     43         structConvImage* o_img_ptr,      /* Points to the output image           */
     44         IC_rect_type*  cropout,          /* how much to resize to in final image */
     45         mmUint16 dummy                   /* Transparent pixel value              */
     46         ) {
     47     LOG_FUNCTION_NAME;
     48 
     49     mmUint16 row,col;
     50     mmUint32 resizeFactorX;
     51     mmUint32 resizeFactorY;
     52 
     53     mmUint16 x, y;
     54 
     55     mmUchar* ptr8;
     56     mmUchar *ptr8Cb, *ptr8Cr;
     57 
     58     mmUint16 xf, yf;
     59     mmUchar* inImgPtrY;
     60     mmUchar* inImgPtrU;
     61     mmUchar* inImgPtrV;
     62     mmUint32 cox, coy, codx, cody;
     63     mmUint16 idx,idy, idxC;
     64 
     65     if ( i_img_ptr->uWidth == o_img_ptr->uWidth ) {
     66         if ( i_img_ptr->uHeight == o_img_ptr->uHeight ) {
     67             CAMHAL_LOGV("************************f(i_img_ptr->uHeight == o_img_ptr->uHeight) are same *********************\n");
     68             CAMHAL_LOGV("************************(i_img_ptr->width == %d" , i_img_ptr->uWidth );
     69             CAMHAL_LOGV("************************(i_img_ptr->uHeight == %d" , i_img_ptr->uHeight );
     70             CAMHAL_LOGV("************************(o_img_ptr->width == %d" ,o_img_ptr->uWidth );
     71             CAMHAL_LOGV("************************(o_img_ptr->uHeight == %d" , o_img_ptr->uHeight );
     72         }
     73     }
     74 
     75     if ( !i_img_ptr || !i_img_ptr->imgPtr || !o_img_ptr || !o_img_ptr->imgPtr ) {
     76         CAMHAL_LOGE("Image Point NULL");
     77         return false;
     78     }
     79 
     80     inImgPtrY = (mmUchar *) i_img_ptr->imgPtr + i_img_ptr->uOffset;
     81     inImgPtrU = (mmUchar *) i_img_ptr->clrPtr + i_img_ptr->uOffset/2;
     82     inImgPtrV = (mmUchar*)inImgPtrU + 1;
     83 
     84     if ( !cropout ) {
     85         cox = 0;
     86         coy = 0;
     87         codx = o_img_ptr->uWidth;
     88         cody = o_img_ptr->uHeight;
     89     } else {
     90         cox = cropout->x;
     91         coy = cropout->y;
     92         codx = cropout->uWidth;
     93         cody = cropout->uHeight;
     94     }
     95     idx = i_img_ptr->uWidth;
     96     idy = i_img_ptr->uHeight;
     97 
     98     /* make sure valid input size */
     99     if ( idx < 1 || idy < 1 || i_img_ptr->uStride < 1 ) {
    100         CAMHAL_LOGE("idx or idy less then 1 idx = %d idy = %d stride = %d", idx, idy, i_img_ptr->uStride);
    101         return false;
    102     }
    103 
    104     resizeFactorX = ((idx-1)<<9) / codx;
    105     resizeFactorY = ((idy-1)<<9) / cody;
    106 
    107     if( i_img_ptr->eFormat != IC_FORMAT_YCbCr420_lp ||
    108             o_img_ptr->eFormat != IC_FORMAT_YCbCr420_lp ) {
    109         CAMHAL_LOGE("eFormat not supported");
    110         return false;
    111     }
    112 
    113     ptr8 = (mmUchar*)o_img_ptr->imgPtr + cox + coy*o_img_ptr->uWidth;
    114 
    115     ////////////////////////////for Y//////////////////////////
    116     for ( row = 0; row < cody; row++ ) {
    117         mmUchar *pu8Yrow1 = NULL;
    118         mmUchar *pu8Yrow2 = NULL;
    119         y  = (mmUint16) ((mmUint32) (row*resizeFactorY) >> 9);
    120         yf = (mmUchar)  ((mmUint32)((row*resizeFactorY) >> 6) & 0x7);
    121         pu8Yrow1 = inImgPtrY + (y) * i_img_ptr->uStride;
    122         pu8Yrow2 = pu8Yrow1 + i_img_ptr->uStride;
    123 
    124         for ( col = 0; col < codx; col++ ) {
    125             mmUchar in11, in12, in21, in22;
    126             mmUchar *pu8ptr1 = NULL;
    127             mmUchar *pu8ptr2 = NULL;
    128             mmUchar w;
    129             mmUint16 accum_1;
    130             //mmUint32 accum_W;
    131 
    132             x  = (mmUint16) ((mmUint32)  (col*resizeFactorX) >> 9);
    133             xf = (mmUchar)  ((mmUint32) ((col*resizeFactorX) >> 6) & 0x7);
    134 
    135             //accum_W = 0;
    136             accum_1 =  0;
    137 
    138             pu8ptr1 = pu8Yrow1 + (x);
    139             pu8ptr2 = pu8Yrow2 + (x);
    140 
    141             /* A pixel */
    142             //in = *(inImgPtrY + (y)*idx + (x));
    143             in11 = *(pu8ptr1);
    144 
    145             w = bWeights[xf][yf][0];
    146             accum_1 = (w * in11);
    147             //accum_W += (w);
    148 
    149             /* B pixel */
    150             //in = *(inImgPtrY + (y)*idx + (x+1));
    151             in12 = *(pu8ptr1+1);
    152             w = bWeights[xf][yf][1];
    153             accum_1 += (w * in12);
    154             //accum_W += (w);
    155 
    156             /* C pixel */
    157             //in = *(inImgPtrY + (y+1)*idx + (x));
    158             in21 = *(pu8ptr2);
    159             w = bWeights[xf][yf][3];
    160             accum_1 += (w * in21);
    161             //accum_W += (w);
    162 
    163             /* D pixel */
    164             //in = *(inImgPtrY + (y+1)*idx + (x+1));
    165             in22 = *(pu8ptr2+1);
    166             w = bWeights[xf][yf][2];
    167             accum_1 += (w * in22);
    168             //accum_W += (w);
    169 
    170             /* divide by sum of the weights */
    171             //accum_1 /= (accum_W);
    172             //accum_1 = (accum_1/64);
    173             accum_1 = (accum_1>>6);
    174             *ptr8 = (mmUchar)accum_1 ;
    175 
    176             ptr8++;
    177         }
    178         ptr8 = ptr8 + (o_img_ptr->uStride - codx);
    179     }
    180     ////////////////////////////for Y//////////////////////////
    181 
    182     ///////////////////////////////for Cb-Cr//////////////////////
    183 
    184     ptr8Cb = (mmUchar*)o_img_ptr->clrPtr + cox + coy*o_img_ptr->uWidth;
    185 
    186     ptr8Cr = (mmUchar*)(ptr8Cb+1);
    187 
    188     idxC = (idx>>1);
    189     for ( row = 0; row < (((cody)>>1)); row++ ) {
    190         mmUchar *pu8Cbr1 = NULL;
    191         mmUchar *pu8Cbr2 = NULL;
    192         mmUchar *pu8Crr1 = NULL;
    193         mmUchar *pu8Crr2 = NULL;
    194 
    195         y  = (mmUint16) ((mmUint32) (row*resizeFactorY) >> 9);
    196         yf = (mmUchar)  ((mmUint32)((row*resizeFactorY) >> 6) & 0x7);
    197 
    198         pu8Cbr1 = inImgPtrU + (y) * i_img_ptr->uStride;
    199         pu8Cbr2 = pu8Cbr1 + i_img_ptr->uStride;
    200         pu8Crr1 = inImgPtrV + (y) * i_img_ptr->uStride;
    201         pu8Crr2 = pu8Crr1 + i_img_ptr->uStride;
    202 
    203         for ( col = 0; col < (((codx)>>1)); col++ ) {
    204             mmUchar in11, in12, in21, in22;
    205             mmUchar *pu8Cbc1 = NULL;
    206             mmUchar *pu8Cbc2 = NULL;
    207             mmUchar *pu8Crc1 = NULL;
    208             mmUchar *pu8Crc2 = NULL;
    209 
    210             mmUchar w;
    211             mmUint16 accum_1Cb, accum_1Cr;
    212             //mmUint32 accum_WCb, accum_WCr;
    213 
    214             x  = (mmUint16) ((mmUint32)  (col*resizeFactorX) >> 9);
    215             xf = (mmUchar)  ((mmUint32) ((col*resizeFactorX) >> 6) & 0x7);
    216 
    217             //accum_WCb = accum_WCr =  0;
    218             accum_1Cb = accum_1Cr =  0;
    219 
    220             pu8Cbc1 = pu8Cbr1 + (x*2);
    221             pu8Cbc2 = pu8Cbr2 + (x*2);
    222             pu8Crc1 = pu8Crr1 + (x*2);
    223             pu8Crc2 = pu8Crr2 + (x*2);
    224 
    225             /* A pixel */
    226             w = bWeights[xf][yf][0];
    227 
    228             in11 = *(pu8Cbc1);
    229             accum_1Cb = (w * in11);
    230             //    accum_WCb += (w);
    231 
    232             in11 = *(pu8Crc1);
    233             accum_1Cr = (w * in11);
    234             //accum_WCr += (w);
    235 
    236             /* B pixel */
    237             w = bWeights[xf][yf][1];
    238 
    239             in12 = *(pu8Cbc1+2);
    240             accum_1Cb += (w * in12);
    241             //accum_WCb += (w);
    242 
    243             in12 = *(pu8Crc1+2);
    244             accum_1Cr += (w * in12);
    245             //accum_WCr += (w);
    246 
    247             /* C pixel */
    248             w = bWeights[xf][yf][3];
    249 
    250             in21 = *(pu8Cbc2);
    251             accum_1Cb += (w * in21);
    252             //accum_WCb += (w);
    253 
    254             in21 = *(pu8Crc2);
    255             accum_1Cr += (w * in21);
    256             //accum_WCr += (w);
    257 
    258             /* D pixel */
    259             w = bWeights[xf][yf][2];
    260 
    261             in22 = *(pu8Cbc2+2);
    262             accum_1Cb += (w * in22);
    263             //accum_WCb += (w);
    264 
    265             in22 = *(pu8Crc2+2);
    266             accum_1Cr += (w * in22);
    267             //accum_WCr += (w);
    268 
    269             /* divide by sum of the weights */
    270             //accum_1Cb /= (accum_WCb);
    271             accum_1Cb = (accum_1Cb>>6);
    272             *ptr8Cb = (mmUchar)accum_1Cb ;
    273 
    274             accum_1Cr = (accum_1Cr >> 6);
    275             *ptr8Cr = (mmUchar)accum_1Cr ;
    276 
    277             ptr8Cb++;
    278             ptr8Cr++;
    279 
    280             ptr8Cb++;
    281             ptr8Cr++;
    282         }
    283         ptr8Cb = ptr8Cb + (o_img_ptr->uStride-codx);
    284         ptr8Cr = ptr8Cr + (o_img_ptr->uStride-codx);
    285     }
    286     ///////////////////For Cb- Cr////////////////////////////////////////
    287 
    288     CAMHAL_LOGV("success");
    289     return true;
    290 }
    291