fixed coverity issues
[platform/adaptation/ap_samsung/libomxil-e3250-v4l2.git] / exynos4 / libswconverter / swconvertor.c
1 /*
2  *
3  * Copyright 2012 Samsung Electronics S.LSI Co. LTD
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  *      http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  */
17
18 /*
19  * @file    swconvertor.c
20  *
21  * @brief   SEC_OMX specific define
22  *
23  * @author  ShinWon Lee (shinwon.lee@samsung.com)
24  *
25  * @version 1.0
26  *
27  * @history
28  *   2012.02.01 : Create
29  */
30
31 #include <stdio.h>
32 #include <stdlib.h>
33 #include <string.h>
34
35 #include "swconverter.h"
36
37 /*
38  * Get tiled address of position(x,y)
39  *
40  * @param x_size
41  *   width of tiled[in]
42  *
43  * @param y_size
44  *   height of tiled[in]
45  *
46  * @param x_pos
47  *   x position of tield[in]
48  *
49  * @param src_size
50  *   y position of tield[in]
51  *
52  * @return
53  *   address of tiled data
54  */
55 static int tile_4x2_read(int x_size, int y_size, int x_pos, int y_pos)
56 {
57     int pixel_x_m1, pixel_y_m1;
58     int roundup_x;
59     int linear_addr0, linear_addr1, bank_addr ;
60     int x_addr;
61     int trans_addr;
62
63     pixel_x_m1 = x_size -1;
64     pixel_y_m1 = y_size -1;
65
66     roundup_x = ((pixel_x_m1 >> 7) + 1);
67
68     x_addr = x_pos >> 2;
69
70     if ((y_size <= y_pos+32) && ( y_pos < y_size) &&
71         (((pixel_y_m1 >> 5) & 0x1) == 0) && (((y_pos >> 5) & 0x1) == 0)) {
72         linear_addr0 = (((y_pos & 0x1f) <<4) | (x_addr & 0xf));
73         linear_addr1 = (((y_pos >> 6) & 0xff) * roundup_x + ((x_addr >> 6) & 0x3f));
74
75         if (((x_addr >> 5) & 0x1) == ((y_pos >> 5) & 0x1))
76             bank_addr = ((x_addr >> 4) & 0x1);
77         else
78             bank_addr = 0x2 | ((x_addr >> 4) & 0x1);
79     } else {
80         linear_addr0 = (((y_pos & 0x1f) << 4) | (x_addr & 0xf));
81         linear_addr1 = (((y_pos >> 6) & 0xff) * roundup_x + ((x_addr >> 5) & 0x7f));
82
83         if (((x_addr >> 5) & 0x1) == ((y_pos >> 5) & 0x1))
84             bank_addr = ((x_addr >> 4) & 0x1);
85         else
86             bank_addr = 0x2 | ((x_addr >> 4) & 0x1);
87     }
88
89     linear_addr0 = linear_addr0 << 2;
90     trans_addr = (linear_addr1 <<13) | (bank_addr << 11) | linear_addr0;
91
92     return trans_addr;
93 }
94
95 /*
96  * De-interleaves src to dest1, dest2
97  *
98  * @param dest1
99  *   Address of de-interleaved data[out]
100  *
101  * @param dest2
102  *   Address of de-interleaved data[out]
103  *
104  * @param src
105  *   Address of interleaved data[in]
106  *
107  * @param src_size
108  *   Size of interleaved data[in]
109  */
110 void csc_deinterleave_memcpy(
111     unsigned char *dest1,
112     unsigned char *dest2,
113     unsigned char *src,
114     unsigned int src_size)
115 {
116     unsigned int i = 0;
117     for(i=0; i<src_size/2; i++) {
118         dest1[i] = src[i*2];
119         dest2[i] = src[i*2+1];
120     }
121 }
122
123 /*
124  * Interleaves src1, src2 to dest
125  *
126  * @param dest
127  *   Address of interleaved data[out]
128  *
129  * @param src1
130  *   Address of de-interleaved data[in]
131  *
132  * @param src2
133  *   Address of de-interleaved data[in]
134  *
135  * @param src_size
136  *   Size of de-interleaved data[in]
137  */
138 void csc_interleave_memcpy(
139     unsigned char *dest,
140     unsigned char *src1,
141     unsigned char *src2,
142     unsigned int src_size)
143 {
144     unsigned int i = 0;
145     for(i=0; i<src_size; i++) {
146         dest[i * 2] = src1[i];
147         dest[i * 2 + 1] = src2[i];
148     }
149 }
150
151 /*
152  * Converts tiled data to linear
153  * Crops left, top, right, buttom
154  * 1. Y of NV12T to Y of YUV420P
155  * 2. Y of NV12T to Y of YUV420S
156  * 3. UV of NV12T to UV of YUV420S
157  *
158  * @param yuv420_dest
159  *   Y or UV plane address of YUV420[out]
160  *
161  * @param nv12t_src
162  *   Y or UV plane address of NV12T[in]
163  *
164  * @param yuv420_width
165  *   Width of YUV420[in]
166  *
167  * @param yuv420_height
168  *   Y: Height of YUV420, UV: Height/2 of YUV420[in]
169  *
170  * @param left
171  *   Crop size of left
172  *
173  * @param top
174  *   Crop size of top
175  *
176  * @param right
177  *   Crop size of right
178  *
179  * @param buttom
180  *   Crop size of buttom
181  */
182 static void csc_tiled_to_linear_crop(
183     unsigned char *yuv420_dest,
184     unsigned char *nv12t_src,
185     unsigned int yuv420_width,
186     unsigned int yuv420_height,
187     unsigned int left,
188     unsigned int top,
189     unsigned int right,
190     unsigned int buttom)
191 {
192     unsigned int i, j;
193     unsigned int tiled_offset = 0, tiled_offset1 = 0;
194     unsigned int linear_offset = 0;
195     unsigned int temp1 = 0, temp2 = 0, temp3 = 0, temp4 = 0;
196
197     temp3 = yuv420_width-right;
198     temp1 = temp3-left;
199     /* real width is greater than or equal 256 */
200     if (temp1 >= 256) {
201         for (i=top; i<yuv420_height-buttom; i=i+1) {
202             j = left;
203             temp3 = (j>>8)<<8;
204             temp3 = temp3>>6;
205             temp4 = i>>5;
206             if (temp4 & 0x1) {
207                 /* odd fomula: 2+x+(x>>2)<<2+x_block_num*(y-1) */
208                 tiled_offset = temp4-1;
209                 temp1 = ((yuv420_width+127)>>7)<<7;
210                 tiled_offset = tiled_offset*(temp1>>6);
211                 tiled_offset = tiled_offset+temp3;
212                 tiled_offset = tiled_offset+2;
213                 temp1 = (temp3>>2)<<2;
214                 tiled_offset = tiled_offset+temp1;
215                 tiled_offset = tiled_offset<<11;
216                 tiled_offset1 = tiled_offset+2048*2;
217                 temp4 = 8;
218             } else {
219                 temp2 = ((yuv420_height+31)>>5)<<5;
220                 if ((i+32)<temp2) {
221                     /* even1 fomula: x+((x+2)>>2)<<2+x_block_num*y */
222                     temp1 = temp3+2;
223                     temp1 = (temp1>>2)<<2;
224                     tiled_offset = temp3+temp1;
225                     temp1 = ((yuv420_width+127)>>7)<<7;
226                     tiled_offset = tiled_offset+temp4*(temp1>>6);
227                     tiled_offset = tiled_offset<<11;
228                     tiled_offset1 = tiled_offset+2048*6;
229                     temp4 = 8;
230                 } else {
231                     /* even2 fomula: x+x_block_num*y */
232                     temp1 = ((yuv420_width+127)>>7)<<7;
233                     tiled_offset = temp4*(temp1>>6);
234                     tiled_offset = tiled_offset+temp3;
235                     tiled_offset = tiled_offset<<11;
236                     tiled_offset1 = tiled_offset+2048*2;
237                     temp4 = 4;
238                 }
239             }
240
241             temp1 = i&0x1F;
242             tiled_offset = tiled_offset+64*(temp1);
243             tiled_offset1 = tiled_offset1+64*(temp1);
244             temp2 = yuv420_width-left-right;
245             linear_offset = temp2*(i-top);
246             temp3 = ((j+256)>>8)<<8;
247             temp3 = temp3-j;
248             temp1 = left&0x3F;
249             if (temp3 > 192) {
250                 memcpy(yuv420_dest+linear_offset, nv12t_src+tiled_offset+temp1, 64-temp1);
251                 memcpy(yuv420_dest+linear_offset+64-temp1, nv12t_src+tiled_offset+2048, 64);
252                 memcpy(yuv420_dest+linear_offset+128-temp1, nv12t_src+tiled_offset1, 64);
253                 memcpy(yuv420_dest+linear_offset+192-temp1, nv12t_src+tiled_offset1+2048, 64);
254                 linear_offset = linear_offset+256-temp1;
255             } else if (temp3 > 128) {
256                 memcpy(yuv420_dest+linear_offset, nv12t_src+tiled_offset+2048+temp1, 64-temp1);
257                 memcpy(yuv420_dest+linear_offset+64-temp1, nv12t_src+tiled_offset1, 64);
258                 memcpy(yuv420_dest+linear_offset+128-temp1, nv12t_src+tiled_offset1+2048, 64);
259                 linear_offset = linear_offset+192-temp1;
260             } else if (temp3 > 64) {
261                 memcpy(yuv420_dest+linear_offset, nv12t_src+tiled_offset1+temp1, 64-temp1);
262                 memcpy(yuv420_dest+linear_offset+64-temp1, nv12t_src+tiled_offset1+2048, 64);
263                 linear_offset = linear_offset+128-temp1;
264             } else if (temp3 > 0) {
265                 memcpy(yuv420_dest+linear_offset, nv12t_src+tiled_offset1+2048+temp1, 64-temp1);
266                 linear_offset = linear_offset+64-temp1;
267             }
268
269             tiled_offset = tiled_offset+temp4*2048;
270             j = (left>>8)<<8;
271             j = j + 256;
272             temp2 = yuv420_width-right-256;
273             for (; j<=temp2; j=j+256) {
274                 memcpy(yuv420_dest+linear_offset, nv12t_src+tiled_offset, 64);
275                 tiled_offset1 = tiled_offset1+temp4*2048;
276                 memcpy(yuv420_dest+linear_offset+64, nv12t_src+tiled_offset+2048, 64);
277                 memcpy(yuv420_dest+linear_offset+128, nv12t_src+tiled_offset1, 64);
278                 tiled_offset = tiled_offset+temp4*2048;
279                 memcpy(yuv420_dest+linear_offset+192, nv12t_src+tiled_offset1+2048, 64);
280                 linear_offset = linear_offset+256;
281             }
282
283             tiled_offset1 = tiled_offset1+temp4*2048;
284             temp2 = yuv420_width-right-j;
285             if (temp2 > 192) {
286                 memcpy(yuv420_dest+linear_offset, nv12t_src+tiled_offset, 64);
287                 memcpy(yuv420_dest+linear_offset+64, nv12t_src+tiled_offset+2048, 64);
288                 memcpy(yuv420_dest+linear_offset+128, nv12t_src+tiled_offset1, 64);
289                 memcpy(yuv420_dest+linear_offset+192, nv12t_src+tiled_offset1+2048, temp2-192);
290             } else if (temp2 > 128) {
291                 memcpy(yuv420_dest+linear_offset, nv12t_src+tiled_offset, 64);
292                 memcpy(yuv420_dest+linear_offset+64, nv12t_src+tiled_offset+2048, 64);
293                 memcpy(yuv420_dest+linear_offset+128, nv12t_src+tiled_offset1, temp2-128);
294             } else if (temp2 > 64) {
295                 memcpy(yuv420_dest+linear_offset, nv12t_src+tiled_offset, 64);
296                 memcpy(yuv420_dest+linear_offset+64, nv12t_src+tiled_offset+2048, temp2-64);
297             } else {
298                 memcpy(yuv420_dest+linear_offset, nv12t_src+tiled_offset, temp2);
299             }
300         }
301     } else if (temp1 >= 64) {
302         for (i=top; i<(yuv420_height-buttom); i=i+1) {
303             j = left;
304             tiled_offset = tile_4x2_read(yuv420_width, yuv420_height, j, i);
305             temp2 = ((j+64)>>6)<<6;
306             temp2 = temp2-j;
307             linear_offset = temp1*(i-top);
308             temp4 = j&0x3;
309             tiled_offset = tiled_offset+temp4;
310             memcpy(yuv420_dest+linear_offset, nv12t_src+tiled_offset, temp2);
311             linear_offset = linear_offset+temp2;
312             j = j+temp2;
313             if ((j+64) <= temp3) {
314                 tiled_offset = tile_4x2_read(yuv420_width, yuv420_height, j, i);
315                 memcpy(yuv420_dest+linear_offset, nv12t_src+tiled_offset, 64);
316                 linear_offset = linear_offset+64;
317                 j = j+64;
318             }
319             if ((j+64) <= temp3) {
320                 tiled_offset = tile_4x2_read(yuv420_width, yuv420_height, j, i);
321                 memcpy(yuv420_dest+linear_offset, nv12t_src+tiled_offset, 64);
322                 linear_offset = linear_offset+64;
323                 j = j+64;
324             }
325             if (j < temp3) {
326                 tiled_offset = tile_4x2_read(yuv420_width, yuv420_height, j, i);
327                 temp2 = temp3-j;
328                 memcpy(yuv420_dest+linear_offset, nv12t_src+tiled_offset, temp2);
329             }
330         }
331     } else {
332         for (i=top; i<(yuv420_height-buttom); i=i+1) {
333             linear_offset = temp1*(i-top);
334             for (j=left; j<(yuv420_width-right); j=j+2) {
335                 tiled_offset = tile_4x2_read(yuv420_width, yuv420_height, j, i);
336                 temp4 = j&0x3;
337                 tiled_offset = tiled_offset+temp4;
338                 memcpy(yuv420_dest+linear_offset, nv12t_src+tiled_offset, 2);
339                 linear_offset = linear_offset+2;
340             }
341         }
342     }
343 }
344
345 /*
346  * Converts and Deinterleaves tiled data to linear
347  * Crops left, top, right, buttom
348  * 1. UV of NV12T to UV of YUV420P
349  *
350  * @param yuv420_u_dest
351  *   U plane address of YUV420P[out]
352  *
353  * @param yuv420_v_dest
354  *   V plane address of YUV420P[out]
355  *
356  * @param nv12t_src
357  *   UV plane address of NV12T[in]
358  *
359  * @param yuv420_width
360  *   Width of YUV420[in]
361  *
362  * @param yuv420_uv_height
363  *   Height/2 of YUV420[in]
364  *
365  * @param left
366  *   Crop size of left
367  *
368  * @param top
369  *   Crop size of top
370  *
371  * @param right
372  *   Crop size of right
373  *
374  * @param buttom
375  *   Crop size of buttom
376  */
377 static void csc_tiled_to_linear_deinterleave_crop(
378     unsigned char *yuv420_u_dest,
379     unsigned char *yuv420_v_dest,
380     unsigned char *nv12t_uv_src,
381     unsigned int yuv420_width,
382     unsigned int yuv420_uv_height,
383     unsigned int left,
384     unsigned int top,
385     unsigned int right,
386     unsigned int buttom)
387 {
388     unsigned int i, j;
389     unsigned int tiled_offset = 0, tiled_offset1 = 0;
390     unsigned int linear_offset = 0;
391     unsigned int temp1 = 0, temp2 = 0, temp3 = 0, temp4 = 0;
392
393     temp3 = yuv420_width-right;
394     temp1 = temp3-left;
395     /* real width is greater than or equal 256 */
396     if (temp1 >= 256) {
397         for (i=top; i<yuv420_uv_height-buttom; i=i+1) {
398             j = left;
399             temp3 = (j>>8)<<8;
400             temp3 = temp3>>6;
401             temp4 = i>>5;
402             if (temp4 & 0x1) {
403                 /* odd fomula: 2+x+(x>>2)<<2+x_block_num*(y-1) */
404                 tiled_offset = temp4-1;
405                 temp1 = ((yuv420_width+127)>>7)<<7;
406                 tiled_offset = tiled_offset*(temp1>>6);
407                 tiled_offset = tiled_offset+temp3;
408                 tiled_offset = tiled_offset+2;
409                 temp1 = (temp3>>2)<<2;
410                 tiled_offset = tiled_offset+temp1;
411                 tiled_offset = tiled_offset<<11;
412                 tiled_offset1 = tiled_offset+2048*2;
413                 temp4 = 8;
414             } else {
415                 temp2 = ((yuv420_uv_height+31)>>5)<<5;
416                 if ((i+32)<temp2) {
417                     /* even1 fomula: x+((x+2)>>2)<<2+x_block_num*y */
418                     temp1 = temp3+2;
419                     temp1 = (temp1>>2)<<2;
420                     tiled_offset = temp3+temp1;
421                     temp1 = ((yuv420_width+127)>>7)<<7;
422                     tiled_offset = tiled_offset+temp4*(temp1>>6);
423                     tiled_offset = tiled_offset<<11;
424                     tiled_offset1 = tiled_offset+2048*6;
425                     temp4 = 8;
426                 } else {
427                     /* even2 fomula: x+x_block_num*y */
428                     temp1 = ((yuv420_width+127)>>7)<<7;
429                     tiled_offset = temp4*(temp1>>6);
430                     tiled_offset = tiled_offset+temp3;
431                     tiled_offset = tiled_offset<<11;
432                     tiled_offset1 = tiled_offset+2048*2;
433                     temp4 = 4;
434                 }
435             }
436
437             temp1 = i&0x1F;
438             tiled_offset = tiled_offset+64*(temp1);
439             tiled_offset1 = tiled_offset1+64*(temp1);
440             temp2 = yuv420_width-left-right;
441             linear_offset = temp2*(i-top)/2;
442             temp3 = ((j+256)>>8)<<8;
443             temp3 = temp3-j;
444             temp1 = left&0x3F;
445             if (temp3 > 192) {
446                 csc_deinterleave_memcpy(yuv420_u_dest+linear_offset, yuv420_v_dest+linear_offset, nv12t_uv_src+tiled_offset+temp1, 64-temp1);
447                 csc_deinterleave_memcpy(yuv420_u_dest+linear_offset+(32-temp1/2),
448                                         yuv420_v_dest+linear_offset+(32-temp1/2),
449                                         nv12t_uv_src+tiled_offset+2048, 64);
450                 csc_deinterleave_memcpy(yuv420_u_dest+linear_offset+(64-temp1/2),
451                                         yuv420_v_dest+linear_offset+(64-temp1/2),
452                                         nv12t_uv_src+tiled_offset1, 64);
453                 csc_deinterleave_memcpy(yuv420_u_dest+linear_offset+(96-temp1/2),
454                                         yuv420_v_dest+linear_offset+(96-temp1/2),
455                                         nv12t_uv_src+tiled_offset1+2048, 64);
456                 linear_offset = linear_offset+128-temp1/2;
457             } else if (temp3 > 128) {
458                 csc_deinterleave_memcpy(yuv420_u_dest+linear_offset,
459                                         yuv420_v_dest+linear_offset,
460                                         nv12t_uv_src+tiled_offset+2048+temp1, 64-temp1);
461                 csc_deinterleave_memcpy(yuv420_u_dest+linear_offset+(32-temp1/2),
462                                         yuv420_v_dest+linear_offset+(32-temp1/2),
463                                         nv12t_uv_src+tiled_offset1, 64);
464                 csc_deinterleave_memcpy(yuv420_u_dest+linear_offset+(64-temp1/2),
465                                         yuv420_v_dest+linear_offset+(64-temp1/2),
466                                         nv12t_uv_src+tiled_offset1+2048, 64);
467                 linear_offset = linear_offset+96-temp1/2;
468             } else if (temp3 > 64) {
469                 csc_deinterleave_memcpy(yuv420_u_dest+linear_offset,
470                                         yuv420_v_dest+linear_offset,
471                                         nv12t_uv_src+tiled_offset1+temp1, 64-temp1);
472                 csc_deinterleave_memcpy(yuv420_u_dest+linear_offset+(32-temp1/2),
473                                         yuv420_v_dest+linear_offset+(32-temp1/2),
474                                         nv12t_uv_src+tiled_offset1+2048, 64);
475                 linear_offset = linear_offset+64-temp1/2;
476             } else if (temp3 > 0) {
477                 csc_deinterleave_memcpy(yuv420_u_dest+linear_offset,
478                                         yuv420_v_dest+linear_offset,
479                                         nv12t_uv_src+tiled_offset1+2048+temp1, 64-temp1);
480                 linear_offset = linear_offset+32-temp1/2;
481             }
482
483             tiled_offset = tiled_offset+temp4*2048;
484             j = (left>>8)<<8;
485             j = j + 256;
486             temp2 = yuv420_width-right-256;
487             for (; j<=temp2; j=j+256) {
488                 csc_deinterleave_memcpy(yuv420_u_dest+linear_offset,
489                                         yuv420_v_dest+linear_offset,
490                                         nv12t_uv_src+tiled_offset, 64);
491                 tiled_offset1 = tiled_offset1+temp4*2048;
492                 csc_deinterleave_memcpy(yuv420_u_dest+linear_offset+32,
493                                         yuv420_v_dest+linear_offset+32,
494                                         nv12t_uv_src+tiled_offset+2048, 64);
495                 csc_deinterleave_memcpy(yuv420_u_dest+linear_offset+64,
496                                         yuv420_v_dest+linear_offset+64,
497                                         nv12t_uv_src+tiled_offset1, 64);
498                 tiled_offset = tiled_offset+temp4*2048;
499                 csc_deinterleave_memcpy(yuv420_u_dest+linear_offset+96,
500                                         yuv420_v_dest+linear_offset+96,
501                                         nv12t_uv_src+tiled_offset1+2048, 64);
502                 linear_offset = linear_offset+128;
503             }
504
505             tiled_offset1 = tiled_offset1+temp4*2048;
506             temp2 = yuv420_width-right-j;
507             if (temp2 > 192) {
508                 csc_deinterleave_memcpy(yuv420_u_dest+linear_offset,
509                                         yuv420_v_dest+linear_offset,
510                                         nv12t_uv_src+tiled_offset, 64);
511                 csc_deinterleave_memcpy(yuv420_u_dest+linear_offset+32,
512                                         yuv420_v_dest+linear_offset+32,
513                                         nv12t_uv_src+tiled_offset+2048, 64);
514                 csc_deinterleave_memcpy(yuv420_u_dest+linear_offset+64,
515                                         yuv420_v_dest+linear_offset+64,
516                                         nv12t_uv_src+tiled_offset1, 64);
517                 csc_deinterleave_memcpy(yuv420_u_dest+linear_offset+96,
518                                         yuv420_v_dest+linear_offset+96,
519                                         nv12t_uv_src+tiled_offset1+2048, temp2-192);
520             } else if (temp2 > 128) {
521                 csc_deinterleave_memcpy(yuv420_u_dest+linear_offset,
522                                         yuv420_v_dest+linear_offset,
523                                         nv12t_uv_src+tiled_offset, 64);
524                 csc_deinterleave_memcpy(yuv420_u_dest+linear_offset+32,
525                                         yuv420_v_dest+linear_offset+32,
526                                         nv12t_uv_src+tiled_offset+2048, 64);
527                 csc_deinterleave_memcpy(yuv420_u_dest+linear_offset+64,
528                                         yuv420_v_dest+linear_offset+64,
529                                         nv12t_uv_src+tiled_offset1, temp2-128);
530             } else if (temp2 > 64) {
531                 csc_deinterleave_memcpy(yuv420_u_dest+linear_offset,
532                                         yuv420_v_dest+linear_offset,
533                                         nv12t_uv_src+tiled_offset, 64);
534                 csc_deinterleave_memcpy(yuv420_u_dest+linear_offset+32,
535                                         yuv420_v_dest+linear_offset+32,
536                                         nv12t_uv_src+tiled_offset+2048, temp2-64);
537             } else {
538                 csc_deinterleave_memcpy(yuv420_u_dest+linear_offset,
539                                         yuv420_v_dest+linear_offset,
540                                         nv12t_uv_src+tiled_offset, temp2);
541             }
542         }
543     } else if (temp1 >= 64) {
544         for (i=top; i<(yuv420_uv_height-buttom); i=i+1) {
545             j = left;
546             tiled_offset = tile_4x2_read(yuv420_width, yuv420_uv_height, j, i);
547             temp2 = ((j+64)>>6)<<6;
548             temp2 = temp2-j;
549             temp3 = yuv420_width-right;
550             temp4 = temp3-left;
551             linear_offset = temp4*(i-top)/2;
552             temp4 = j&0x3;
553             tiled_offset = tiled_offset+temp4;
554             csc_deinterleave_memcpy(yuv420_u_dest+linear_offset,
555                                     yuv420_v_dest+linear_offset,
556                                     nv12t_uv_src+tiled_offset, temp2);
557             linear_offset = linear_offset+temp2/2;
558             j = j+temp2;
559             if ((j+64) <= temp3) {
560                 tiled_offset = tile_4x2_read(yuv420_width, yuv420_uv_height, j, i);
561                 csc_deinterleave_memcpy(yuv420_u_dest+linear_offset,
562                                         yuv420_v_dest+linear_offset,
563                                         nv12t_uv_src+tiled_offset, 64);
564                 linear_offset = linear_offset+32;
565                 j = j+64;
566             }
567             if ((j+64) <= temp3) {
568                 tiled_offset = tile_4x2_read(yuv420_width, yuv420_uv_height, j, i);
569                 csc_deinterleave_memcpy(yuv420_u_dest+linear_offset,
570                                         yuv420_v_dest+linear_offset,
571                                         nv12t_uv_src+tiled_offset, 64);
572                 linear_offset = linear_offset+32;
573                 j = j+64;
574             }
575             if (j < temp3) {
576                 tiled_offset = tile_4x2_read(yuv420_width, yuv420_uv_height, j, i);
577                 temp1 = temp3-j;
578                 csc_deinterleave_memcpy(yuv420_u_dest+linear_offset,
579                                         yuv420_v_dest+linear_offset,
580                                         nv12t_uv_src+tiled_offset, temp1);
581             }
582         }
583     } else {
584         for (i=top; i<(yuv420_uv_height-buttom); i=i+1) {
585             temp3 = yuv420_width-right;
586             temp4 = temp3-left;
587             linear_offset = temp4*(i-top)/2;
588             for (j=left; j<(yuv420_width-right); j=j+2) {
589                 tiled_offset = tile_4x2_read(yuv420_width, yuv420_uv_height, j, i);
590                 temp3 = j&0x3;
591                 tiled_offset = tiled_offset+temp3;
592                 csc_deinterleave_memcpy(yuv420_u_dest+linear_offset,
593                                         yuv420_v_dest+linear_offset,
594                                         nv12t_uv_src+tiled_offset, 2);
595                 linear_offset = linear_offset+1;
596             }
597         }
598     }
599 }
600
601 /*
602  * Converts linear data to tiled
603  * Crops left, top, right, buttom
604  * 1. Y of YUV420P to Y of NV12T
605  * 2. Y of YUV420S to Y of NV12T
606  * 3. UV of YUV420S to UV of NV12T
607  *
608  * @param nv12t_dest
609  *   Y or UV plane address of NV12T[out]
610  *
611  * @param yuv420_src
612  *   Y or UV plane address of YUV420P(S)[in]
613  *
614  * @param yuv420_width
615  *   Width of YUV420[in]
616  *
617  * @param yuv420_height
618  *   Y: Height of YUV420, UV: Height/2 of YUV420[in]
619  *
620  * @param left
621  *   Crop size of left
622  *
623  * @param top
624  *   Crop size of top
625  *
626  * @param right
627  *   Crop size of right
628  *
629  * @param buttom
630  *   Crop size of buttom
631  */
632 static void csc_linear_to_tiled_crop(
633     unsigned char *nv12t_dest,
634     unsigned char *yuv420_src,
635     unsigned int yuv420_width,
636     unsigned int yuv420_height,
637     unsigned int left,
638     unsigned int top,
639     unsigned int right,
640     unsigned int buttom)
641 {
642     unsigned int i, j;
643     unsigned int tiled_x_index = 0, tiled_y_index = 0;
644     unsigned int aligned_x_size = 0, aligned_y_size = 0;
645     unsigned int tiled_offset = 0;
646     unsigned int temp1 = 0, temp2 = 0;
647
648     aligned_y_size = ((yuv420_height-top-buttom)>>5)<<5;
649     aligned_x_size = ((yuv420_width-left-right)>>6)<<6;
650
651     for (i=0; i<aligned_y_size; i=i+32) {
652         for (j=0; j<aligned_x_size; j=j+64) {
653             tiled_offset = 0;
654             tiled_x_index = j>>6;
655             tiled_y_index = i>>5;
656             if (tiled_y_index & 0x1) {
657                 /* odd fomula: 2+x+(x>>2)<<2+x_block_num*(y-1) */
658                 tiled_offset = tiled_y_index-1;
659                 temp1 = (((yuv420_width-left-right)+127)>>7)<<7;
660                 tiled_offset = tiled_offset*(temp1>>6);
661                 tiled_offset = tiled_offset+tiled_x_index;
662                 tiled_offset = tiled_offset+2;
663                 temp1 = (tiled_x_index>>2)<<2;
664                 tiled_offset = tiled_offset+temp1;
665                 tiled_offset = tiled_offset<<11;
666             } else {
667                 temp2 = (((yuv420_height-top-buttom)+31)>>5)<<5;
668                 if ((i+32)<temp2) {
669                     /* even1 fomula: x+((x+2)>>2)<<2+x_block_num*y */
670                     temp1 = tiled_x_index+2;
671                     temp1 = (temp1>>2)<<2;
672                     tiled_offset = tiled_x_index+temp1;
673                     temp1 = (((yuv420_width-left-right)+127)>>7)<<7;
674                     tiled_offset = tiled_offset+tiled_y_index*(temp1>>6);
675                     tiled_offset = tiled_offset<<11;
676                 } else {
677                     /* even2 fomula: x+x_block_num*y */
678                     temp1 = (((yuv420_width-left-right)+127)>>7)<<7;
679                     tiled_offset = tiled_y_index*(temp1>>6);
680                     tiled_offset = tiled_offset+tiled_x_index;
681                     tiled_offset = tiled_offset<<11;
682                 }
683             }
684
685             memcpy(nv12t_dest+tiled_offset, yuv420_src+left+j+yuv420_width*(i+top), 64);
686             memcpy(nv12t_dest+tiled_offset+64*1, yuv420_src+left+j+yuv420_width*(i+top+1), 64);
687             memcpy(nv12t_dest+tiled_offset+64*2, yuv420_src+left+j+yuv420_width*(i+top+2), 64);
688             memcpy(nv12t_dest+tiled_offset+64*3, yuv420_src+left+j+yuv420_width*(i+top+3), 64);
689             memcpy(nv12t_dest+tiled_offset+64*4, yuv420_src+left+j+yuv420_width*(i+top+4), 64);
690             memcpy(nv12t_dest+tiled_offset+64*5, yuv420_src+left+j+yuv420_width*(i+top+5), 64);
691             memcpy(nv12t_dest+tiled_offset+64*6, yuv420_src+left+j+yuv420_width*(i+top+6), 64);
692             memcpy(nv12t_dest+tiled_offset+64*7, yuv420_src+left+j+yuv420_width*(i+top+7), 64);
693             memcpy(nv12t_dest+tiled_offset+64*8, yuv420_src+left+j+yuv420_width*(i+top+8), 64);
694             memcpy(nv12t_dest+tiled_offset+64*9, yuv420_src+left+j+yuv420_width*(i+top+9), 64);
695             memcpy(nv12t_dest+tiled_offset+64*10, yuv420_src+left+j+yuv420_width*(i+top+10), 64);
696             memcpy(nv12t_dest+tiled_offset+64*11, yuv420_src+left+j+yuv420_width*(i+top+11), 64);
697             memcpy(nv12t_dest+tiled_offset+64*12, yuv420_src+left+j+yuv420_width*(i+top+12), 64);
698             memcpy(nv12t_dest+tiled_offset+64*13, yuv420_src+left+j+yuv420_width*(i+top+13), 64);
699             memcpy(nv12t_dest+tiled_offset+64*14, yuv420_src+left+j+yuv420_width*(i+top+14), 64);
700             memcpy(nv12t_dest+tiled_offset+64*15, yuv420_src+left+j+yuv420_width*(i+top+15), 64);
701             memcpy(nv12t_dest+tiled_offset+64*16, yuv420_src+left+j+yuv420_width*(i+top+16), 64);
702             memcpy(nv12t_dest+tiled_offset+64*17, yuv420_src+left+j+yuv420_width*(i+top+17), 64);
703             memcpy(nv12t_dest+tiled_offset+64*18, yuv420_src+left+j+yuv420_width*(i+top+18), 64);
704             memcpy(nv12t_dest+tiled_offset+64*19, yuv420_src+left+j+yuv420_width*(i+top+19), 64);
705             memcpy(nv12t_dest+tiled_offset+64*20, yuv420_src+left+j+yuv420_width*(i+top+20), 64);
706             memcpy(nv12t_dest+tiled_offset+64*21, yuv420_src+left+j+yuv420_width*(i+top+21), 64);
707             memcpy(nv12t_dest+tiled_offset+64*22, yuv420_src+left+j+yuv420_width*(i+top+22), 64);
708             memcpy(nv12t_dest+tiled_offset+64*23, yuv420_src+left+j+yuv420_width*(i+top+23), 64);
709             memcpy(nv12t_dest+tiled_offset+64*24, yuv420_src+left+j+yuv420_width*(i+top+24), 64);
710             memcpy(nv12t_dest+tiled_offset+64*25, yuv420_src+left+j+yuv420_width*(i+top+25), 64);
711             memcpy(nv12t_dest+tiled_offset+64*26, yuv420_src+left+j+yuv420_width*(i+top+26), 64);
712             memcpy(nv12t_dest+tiled_offset+64*27, yuv420_src+left+j+yuv420_width*(i+top+27), 64);
713             memcpy(nv12t_dest+tiled_offset+64*28, yuv420_src+left+j+yuv420_width*(i+top+28), 64);
714             memcpy(nv12t_dest+tiled_offset+64*29, yuv420_src+left+j+yuv420_width*(i+top+29), 64);
715             memcpy(nv12t_dest+tiled_offset+64*30, yuv420_src+left+j+yuv420_width*(i+top+30), 64);
716             memcpy(nv12t_dest+tiled_offset+64*31, yuv420_src+left+j+yuv420_width*(i+top+31), 64);
717         }
718     }
719
720     for (i=aligned_y_size; i<(yuv420_height-top-buttom); i=i+2) {
721         for (j=0; j<aligned_x_size; j=j+64) {
722             tiled_offset = 0;
723             tiled_x_index = j>>6;
724             tiled_y_index = i>>5;
725             if (tiled_y_index & 0x1) {
726                 /* odd fomula: 2+x+(x>>2)<<2+x_block_num*(y-1) */
727                 tiled_offset = tiled_y_index-1;
728                 temp1 = (((yuv420_width-left-right)+127)>>7)<<7;
729                 tiled_offset = tiled_offset*(temp1>>6);
730                 tiled_offset = tiled_offset+tiled_x_index;
731                 tiled_offset = tiled_offset+2;
732                 temp1 = (tiled_x_index>>2)<<2;
733                 tiled_offset = tiled_offset+temp1;
734                 tiled_offset = tiled_offset<<11;
735             } else {
736                 temp2 = (((yuv420_height-top-buttom)+31)>>5)<<5;
737                 if ((i+32)<temp2) {
738                     /* even1 fomula: x+((x+2)>>2)<<2+x_block_num*y */
739                     temp1 = tiled_x_index+2;
740                     temp1 = (temp1>>2)<<2;
741                     tiled_offset = tiled_x_index+temp1;
742                     temp1 = (((yuv420_width-left-right)+127)>>7)<<7;
743                     tiled_offset = tiled_offset+tiled_y_index*(temp1>>6);
744                     tiled_offset = tiled_offset<<11;
745                 } else {
746                     /* even2 fomula: x+x_block_num*y */
747                     temp1 = (((yuv420_width-left-right)+127)>>7)<<7;
748                     tiled_offset = tiled_y_index*(temp1>>6);
749                     tiled_offset = tiled_offset+tiled_x_index;
750                     tiled_offset = tiled_offset<<11;
751                 }
752             }
753
754             temp1 = i&0x1F;
755             memcpy(nv12t_dest+tiled_offset+64*(temp1), yuv420_src+left+j+yuv420_width*(i+top), 64);
756             memcpy(nv12t_dest+tiled_offset+64*(temp1+1), yuv420_src+left+j+yuv420_width*(i+top+1), 64);
757         }
758     }
759
760     for (i=0; i<(yuv420_height-top-buttom); i=i+2) {
761         for (j=aligned_x_size; j<(yuv420_width-left-right); j=j+2) {
762             tiled_offset = 0;
763             tiled_x_index = j>>6;
764             tiled_y_index = i>>5;
765             if (tiled_y_index & 0x1) {
766                 /* odd fomula: 2+x+(x>>2)<<2+x_block_num*(y-1) */
767                 tiled_offset = tiled_y_index-1;
768                 temp1 = (((yuv420_width-left-right)+127)>>7)<<7;
769                 tiled_offset = tiled_offset*(temp1>>6);
770                 tiled_offset = tiled_offset+tiled_x_index;
771                 tiled_offset = tiled_offset+2;
772                 temp1 = (tiled_x_index>>2)<<2;
773                 tiled_offset = tiled_offset+temp1;
774                 tiled_offset = tiled_offset<<11;
775             } else {
776                 temp2 = (((yuv420_height-top-buttom)+31)>>5)<<5;
777                 if ((i+32)<temp2) {
778                     /* even1 fomula: x+((x+2)>>2)<<2+x_block_num*y */
779                     temp1 = tiled_x_index+2;
780                     temp1 = (temp1>>2)<<2;
781                     tiled_offset = tiled_x_index+temp1;
782                     temp1 = (((yuv420_width-left-right)+127)>>7)<<7;
783                     tiled_offset = tiled_offset+tiled_y_index*(temp1>>6);
784                     tiled_offset = tiled_offset<<11;
785                 } else {
786                     /* even2 fomula: x+x_block_num*y */
787                     temp1 = (((yuv420_width-left-right)+127)>>7)<<7;
788                     tiled_offset = tiled_y_index*(temp1>>6);
789                     tiled_offset = tiled_offset+tiled_x_index;
790                     tiled_offset = tiled_offset<<11;
791                 }
792             }
793
794             temp1 = i&0x1F;
795             temp2 = j&0x3F;
796             memcpy(nv12t_dest+tiled_offset+temp2+64*(temp1), yuv420_src+left+j+yuv420_width*(i+top), 2);
797             memcpy(nv12t_dest+tiled_offset+temp2+64*(temp1+1), yuv420_src+left+j+yuv420_width*(i+top+1), 2);
798         }
799     }
800
801 }
802
803 /*
804  * Converts and Interleaves linear to tiled
805  * Crops left, top, right, buttom
806  * 1. UV of YUV420P to UV of NV12T
807  *
808  * @param nv12t_uv_dest
809  *   UV plane address of NV12T[out]
810  *
811  * @param yuv420p_u_src
812  *   U plane address of YUV420P[in]
813  *
814  * @param yuv420p_v_src
815  *   V plane address of YUV420P[in]
816  *
817  * @param yuv420_width
818  *   Width of YUV420[in]
819  *
820  * @param yuv420_uv_height
821  *   Height/2 of YUV420[in]
822  *
823  * @param left
824  *   Crop size of left
825  *
826  * @param top
827  *   Crop size of top
828  *
829  * @param right
830  *   Crop size of right
831  *
832  * @param buttom
833  *   Crop size of buttom
834  */
835 static void csc_linear_to_tiled_interleave_crop(
836     unsigned char *nv12t_uv_dest,
837     unsigned char *yuv420_u_src,
838     unsigned char *yuv420_v_src,
839     unsigned int yuv420_width,
840     unsigned int yuv420_height,
841     unsigned int left,
842     unsigned int top,
843     unsigned int right,
844     unsigned int buttom)
845 {
846     unsigned int i, j;
847     unsigned int tiled_x_index = 0, tiled_y_index = 0;
848     unsigned int aligned_x_size = 0, aligned_y_size = 0;
849     unsigned int tiled_offset = 0;
850     unsigned int temp1 = 0, temp2 = 0;
851
852     aligned_y_size = ((yuv420_height-top-buttom)>>5)<<5;
853     aligned_x_size = ((yuv420_width-left-right)>>6)<<6;
854
855     for (i=0; i<aligned_y_size; i=i+32) {
856         for (j=0; j<aligned_x_size; j=j+64) {
857             tiled_offset = 0;
858             tiled_x_index = j>>6;
859             tiled_y_index = i>>5;
860             if (tiled_y_index & 0x1) {
861                 /* odd fomula: 2+x+(x>>2)<<2+x_block_num*(y-1) */
862                 tiled_offset = tiled_y_index-1;
863                 temp1 = (((yuv420_width-left-right)+127)>>7)<<7;
864                 tiled_offset = tiled_offset*(temp1>>6);
865                 tiled_offset = tiled_offset+tiled_x_index;
866                 tiled_offset = tiled_offset+2;
867                 temp1 = (tiled_x_index>>2)<<2;
868                 tiled_offset = tiled_offset+temp1;
869                 tiled_offset = tiled_offset<<11;
870             } else {
871                 temp2 = (((yuv420_height-top-buttom)+31)>>5)<<5;
872                 if ((i+32)<temp2) {
873                     /* even1 fomula: x+((x+2)>>2)<<2+x_block_num*y */
874                     temp1 = tiled_x_index+2;
875                     temp1 = (temp1>>2)<<2;
876                     tiled_offset = tiled_x_index+temp1;
877                     temp1 = (((yuv420_width-left-right)+127)>>7)<<7;
878                     tiled_offset = tiled_offset+tiled_y_index*(temp1>>6);
879                     tiled_offset = tiled_offset<<11;
880                 } else {
881                     /* even2 fomula: x+x_block_num*y */
882                     temp1 = (((yuv420_width-left-right)+127)>>7)<<7;
883                     tiled_offset = tiled_y_index*(temp1>>6);
884                     tiled_offset = tiled_offset+tiled_x_index;
885                     tiled_offset = tiled_offset<<11;
886                 }
887             }
888
889             csc_interleave_memcpy(nv12t_uv_dest+tiled_offset,
890                                     yuv420_u_src+left/2+j/2+yuv420_width/2*(i+top),
891                                     yuv420_v_src+left/2+j/2+yuv420_width/2*(i+top), 32);
892             csc_interleave_memcpy(nv12t_uv_dest+tiled_offset+64*1,
893                                     yuv420_u_src+left/2+j/2+yuv420_width/2*(i+top+1),
894                                     yuv420_v_src+left/2+j/2+yuv420_width/2*(i+top+1), 32);
895             csc_interleave_memcpy(nv12t_uv_dest+tiled_offset+64*2,
896                                     yuv420_u_src+left/2+j/2+yuv420_width/2*(i+top+2),
897                                     yuv420_v_src+left/2+j/2+yuv420_width/2*(i+top+2), 32);
898             csc_interleave_memcpy(nv12t_uv_dest+tiled_offset+64*3,
899                                     yuv420_u_src+left/2+j/2+yuv420_width/2*(i+top+3),
900                                     yuv420_v_src+left/2+j/2+yuv420_width/2*(i+top+3), 32);
901             csc_interleave_memcpy(nv12t_uv_dest+tiled_offset+64*4,
902                                     yuv420_u_src+left/2+j/2+yuv420_width/2*(i+top+4),
903                                     yuv420_v_src+left/2+j/2+yuv420_width/2*(i+top+4), 32);
904             csc_interleave_memcpy(nv12t_uv_dest+tiled_offset+64*5,
905                                     yuv420_u_src+left/2+j/2+yuv420_width/2*(i+top+5),
906                                     yuv420_v_src+left/2+j/2+yuv420_width/2*(i+top+5), 32);
907             csc_interleave_memcpy(nv12t_uv_dest+tiled_offset+64*6,
908                                     yuv420_u_src+left/2+j/2+yuv420_width/2*(i+top+6),
909                                     yuv420_v_src+left/2+j/2+yuv420_width/2*(i+top+6), 32);
910             csc_interleave_memcpy(nv12t_uv_dest+tiled_offset+64*7,
911                                     yuv420_u_src+left/2+j/2+yuv420_width/2*(i+top+7),
912                                     yuv420_v_src+left/2+j/2+yuv420_width/2*(i+top+7), 32);
913             csc_interleave_memcpy(nv12t_uv_dest+tiled_offset+64*8,
914                                     yuv420_u_src+left/2+j/2+yuv420_width/2*(i+top+8),
915                                     yuv420_v_src+left/2+j/2+yuv420_width/2*(i+top+8), 32);
916             csc_interleave_memcpy(nv12t_uv_dest+tiled_offset+64*9,
917                                     yuv420_u_src+left/2+j/2+yuv420_width/2*(i+top+9),
918                                     yuv420_v_src+left/2+j/2+yuv420_width/2*(i+top+9), 32);
919             csc_interleave_memcpy(nv12t_uv_dest+tiled_offset+64*10,
920                                     yuv420_u_src+left/2+j/2+yuv420_width/2*(i+top+10),
921                                     yuv420_v_src+left/2+j/2+yuv420_width/2*(i+top+10), 32);
922             csc_interleave_memcpy(nv12t_uv_dest+tiled_offset+64*11,
923                                     yuv420_u_src+left/2+j/2+yuv420_width/2*(i+top+11),
924                                     yuv420_v_src+left/2+j/2+yuv420_width/2*(i+top+11), 32);
925             csc_interleave_memcpy(nv12t_uv_dest+tiled_offset+64*12,
926                                     yuv420_u_src+left/2+j/2+yuv420_width/2*(i+top+12),
927                                     yuv420_v_src+left/2+j/2+yuv420_width/2*(i+top+12), 32);
928             csc_interleave_memcpy(nv12t_uv_dest+tiled_offset+64*13,
929                                     yuv420_u_src+left/2+j/2+yuv420_width/2*(i+top+13),
930                                     yuv420_v_src+left/2+j/2+yuv420_width/2*(i+top+13), 32);
931             csc_interleave_memcpy(nv12t_uv_dest+tiled_offset+64*14,
932                                     yuv420_u_src+left/2+j/2+yuv420_width/2*(i+top+14),
933                                     yuv420_v_src+left/2+j/2+yuv420_width/2*(i+top+14), 32);
934             csc_interleave_memcpy(nv12t_uv_dest+tiled_offset+64*15,
935                                     yuv420_u_src+left/2+j/2+yuv420_width/2*(i+top+15),
936                                     yuv420_v_src+left/2+j/2+yuv420_width/2*(i+top+15), 32);
937             csc_interleave_memcpy(nv12t_uv_dest+tiled_offset+64*16,
938                                     yuv420_u_src+left/2+j/2+yuv420_width/2*(i+top+16),
939                                     yuv420_v_src+left/2+j/2+yuv420_width/2*(i+top+16), 32);
940             csc_interleave_memcpy(nv12t_uv_dest+tiled_offset+64*17,
941                                     yuv420_u_src+left/2+j/2+yuv420_width/2*(i+top+17),
942                                     yuv420_v_src+left/2+j/2+yuv420_width/2*(i+top+17), 32);
943             csc_interleave_memcpy(nv12t_uv_dest+tiled_offset+64*18,
944                                     yuv420_u_src+left/2+j/2+yuv420_width/2*(i+top+18),
945                                     yuv420_v_src+left/2+j/2+yuv420_width/2*(i+top+18), 32);
946             csc_interleave_memcpy(nv12t_uv_dest+tiled_offset+64*19,
947                                     yuv420_u_src+left/2+j/2+yuv420_width/2*(i+top+19),
948                                     yuv420_v_src+left/2+j/2+yuv420_width/2*(i+top+19), 32);
949             csc_interleave_memcpy(nv12t_uv_dest+tiled_offset+64*20,
950                                     yuv420_u_src+left/2+j/2+yuv420_width/2*(i+top+20),
951                                     yuv420_v_src+left/2+j/2+yuv420_width/2*(i+top+20), 32);
952             csc_interleave_memcpy(nv12t_uv_dest+tiled_offset+64*21,
953                                     yuv420_u_src+left/2+j/2+yuv420_width/2*(i+top+21),
954                                     yuv420_v_src+left/2+j/2+yuv420_width/2*(i+top+21), 32);
955             csc_interleave_memcpy(nv12t_uv_dest+tiled_offset+64*22,
956                                     yuv420_u_src+left/2+j/2+yuv420_width/2*(i+top+22),
957                                     yuv420_v_src+left/2+j/2+yuv420_width/2*(i+top+22), 32);
958             csc_interleave_memcpy(nv12t_uv_dest+tiled_offset+64*23,
959                                     yuv420_u_src+left/2+j/2+yuv420_width/2*(i+top+23),
960                                     yuv420_v_src+left/2+j/2+yuv420_width/2*(i+top+23), 32);
961             csc_interleave_memcpy(nv12t_uv_dest+tiled_offset+64*24,
962                                     yuv420_u_src+left/2+j/2+yuv420_width/2*(i+top+24),
963                                     yuv420_v_src+left/2+j/2+yuv420_width/2*(i+top+24), 32);
964             csc_interleave_memcpy(nv12t_uv_dest+tiled_offset+64*25,
965                                     yuv420_u_src+left/2+j/2+yuv420_width/2*(i+top+25),
966                                     yuv420_v_src+left/2+j/2+yuv420_width/2*(i+top+25), 32);
967             csc_interleave_memcpy(nv12t_uv_dest+tiled_offset+64*26,
968                                     yuv420_u_src+left/2+j/2+yuv420_width/2*(i+top+26),
969                                     yuv420_v_src+left/2+j/2+yuv420_width/2*(i+top+26), 32);
970             csc_interleave_memcpy(nv12t_uv_dest+tiled_offset+64*27,
971                                     yuv420_u_src+left/2+j/2+yuv420_width/2*(i+top+27),
972                                     yuv420_v_src+left/2+j/2+yuv420_width/2*(i+top+27), 32);
973             csc_interleave_memcpy(nv12t_uv_dest+tiled_offset+64*28,
974                                     yuv420_u_src+left/2+j/2+yuv420_width/2*(i+top+28),
975                                     yuv420_v_src+left/2+j/2+yuv420_width/2*(i+top+28), 32);
976             csc_interleave_memcpy(nv12t_uv_dest+tiled_offset+64*29,
977                                     yuv420_u_src+left/2+j/2+yuv420_width/2*(i+top+29),
978                                     yuv420_v_src+left/2+j/2+yuv420_width/2*(i+top+29), 32);
979             csc_interleave_memcpy(nv12t_uv_dest+tiled_offset+64*30,
980                                     yuv420_u_src+left/2+j/2+yuv420_width/2*(i+top+30),
981                                     yuv420_v_src+left/2+j/2+yuv420_width/2*(i+top+30), 32);
982             csc_interleave_memcpy(nv12t_uv_dest+tiled_offset+64*31,
983                                     yuv420_u_src+left/2+j/2+yuv420_width/2*(i+top+31),
984                                     yuv420_v_src+left/2+j/2+yuv420_width/2*(i+top+31), 32);
985
986         }
987     }
988
989     for (i=aligned_y_size; i<(yuv420_height-top-buttom); i=i+1) {
990         for (j=0; j<aligned_x_size; j=j+64) {
991             tiled_offset = 0;
992             tiled_x_index = j>>6;
993             tiled_y_index = i>>5;
994             if (tiled_y_index & 0x1) {
995                 /* odd fomula: 2+x+(x>>2)<<2+x_block_num*(y-1) */
996                 tiled_offset = tiled_y_index-1;
997                 temp1 = (((yuv420_width-left-right)+127)>>7)<<7;
998                 tiled_offset = tiled_offset*(temp1>>6);
999                 tiled_offset = tiled_offset+tiled_x_index;
1000                 tiled_offset = tiled_offset+2;
1001                 temp1 = (tiled_x_index>>2)<<2;
1002                 tiled_offset = tiled_offset+temp1;
1003                 tiled_offset = tiled_offset<<11;
1004             } else {
1005                 temp2 = (((yuv420_height-top-buttom)+31)>>5)<<5;
1006                 if ((i+32)<temp2) {
1007                     /* even1 fomula: x+((x+2)>>2)<<2+x_block_num*y */
1008                     temp1 = tiled_x_index+2;
1009                     temp1 = (temp1>>2)<<2;
1010                     tiled_offset = tiled_x_index+temp1;
1011                     temp1 = (((yuv420_width-left-right)+127)>>7)<<7;
1012                     tiled_offset = tiled_offset+tiled_y_index*(temp1>>6);
1013                     tiled_offset = tiled_offset<<11;
1014                 } else {
1015                     /* even2 fomula: x+x_block_num*y */
1016                     temp1 = (((yuv420_width-left-right)+127)>>7)<<7;
1017                     tiled_offset = tiled_y_index*(temp1>>6);
1018                     tiled_offset = tiled_offset+tiled_x_index;
1019                     tiled_offset = tiled_offset<<11;
1020                 }
1021             }
1022             temp1 = i&0x1F;
1023             csc_interleave_memcpy(nv12t_uv_dest+tiled_offset+64*(temp1),
1024                                     yuv420_u_src+left/2+j/2+yuv420_width/2*(i+top),
1025                                     yuv420_v_src+left/2+j/2+yuv420_width/2*(i+top), 32);
1026        }
1027     }
1028
1029     for (i=0; i<(yuv420_height-top-buttom); i=i+1) {
1030         for (j=aligned_x_size; j<(yuv420_width-left-right); j=j+2) {
1031             tiled_offset = 0;
1032             tiled_x_index = j>>6;
1033             tiled_y_index = i>>5;
1034             if (tiled_y_index & 0x1) {
1035                 /* odd fomula: 2+x+(x>>2)<<2+x_block_num*(y-1) */
1036                 tiled_offset = tiled_y_index-1;
1037                 temp1 = (((yuv420_width-left-right)+127)>>7)<<7;
1038                 tiled_offset = tiled_offset*(temp1>>6);
1039                 tiled_offset = tiled_offset+tiled_x_index;
1040                 tiled_offset = tiled_offset+2;
1041                 temp1 = (tiled_x_index>>2)<<2;
1042                 tiled_offset = tiled_offset+temp1;
1043                 tiled_offset = tiled_offset<<11;
1044             } else {
1045                 temp2 = (((yuv420_height-top-buttom)+31)>>5)<<5;
1046                 if ((i+32)<temp2) {
1047                     /* even1 fomula: x+((x+2)>>2)<<2+x_block_num*y */
1048                     temp1 = tiled_x_index+2;
1049                     temp1 = (temp1>>2)<<2;
1050                     tiled_offset = tiled_x_index+temp1;
1051                     temp1 = (((yuv420_width-left-right)+127)>>7)<<7;
1052                     tiled_offset = tiled_offset+tiled_y_index*(temp1>>6);
1053                     tiled_offset = tiled_offset<<11;
1054                 } else {
1055                     /* even2 fomula: x+x_block_num*y */
1056                     temp1 = (((yuv420_width-left-right)+127)>>7)<<7;
1057                     tiled_offset = tiled_y_index*(temp1>>6);
1058                     tiled_offset = tiled_offset+tiled_x_index;
1059                     tiled_offset = tiled_offset<<11;
1060                 }
1061             }
1062             temp1 = i&0x1F;
1063             temp2 = j&0x3F;
1064             csc_interleave_memcpy(nv12t_uv_dest+tiled_offset+temp2+64*(temp1),
1065                                     yuv420_u_src+left/2+j/2+yuv420_width/2*(i+top),
1066                                     yuv420_v_src+left/2+j/2+yuv420_width/2*(i+top), 1);
1067        }
1068     }
1069
1070 }
1071
1072
1073 /*
1074  * Converts tiled data to linear
1075  * Crops left, top, right, buttom
1076  * 1. Y of NV12T to Y of YUV420P
1077  * 2. Y of NV12T to Y of YUV420S
1078  * 3. UV of NV12T to UV of YUV420S
1079  *
1080  * @param yuv420_dest
1081  *   Y or UV plane address of YUV420[out]
1082  *
1083  * @param nv12t_src
1084  *   Y or UV plane address of NV12T[in]
1085  *
1086  * @param yuv420_width
1087  *   Width of YUV420[in]
1088  *
1089  * @param yuv420_height
1090  *   Y: Height of YUV420, UV: Height/2 of YUV420[in]
1091  *
1092  * @param left
1093  *   Crop size of left
1094  *
1095  * @param top
1096  *   Crop size of top
1097  *
1098  * @param right
1099  *   Crop size of right
1100  *
1101  * @param buttom
1102  *   Crop size of buttom
1103  */
1104 void csc_tiled_to_linear_crop_neon(
1105     unsigned char *yuv420_dest,
1106     unsigned char *nv12t_src,
1107     unsigned int yuv420_width,
1108     unsigned int yuv420_height,
1109     unsigned int left,
1110     unsigned int top,
1111     unsigned int right,
1112     unsigned int buttom);
1113
1114 /*
1115  * Converts and Deinterleaves tiled data to linear
1116  * Crops left, top, right, buttom
1117  * 1. UV of NV12T to UV of YUV420P
1118  *
1119  * @param yuv420_u_dest
1120  *   U plane address of YUV420P[out]
1121  *
1122  * @param yuv420_v_dest
1123  *   V plane address of YUV420P[out]
1124  *
1125  * @param nv12t_src
1126  *   UV plane address of NV12T[in]
1127  *
1128  * @param yuv420_width
1129  *   Width of YUV420[in]
1130  *
1131  * @param yuv420_uv_height
1132  *   Height/2 of YUV420[in]
1133  *
1134  * @param left
1135  *   Crop size of left
1136  *
1137  * @param top
1138  *   Crop size of top
1139  *
1140  * @param right
1141  *   Crop size of right
1142  *
1143  * @param buttom
1144  *   Crop size of buttom
1145  */
1146 void csc_tiled_to_linear_deinterleave_crop_neon(
1147     unsigned char *yuv420_u_dest,
1148     unsigned char *yuv420_v_dest,
1149     unsigned char *nv12t_uv_src,
1150     unsigned int yuv420_width,
1151     unsigned int yuv420_uv_height,
1152     unsigned int left,
1153     unsigned int top,
1154     unsigned int right,
1155     unsigned int buttom);
1156
1157 /*
1158  * Converts linear data to tiled
1159  * Crops left, top, right, buttom
1160  * 1. Y of YUV420P to Y of NV12T
1161  * 2. Y of YUV420S to Y of NV12T
1162  * 3. UV of YUV420S to UV of NV12T
1163  *
1164  * @param nv12t_dest
1165  *   Y or UV plane address of NV12T[out]
1166  *
1167  * @param yuv420_src
1168  *   Y or UV plane address of YUV420P(S)[in]
1169  *
1170  * @param yuv420_width
1171  *   Width of YUV420[in]
1172  *
1173  * @param yuv420_height
1174  *   Y: Height of YUV420, UV: Height/2 of YUV420[in]
1175  *
1176  * @param left
1177  *   Crop size of left
1178  *
1179  * @param top
1180  *   Crop size of top
1181  *
1182  * @param right
1183  *   Crop size of right
1184  *
1185  * @param buttom
1186  *   Crop size of buttom
1187  */
1188 void csc_linear_to_tiled_crop_neon(
1189     unsigned char *nv12t_dest,
1190     unsigned char *yuv420_src,
1191     unsigned int yuv420_width,
1192     unsigned int yuv420_height,
1193     unsigned int left,
1194     unsigned int top,
1195     unsigned int right,
1196     unsigned int buttom);
1197
1198 /*
1199  * Converts and Interleaves linear to tiled
1200  * Crops left, top, right, buttom
1201  * 1. UV of YUV420P to UV of NV12T
1202  *
1203  * @param nv12t_uv_dest
1204  *   UV plane address of NV12T[out]
1205  *
1206  * @param yuv420p_u_src
1207  *   U plane address of YUV420P[in]
1208  *
1209  * @param yuv420p_v_src
1210  *   V plane address of YUV420P[in]
1211  *
1212  * @param yuv420_width
1213  *   Width of YUV420[in]
1214  *
1215  * @param yuv420_uv_height
1216  *   Height/2 of YUV420[in]
1217  *
1218  * @param left
1219  *   Crop size of left
1220  *
1221  * @param top
1222  *   Crop size of top
1223  *
1224  * @param right
1225  *   Crop size of right
1226  *
1227  * @param buttom
1228  *   Crop size of buttom
1229  */
1230 void csc_linear_to_tiled_interleave_crop_neon(
1231     unsigned char *nv12t_uv_dest,
1232     unsigned char *yuv420_u_src,
1233     unsigned char *yuv420_v_src,
1234     unsigned int yuv420_width,
1235     unsigned int yuv420_height,
1236     unsigned int left,
1237     unsigned int top,
1238     unsigned int right,
1239     unsigned int buttom);
1240
1241 /*
1242  * Converts tiled data to linear.
1243  * 1. y of nv12t to y of yuv420p
1244  * 2. y of nv12t to y of yuv420s
1245  *
1246  * @param dst
1247  *   y address of yuv420[out]
1248  *
1249  * @param src
1250  *   y address of nv12t[in]
1251  *
1252  * @param yuv420_width
1253  *   real width of yuv420[in]
1254  *   it should be even
1255  *
1256  * @param yuv420_height
1257  *   real height of yuv420[in]
1258  *   it should be even.
1259  *
1260  */
1261 void csc_tiled_to_linear_y(
1262     unsigned char *y_dst,
1263     unsigned char *y_src,
1264     unsigned int width,
1265     unsigned int height)
1266 {
1267     csc_tiled_to_linear_crop(y_dst, y_src, width, height, 0, 0, 0, 0);
1268 }
1269
1270 /*
1271  * Converts tiled data to linear
1272  * 1. uv of nv12t to y of yuv420s
1273  *
1274  * @param dst
1275  *   uv address of yuv420s[out]
1276  *
1277  * @param src
1278  *   uv address of nv12t[in]
1279  *
1280  * @param yuv420_width
1281  *   real width of yuv420s[in]
1282  *
1283  * @param yuv420_height
1284  *   real height of yuv420s[in]
1285  *
1286  */
1287 void csc_tiled_to_linear_uv(
1288     unsigned char *uv_dst,
1289     unsigned char *uv_src,
1290     unsigned int width,
1291     unsigned int height)
1292 {
1293     csc_tiled_to_linear_crop(uv_dst, uv_src, width, height, 0, 0, 0, 0);
1294 }
1295
1296 /*
1297  * Converts tiled data to linear
1298  * 1. uv of nt12t to uv of yuv420p
1299  *
1300  * @param u_dst
1301  *   u address of yuv420p[out]
1302  *
1303  * @param v_dst
1304  *   v address of yuv420p[out]
1305  *
1306  * @param uv_src
1307  *   uv address of nt12t[in]
1308  *
1309  * @param yuv420_width
1310  *   real width of yuv420p[in]
1311  *
1312  * @param yuv420_height
1313  *   real height of yuv420p[in]
1314  */
1315 void csc_tiled_to_linear_uv_deinterleave(
1316     unsigned char *u_dst,
1317     unsigned char *v_dst,
1318     unsigned char *uv_src,
1319     unsigned int width,
1320     unsigned int height)
1321 {
1322     csc_tiled_to_linear_deinterleave_crop(u_dst, v_dst, uv_src, width, height,
1323                                           0, 0, 0, 0);
1324 }
1325
1326 /*
1327  * Converts linear data to tiled
1328  * 1. y of yuv420 to y of nv12t
1329  *
1330  * @param dst
1331  *   y address of nv12t[out]
1332  *
1333  * @param src
1334  *   y address of yuv420[in]
1335  *
1336  * @param yuv420_width
1337  *   real width of yuv420[in]
1338  *   it should be even
1339  *
1340  * @param yuv420_height
1341  *   real height of yuv420[in]
1342  *   it should be even.
1343  *
1344  */
1345 void csc_linear_to_tiled_y(
1346     unsigned char *y_dst,
1347     unsigned char *y_src,
1348     unsigned int width,
1349     unsigned int height)
1350 {
1351     csc_linear_to_tiled_crop(y_dst, y_src, width, height, 0, 0, 0, 0);
1352 }
1353
1354 /*
1355  * Converts and interleaves linear data to tiled
1356  * 1. uv of nv12t to uv of yuv420
1357  *
1358  * @param dst
1359  *   uv address of nv12t[out]
1360  *
1361  * @param src
1362  *   u address of yuv420[in]
1363  *
1364  * @param src
1365  *   v address of yuv420[in]
1366  *
1367  * @param yuv420_width
1368  *   real width of yuv420[in]
1369  *
1370  * @param yuv420_height
1371  *   real height of yuv420[in]
1372  *
1373  */
1374 void csc_linear_to_tiled_uv(
1375     unsigned char *uv_dst,
1376     unsigned char *u_src,
1377     unsigned char *v_src,
1378     unsigned int width,
1379     unsigned int height)
1380 {
1381     csc_linear_to_tiled_interleave_crop(uv_dst, u_src, v_src, width, height,
1382                                         0, 0, 0, 0);
1383 }
1384
1385 #ifdef USE_NEON
1386 /*
1387  * Converts tiled data to linear for mfc 6.x
1388  * 1. Y of NV12T to Y of YUV420P
1389  * 2. Y of NV12T to Y of YUV420S
1390  *
1391  * @param dst
1392  *   Y address of YUV420[out]
1393  *
1394  * @param src
1395  *   Y address of NV12T[in]
1396  *
1397  * @param yuv420_width
1398  *   real width of YUV420[in]
1399  *
1400  * @param yuv420_height
1401  *   Y: real height of YUV420[in]
1402  *
1403  */
1404 void csc_tiled_to_linear_y_neon(
1405     unsigned char *y_dst,
1406     unsigned char *y_src,
1407     unsigned int width,
1408     unsigned int height)
1409 {
1410     csc_tiled_to_linear_crop_neon(y_dst, y_src, width, height, 0, 0, 0, 0);
1411 }
1412
1413 /*
1414  * Converts tiled data to linear for mfc 6.x
1415  * 1. UV of NV12T to Y of YUV420S
1416  *
1417  * @param u_dst
1418  *   UV plane address of YUV420P[out]
1419  *
1420  * @param nv12t_src
1421  *   Y or UV plane address of NV12T[in]
1422  *
1423  * @param yuv420_width
1424  *   real width of YUV420[in]
1425  *
1426  * @param yuv420_height
1427  *   (real height)/2 of YUV420[in]
1428  */
1429 void csc_tiled_to_linear_uv_neon(
1430     unsigned char *uv_dst,
1431     unsigned char *uv_src,
1432     unsigned int width,
1433     unsigned int height)
1434 {
1435     csc_tiled_to_linear_crop_neon(uv_dst, uv_src, width, height, 0, 0, 0, 0);
1436 }
1437
1438 /*
1439  * Converts tiled data to linear for mfc 6.x
1440  * Deinterleave src to u_dst, v_dst
1441  * 1. UV of NV12T to Y of YUV420P
1442  *
1443  * @param u_dst
1444  *   U plane address of YUV420P[out]
1445  *
1446  * @param v_dst
1447  *   V plane address of YUV420P[out]
1448  *
1449  * @param nv12t_src
1450  *   Y or UV plane address of NV12T[in]
1451  *
1452  * @param yuv420_width
1453  *   real width of YUV420[in]
1454  *
1455  * @param yuv420_height
1456  *   (real height)/2 of YUV420[in]
1457  */
1458 void csc_tiled_to_linear_uv_deinterleave_neon(
1459     unsigned char *u_dst,
1460     unsigned char *v_dst,
1461     unsigned char *uv_src,
1462     unsigned int width,
1463     unsigned int height)
1464 {
1465     csc_tiled_to_linear_deinterleave_crop_neon(u_dst, v_dst, uv_src, width, height,
1466                                           0, 0, 0, 0);
1467 }
1468
1469 /*
1470  * Converts linear data to tiled
1471  * 1. y of yuv420 to y of nv12t
1472  *
1473  * @param dst
1474  *   y address of nv12t[out]
1475  *
1476  * @param src
1477  *   y address of yuv420[in]
1478  *
1479  * @param yuv420_width
1480  *   real width of yuv420[in]
1481  *   it should be even
1482  *
1483  * @param yuv420_height
1484  *   real height of yuv420[in]
1485  *   it should be even.
1486  *
1487  */
1488 void csc_linear_to_tiled_y_neon(
1489     unsigned char *y_dst,
1490     unsigned char *y_src,
1491     unsigned int width,
1492     unsigned int height)
1493 {
1494     csc_linear_to_tiled_crop_neon(y_dst, y_src, width, height, 0, 0, 0, 0);
1495 }
1496
1497 /*
1498  * Converts and interleaves linear data to tiled
1499  * 1. uv of nv12t to uv of yuv420
1500  *
1501  * @param dst
1502  *   uv address of nv12t[out]
1503  *
1504  * @param src
1505  *   u address of yuv420[in]
1506  *
1507  * @param src
1508  *   v address of yuv420[in]
1509  *
1510  * @param yuv420_width
1511  *   real width of yuv420[in]
1512  *
1513  * @param yuv420_height
1514  *   real height of yuv420[in]
1515  *
1516  */
1517 void csc_linear_to_tiled_uv_neon(
1518     unsigned char *uv_dst,
1519     unsigned char *u_src,
1520     unsigned char *v_src,
1521     unsigned int width,
1522     unsigned int height)
1523 {
1524     csc_linear_to_tiled_interleave_crop_neon(uv_dst, u_src, v_src,
1525                                              width, height, 0, 0, 0, 0);
1526 }
1527 #endif
1528
1529 /*
1530  * Converts RGB565 to YUV420P
1531  *
1532  * @param y_dst
1533  *   Y plane address of YUV420P[out]
1534  *
1535  * @param u_dst
1536  *   U plane address of YUV420P[out]
1537  *
1538  * @param v_dst
1539  *   V plane address of YUV420P[out]
1540  *
1541  * @param rgb_src
1542  *   Address of RGB565[in]
1543  *
1544  * @param width
1545  *   Width of RGB565[in]
1546  *
1547  * @param height
1548  *   Height of RGB565[in]
1549  */
1550 void csc_RGB565_to_YUV420P(
1551     unsigned char *y_dst,
1552     unsigned char *u_dst,
1553     unsigned char *v_dst,
1554     unsigned char *rgb_src,
1555     unsigned int width,
1556     unsigned int height)
1557 {
1558     unsigned int i, j;
1559     unsigned int tmp;
1560
1561     unsigned int R, G, B;
1562     unsigned int Y, U, V;
1563
1564     unsigned short int *pSrc = (unsigned short int *)rgb_src;
1565
1566     unsigned char *pDstY = (unsigned char *)y_dst;
1567     unsigned char *pDstU = (unsigned char *)u_dst;
1568     unsigned char *pDstV = (unsigned char *)v_dst;
1569
1570     unsigned int yIndex = 0;
1571     unsigned int uIndex = 0;
1572     unsigned int vIndex = 0;
1573
1574     for (j = 0; j < height; j++) {
1575         for (i = 0; i < width; i++) {
1576             tmp = pSrc[j * width + i];
1577
1578             R = (tmp & 0x0000F800) >> 8;
1579             G = (tmp & 0x000007E0) >> 3;
1580             B = (tmp & 0x0000001F);
1581             B = B << 3;
1582
1583             Y = ((66 * R) + (129 * G) + (25 * B) + 128);
1584             Y = Y >> 8;
1585             Y += 16;
1586
1587             pDstY[yIndex++] = (unsigned char)Y;
1588
1589             if ((j % 2) == 0 && (i % 2) == 0) {
1590                 U = ((-38 * R) - (74 * G) + (112 * B) + 128);
1591                 U = U >> 8;
1592                 U += 128;
1593                 V = ((112 * R) - (94 * G) - (18 * B) + 128);
1594                 V = V >> 8;
1595                 V += 128;
1596
1597                 pDstU[uIndex++] = (unsigned char)U;
1598                 pDstV[vIndex++] = (unsigned char)V;
1599             }
1600         }
1601     }
1602 }
1603
1604 /*
1605  * Converts RGB565 to YUV420SP
1606  *
1607  * @param y_dst
1608  *   Y plane address of YUV420SP[out]
1609  *
1610  * @param uv_dst
1611  *   UV plane address of YUV420SP[out]
1612  *
1613  * @param rgb_src
1614  *   Address of RGB565[in]
1615  *
1616  * @param width
1617  *   Width of RGB565[in]
1618  *
1619  * @param height
1620  *   Height of RGB565[in]
1621  */
1622 void csc_RGB565_to_YUV420SP(
1623     unsigned char *y_dst,
1624     unsigned char *uv_dst,
1625     unsigned char *rgb_src,
1626     unsigned int width,
1627     unsigned int height)
1628 {
1629     unsigned int i, j;
1630     unsigned int tmp;
1631
1632     unsigned int R, G, B;
1633     unsigned int Y, U, V;
1634
1635     unsigned short int *pSrc = (unsigned short int *)rgb_src;
1636
1637     unsigned char *pDstY = (unsigned char *)y_dst;
1638     unsigned char *pDstUV = (unsigned char *)uv_dst;
1639
1640     unsigned int yIndex = 0;
1641     unsigned int uvIndex = 0;
1642
1643     for (j = 0; j < height; j++) {
1644         for (i = 0; i < width; i++) {
1645             tmp = pSrc[j * width + i];
1646
1647             R = (tmp & 0x0000F800) >> 11;
1648             R = R * 8;
1649             G = (tmp & 0x000007E0) >> 5;
1650             G = G * 4;
1651             B = (tmp & 0x0000001F);
1652             B = B * 8;
1653
1654             Y = ((66 * R) + (129 * G) + (25 * B) + 128);
1655             Y = Y >> 8;
1656             Y += 16;
1657
1658             pDstY[yIndex++] = (unsigned char)Y;
1659
1660             if ((j % 2) == 0 && (i % 2) == 0) {
1661                 U = ((-38 * R) - (74 * G) + (112 * B) + 128);
1662                 U = U >> 8;
1663                 U += 128;
1664                 V = ((112 * R) - (94 * G) - (18 * B) + 128);
1665                 V = V >> 8;
1666                 V += 128;
1667
1668                 pDstUV[uvIndex++] = (unsigned char)U;
1669                 pDstUV[uvIndex++] = (unsigned char)V;
1670             }
1671         }
1672     }
1673 }
1674
1675 /*
1676  * Converts ARGB8888 to YUV420P
1677  *
1678  * @param y_dst
1679  *   Y plane address of YUV420P[out]
1680  *
1681  * @param u_dst
1682  *   U plane address of YUV420P[out]
1683  *
1684  * @param v_dst
1685  *   V plane address of YUV420P[out]
1686  *
1687  * @param rgb_src
1688  *   Address of ARGB8888[in]
1689  *
1690  * @param width
1691  *   Width of ARGB8888[in]
1692  *
1693  * @param height
1694  *   Height of ARGB8888[in]
1695  */
1696 void csc_ARGB8888_to_YUV420P(
1697     unsigned char *y_dst,
1698     unsigned char *u_dst,
1699     unsigned char *v_dst,
1700     unsigned char *rgb_src,
1701     unsigned int width,
1702     unsigned int height)
1703 {
1704     unsigned int i, j;
1705     unsigned int tmp;
1706
1707     unsigned int R, G, B;
1708     unsigned int Y, U, V;
1709
1710     unsigned int *pSrc = (unsigned int *)rgb_src;
1711
1712     unsigned char *pDstY = (unsigned char *)y_dst;
1713     unsigned char *pDstU = (unsigned char *)u_dst;
1714     unsigned char *pDstV = (unsigned char *)v_dst;
1715
1716     unsigned int yIndex = 0;
1717     unsigned int uIndex = 0;
1718     unsigned int vIndex = 0;
1719
1720     for (j = 0; j < height; j++) {
1721         for (i = 0; i < width; i++) {
1722             tmp = pSrc[j * width + i];
1723
1724             R = (tmp & 0x00FF0000) >> 16;
1725             G = (tmp & 0x0000FF00) >> 8;
1726             B = (tmp & 0x000000FF);
1727
1728             Y = ((66 * R) + (129 * G) + (25 * B) + 128);
1729             Y = Y >> 8;
1730             Y += 16;
1731
1732             pDstY[yIndex++] = (unsigned char)Y;
1733
1734             if ((j % 2) == 0 && (i % 2) == 0) {
1735                 U = ((-38 * R) - (74 * G) + (112 * B) + 128);
1736                 U = U >> 8;
1737                 U += 128;
1738                 V = ((112 * R) - (94 * G) - (18 * B) + 128);
1739                 V = V >> 8;
1740                 V += 128;
1741
1742                 pDstU[uIndex++] = (unsigned char)U;
1743                 pDstV[vIndex++] = (unsigned char)V;
1744             }
1745         }
1746     }
1747 }
1748
1749
1750 /*
1751  * Converts ARGB8888 to YUV420SP
1752  *
1753  * @param y_dst
1754  *   Y plane address of YUV420SP[out]
1755  *
1756  * @param uv_dst
1757  *   UV plane address of YUV420SP[out]
1758  *
1759  * @param rgb_src
1760  *   Address of ARGB8888[in]
1761  *
1762  * @param width
1763  *   Width of ARGB8888[in]
1764  *
1765  * @param height
1766  *   Height of ARGB8888[in]
1767  */
1768 void csc_ARGB8888_to_YUV420SP(
1769     unsigned char *y_dst,
1770     unsigned char *uv_dst,
1771     unsigned char *rgb_src,
1772     unsigned int width,
1773     unsigned int height)
1774 {
1775     unsigned int i, j;
1776     unsigned int tmp;
1777
1778     unsigned int R, G, B;
1779     unsigned int Y, U, V;
1780
1781     unsigned int *pSrc = (unsigned int *)rgb_src;
1782
1783     unsigned char *pDstY = (unsigned char *)y_dst;
1784     unsigned char *pDstUV = (unsigned char *)uv_dst;
1785
1786     unsigned int yIndex = 0;
1787     unsigned int uvIndex = 0;
1788
1789     for (j = 0; j < height; j++) {
1790         for (i = 0; i < width; i++) {
1791             tmp = pSrc[j * width + i];
1792
1793             R = (tmp & 0x00FF0000) >> 16;
1794             G = (tmp & 0x0000FF00) >> 8;
1795             B = (tmp & 0x000000FF);
1796
1797             Y = ((66 * R) + (129 * G) + (25 * B) + 128);
1798             Y = Y >> 8;
1799             Y += 16;
1800
1801             pDstY[yIndex++] = (unsigned char)Y;
1802
1803             if ((j % 2) == 0 && (i % 2) == 0) {
1804                 U = ((-38 * R) - (74 * G) + (112 * B) + 128);
1805                 U = U >> 8;
1806                 U += 128;
1807                 V = ((112 * R) - (94 * G) - (18 * B) + 128);
1808                 V = V >> 8;
1809                 V += 128;
1810
1811                 pDstUV[uvIndex++] = (unsigned char)U;
1812                 pDstUV[uvIndex++] = (unsigned char)V;
1813             }
1814         }
1815     }
1816 }