blob: 74797eaa549a748752d13bba5208fe10cca9d166 [file] [log] [blame]
Jiho Chang9b81eb72012-03-24 06:01:16 +09001/*
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. It support MFC 6.x tiled.
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/* 2D Configurable tiled memory access (TM)
36 * Return the linear address from tiled position (x, y) */
37unsigned int Tile2D_To_Linear(
38 unsigned int width,
39 unsigned int height,
40 unsigned int xpos,
41 unsigned int ypos,
42 int crFlag)
43{
44 int tileNumX;
45 int tileX, tileY;
46 int tileAddr;
47 int offset;
48 int addr;
49
50 width = ((width + 15) / 16) * 16;
51 tileNumX = width / 16;
52
53 /* crFlag - 0: Y plane, 1: CbCr plane */
54 if (crFlag == 0) {
55 tileX = xpos / 16;
56 tileY = ypos / 16;
57 tileAddr = tileY * tileNumX + tileX;
58 offset = (ypos & 15) * 16 + (xpos & 15);
59 addr = (tileAddr << 8) | offset;
60 } else {
61 tileX = xpos / 16;
62 tileY = ypos / 8;
63 tileAddr = tileY * tileNumX + tileX;
64 offset = (ypos & 7) * 16 + (xpos & 15);
65 addr = (tileAddr << 7) | offset;
66 }
67
68 return addr;
69}
70
71/*
72 * De-interleaves src to dest1, dest2
73 *
74 * @param dest1
75 * Address of de-interleaved data[out]
76 *
77 * @param dest2
78 * Address of de-interleaved data[out]
79 *
80 * @param src
81 * Address of interleaved data[in]
82 *
83 * @param src_size
84 * Size of interleaved data[in]
85 */
86void csc_deinterleave_memcpy(
87 unsigned char *dest1,
88 unsigned char *dest2,
89 unsigned char *src,
90 unsigned int src_size)
91{
92 unsigned int i = 0;
93 for(i=0; i<src_size/2; i++) {
94 dest1[i] = src[i*2];
95 dest2[i] = src[i*2+1];
96 }
97}
98
99/*
100 * Interleaves src1, src2 to dest
101 *
102 * @param dest
103 * Address of interleaved data[out]
104 *
105 * @param src1
106 * Address of de-interleaved data[in]
107 *
108 * @param src2
109 * Address of de-interleaved data[in]
110 *
111 * @param src_size
112 * Size of de-interleaved data[in]
113 */
114void csc_interleave_memcpy(
115 unsigned char *dest,
116 unsigned char *src1,
117 unsigned char *src2,
118 unsigned int src_size)
119{
120 unsigned int i = 0;
121 for(i=0; i<src_size; i++) {
122 dest[i*2] = src1[i];
123 dest[i*2+1] = src2[i];
124 }
125}
126
127/*
128 * Converts tiled data to linear for mfc 6.x tiled
129 * 1. y of nv12t to y of yuv420p
130 * 2. y of nv12t to y of yuv420s
131 *
132 * @param dst
133 * y address of yuv420[out]
134 *
135 * @param src
136 * y address of nv12t[in]
137 *
138 * @param yuv420_width
139 * real width of yuv420[in]
140 * it should be even
141 *
142 * @param yuv420_height
143 * real height of yuv420[in]
144 * it should be even.
145 *
146 */
147void csc_tiled_to_linear_y(
148 unsigned char *y_dst,
149 unsigned char *y_src,
150 unsigned int width,
151 unsigned int height)
152{
153 unsigned int i, j, k;
154 unsigned int aligned_width, aligned_height;
155 unsigned int tiled_width;
156 unsigned int src_offset, dst_offset;
157
158 aligned_height = height & (~0xF);
159 aligned_width = width & (~0xF);
160 tiled_width = ((width + 15) >> 4) << 4;
161
162 for (i = 0; i < aligned_height; i = i + 16) {
163 for (j = 0; j<aligned_width; j = j + 16) {
164 src_offset = (tiled_width * i) + (j << 4);
165 dst_offset = width * i + j;
166 for (k = 0; k < 8; k++) {
167 memcpy(y_dst + dst_offset, y_src + src_offset, 16);
168 src_offset += 16;
169 dst_offset += width;
170 memcpy(y_dst + dst_offset, y_src + src_offset, 16);
171 src_offset += 16;
172 dst_offset += width;
173 }
174 }
175 if (aligned_width != width) {
176 src_offset = (tiled_width * i) + (j << 4);
177 dst_offset = width * i + j;
178 for (k = 0; k < 8; k++) {
179 memcpy(y_dst + dst_offset, y_src + src_offset, width - j);
180 src_offset += 16;
181 dst_offset += width;
182 memcpy(y_dst + dst_offset, y_src + src_offset, width - j);
183 src_offset += 16;
184 dst_offset += width;
185 }
186 }
187 }
188
189 if (aligned_height != height) {
190 for (j = 0; j<aligned_width; j = j + 16) {
191 src_offset = (tiled_width * i) + (j << 4);
192 dst_offset = width * i + j;
193 for (k = 0; k < height - aligned_height; k = k + 2) {
194 memcpy(y_dst + dst_offset, y_src + src_offset, 16);
195 src_offset += 16;
196 dst_offset += width;
197 memcpy(y_dst + dst_offset, y_src + src_offset, 16);
198 src_offset += 16;
199 dst_offset += width;
200 }
201 }
202 if (aligned_width != width) {
203 src_offset = (tiled_width * i) + (j << 4);
204 dst_offset = width * i + j;
205 for (k = 0; k < height - aligned_height; k = k + 2) {
206 memcpy(y_dst + dst_offset, y_src + src_offset, width - j);
207 src_offset += 16;
208 dst_offset += width;
209 memcpy(y_dst + dst_offset, y_src + src_offset, width - j);
210 src_offset += 16;
211 dst_offset += width;
212 }
213 }
214 }
215}
216
217/*
218 * Converts tiled data to linear for mfc 6.x tiled
219 * 1. uv of nv12t to uv of yuv420s
220 *
221 * @param dst
222 * uv address of yuv420s[out]
223 *
224 * @param src
225 * uv address of nv12t[in]
226 *
227 * @param yuv420_width
228 * real width of yuv420s[in]
229 *
230 * @param yuv420_height
231 * real height of yuv420s[in]
232 *
233 */
234void csc_tiled_to_linear_uv(
235 unsigned char *uv_dst,
236 unsigned char *uv_src,
237 unsigned int width,
238 unsigned int height)
239{
240 unsigned int i, j, k;
241 unsigned int aligned_width, aligned_height;
242 unsigned int tiled_width;
243 unsigned int src_offset, dst_offset;
244
245 aligned_height = height & (~0x7);
246 aligned_width = width & (~0xF);
247 tiled_width = ((width + 15) >> 4) << 4;
248
249 for (i = 0; i < aligned_height; i = i + 8) {
250 for (j = 0; j<aligned_width; j = j + 16) {
251 src_offset = (tiled_width * i) + (j << 3);
252 dst_offset = width * i + j;
253 for (k = 0; k < 4; k++) {
254 memcpy(uv_dst + dst_offset, uv_src + src_offset, 16);
255 src_offset += 16;
256 dst_offset += width;
257 memcpy(uv_dst + dst_offset, uv_src + src_offset, 16);
258 src_offset += 16;
259 dst_offset += width;
260 }
261 }
262 if (aligned_width != width) {
263 src_offset = (tiled_width * i) + (j << 3);
264 dst_offset = width * i + j;
265 for (k = 0; k < 4; k++) {
266 memcpy(uv_dst + dst_offset, uv_src + src_offset, width - j);
267 src_offset += 16;
268 dst_offset += width;
269 memcpy(uv_dst + dst_offset, uv_src + src_offset, width - j);
270 src_offset += 16;
271 dst_offset += width;
272 }
273 }
274 }
275
276 if (aligned_height != height) {
277 for (j = 0; j<aligned_width; j = j + 16) {
278 src_offset = (tiled_width * i) + (j << 3);
279 dst_offset = width * i + j;
280 for (k = 0; k < height - aligned_height; k = k + 1) {
281 memcpy(uv_dst + dst_offset, uv_src + src_offset, 16);
282 src_offset += 16;
283 dst_offset += width;
284 }
285 }
286 if (aligned_width != width) {
287 src_offset = (tiled_width * i) + (j << 3);
288 dst_offset = width * i + j;
289 for (k = 0; k < height - aligned_height; k = k + 1) {
290 memcpy(uv_dst + dst_offset, uv_src + src_offset, width - j);
291 src_offset += 16;
292 dst_offset += width;
293 }
294 }
295 }
296}
297
298/*
299 * Converts tiled data to linear for mfc 6.x tiled
300 * 1. uv of nt12t to uv of yuv420p
301 *
302 * @param u_dst
303 * u address of yuv420p[out]
304 *
305 * @param v_dst
306 * v address of yuv420p[out]
307 *
308 * @param uv_src
309 * uv address of nt12t[in]
310 *
311 * @param yuv420_width
312 * real width of yuv420p[in]
313 *
314 * @param yuv420_height
315 * real height of yuv420p[in]
316 */
317void csc_tiled_to_linear_uv_deinterleave(
318 unsigned char *u_dst,
319 unsigned char *v_dst,
320 unsigned char *uv_src,
321 unsigned int width,
322 unsigned int height)
323{
324 unsigned int i, j, k;
325 unsigned int aligned_width, aligned_height;
326 unsigned int tiled_width;
327 unsigned int src_offset, dst_offset;
328
329 aligned_height = height & (~0x7);
330 aligned_width = width & (~0xF);
331 tiled_width = ((width + 15) >> 4) << 4;
332
333 for (i = 0; i < aligned_height; i = i + 8) {
334 for (j = 0; j<aligned_width; j = j + 16) {
335 src_offset = (tiled_width * i) + (j << 3);
336 dst_offset = (width >> 1) * i + (j >> 1);
337 for (k = 0; k < 4; k++) {
338 csc_deinterleave_memcpy(u_dst + dst_offset, v_dst + dst_offset,
339 uv_src + src_offset, 16);
340 src_offset += 16;
341 dst_offset += width >> 1;
342 csc_deinterleave_memcpy(u_dst + dst_offset, v_dst + dst_offset,
343 uv_src + src_offset, 16);
344 src_offset += 16;
345 dst_offset += width >> 1;
346 }
347 }
348 if (aligned_width != width) {
349 src_offset = (tiled_width * i) + (j << 3);
350 dst_offset = (width >> 1) * i + (j >> 1);
351 for (k = 0; k < 4; k++) {
352 csc_deinterleave_memcpy(u_dst + dst_offset, v_dst + dst_offset,
353 uv_src + src_offset, width - j);
354 src_offset += 16;
355 dst_offset += width >> 1;
356 csc_deinterleave_memcpy(u_dst + dst_offset, v_dst + dst_offset,
357 uv_src + src_offset, width - j);
358 src_offset += 16;
359 dst_offset += width >> 1;
360 }
361 }
362 }
363 if (aligned_height != height) {
364 for (j = 0; j<aligned_width; j = j + 16) {
365 src_offset = (tiled_width * i) + (j << 3);
366 dst_offset = (width >> 1) * i + (j >> 1);
367 for (k = 0; k < height - aligned_height; k = k + 1) {
368 csc_deinterleave_memcpy(u_dst + dst_offset, v_dst + dst_offset,
369 uv_src + src_offset, 16);
370 src_offset += 16;
371 dst_offset += width >> 1;
372 }
373 }
374 if (aligned_width != width) {
375 src_offset = (tiled_width * i) + (j << 3);
376 dst_offset = (width >> 1) * i + (j >> 1);
377 for (k = 0; k < height - aligned_height; k = k + 1) {
378 csc_deinterleave_memcpy(u_dst + dst_offset, v_dst + dst_offset,
379 uv_src + src_offset, width - j);
380 src_offset += 16;
381 dst_offset += width >> 1;
382 }
383 }
384 }
385}
386
387/*
388 * Converts linear data to tiled
389 * It supports mfc 6.x tiled
390 * 1. y of yuv420 to y of nv12t
391 *
392 * @param dst
393 * y address of nv12t[out]
394 *
395 * @param src
396 * y address of yuv420[in]
397 *
398 * @param yuv420_width
399 * real width of yuv420[in]
400 * it should be even
401 *
402 * @param yuv420_height
403 * real height of yuv420[in]
404 * it should be even.
405 *
406 */
407void csc_linear_to_tiled_y(
408 unsigned char *y_dst,
409 unsigned char *y_src,
410 unsigned int width,
411 unsigned int height)
412{
413
414}
415
416/*
417 * Converts and interleaves linear data to tiled
418 * It supports mfc 6.x tiled
419 * 1. uv of nv12t to uv of yuv420
420 *
421 * @param dst
422 * uv address of nv12t[out]
423 *
424 * @param src
425 * u address of yuv420[in]
426 *
427 * @param src
428 * v address of yuv420[in]
429 *
430 * @param yuv420_width
431 * real width of yuv420[in]
432 *
433 * @param yuv420_height
434 * real height of yuv420[in]
435 *
436 */
437void csc_linear_to_tiled_uv(
438 unsigned char *uv_dst,
439 unsigned char *u_src,
440 unsigned char *v_src,
441 unsigned int width,
442 unsigned int height)
443{
444
445}
446
447void Tile2D_To_YUV420(unsigned char *Y_plane, unsigned char *Cb_plane, unsigned char *Cr_plane,
448 unsigned int y_addr, unsigned int c_addr, unsigned int width, unsigned int height)
449{
450 int x, y, j, k, l;
451 int out_of_width, actual_width;
452 unsigned int base_addr, data;
453
454 // y: 0, 16, 32, ...
455 for (y = 0; y < height; y += 16) {
456 // x: 0, 16, 32, ...
457 for (x = 0; x < width; x += 16) {
458 out_of_width = (x + 16) > width ? 1 : 0;
459 base_addr = y_addr + Tile2D_To_Linear(width, height, x, y, 0);
460
461 for (k = 0; (k < 16) && ((y + k) < height); k++) {
462 actual_width = out_of_width ? ((width%4)?((width%16) / 4 + 1) : ((width%16) / 4)) : 4;
463 for (l = 0; l < actual_width; l++) {
464 data = *((unsigned int*)(base_addr + 16*k + l*4));
465 for (j = 0; (j < 4) && (x + l*4 + j) < width; j++) {
466 Y_plane[(y+k)*width + x + l*4 +j] = (data>>(8*j))&0xff;
467 }
468 }
469 }
470 }
471 }
472
473 for (y = 0; y < height/2; y += 8) {
474 for (x = 0; x < width; x += 16) {
475 out_of_width = (x + 16) > width ? 1 : 0;
476 base_addr = c_addr + Tile2D_To_Linear(width, height/2, x, y, 1);
477 for (k = 0; (k < 8) && ((y+k) < height/2); k++) {
478 actual_width = out_of_width ? ((width%4) ? ((width%16) / 4 + 1) : ((width%16) / 4)) : 4;
479 for (l = 0; l < actual_width; l++) {
480 data = *((unsigned int*)(base_addr + 16*k + l*4));
481 for (j = 0; (j < 2) && (x/2 + l*2 +j) < width/2; j++) {
482 Cb_plane[(y+k)*width/2 + x/2 + l*2 +j] = (data>> (8*2*j))&0xff;
483 Cr_plane[(y+k)*width/2 + x/2 + l*2 +j] = (data>>(8*2*j+8))&0xff;
484 }
485 }
486 }
487 }
488 }
489}
490
491/*
492 * Converts RGB565 to YUV420P
493 *
494 * @param y_dst
495 * Y plane address of YUV420P[out]
496 *
497 * @param u_dst
498 * U plane address of YUV420P[out]
499 *
500 * @param v_dst
501 * V plane address of YUV420P[out]
502 *
503 * @param rgb_src
504 * Address of RGB565[in]
505 *
506 * @param width
507 * Width of RGB565[in]
508 *
509 * @param height
510 * Height of RGB565[in]
511 */
512void csc_RGB565_to_YUV420P(
513 unsigned char *y_dst,
514 unsigned char *u_dst,
515 unsigned char *v_dst,
516 unsigned char *rgb_src,
517 int width,
518 int height)
519{
520 unsigned int i, j;
521 unsigned int tmp;
522
523 unsigned int R, G, B;
524 unsigned int Y, U, V;
525
526 unsigned int offset1 = width * height;
527 unsigned int offset2 = width/2 * height/2;
528
529 unsigned short int *pSrc = (unsigned short int *)rgb_src;
530
531 unsigned char *pDstY = (unsigned char *)y_dst;
532 unsigned char *pDstU = (unsigned char *)u_dst;
533 unsigned char *pDstV = (unsigned char *)v_dst;
534
535 unsigned int yIndex = 0;
536 unsigned int uIndex = 0;
537 unsigned int vIndex = 0;
538
539 for (j = 0; j < height; j++) {
540 for (i = 0; i < width; i++) {
541 tmp = pSrc[j * width + i];
542
543 R = (tmp & 0x0000F800) >> 8;
544 G = (tmp & 0x000007E0) >> 3;
545 B = (tmp & 0x0000001F);
546 B = B << 3;
547
548 Y = ((66 * R) + (129 * G) + (25 * B) + 128);
549 Y = Y >> 8;
550 Y += 16;
551
552 pDstY[yIndex++] = (unsigned char)Y;
553
554 if ((j % 2) == 0 && (i % 2) == 0) {
555 U = ((-38 * R) - (74 * G) + (112 * B) + 128);
556 U = U >> 8;
557 U += 128;
558 V = ((112 * R) - (94 * G) - (18 * B) + 128);
559 V = V >> 8;
560 V += 128;
561
562 pDstU[uIndex++] = (unsigned char)U;
563 pDstV[vIndex++] = (unsigned char)V;
564 }
565 }
566 }
567}
568
569/*
570 * Converts RGB565 to YUV420SP
571 *
572 * @param y_dst
573 * Y plane address of YUV420SP[out]
574 *
575 * @param uv_dst
576 * UV plane address of YUV420SP[out]
577 *
578 * @param rgb_src
579 * Address of RGB565[in]
580 *
581 * @param width
582 * Width of RGB565[in]
583 *
584 * @param height
585 * Height of RGB565[in]
586 */
587void csc_RGB565_to_YUV420SP(
588 unsigned char *y_dst,
589 unsigned char *uv_dst,
590 unsigned char *rgb_src,
591 int width,
592 int height)
593{
594 unsigned int i, j;
595 unsigned int tmp;
596
597 unsigned int R, G, B;
598 unsigned int Y, U, V;
599
600 unsigned int offset = width * height;
601
602 unsigned short int *pSrc = (unsigned short int *)rgb_src;
603
604 unsigned char *pDstY = (unsigned char *)y_dst;
605 unsigned char *pDstUV = (unsigned char *)uv_dst;
606
607 unsigned int yIndex = 0;
608 unsigned int uvIndex = 0;
609
610 for (j = 0; j < height; j++) {
611 for (i = 0; i < width; i++) {
612 tmp = pSrc[j * width + i];
613
614 R = (tmp & 0x0000F800) >> 11;
615 R = R * 8;
616 G = (tmp & 0x000007E0) >> 5;
617 G = G * 4;
618 B = (tmp & 0x0000001F);
619 B = B * 8;
620
621 Y = ((66 * R) + (129 * G) + (25 * B) + 128);
622 Y = Y >> 8;
623 Y += 16;
624
625 pDstY[yIndex++] = (unsigned char)Y;
626
627 if ((j % 2) == 0 && (i % 2) == 0) {
628 U = ((-38 * R) - (74 * G) + (112 * B) + 128);
629 U = U >> 8;
630 U += 128;
631 V = ((112 * R) - (94 * G) - (18 * B) + 128);
632 V = V >> 8;
633 V += 128;
634
635 pDstUV[uvIndex++] = (unsigned char)U;
636 pDstUV[uvIndex++] = (unsigned char)V;
637 }
638 }
639 }
640}
641
642/*
643 * Converts RGB8888 to YUV420P
644 *
645 * @param y_dst
646 * Y plane address of YUV420P[out]
647 *
648 * @param u_dst
649 * U plane address of YUV420P[out]
650 *
651 * @param v_dst
652 * V plane address of YUV420P[out]
653 *
654 * @param rgb_src
655 * Address of ARGB8888[in]
656 *
657 * @param width
658 * Width of ARGB8888[in]
659 *
660 * @param height
661 * Height of ARGB8888[in]
662 */
663void csc_ARGB8888_to_YUV420P(
664 unsigned char *y_dst,
665 unsigned char *u_dst,
666 unsigned char *v_dst,
667 unsigned char *rgb_src,
668 unsigned int width,
669 unsigned int height)
670{
671 unsigned int i, j;
672 unsigned int tmp;
673
674 unsigned int R, G, B;
675 unsigned int Y, U, V;
676
677 unsigned int offset1 = width * height;
678 unsigned int offset2 = width/2 * height/2;
679
680 unsigned int *pSrc = (unsigned int *)rgb_src;
681
682 unsigned char *pDstY = (unsigned char *)y_dst;
683 unsigned char *pDstU = (unsigned char *)u_dst;
684 unsigned char *pDstV = (unsigned char *)v_dst;
685
686 unsigned int yIndex = 0;
687 unsigned int uIndex = 0;
688 unsigned int vIndex = 0;
689
690 for (j = 0; j < height; j++) {
691 for (i = 0; i < width; i++) {
692 tmp = pSrc[j * width + i];
693
694 R = (tmp & 0x00FF0000) >> 16;
695 G = (tmp & 0x0000FF00) >> 8;
696 B = (tmp & 0x000000FF);
697
698 Y = ((66 * R) + (129 * G) + (25 * B) + 128);
699 Y = Y >> 8;
700 Y += 16;
701
702 pDstY[yIndex++] = (unsigned char)Y;
703
704 if ((j % 2) == 0 && (i % 2) == 0) {
705 U = ((-38 * R) - (74 * G) + (112 * B) + 128);
706 U = U >> 8;
707 U += 128;
708 V = ((112 * R) - (94 * G) - (18 * B) + 128);
709 V = V >> 8;
710 V += 128;
711
712 pDstU[uIndex++] = (unsigned char)U;
713 pDstV[vIndex++] = (unsigned char)V;
714 }
715 }
716 }
717}
718
719
720/*
721 * Converts ARGB8888 to YUV420S
722 *
723 * @param y_dst
724 * Y plane address of YUV420S[out]
725 *
726 * @param uv_dst
727 * UV plane address of YUV420S[out]
728 *
729 * @param rgb_src
730 * Address of ARGB8888[in]
731 *
732 * @param width
733 * Width of ARGB8888[in]
734 *
735 * @param height
736 * Height of ARGB8888[in]
737 */
738void csc_ARGB8888_to_YUV420SP(
739 unsigned char *y_dst,
740 unsigned char *uv_dst,
741 unsigned char *rgb_src,
742 unsigned int width,
743 unsigned int height)
744{
745 unsigned int i, j;
746 unsigned int tmp;
747
748 unsigned int R, G, B;
749 unsigned int Y, U, V;
750
751 unsigned int offset = width * height;
752
753 unsigned int *pSrc = (unsigned int *)rgb_src;
754
755 unsigned char *pDstY = (unsigned char *)y_dst;
756 unsigned char *pDstUV = (unsigned char *)uv_dst;
757
758 unsigned int yIndex = 0;
759 unsigned int uvIndex = 0;
760
761 for (j = 0; j < height; j++) {
762 for (i = 0; i < width; i++) {
763 tmp = pSrc[j * width + i];
764
765 R = (tmp & 0x00FF0000) >> 16;
766 G = (tmp & 0x0000FF00) >> 8;
767 B = (tmp & 0x000000FF);
768
769 Y = ((66 * R) + (129 * G) + (25 * B) + 128);
770 Y = Y >> 8;
771 Y += 16;
772
773 pDstY[yIndex++] = (unsigned char)Y;
774
775 if ((j % 2) == 0 && (i % 2) == 0) {
776 U = ((-38 * R) - (74 * G) + (112 * B) + 128);
777 U = U >> 8;
778 U += 128;
779 V = ((112 * R) - (94 * G) - (18 * B) + 128);
780 V = V >> 8;
781 V += 128;
782
783 pDstUV[uvIndex++] = (unsigned char)U;
784 pDstUV[uvIndex++] = (unsigned char)V;
785 }
786 }
787 }
788}