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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 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);
261 p += -wrap3 + 2 * BPP;
269 lum[0] = RGB_TO_Y_CCIR(r, g, b);
276 lum[0] = RGB_TO_Y_CCIR(r, g, b);
277 cb[0] = RGB_TO_U_CCIR(r1, g1, b1, 1);
278 cr[0] = RGB_TO_V_CCIR(r1, g1, b1, 1);
284 p += wrap3 + (wrap3 - width * BPP);
285 lum += wrap + (wrap - width);
286 cb += dst->linesize[1] - width2;
287 cr += dst->linesize[2] - width2;
289 /* handle odd height */
291 for(w = width; w >= 2; w -= 2) {
296 lum[0] = RGB_TO_Y_CCIR(r, g, b);
298 RGB_IN(r, g, b, p + BPP);
302 lum[1] = RGB_TO_Y_CCIR(r, g, b);
303 cb[0] = RGB_TO_U_CCIR(r1, g1, b1, 1);
304 cr[0] = RGB_TO_V_CCIR(r1, g1, b1, 1);
312 lum[0] = RGB_TO_Y_CCIR(r, g, b);
313 cb[0] = RGB_TO_U_CCIR(r, g, b, 0);
314 cr[0] = RGB_TO_V_CCIR(r, g, b, 0);
319 static void glue(RGB_NAME, _to_gray)(AVPicture *dst, const AVPicture *src,
320 int width, int height)
322 const unsigned char *p;
324 int r, g, b, dst_wrap, src_wrap;
328 src_wrap = src->linesize[0] - BPP * width;
331 dst_wrap = dst->linesize[0] - width;
333 for(y=0;y<height;y++) {
334 for(x=0;x<width;x++) {
336 q[0] = RGB_TO_Y(r, g, b);
345 static void glue(gray_to_, RGB_NAME)(AVPicture *dst, const AVPicture *src,
346 int width, int height)
348 const unsigned char *p;
350 int r, dst_wrap, src_wrap;
354 src_wrap = src->linesize[0] - width;
357 dst_wrap = dst->linesize[0] - BPP * width;
359 for(y=0;y<height;y++) {
360 for(x=0;x<width;x++) {
371 static void glue(pal8_to_, RGB_NAME)(AVPicture *dst, const AVPicture *src,
372 int width, int height)
374 const unsigned char *p;
376 int r, g, b, dst_wrap, src_wrap;
379 const uint32_t *palette;
382 src_wrap = src->linesize[0] - width;
383 palette = (uint32_t *)src->data[1];
386 dst_wrap = dst->linesize[0] - BPP * width;
388 for(y=0;y<height;y++) {
389 for(x=0;x<width;x++) {
391 r = (v >> 16) & 0xff;
397 a = (v >> 24) & 0xff;
398 RGBA_OUT(q, r, g, b, a);
411 #if !defined(FMT_RGBA32) && defined(RGBA_OUT)
414 static void glue(rgba32_to_, RGB_NAME)(AVPicture *dst, const AVPicture *src,
415 int width, int height)
419 int src_wrap, dst_wrap, j, y;
420 unsigned int v, r, g, b, a;
423 src_wrap = src->linesize[0] - width * 4;
426 dst_wrap = dst->linesize[0] - width * BPP;
428 for(y=0;y<height;y++) {
429 for(j = 0;j < width; j++) {
430 v = ((const uint32_t *)(s))[0];
431 a = (v >> 24) & 0xff;
432 r = (v >> 16) & 0xff;
435 RGBA_OUT(d, r, g, b, a);
444 static void glue(RGB_NAME, _to_rgba32)(AVPicture *dst, const AVPicture *src,
445 int width, int height)
449 int src_wrap, dst_wrap, j, y;
450 unsigned int r, g, b, a;
453 src_wrap = src->linesize[0] - width * BPP;
456 dst_wrap = dst->linesize[0] - width * 4;
458 for(y=0;y<height;y++) {
459 for(j = 0;j < width; j++) {
460 RGBA_IN(r, g, b, a, s);
461 ((uint32_t *)(d))[0] = (a << 24) | (r << 16) | (g << 8) | b;
470 #endif /* !defined(FMT_RGBA32) && defined(RGBA_IN) */
474 static void glue(rgb24_to_, RGB_NAME)(AVPicture *dst, const AVPicture *src,
475 int width, int height)
479 int src_wrap, dst_wrap, j, y;
480 unsigned int r, g, b;
483 src_wrap = src->linesize[0] - width * 3;
486 dst_wrap = dst->linesize[0] - width * BPP;
488 for(y=0;y<height;y++) {
489 for(j = 0;j < width; j++) {
502 static void glue(RGB_NAME, _to_rgb24)(AVPicture *dst, const AVPicture *src,
503 int width, int height)
507 int src_wrap, dst_wrap, j, y;
508 unsigned int r, g , b;
511 src_wrap = src->linesize[0] - width * BPP;
514 dst_wrap = dst->linesize[0] - width * 3;
516 for(y=0;y<height;y++) {
517 for(j = 0;j < width; j++) {
530 #endif /* !FMT_RGB24 */
534 static void yuv444p_to_rgb24(AVPicture *dst, const AVPicture *src,
535 int width, int height)
537 const uint8_t *y1_ptr, *cb_ptr, *cr_ptr;
539 int w, y, cb, cr, r_add, g_add, b_add;
540 uint8_t *cm = cropTbl + MAX_NEG_CROP;
541 unsigned int r, g, b;
544 y1_ptr = src->data[0];
545 cb_ptr = src->data[1];
546 cr_ptr = src->data[2];
547 for(;height > 0; height --) {
549 for(w = width; w > 0; w--) {
550 YUV_TO_RGB1_CCIR(cb_ptr[0], cr_ptr[0]);
552 YUV_TO_RGB2_CCIR(r, g, b, y1_ptr[0]);
553 RGB_OUT(d1, r, g, b);
560 d += dst->linesize[0];
561 y1_ptr += src->linesize[0] - width;
562 cb_ptr += src->linesize[1] - width;
563 cr_ptr += src->linesize[2] - width;
567 static void yuvj444p_to_rgb24(AVPicture *dst, const AVPicture *src,
568 int width, int height)
570 const uint8_t *y1_ptr, *cb_ptr, *cr_ptr;
572 int w, y, cb, cr, r_add, g_add, b_add;
573 uint8_t *cm = cropTbl + MAX_NEG_CROP;
574 unsigned int r, g, b;
577 y1_ptr = src->data[0];
578 cb_ptr = src->data[1];
579 cr_ptr = src->data[2];
580 for(;height > 0; height --) {
582 for(w = width; w > 0; w--) {
583 YUV_TO_RGB1(cb_ptr[0], cr_ptr[0]);
585 YUV_TO_RGB2(r, g, b, y1_ptr[0]);
586 RGB_OUT(d1, r, g, b);
593 d += dst->linesize[0];
594 y1_ptr += src->linesize[0] - width;
595 cb_ptr += src->linesize[1] - width;
596 cr_ptr += src->linesize[2] - width;
600 static void rgb24_to_yuv444p(AVPicture *dst, const AVPicture *src,
601 int width, int height)
605 uint8_t *lum, *cb, *cr;
612 src_wrap = src->linesize[0] - width * BPP;
614 for(y=0;y<height;y++) {
615 for(x=0;x<width;x++) {
617 lum[0] = RGB_TO_Y_CCIR(r, g, b);
618 cb[0] = RGB_TO_U_CCIR(r, g, b, 0);
619 cr[0] = RGB_TO_V_CCIR(r, g, b, 0);
626 lum += dst->linesize[0] - width;
627 cb += dst->linesize[1] - width;
628 cr += dst->linesize[2] - width;
632 static void rgb24_to_yuvj420p(AVPicture *dst, const AVPicture *src,
633 int width, int height)
635 int wrap, wrap3, width2;
636 int r, g, b, r1, g1, b1, w;
637 uint8_t *lum, *cb, *cr;
644 width2 = (width + 1) >> 1;
645 wrap = dst->linesize[0];
646 wrap3 = src->linesize[0];
648 for(;height>=2;height -= 2) {
649 for(w = width; w >= 2; w -= 2) {
654 lum[0] = RGB_TO_Y(r, g, b);
656 RGB_IN(r, g, b, p + BPP);
660 lum[1] = RGB_TO_Y(r, g, b);
668 lum[0] = RGB_TO_Y(r, g, b);
670 RGB_IN(r, g, b, p + BPP);
674 lum[1] = RGB_TO_Y(r, g, b);
676 cb[0] = RGB_TO_U(r1, g1, b1, 2);
677 cr[0] = RGB_TO_V(r1, g1, b1, 2);
681 p += -wrap3 + 2 * BPP;
689 lum[0] = RGB_TO_Y(r, g, b);
696 lum[0] = RGB_TO_Y(r, g, b);
697 cb[0] = RGB_TO_U(r1, g1, b1, 1);
698 cr[0] = RGB_TO_V(r1, g1, b1, 1);
704 p += wrap3 + (wrap3 - width * BPP);
705 lum += wrap + (wrap - width);
706 cb += dst->linesize[1] - width2;
707 cr += dst->linesize[2] - width2;
709 /* handle odd height */
711 for(w = width; w >= 2; w -= 2) {
716 lum[0] = RGB_TO_Y(r, g, b);
718 RGB_IN(r, g, b, p + BPP);
722 lum[1] = RGB_TO_Y(r, g, b);
723 cb[0] = RGB_TO_U(r1, g1, b1, 1);
724 cr[0] = RGB_TO_V(r1, g1, b1, 1);
732 lum[0] = RGB_TO_Y(r, g, b);
733 cb[0] = RGB_TO_U(r, g, b, 0);
734 cr[0] = RGB_TO_V(r, g, b, 0);
739 static void rgb24_to_yuvj444p(AVPicture *dst, const AVPicture *src,
740 int width, int height)
744 uint8_t *lum, *cb, *cr;
751 src_wrap = src->linesize[0] - width * BPP;
753 for(y=0;y<height;y++) {
754 for(x=0;x<width;x++) {
756 lum[0] = RGB_TO_Y(r, g, b);
757 cb[0] = RGB_TO_U(r, g, b, 0);
758 cr[0] = RGB_TO_V(r, g, b, 0);
765 lum += dst->linesize[0] - width;
766 cb += dst->linesize[1] - width;
767 cr += dst->linesize[2] - width;
771 #endif /* FMT_RGB24 */
773 #if defined(FMT_RGB24) || defined(FMT_RGBA32)
775 static void glue(RGB_NAME, _to_pal8)(AVPicture *dst, const AVPicture *src,
776 int width, int height)
778 const unsigned char *p;
780 int dst_wrap, src_wrap;
782 unsigned int r, g, b;
785 src_wrap = src->linesize[0] - BPP * width;
788 dst_wrap = dst->linesize[0] - width;
791 for(y=0;y<height;y++) {
792 for(x=0;x<width;x++) {
796 RGBA_IN(r, g, b, a, p);
797 /* crude approximation for alpha ! */
802 q[0] = gif_clut_index(r, g, b);
807 q[0] = gif_clut_index(r, g, b);
816 build_rgb_palette(dst->data[1], has_alpha);
819 #endif /* defined(FMT_RGB24) || defined(FMT_RGBA32) */
823 static int glue(get_alpha_info_, RGB_NAME)(const AVPicture *src,
824 int width, int height)
826 const unsigned char *p;
827 int src_wrap, ret, x, y;
828 unsigned int r, g, b, a;
831 src_wrap = src->linesize[0] - BPP * width;
833 for(y=0;y<height;y++) {
834 for(x=0;x<width;x++) {
835 RGBA_IN(r, g, b, a, p);
837 ret |= FF_ALPHA_TRANSP;
838 } else if (a != 0xff) {
839 ret |= FF_ALPHA_SEMI_TRANSP;