2 * Templates for image convertion routines
3 * Copyright (c) 2001, 2002, 2003 Fabrice Bellard.
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2 of the License, or (at your option) any later version.
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this library; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 #define RGB_OUT(d, r, g, b) RGBA_OUT(d, r, g, b, 0xff)
24 static void glue(yuv420p_to_, RGB_NAME)(AVPicture *dst, const AVPicture *src,
25 int width, int height)
27 const uint8_t *y1_ptr, *y2_ptr, *cb_ptr, *cr_ptr;
29 int w, y, cb, cr, r_add, g_add, b_add, width2;
30 uint8_t *cm = cropTbl + MAX_NEG_CROP;
34 y1_ptr = src->data[0];
35 cb_ptr = src->data[1];
36 cr_ptr = src->data[2];
37 width2 = (width + 1) >> 1;
38 for(;height >= 2; height -= 2) {
40 d2 = d + dst->linesize[0];
41 y2_ptr = y1_ptr + src->linesize[0];
42 for(w = width; w >= 2; w -= 2) {
43 YUV_TO_RGB1_CCIR(cb_ptr[0], cr_ptr[0]);
45 YUV_TO_RGB2_CCIR(r, g, b, y1_ptr[0]);
48 YUV_TO_RGB2_CCIR(r, g, b, y1_ptr[1]);
49 RGB_OUT(d1 + BPP, r, g, b);
51 YUV_TO_RGB2_CCIR(r, g, b, y2_ptr[0]);
54 YUV_TO_RGB2_CCIR(r, g, b, y2_ptr[1]);
55 RGB_OUT(d2 + BPP, r, g, b);
65 /* handle odd width */
67 YUV_TO_RGB1_CCIR(cb_ptr[0], cr_ptr[0]);
68 YUV_TO_RGB2_CCIR(r, g, b, y1_ptr[0]);
71 YUV_TO_RGB2_CCIR(r, g, b, y2_ptr[0]);
80 d += 2 * dst->linesize[0];
81 y1_ptr += 2 * src->linesize[0] - width;
82 cb_ptr += src->linesize[1] - width2;
83 cr_ptr += src->linesize[2] - width2;
85 /* handle odd height */
88 for(w = width; w >= 2; w -= 2) {
89 YUV_TO_RGB1_CCIR(cb_ptr[0], cr_ptr[0]);
91 YUV_TO_RGB2_CCIR(r, g, b, y1_ptr[0]);
94 YUV_TO_RGB2_CCIR(r, g, b, y1_ptr[1]);
95 RGB_OUT(d1 + BPP, r, g, b);
105 YUV_TO_RGB1_CCIR(cb_ptr[0], cr_ptr[0]);
106 /* output 2 pixels */
107 YUV_TO_RGB2_CCIR(r, g, b, y1_ptr[0]);
108 RGB_OUT(d1, r, g, b);
118 static void glue(yuvj420p_to_, RGB_NAME)(AVPicture *dst, const AVPicture *src,
119 int width, int height)
121 const uint8_t *y1_ptr, *y2_ptr, *cb_ptr, *cr_ptr;
122 uint8_t *d, *d1, *d2;
123 int w, y, cb, cr, r_add, g_add, b_add, width2;
124 uint8_t *cm = cropTbl + MAX_NEG_CROP;
125 unsigned int r, g, b;
128 y1_ptr = src->data[0];
129 cb_ptr = src->data[1];
130 cr_ptr = src->data[2];
131 width2 = (width + 1) >> 1;
132 for(;height >= 2; height -= 2) {
134 d2 = d + dst->linesize[0];
135 y2_ptr = y1_ptr + src->linesize[0];
136 for(w = width; w >= 2; w -= 2) {
137 YUV_TO_RGB1(cb_ptr[0], cr_ptr[0]);
138 /* output 4 pixels */
139 YUV_TO_RGB2(r, g, b, y1_ptr[0]);
140 RGB_OUT(d1, r, g, b);
142 YUV_TO_RGB2(r, g, b, y1_ptr[1]);
143 RGB_OUT(d1 + BPP, r, g, b);
145 YUV_TO_RGB2(r, g, b, y2_ptr[0]);
146 RGB_OUT(d2, r, g, b);
148 YUV_TO_RGB2(r, g, b, y2_ptr[1]);
149 RGB_OUT(d2 + BPP, r, g, b);
159 /* handle odd width */
161 YUV_TO_RGB1(cb_ptr[0], cr_ptr[0]);
162 YUV_TO_RGB2(r, g, b, y1_ptr[0]);
163 RGB_OUT(d1, r, g, b);
165 YUV_TO_RGB2(r, g, b, y2_ptr[0]);
166 RGB_OUT(d2, r, g, b);
174 d += 2 * dst->linesize[0];
175 y1_ptr += 2 * src->linesize[0] - width;
176 cb_ptr += src->linesize[1] - width2;
177 cr_ptr += src->linesize[2] - width2;
179 /* handle odd height */
182 for(w = width; w >= 2; w -= 2) {
183 YUV_TO_RGB1(cb_ptr[0], cr_ptr[0]);
184 /* output 2 pixels */
185 YUV_TO_RGB2(r, g, b, y1_ptr[0]);
186 RGB_OUT(d1, r, g, b);
188 YUV_TO_RGB2(r, g, b, y1_ptr[1]);
189 RGB_OUT(d1 + BPP, r, g, b);
199 YUV_TO_RGB1(cb_ptr[0], cr_ptr[0]);
200 /* output 2 pixels */
201 YUV_TO_RGB2(r, g, b, y1_ptr[0]);
202 RGB_OUT(d1, r, g, b);
212 static void glue(RGB_NAME, _to_yuv420p)(AVPicture *dst, const AVPicture *src,
213 int width, int height)
215 int wrap, wrap3, width2;
216 int r, g, b, r1, g1, b1, w;
217 uint8_t *lum, *cb, *cr;
224 width2 = (width + 1) >> 1;
225 wrap = dst->linesize[0];
226 wrap3 = src->linesize[0];
228 for(;height>=2;height -= 2) {
229 for(w = width; w >= 2; w -= 2) {
234 lum[0] = RGB_TO_Y_CCIR(r, g, b);
236 RGB_IN(r, g, b, p + BPP);
240 lum[1] = RGB_TO_Y_CCIR(r, g, b);
248 lum[0] = RGB_TO_Y_CCIR(r, g, b);
250 RGB_IN(r, g, b, p + BPP);
254 lum[1] = RGB_TO_Y_CCIR(r, g, b);
256 cb[0] = RGB_TO_U_CCIR(r1, g1, b1, 2);
257 cr[0] = RGB_TO_V_CCIR(r1, g1, b1, 2);
262 p += -wrap3 + 2 * BPP;
270 lum[0] = RGB_TO_Y_CCIR(r, g, b);
277 lum[0] = RGB_TO_Y_CCIR(r, g, b);
278 cb[0] = RGB_TO_U_CCIR(r1, g1, b1, 1);
279 cr[0] = RGB_TO_V_CCIR(r1, g1, b1, 1);
285 p += wrap3 + (wrap3 - width * BPP);
286 lum += wrap + (wrap - width);
287 cb += dst->linesize[1] - width2;
288 cr += dst->linesize[2] - width2;
290 /* handle odd height */
292 for(w = width; w >= 2; w -= 2) {
297 lum[0] = RGB_TO_Y_CCIR(r, g, b);
299 RGB_IN(r, g, b, p + BPP);
303 lum[1] = RGB_TO_Y_CCIR(r, g, b);
304 cb[0] = RGB_TO_U_CCIR(r1, g1, b1, 1);
305 cr[0] = RGB_TO_V_CCIR(r1, g1, b1, 1);
313 lum[0] = RGB_TO_Y_CCIR(r, g, b);
314 cb[0] = RGB_TO_U_CCIR(r, g, b, 0);
315 cr[0] = RGB_TO_V_CCIR(r, g, b, 0);
320 static void glue(RGB_NAME, _to_gray)(AVPicture *dst, const AVPicture *src,
321 int width, int height)
323 const unsigned char *p;
325 int r, g, b, dst_wrap, src_wrap;
329 src_wrap = src->linesize[0] - BPP * width;
332 dst_wrap = dst->linesize[0] - width;
334 for(y=0;y<height;y++) {
335 for(x=0;x<width;x++) {
337 q[0] = RGB_TO_Y(r, g, b);
346 static void glue(gray_to_, RGB_NAME)(AVPicture *dst, const AVPicture *src,
347 int width, int height)
349 const unsigned char *p;
351 int r, dst_wrap, src_wrap;
355 src_wrap = src->linesize[0] - width;
358 dst_wrap = dst->linesize[0] - BPP * width;
360 for(y=0;y<height;y++) {
361 for(x=0;x<width;x++) {
372 static void glue(pal8_to_, RGB_NAME)(AVPicture *dst, const AVPicture *src,
373 int width, int height)
375 const unsigned char *p;
377 int r, g, b, dst_wrap, src_wrap;
380 const uint32_t *palette;
383 src_wrap = src->linesize[0] - width;
384 palette = (uint32_t *)src->data[1];
387 dst_wrap = dst->linesize[0] - BPP * width;
389 for(y=0;y<height;y++) {
390 for(x=0;x<width;x++) {
392 r = (v >> 16) & 0xff;
398 a = (v >> 24) & 0xff;
399 RGBA_OUT(q, r, g, b, a);
412 #if !defined(FMT_RGBA32) && defined(RGBA_OUT)
415 static void glue(rgba32_to_, RGB_NAME)(AVPicture *dst, const AVPicture *src,
416 int width, int height)
420 int src_wrap, dst_wrap, j, y;
421 unsigned int v, r, g, b, a;
424 src_wrap = src->linesize[0] - width * 4;
427 dst_wrap = dst->linesize[0] - width * BPP;
429 for(y=0;y<height;y++) {
430 for(j = 0;j < width; j++) {
431 v = ((const uint32_t *)(s))[0];
432 a = (v >> 24) & 0xff;
433 r = (v >> 16) & 0xff;
436 RGBA_OUT(d, r, g, b, a);
445 static void glue(RGB_NAME, _to_rgba32)(AVPicture *dst, const AVPicture *src,
446 int width, int height)
450 int src_wrap, dst_wrap, j, y;
451 unsigned int r, g, b, a;
454 src_wrap = src->linesize[0] - width * BPP;
457 dst_wrap = dst->linesize[0] - width * 4;
459 for(y=0;y<height;y++) {
460 for(j = 0;j < width; j++) {
461 RGBA_IN(r, g, b, a, s);
462 ((uint32_t *)(d))[0] = (a << 24) | (r << 16) | (g << 8) | b;
470 #endif /* !defined(FMT_RGBA32) && defined(RGBA_OUT) */
472 #if defined(FMT_RGBA32)
474 #if !defined(rgba32_fcts_done)
475 #define rgba32_fcts_done
477 static void ayuv4444_to_rgba32(AVPicture *dst, const AVPicture *src,
478 int width, int height)
480 uint8_t *s, *d, *d1, *s1;
481 int w, y, cb, cr, r_add, g_add, b_add;
482 uint8_t *cm = cropTbl + MAX_NEG_CROP;
483 unsigned int r, g, b, a;
487 for(;height > 0; height --) {
490 for(w = width; w > 0; w--) {
492 YUV_TO_RGB1_CCIR(s1[2], s1[3]);
494 YUV_TO_RGB2_CCIR(r, g, b, s1[1]);
495 RGBA_OUT(d1, r, g, b, a);
499 d += dst->linesize[0];
500 s += src->linesize[0];
504 static void rgba32_to_ayuv4444(AVPicture *dst, const AVPicture *src,
505 int width, int height)
507 int src_wrap, dst_wrap, x, y;
512 src_wrap = src->linesize[0] - width * BPP;
513 dst_wrap = dst->linesize[0] - width * 4;
516 for(y=0;y<height;y++) {
517 for(x=0;x<width;x++) {
518 RGBA_IN(r, g, b, a, p);
520 d[1] = RGB_TO_Y_CCIR(r, g, b);
521 d[2] = RGB_TO_U_CCIR(r, g, b, 0);
522 d[3] = RGB_TO_V_CCIR(r, g, b, 0);
531 #endif /* !defined(rgba32_fcts_done) */
533 #endif /* defined(FMT_RGBA32) */
535 #if defined(FMT_BGRA32)
536 #if !defined(bgra32_fcts_done)
537 #define bgra32_fcts_done
539 static void bgra32_to_ayuv4444(AVPicture *dst, const AVPicture *src,
540 int width, int height)
542 int src_wrap, dst_wrap, x, y;
547 src_wrap = src->linesize[0] - width * BPP;
548 dst_wrap = dst->linesize[0] - width * 4;
551 for(y=0;y<height;y++) {
552 for(x=0;x<width;x++) {
553 RGBA_IN(r, g, b, a, p);
555 d[1] = RGB_TO_Y_CCIR(r, g, b);
556 d[2] = RGB_TO_U_CCIR(r, g, b, 0);
557 d[3] = RGB_TO_V_CCIR(r, g, b, 0);
566 #endif /* !defined(bgra32_fcts_done) */
568 #endif /* defined(FMT_BGRA32) */
572 static void glue(rgb24_to_, RGB_NAME)(AVPicture *dst, const AVPicture *src,
573 int width, int height)
577 int src_wrap, dst_wrap, j, y;
578 unsigned int r, g, b;
581 src_wrap = src->linesize[0] - width * 3;
584 dst_wrap = dst->linesize[0] - width * BPP;
586 for(y=0;y<height;y++) {
587 for(j = 0;j < width; j++) {
600 static void glue(RGB_NAME, _to_rgb24)(AVPicture *dst, const AVPicture *src,
601 int width, int height)
605 int src_wrap, dst_wrap, j, y;
606 unsigned int r, g , b;
609 src_wrap = src->linesize[0] - width * BPP;
612 dst_wrap = dst->linesize[0] - width * 3;
614 for(y=0;y<height;y++) {
615 for(j = 0;j < width; j++) {
628 #endif /* !FMT_RGB24 */
632 static void yuv444p_to_rgb24(AVPicture *dst, const AVPicture *src,
633 int width, int height)
635 const uint8_t *y1_ptr, *cb_ptr, *cr_ptr;
637 int w, y, cb, cr, r_add, g_add, b_add;
638 uint8_t *cm = cropTbl + MAX_NEG_CROP;
639 unsigned int r, g, b;
642 y1_ptr = src->data[0];
643 cb_ptr = src->data[1];
644 cr_ptr = src->data[2];
645 for(;height > 0; height --) {
647 for(w = width; w > 0; w--) {
648 YUV_TO_RGB1_CCIR(cb_ptr[0], cr_ptr[0]);
650 YUV_TO_RGB2_CCIR(r, g, b, y1_ptr[0]);
651 RGB_OUT(d1, r, g, b);
658 d += dst->linesize[0];
659 y1_ptr += src->linesize[0] - width;
660 cb_ptr += src->linesize[1] - width;
661 cr_ptr += src->linesize[2] - width;
665 static void yuvj444p_to_rgb24(AVPicture *dst, const AVPicture *src,
666 int width, int height)
668 const uint8_t *y1_ptr, *cb_ptr, *cr_ptr;
670 int w, y, cb, cr, r_add, g_add, b_add;
671 uint8_t *cm = cropTbl + MAX_NEG_CROP;
672 unsigned int r, g, b;
675 y1_ptr = src->data[0];
676 cb_ptr = src->data[1];
677 cr_ptr = src->data[2];
678 for(;height > 0; height --) {
680 for(w = width; w > 0; w--) {
681 YUV_TO_RGB1(cb_ptr[0], cr_ptr[0]);
683 YUV_TO_RGB2(r, g, b, y1_ptr[0]);
684 RGB_OUT(d1, r, g, b);
691 d += dst->linesize[0];
692 y1_ptr += src->linesize[0] - width;
693 cb_ptr += src->linesize[1] - width;
694 cr_ptr += src->linesize[2] - width;
698 static void rgb24_to_yuv444p(AVPicture *dst, const AVPicture *src,
699 int width, int height)
703 uint8_t *lum, *cb, *cr;
710 src_wrap = src->linesize[0] - width * BPP;
712 for(y=0;y<height;y++) {
713 for(x=0;x<width;x++) {
715 lum[0] = RGB_TO_Y_CCIR(r, g, b);
716 cb[0] = RGB_TO_U_CCIR(r, g, b, 0);
717 cr[0] = RGB_TO_V_CCIR(r, g, b, 0);
724 lum += dst->linesize[0] - width;
725 cb += dst->linesize[1] - width;
726 cr += dst->linesize[2] - width;
730 static void rgb24_to_yuvj420p(AVPicture *dst, const AVPicture *src,
731 int width, int height)
733 int wrap, wrap3, width2;
734 int r, g, b, r1, g1, b1, w;
735 uint8_t *lum, *cb, *cr;
742 width2 = (width + 1) >> 1;
743 wrap = dst->linesize[0];
744 wrap3 = src->linesize[0];
746 for(;height>=2;height -= 2) {
747 for(w = width; w >= 2; w -= 2) {
752 lum[0] = RGB_TO_Y(r, g, b);
754 RGB_IN(r, g, b, p + BPP);
758 lum[1] = RGB_TO_Y(r, g, b);
766 lum[0] = RGB_TO_Y(r, g, b);
768 RGB_IN(r, g, b, p + BPP);
772 lum[1] = RGB_TO_Y(r, g, b);
774 cb[0] = RGB_TO_U(r1, g1, b1, 2);
775 cr[0] = RGB_TO_V(r1, g1, b1, 2);
779 p += -wrap3 + 2 * BPP;
787 lum[0] = RGB_TO_Y(r, g, b);
794 lum[0] = RGB_TO_Y(r, g, b);
795 cb[0] = RGB_TO_U(r1, g1, b1, 1);
796 cr[0] = RGB_TO_V(r1, g1, b1, 1);
802 p += wrap3 + (wrap3 - width * BPP);
803 lum += wrap + (wrap - width);
804 cb += dst->linesize[1] - width2;
805 cr += dst->linesize[2] - width2;
807 /* handle odd height */
809 for(w = width; w >= 2; w -= 2) {
814 lum[0] = RGB_TO_Y(r, g, b);
816 RGB_IN(r, g, b, p + BPP);
820 lum[1] = RGB_TO_Y(r, g, b);
821 cb[0] = RGB_TO_U(r1, g1, b1, 1);
822 cr[0] = RGB_TO_V(r1, g1, b1, 1);
830 lum[0] = RGB_TO_Y(r, g, b);
831 cb[0] = RGB_TO_U(r, g, b, 0);
832 cr[0] = RGB_TO_V(r, g, b, 0);
837 static void rgb24_to_yuvj444p(AVPicture *dst, const AVPicture *src,
838 int width, int height)
842 uint8_t *lum, *cb, *cr;
849 src_wrap = src->linesize[0] - width * BPP;
851 for(y=0;y<height;y++) {
852 for(x=0;x<width;x++) {
854 lum[0] = RGB_TO_Y(r, g, b);
855 cb[0] = RGB_TO_U(r, g, b, 0);
856 cr[0] = RGB_TO_V(r, g, b, 0);
863 lum += dst->linesize[0] - width;
864 cb += dst->linesize[1] - width;
865 cr += dst->linesize[2] - width;
869 static void ayuv4444_to_rgb24(AVPicture *dst, const AVPicture *src,
870 int width, int height)
872 uint8_t *s, *d, *d1, *s1;
873 int w, y, cb, cr, r_add, g_add, b_add;
874 uint8_t *cm = cropTbl + MAX_NEG_CROP;
875 unsigned int r, g, b;
879 for(;height > 0; height --) {
882 for(w = width; w > 0; w--) {
883 YUV_TO_RGB1_CCIR(s1[2], s1[3]);
885 YUV_TO_RGB2_CCIR(r, g, b, s1[1]);
886 RGB_OUT(d1, r, g, b);
890 d += dst->linesize[0];
891 s += src->linesize[0];
895 static void rgb24_to_ayuv4444(AVPicture *dst, const AVPicture *src,
896 int width, int height)
898 int src_wrap, dst_wrap, x, y;
903 src_wrap = src->linesize[0] - width * BPP;
904 dst_wrap = dst->linesize[0] - width * 4;
907 for(y=0;y<height;y++) {
908 for(x=0;x<width;x++) {
911 d[1] = RGB_TO_Y_CCIR(r, g, b);
912 d[2] = RGB_TO_U_CCIR(r, g, b, 0);
913 d[3] = RGB_TO_V_CCIR(r, g, b, 0);
921 #endif /* FMT_RGB24 */
923 #if defined(FMT_RGB24) || defined(FMT_RGBA32)
925 static void glue(RGB_NAME, _to_pal8)(AVPicture *dst, const AVPicture *src,
926 int width, int height)
928 const unsigned char *p;
930 int dst_wrap, src_wrap;
932 unsigned int r, g, b;
935 src_wrap = src->linesize[0] - BPP * width;
938 dst_wrap = dst->linesize[0] - width;
941 for(y=0;y<height;y++) {
942 for(x=0;x<width;x++) {
946 RGBA_IN(r, g, b, a, p);
947 /* crude approximation for alpha ! */
952 q[0] = gif_clut_index(r, g, b);
957 q[0] = gif_clut_index(r, g, b);
966 build_rgb_palette(dst->data[1], has_alpha);
969 #endif /* defined(FMT_RGB24) || defined(FMT_RGBA32) */
973 static int glue(get_alpha_info_, RGB_NAME)(const AVPicture *src,
974 int width, int height)
976 const unsigned char *p;
977 int src_wrap, ret, x, y;
978 unsigned int r, g, b, a;
981 src_wrap = src->linesize[0] - BPP * width;
983 for(y=0;y<height;y++) {
984 for(x=0;x<width;x++) {
985 RGBA_IN(r, g, b, a, p);
987 ret |= FF_ALPHA_TRANSP;
988 } else if (a != 0xff) {
989 ret |= FF_ALPHA_SEMI_TRANSP;