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============================================================================*/
40mmBool
41VT_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