2 * Templates for image convertion routines
3 * Copyright (c) 2001, 2002, 2003 Fabrice Bellard.
5 * This file is part of FFmpeg.
7 * FFmpeg is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
12 * FFmpeg is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with FFmpeg; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
23 #define RGB_OUT(d, r, g, b) RGBA_OUT(d, r, g, b, 0xff)
26 static void glue(yuv420p_to_, RGB_NAME)(AVPicture *dst, const AVPicture *src,
27 int width, int height)
29 const uint8_t *y1_ptr, *y2_ptr, *cb_ptr, *cr_ptr;
31 int w, y, cb, cr, r_add, g_add, b_add, width2;
32 uint8_t *cm = cropTbl + MAX_NEG_CROP;
36 y1_ptr = src->data[0];
37 cb_ptr = src->data[1];
38 cr_ptr = src->data[2];
39 width2 = (width + 1) >> 1;
40 for(;height >= 2; height -= 2) {
42 d2 = d + dst->linesize[0];
43 y2_ptr = y1_ptr + src->linesize[0];
44 for(w = width; w >= 2; w -= 2) {
45 YUV_TO_RGB1_CCIR(cb_ptr[0], cr_ptr[0]);
47 YUV_TO_RGB2_CCIR(r, g, b, y1_ptr[0]);
50 YUV_TO_RGB2_CCIR(r, g, b, y1_ptr[1]);
51 RGB_OUT(d1 + BPP, r, g, b);
53 YUV_TO_RGB2_CCIR(r, g, b, y2_ptr[0]);
56 YUV_TO_RGB2_CCIR(r, g, b, y2_ptr[1]);
57 RGB_OUT(d2 + BPP, r, g, b);
67 /* handle odd width */
69 YUV_TO_RGB1_CCIR(cb_ptr[0], cr_ptr[0]);
70 YUV_TO_RGB2_CCIR(r, g, b, y1_ptr[0]);
73 YUV_TO_RGB2_CCIR(r, g, b, y2_ptr[0]);
82 d += 2 * dst->linesize[0];
83 y1_ptr += 2 * src->linesize[0] - width;
84 cb_ptr += src->linesize[1] - width2;
85 cr_ptr += src->linesize[2] - width2;
87 /* handle odd height */
90 for(w = width; w >= 2; w -= 2) {
91 YUV_TO_RGB1_CCIR(cb_ptr[0], cr_ptr[0]);
93 YUV_TO_RGB2_CCIR(r, g, b, y1_ptr[0]);
96 YUV_TO_RGB2_CCIR(r, g, b, y1_ptr[1]);
97 RGB_OUT(d1 + BPP, r, g, b);
107 YUV_TO_RGB1_CCIR(cb_ptr[0], cr_ptr[0]);
108 /* output 2 pixels */
109 YUV_TO_RGB2_CCIR(r, g, b, y1_ptr[0]);
110 RGB_OUT(d1, r, g, b);
120 static void glue(yuvj420p_to_, RGB_NAME)(AVPicture *dst, const AVPicture *src,
121 int width, int height)
123 const uint8_t *y1_ptr, *y2_ptr, *cb_ptr, *cr_ptr;
124 uint8_t *d, *d1, *d2;
125 int w, y, cb, cr, r_add, g_add, b_add, width2;
126 uint8_t *cm = cropTbl + MAX_NEG_CROP;
127 unsigned int r, g, b;
130 y1_ptr = src->data[0];
131 cb_ptr = src->data[1];
132 cr_ptr = src->data[2];
133 width2 = (width + 1) >> 1;
134 for(;height >= 2; height -= 2) {
136 d2 = d + dst->linesize[0];
137 y2_ptr = y1_ptr + src->linesize[0];
138 for(w = width; w >= 2; w -= 2) {
139 YUV_TO_RGB1(cb_ptr[0], cr_ptr[0]);
140 /* output 4 pixels */
141 YUV_TO_RGB2(r, g, b, y1_ptr[0]);
142 RGB_OUT(d1, r, g, b);
144 YUV_TO_RGB2(r, g, b, y1_ptr[1]);
145 RGB_OUT(d1 + BPP, r, g, b);
147 YUV_TO_RGB2(r, g, b, y2_ptr[0]);
148 RGB_OUT(d2, r, g, b);
150 YUV_TO_RGB2(r, g, b, y2_ptr[1]);
151 RGB_OUT(d2 + BPP, r, g, b);
161 /* handle odd width */
163 YUV_TO_RGB1(cb_ptr[0], cr_ptr[0]);
164 YUV_TO_RGB2(r, g, b, y1_ptr[0]);
165 RGB_OUT(d1, r, g, b);
167 YUV_TO_RGB2(r, g, b, y2_ptr[0]);
168 RGB_OUT(d2, r, g, b);
176 d += 2 * dst->linesize[0];
177 y1_ptr += 2 * src->linesize[0] - width;
178 cb_ptr += src->linesize[1] - width2;
179 cr_ptr += src->linesize[2] - width2;
181 /* handle odd height */
184 for(w = width; w >= 2; w -= 2) {
185 YUV_TO_RGB1(cb_ptr[0], cr_ptr[0]);
186 /* output 2 pixels */
187 YUV_TO_RGB2(r, g, b, y1_ptr[0]);
188 RGB_OUT(d1, r, g, b);
190 YUV_TO_RGB2(r, g, b, y1_ptr[1]);
191 RGB_OUT(d1 + BPP, r, g, b);
201 YUV_TO_RGB1(cb_ptr[0], cr_ptr[0]);
202 /* output 2 pixels */
203 YUV_TO_RGB2(r, g, b, y1_ptr[0]);
204 RGB_OUT(d1, r, g, b);
214 static void glue(RGB_NAME, _to_yuv420p)(AVPicture *dst, const AVPicture *src,
215 int width, int height)
217 int wrap, wrap3, width2;
218 int r, g, b, r1, g1, b1, w;
219 uint8_t *lum, *cb, *cr;
226 width2 = (width + 1) >> 1;
227 wrap = dst->linesize[0];
228 wrap3 = src->linesize[0];
230 for(;height>=2;height -= 2) {
231 for(w = width; w >= 2; w -= 2) {
236 lum[0] = RGB_TO_Y_CCIR(r, g, b);
238 RGB_IN(r, g, b, p + BPP);
242 lum[1] = RGB_TO_Y_CCIR(r, g, b);
250 lum[0] = RGB_TO_Y_CCIR(r, g, b);
252 RGB_IN(r, g, b, p + BPP);
256 lum[1] = RGB_TO_Y_CCIR(r, g, b);
258 cb[0] = RGB_TO_U_CCIR(r1, g1, b1, 2);
259 cr[0] = RGB_TO_V_CCIR(r1, g1, b1, 2);
263 p += -wrap3 + 2 * BPP;
271 lum[0] = RGB_TO_Y_CCIR(r, g, b);
278 lum[0] = RGB_TO_Y_CCIR(r, g, b);
279 cb[0] = RGB_TO_U_CCIR(r1, g1, b1, 1);
280 cr[0] = RGB_TO_V_CCIR(r1, g1, b1, 1);
286 p += wrap3 + (wrap3 - width * BPP);
287 lum += wrap + (wrap - width);
288 cb += dst->linesize[1] - width2;
289 cr += dst->linesize[2] - width2;
291 /* handle odd height */
293 for(w = width; w >= 2; w -= 2) {
298 lum[0] = RGB_TO_Y_CCIR(r, g, b);
300 RGB_IN(r, g, b, p + BPP);
304 lum[1] = RGB_TO_Y_CCIR(r, g, b);
305 cb[0] = RGB_TO_U_CCIR(r1, g1, b1, 1);
306 cr[0] = RGB_TO_V_CCIR(r1, g1, b1, 1);
314 lum[0] = RGB_TO_Y_CCIR(r, g, b);
315 cb[0] = RGB_TO_U_CCIR(r, g, b, 0);
316 cr[0] = RGB_TO_V_CCIR(r, g, b, 0);
321 static void glue(RGB_NAME, _to_gray)(AVPicture *dst, const AVPicture *src,
322 int width, int height)
324 const unsigned char *p;
326 int r, g, b, dst_wrap, src_wrap;
330 src_wrap = src->linesize[0] - BPP * width;
333 dst_wrap = dst->linesize[0] - width;
335 for(y=0;y<height;y++) {
336 for(x=0;x<width;x++) {
338 q[0] = RGB_TO_Y(r, g, b);
347 static void glue(gray_to_, RGB_NAME)(AVPicture *dst, const AVPicture *src,
348 int width, int height)
350 const unsigned char *p;
352 int r, dst_wrap, src_wrap;
356 src_wrap = src->linesize[0] - width;
359 dst_wrap = dst->linesize[0] - BPP * width;
361 for(y=0;y<height;y++) {
362 for(x=0;x<width;x++) {
373 static void glue(pal8_to_, RGB_NAME)(AVPicture *dst, const AVPicture *src,
374 int width, int height)
376 const unsigned char *p;
378 int r, g, b, dst_wrap, src_wrap;
381 const uint32_t *palette;
384 src_wrap = src->linesize[0] - width;
385 palette = (uint32_t *)src->data[1];
388 dst_wrap = dst->linesize[0] - BPP * width;
390 for(y=0;y<height;y++) {
391 for(x=0;x<width;x++) {
393 r = (v >> 16) & 0xff;
399 a = (v >> 24) & 0xff;
400 RGBA_OUT(q, r, g, b, a);
413 #if !defined(FMT_RGBA32) && defined(RGBA_OUT)
416 static void glue(rgba32_to_, RGB_NAME)(AVPicture *dst, const AVPicture *src,
417 int width, int height)
421 int src_wrap, dst_wrap, j, y;
422 unsigned int v, r, g, b, a;
425 src_wrap = src->linesize[0] - width * 4;
428 dst_wrap = dst->linesize[0] - width * BPP;
430 for(y=0;y<height;y++) {
431 for(j = 0;j < width; j++) {
432 v = ((const uint32_t *)(s))[0];
433 a = (v >> 24) & 0xff;
434 r = (v >> 16) & 0xff;
437 RGBA_OUT(d, r, g, b, a);
446 static void glue(RGB_NAME, _to_rgba32)(AVPicture *dst, const AVPicture *src,
447 int width, int height)
451 int src_wrap, dst_wrap, j, y;
452 unsigned int r, g, b, a;
455 src_wrap = src->linesize[0] - width * BPP;
458 dst_wrap = dst->linesize[0] - width * 4;
460 for(y=0;y<height;y++) {
461 for(j = 0;j < width; j++) {
462 RGBA_IN(r, g, b, a, s);
463 ((uint32_t *)(d))[0] = (a << 24) | (r << 16) | (g << 8) | b;
472 #endif /* !defined(FMT_RGBA32) && defined(RGBA_IN) */
476 static void glue(rgb24_to_, RGB_NAME)(AVPicture *dst, const AVPicture *src,
477 int width, int height)
481 int src_wrap, dst_wrap, j, y;
482 unsigned int r, g, b;
485 src_wrap = src->linesize[0] - width * 3;
488 dst_wrap = dst->linesize[0] - width * BPP;
490 for(y=0;y<height;y++) {
491 for(j = 0;j < width; j++) {
504 static void glue(RGB_NAME, _to_rgb24)(AVPicture *dst, const AVPicture *src,
505 int width, int height)
509 int src_wrap, dst_wrap, j, y;
510 unsigned int r, g , b;
513 src_wrap = src->linesize[0] - width * BPP;
516 dst_wrap = dst->linesize[0] - width * 3;
518 for(y=0;y<height;y++) {
519 for(j = 0;j < width; j++) {
532 #endif /* !FMT_RGB24 */
536 static void yuv444p_to_rgb24(AVPicture *dst, const AVPicture *src,
537 int width, int height)
539 const uint8_t *y1_ptr, *cb_ptr, *cr_ptr;
541 int w, y, cb, cr, r_add, g_add, b_add;
542 uint8_t *cm = cropTbl + MAX_NEG_CROP;
543 unsigned int r, g, b;
546 y1_ptr = src->data[0];
547 cb_ptr = src->data[1];
548 cr_ptr = src->data[2];
549 for(;height > 0; height --) {
551 for(w = width; w > 0; w--) {
552 YUV_TO_RGB1_CCIR(cb_ptr[0], cr_ptr[0]);
554 YUV_TO_RGB2_CCIR(r, g, b, y1_ptr[0]);
555 RGB_OUT(d1, r, g, b);
562 d += dst->linesize[0];
563 y1_ptr += src->linesize[0] - width;
564 cb_ptr += src->linesize[1] - width;
565 cr_ptr += src->linesize[2] - width;
569 static void yuvj444p_to_rgb24(AVPicture *dst, const AVPicture *src,
570 int width, int height)
572 const uint8_t *y1_ptr, *cb_ptr, *cr_ptr;
574 int w, y, cb, cr, r_add, g_add, b_add;
575 uint8_t *cm = cropTbl + MAX_NEG_CROP;
576 unsigned int r, g, b;
579 y1_ptr = src->data[0];
580 cb_ptr = src->data[1];
581 cr_ptr = src->data[2];
582 for(;height > 0; height --) {
584 for(w = width; w > 0; w--) {
585 YUV_TO_RGB1(cb_ptr[0], cr_ptr[0]);
587 YUV_TO_RGB2(r, g, b, y1_ptr[0]);
588 RGB_OUT(d1, r, g, b);
595 d += dst->linesize[0];
596 y1_ptr += src->linesize[0] - width;
597 cb_ptr += src->linesize[1] - width;
598 cr_ptr += src->linesize[2] - width;
602 static void rgb24_to_yuv444p(AVPicture *dst, const AVPicture *src,
603 int width, int height)
607 uint8_t *lum, *cb, *cr;
614 src_wrap = src->linesize[0] - width * BPP;
616 for(y=0;y<height;y++) {
617 for(x=0;x<width;x++) {
619 lum[0] = RGB_TO_Y_CCIR(r, g, b);
620 cb[0] = RGB_TO_U_CCIR(r, g, b, 0);
621 cr[0] = RGB_TO_V_CCIR(r, g, b, 0);
628 lum += dst->linesize[0] - width;
629 cb += dst->linesize[1] - width;
630 cr += dst->linesize[2] - width;
634 static void rgb24_to_yuvj420p(AVPicture *dst, const AVPicture *src,
635 int width, int height)
637 int wrap, wrap3, width2;
638 int r, g, b, r1, g1, b1, w;
639 uint8_t *lum, *cb, *cr;
646 width2 = (width + 1) >> 1;
647 wrap = dst->linesize[0];
648 wrap3 = src->linesize[0];
650 for(;height>=2;height -= 2) {
651 for(w = width; w >= 2; w -= 2) {
656 lum[0] = RGB_TO_Y(r, g, b);
658 RGB_IN(r, g, b, p + BPP);
662 lum[1] = RGB_TO_Y(r, g, b);
670 lum[0] = RGB_TO_Y(r, g, b);
672 RGB_IN(r, g, b, p + BPP);
676 lum[1] = RGB_TO_Y(r, g, b);
678 cb[0] = RGB_TO_U(r1, g1, b1, 2);
679 cr[0] = RGB_TO_V(r1, g1, b1, 2);
683 p += -wrap3 + 2 * BPP;
691 lum[0] = RGB_TO_Y(r, g, b);
698 lum[0] = RGB_TO_Y(r, g, b);
699 cb[0] = RGB_TO_U(r1, g1, b1, 1);
700 cr[0] = RGB_TO_V(r1, g1, b1, 1);
706 p += wrap3 + (wrap3 - width * BPP);
707 lum += wrap + (wrap - width);
708 cb += dst->linesize[1] - width2;
709 cr += dst->linesize[2] - width2;
711 /* handle odd height */
713 for(w = width; w >= 2; w -= 2) {
718 lum[0] = RGB_TO_Y(r, g, b);
720 RGB_IN(r, g, b, p + BPP);
724 lum[1] = RGB_TO_Y(r, g, b);
725 cb[0] = RGB_TO_U(r1, g1, b1, 1);
726 cr[0] = RGB_TO_V(r1, g1, b1, 1);
734 lum[0] = RGB_TO_Y(r, g, b);
735 cb[0] = RGB_TO_U(r, g, b, 0);
736 cr[0] = RGB_TO_V(r, g, b, 0);
741 static void rgb24_to_yuvj444p(AVPicture *dst, const AVPicture *src,
742 int width, int height)
746 uint8_t *lum, *cb, *cr;
753 src_wrap = src->linesize[0] - width * BPP;
755 for(y=0;y<height;y++) {
756 for(x=0;x<width;x++) {
758 lum[0] = RGB_TO_Y(r, g, b);
759 cb[0] = RGB_TO_U(r, g, b, 0);
760 cr[0] = RGB_TO_V(r, g, b, 0);
767 lum += dst->linesize[0] - width;
768 cb += dst->linesize[1] - width;
769 cr += dst->linesize[2] - width;
773 #endif /* FMT_RGB24 */
775 #if defined(FMT_RGB24) || defined(FMT_RGBA32)
777 static void glue(RGB_NAME, _to_pal8)(AVPicture *dst, const AVPicture *src,
778 int width, int height)
780 const unsigned char *p;
782 int dst_wrap, src_wrap;
784 unsigned int r, g, b;
787 src_wrap = src->linesize[0] - BPP * width;
790 dst_wrap = dst->linesize[0] - width;
793 for(y=0;y<height;y++) {
794 for(x=0;x<width;x++) {
798 RGBA_IN(r, g, b, a, p);
799 /* crude approximation for alpha ! */
804 q[0] = gif_clut_index(r, g, b);
809 q[0] = gif_clut_index(r, g, b);
818 build_rgb_palette(dst->data[1], has_alpha);
821 #endif /* defined(FMT_RGB24) || defined(FMT_RGBA32) */
825 static int glue(get_alpha_info_, RGB_NAME)(const AVPicture *src,
826 int width, int height)
828 const unsigned char *p;
829 int src_wrap, ret, x, y;
830 unsigned int r, g, b, a;
833 src_wrap = src->linesize[0] - BPP * width;
835 for(y=0;y<height;y++) {
836 for(x=0;x<width;x++) {
837 RGBA_IN(r, g, b, a, p);
839 ret |= FF_ALPHA_TRANSP;
840 } else if (a != 0xff) {
841 ret |= FF_ALPHA_SEMI_TRANSP;