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