/* * Copyright (C) Texas Instruments - http://www.ti.com/ * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "NV12_resize.h" #ifdef LOG_TAG #undef LOG_TAG #endif #define LOG_TAG "NV12_resize" #define STRIDE 4096 /*========================================================================== * Function Name : VT_resizeFrame_Video_opt2_lp * * Description : Resize a yuv frame. * * Input(s) : input_img_ptr -> Input Image Structure * : output_img_ptr -> Output Image Structure * : cropout -> crop structure * * Value Returned : mmBool -> FALSE on error TRUE on success * NOTE: * Not tested for crop funtionallity. * faster version. ============================================================================*/ mmBool VT_resizeFrame_Video_opt2_lp( structConvImage* i_img_ptr, /* Points to the input image */ structConvImage* o_img_ptr, /* Points to the output image */ IC_rect_type* cropout, /* how much to resize to in final image */ mmUint16 dummy /* Transparent pixel value */ ) { LOG_FUNCTION_NAME; mmUint16 row,col; mmUint32 resizeFactorX; mmUint32 resizeFactorY; mmUint16 x, y; mmUchar* ptr8; mmUchar *ptr8Cb, *ptr8Cr; mmUint16 xf, yf; mmUchar* inImgPtrY; mmUchar* inImgPtrU; mmUchar* inImgPtrV; mmUint32 cox, coy, codx, cody; mmUint16 idx,idy, idxC; if ( i_img_ptr->uWidth == o_img_ptr->uWidth ) { if ( i_img_ptr->uHeight == o_img_ptr->uHeight ) { CAMHAL_LOGV("************************f(i_img_ptr->uHeight == o_img_ptr->uHeight) are same *********************\n"); CAMHAL_LOGV("************************(i_img_ptr->width == %d" , i_img_ptr->uWidth ); CAMHAL_LOGV("************************(i_img_ptr->uHeight == %d" , i_img_ptr->uHeight ); CAMHAL_LOGV("************************(o_img_ptr->width == %d" ,o_img_ptr->uWidth ); CAMHAL_LOGV("************************(o_img_ptr->uHeight == %d" , o_img_ptr->uHeight ); } } if ( !i_img_ptr || !i_img_ptr->imgPtr || !o_img_ptr || !o_img_ptr->imgPtr ) { CAMHAL_LOGE("Image Point NULL"); return false; } inImgPtrY = (mmUchar *) i_img_ptr->imgPtr + i_img_ptr->uOffset; inImgPtrU = (mmUchar *) i_img_ptr->clrPtr + i_img_ptr->uOffset/2; inImgPtrV = (mmUchar*)inImgPtrU + 1; if ( !cropout ) { cox = 0; coy = 0; codx = o_img_ptr->uWidth; cody = o_img_ptr->uHeight; } else { cox = cropout->x; coy = cropout->y; codx = cropout->uWidth; cody = cropout->uHeight; } idx = i_img_ptr->uWidth; idy = i_img_ptr->uHeight; /* make sure valid input size */ if ( idx < 1 || idy < 1 || i_img_ptr->uStride < 1 ) { CAMHAL_LOGE("idx or idy less then 1 idx = %d idy = %d stride = %d", idx, idy, i_img_ptr->uStride); return false; } resizeFactorX = ((idx-1)<<9) / codx; resizeFactorY = ((idy-1)<<9) / cody; if( i_img_ptr->eFormat != IC_FORMAT_YCbCr420_lp || o_img_ptr->eFormat != IC_FORMAT_YCbCr420_lp ) { CAMHAL_LOGE("eFormat not supported"); return false; } ptr8 = (mmUchar*)o_img_ptr->imgPtr + cox + coy*o_img_ptr->uWidth; ////////////////////////////for Y////////////////////////// for ( row = 0; row < cody; row++ ) { mmUchar *pu8Yrow1 = NULL; mmUchar *pu8Yrow2 = NULL; y = (mmUint16) ((mmUint32) (row*resizeFactorY) >> 9); yf = (mmUchar) ((mmUint32)((row*resizeFactorY) >> 6) & 0x7); pu8Yrow1 = inImgPtrY + (y) * i_img_ptr->uStride; pu8Yrow2 = pu8Yrow1 + i_img_ptr->uStride; for ( col = 0; col < codx; col++ ) { mmUchar in11, in12, in21, in22; mmUchar *pu8ptr1 = NULL; mmUchar *pu8ptr2 = NULL; mmUchar w; mmUint16 accum_1; //mmUint32 accum_W; x = (mmUint16) ((mmUint32) (col*resizeFactorX) >> 9); xf = (mmUchar) ((mmUint32) ((col*resizeFactorX) >> 6) & 0x7); //accum_W = 0; accum_1 = 0; pu8ptr1 = pu8Yrow1 + (x); pu8ptr2 = pu8Yrow2 + (x); /* A pixel */ //in = *(inImgPtrY + (y)*idx + (x)); in11 = *(pu8ptr1); w = bWeights[xf][yf][0]; accum_1 = (w * in11); //accum_W += (w); /* B pixel */ //in = *(inImgPtrY + (y)*idx + (x+1)); in12 = *(pu8ptr1+1); w = bWeights[xf][yf][1]; accum_1 += (w * in12); //accum_W += (w); /* C pixel */ //in = *(inImgPtrY + (y+1)*idx + (x)); in21 = *(pu8ptr2); w = bWeights[xf][yf][3]; accum_1 += (w * in21); //accum_W += (w); /* D pixel */ //in = *(inImgPtrY + (y+1)*idx + (x+1)); in22 = *(pu8ptr2+1); w = bWeights[xf][yf][2]; accum_1 += (w * in22); //accum_W += (w); /* divide by sum of the weights */ //accum_1 /= (accum_W); //accum_1 = (accum_1/64); accum_1 = (accum_1>>6); *ptr8 = (mmUchar)accum_1 ; ptr8++; } ptr8 = ptr8 + (o_img_ptr->uStride - codx); } ////////////////////////////for Y////////////////////////// ///////////////////////////////for Cb-Cr////////////////////// ptr8Cb = (mmUchar*)o_img_ptr->clrPtr + cox + coy*o_img_ptr->uWidth; ptr8Cr = (mmUchar*)(ptr8Cb+1); idxC = (idx>>1); for ( row = 0; row < (((cody)>>1)); row++ ) { mmUchar *pu8Cbr1 = NULL; mmUchar *pu8Cbr2 = NULL; mmUchar *pu8Crr1 = NULL; mmUchar *pu8Crr2 = NULL; y = (mmUint16) ((mmUint32) (row*resizeFactorY) >> 9); yf = (mmUchar) ((mmUint32)((row*resizeFactorY) >> 6) & 0x7); pu8Cbr1 = inImgPtrU + (y) * i_img_ptr->uStride; pu8Cbr2 = pu8Cbr1 + i_img_ptr->uStride; pu8Crr1 = inImgPtrV + (y) * i_img_ptr->uStride; pu8Crr2 = pu8Crr1 + i_img_ptr->uStride; for ( col = 0; col < (((codx)>>1)); col++ ) { mmUchar in11, in12, in21, in22; mmUchar *pu8Cbc1 = NULL; mmUchar *pu8Cbc2 = NULL; mmUchar *pu8Crc1 = NULL; mmUchar *pu8Crc2 = NULL; mmUchar w; mmUint16 accum_1Cb, accum_1Cr; //mmUint32 accum_WCb, accum_WCr; x = (mmUint16) ((mmUint32) (col*resizeFactorX) >> 9); xf = (mmUchar) ((mmUint32) ((col*resizeFactorX) >> 6) & 0x7); //accum_WCb = accum_WCr = 0; accum_1Cb = accum_1Cr = 0; pu8Cbc1 = pu8Cbr1 + (x*2); pu8Cbc2 = pu8Cbr2 + (x*2); pu8Crc1 = pu8Crr1 + (x*2); pu8Crc2 = pu8Crr2 + (x*2); /* A pixel */ w = bWeights[xf][yf][0]; in11 = *(pu8Cbc1); accum_1Cb = (w * in11); // accum_WCb += (w); in11 = *(pu8Crc1); accum_1Cr = (w * in11); //accum_WCr += (w); /* B pixel */ w = bWeights[xf][yf][1]; in12 = *(pu8Cbc1+2); accum_1Cb += (w * in12); //accum_WCb += (w); in12 = *(pu8Crc1+2); accum_1Cr += (w * in12); //accum_WCr += (w); /* C pixel */ w = bWeights[xf][yf][3]; in21 = *(pu8Cbc2); accum_1Cb += (w * in21); //accum_WCb += (w); in21 = *(pu8Crc2); accum_1Cr += (w * in21); //accum_WCr += (w); /* D pixel */ w = bWeights[xf][yf][2]; in22 = *(pu8Cbc2+2); accum_1Cb += (w * in22); //accum_WCb += (w); in22 = *(pu8Crc2+2); accum_1Cr += (w * in22); //accum_WCr += (w); /* divide by sum of the weights */ //accum_1Cb /= (accum_WCb); accum_1Cb = (accum_1Cb>>6); *ptr8Cb = (mmUchar)accum_1Cb ; accum_1Cr = (accum_1Cr >> 6); *ptr8Cr = (mmUchar)accum_1Cr ; ptr8Cb++; ptr8Cr++; ptr8Cb++; ptr8Cr++; } ptr8Cb = ptr8Cb + (o_img_ptr->uStride-codx); ptr8Cr = ptr8Cr + (o_img_ptr->uStride-codx); } ///////////////////For Cb- Cr//////////////////////////////////////// CAMHAL_LOGV("success"); return true; }