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, AVPicture *src,
25 int width, int height)
27 uint8_t *y1_ptr, *y2_ptr, *cb_ptr, *cr_ptr, *d, *d1, *d2;
28 int w, y, cb, cr, r_add, g_add, b_add, width2;
29 uint8_t *cm = cropTbl + MAX_NEG_CROP;
33 y1_ptr = src->data[0];
34 cb_ptr = src->data[1];
35 cr_ptr = src->data[2];
36 width2 = (width + 1) >> 1;
37 for(;height >= 2; height -= 2) {
39 d2 = d + dst->linesize[0];
40 y2_ptr = y1_ptr + src->linesize[0];
41 for(w = width; w >= 2; w -= 2) {
42 YUV_TO_RGB1_CCIR(cb_ptr[0], cr_ptr[0]);
44 YUV_TO_RGB2_CCIR(r, g, b, y1_ptr[0]);
47 YUV_TO_RGB2_CCIR(r, g, b, y1_ptr[1]);
48 RGB_OUT(d1 + BPP, r, g, b);
50 YUV_TO_RGB2_CCIR(r, g, b, y2_ptr[0]);
53 YUV_TO_RGB2_CCIR(r, g, b, y2_ptr[1]);
54 RGB_OUT(d2 + BPP, r, g, b);
64 /* handle odd width */
66 YUV_TO_RGB1_CCIR(cb_ptr[0], cr_ptr[0]);
67 YUV_TO_RGB2_CCIR(r, g, b, y1_ptr[0]);
70 YUV_TO_RGB2_CCIR(r, g, b, y2_ptr[0]);
79 d += 2 * dst->linesize[0];
80 y1_ptr += 2 * src->linesize[0] - width;
81 cb_ptr += src->linesize[1] - width2;
82 cr_ptr += src->linesize[2] - width2;
84 /* handle odd height */
87 for(w = width; w >= 2; w -= 2) {
88 YUV_TO_RGB1_CCIR(cb_ptr[0], cr_ptr[0]);
90 YUV_TO_RGB2_CCIR(r, g, b, y1_ptr[0]);
93 YUV_TO_RGB2_CCIR(r, g, b, y1_ptr[1]);
94 RGB_OUT(d1 + BPP, r, g, b);
104 YUV_TO_RGB1_CCIR(cb_ptr[0], cr_ptr[0]);
105 /* output 2 pixels */
106 YUV_TO_RGB2_CCIR(r, g, b, y1_ptr[0]);
107 RGB_OUT(d1, r, g, b);
117 static void glue(yuvj420p_to_, RGB_NAME)(AVPicture *dst, AVPicture *src,
118 int width, int height)
120 uint8_t *y1_ptr, *y2_ptr, *cb_ptr, *cr_ptr, *d, *d1, *d2;
121 int w, y, cb, cr, r_add, g_add, b_add, width2;
122 uint8_t *cm = cropTbl + MAX_NEG_CROP;
123 unsigned int r, g, b;
126 y1_ptr = src->data[0];
127 cb_ptr = src->data[1];
128 cr_ptr = src->data[2];
129 width2 = (width + 1) >> 1;
130 for(;height >= 2; height -= 2) {
132 d2 = d + dst->linesize[0];
133 y2_ptr = y1_ptr + src->linesize[0];
134 for(w = width; w >= 2; w -= 2) {
135 YUV_TO_RGB1(cb_ptr[0], cr_ptr[0]);
136 /* output 4 pixels */
137 YUV_TO_RGB2(r, g, b, y1_ptr[0]);
138 RGB_OUT(d1, r, g, b);
140 YUV_TO_RGB2(r, g, b, y1_ptr[1]);
141 RGB_OUT(d1 + BPP, r, g, b);
143 YUV_TO_RGB2(r, g, b, y2_ptr[0]);
144 RGB_OUT(d2, r, g, b);
146 YUV_TO_RGB2(r, g, b, y2_ptr[1]);
147 RGB_OUT(d2 + BPP, r, g, b);
157 /* handle odd width */
159 YUV_TO_RGB1(cb_ptr[0], cr_ptr[0]);
160 YUV_TO_RGB2(r, g, b, y1_ptr[0]);
161 RGB_OUT(d1, r, g, b);
163 YUV_TO_RGB2(r, g, b, y2_ptr[0]);
164 RGB_OUT(d2, r, g, b);
172 d += 2 * dst->linesize[0];
173 y1_ptr += 2 * src->linesize[0] - width;
174 cb_ptr += src->linesize[1] - width2;
175 cr_ptr += src->linesize[2] - width2;
177 /* handle odd height */
180 for(w = width; w >= 2; w -= 2) {
181 YUV_TO_RGB1(cb_ptr[0], cr_ptr[0]);
182 /* output 2 pixels */
183 YUV_TO_RGB2(r, g, b, y1_ptr[0]);
184 RGB_OUT(d1, r, g, b);
186 YUV_TO_RGB2(r, g, b, y1_ptr[1]);
187 RGB_OUT(d1 + BPP, r, g, b);
197 YUV_TO_RGB1(cb_ptr[0], cr_ptr[0]);
198 /* output 2 pixels */
199 YUV_TO_RGB2(r, g, b, y1_ptr[0]);
200 RGB_OUT(d1, r, g, b);
210 static void glue(RGB_NAME, _to_yuv420p)(AVPicture *dst, AVPicture *src,
211 int width, int height)
213 int wrap, wrap3, width2;
214 int r, g, b, r1, g1, b1, w;
215 uint8_t *lum, *cb, *cr;
222 width2 = (width + 1) >> 1;
223 wrap = dst->linesize[0];
224 wrap3 = src->linesize[0];
226 for(;height>=2;height -= 2) {
227 for(w = width; w >= 2; w -= 2) {
232 lum[0] = RGB_TO_Y_CCIR(r, g, b);
234 RGB_IN(r, g, b, p + BPP);
238 lum[1] = RGB_TO_Y_CCIR(r, g, b);
246 lum[0] = RGB_TO_Y_CCIR(r, g, b);
248 RGB_IN(r, g, b, p + BPP);
252 lum[1] = RGB_TO_Y_CCIR(r, g, b);
254 cb[0] = RGB_TO_U_CCIR(r1, g1, b1, 2);
255 cr[0] = RGB_TO_V_CCIR(r1, g1, b1, 2);
259 p += -wrap3 + 2 * BPP;
267 lum[0] = RGB_TO_Y_CCIR(r, g, b);
274 lum[0] = RGB_TO_Y_CCIR(r, g, b);
275 cb[0] = RGB_TO_U_CCIR(r1, g1, b1, 1);
276 cr[0] = RGB_TO_V_CCIR(r1, g1, b1, 1);
282 p += wrap3 + (wrap3 - width * BPP);
283 lum += wrap + (wrap - width);
284 cb += dst->linesize[1] - width2;
285 cr += dst->linesize[2] - width2;
287 /* handle odd height */
289 for(w = width; w >= 2; w -= 2) {
294 lum[0] = RGB_TO_Y_CCIR(r, g, b);
296 RGB_IN(r, g, b, p + BPP);
300 lum[1] = RGB_TO_Y_CCIR(r, g, b);
301 cb[0] = RGB_TO_U_CCIR(r1, g1, b1, 1);
302 cr[0] = RGB_TO_V_CCIR(r1, g1, b1, 1);
310 lum[0] = RGB_TO_Y_CCIR(r, g, b);
311 cb[0] = RGB_TO_U_CCIR(r, g, b, 0);
312 cr[0] = RGB_TO_V_CCIR(r, g, b, 0);
317 static void glue(RGB_NAME, _to_gray)(AVPicture *dst, AVPicture *src,
318 int width, int height)
320 const unsigned char *p;
322 int r, g, b, dst_wrap, src_wrap;
326 src_wrap = src->linesize[0] - BPP * width;
329 dst_wrap = dst->linesize[0] - width;
331 for(y=0;y<height;y++) {
332 for(x=0;x<width;x++) {
334 q[0] = RGB_TO_Y(r, g, b);
343 static void glue(gray_to_, RGB_NAME)(AVPicture *dst, AVPicture *src,
344 int width, int height)
346 const unsigned char *p;
348 int r, dst_wrap, src_wrap;
352 src_wrap = src->linesize[0] - width;
355 dst_wrap = dst->linesize[0] - BPP * width;
357 for(y=0;y<height;y++) {
358 for(x=0;x<width;x++) {
369 static void glue(pal8_to_, RGB_NAME)(AVPicture *dst, AVPicture *src,
370 int width, int height)
372 const unsigned char *p;
374 int r, g, b, dst_wrap, src_wrap;
377 const uint32_t *palette;
380 src_wrap = src->linesize[0] - width;
381 palette = (uint32_t *)src->data[1];
384 dst_wrap = dst->linesize[0] - BPP * width;
386 for(y=0;y<height;y++) {
387 for(x=0;x<width;x++) {
389 r = (v >> 16) & 0xff;
395 a = (v >> 24) & 0xff;
396 RGBA_OUT(q, r, g, b, a);
409 #if !defined(FMT_RGBA32) && defined(RGBA_OUT)
412 static void glue(rgba32_to_, RGB_NAME)(AVPicture *dst, AVPicture *src,
413 int width, int height)
417 int src_wrap, dst_wrap, j, y;
418 unsigned int v, r, g, b, a;
421 src_wrap = src->linesize[0] - width * 4;
424 dst_wrap = dst->linesize[0] - width * BPP;
426 for(y=0;y<height;y++) {
427 for(j = 0;j < width; j++) {
428 v = ((const uint32_t *)(s))[0];
429 a = (v >> 24) & 0xff;
430 r = (v >> 16) & 0xff;
433 RGBA_OUT(d, r, g, b, a);
442 static void glue(RGB_NAME, _to_rgba32)(AVPicture *dst, AVPicture *src,
443 int width, int height)
447 int src_wrap, dst_wrap, j, y;
448 unsigned int r, g, b, a;
451 src_wrap = src->linesize[0] - width * BPP;
454 dst_wrap = dst->linesize[0] - width * 4;
456 for(y=0;y<height;y++) {
457 for(j = 0;j < width; j++) {
458 RGBA_IN(r, g, b, a, s);
459 ((uint32_t *)(d))[0] = (a << 24) | (r << 16) | (g << 8) | b;
468 #endif /* !defined(FMT_RGBA32) && defined(RGBA_IN) */
472 static void glue(rgb24_to_, RGB_NAME)(AVPicture *dst, AVPicture *src,
473 int width, int height)
477 int src_wrap, dst_wrap, j, y;
478 unsigned int r, g, b;
481 src_wrap = src->linesize[0] - width * 3;
484 dst_wrap = dst->linesize[0] - width * BPP;
486 for(y=0;y<height;y++) {
487 for(j = 0;j < width; j++) {
500 static void glue(RGB_NAME, _to_rgb24)(AVPicture *dst, AVPicture *src,
501 int width, int height)
505 int src_wrap, dst_wrap, j, y;
506 unsigned int r, g , b;
509 src_wrap = src->linesize[0] - width * BPP;
512 dst_wrap = dst->linesize[0] - width * 3;
514 for(y=0;y<height;y++) {
515 for(j = 0;j < width; j++) {
528 #endif /* !FMT_RGB24 */
532 static void yuv444p_to_rgb24(AVPicture *dst, AVPicture *src,
533 int width, int height)
535 uint8_t *y1_ptr, *cb_ptr, *cr_ptr, *d, *d1;
536 int w, y, cb, cr, r_add, g_add, b_add;
537 uint8_t *cm = cropTbl + MAX_NEG_CROP;
538 unsigned int r, g, b;
541 y1_ptr = src->data[0];
542 cb_ptr = src->data[1];
543 cr_ptr = src->data[2];
544 for(;height > 0; height --) {
546 for(w = width; w > 0; w--) {
547 YUV_TO_RGB1_CCIR(cb_ptr[0], cr_ptr[0]);
549 YUV_TO_RGB2_CCIR(r, g, b, y1_ptr[0]);
550 RGB_OUT(d1, r, g, b);
557 d += dst->linesize[0];
558 y1_ptr += src->linesize[0] - width;
559 cb_ptr += src->linesize[1] - width;
560 cr_ptr += src->linesize[2] - width;
564 static void yuvj444p_to_rgb24(AVPicture *dst, AVPicture *src,
565 int width, int height)
567 uint8_t *y1_ptr, *cb_ptr, *cr_ptr, *d, *d1;
568 int w, y, cb, cr, r_add, g_add, b_add;
569 uint8_t *cm = cropTbl + MAX_NEG_CROP;
570 unsigned int r, g, b;
573 y1_ptr = src->data[0];
574 cb_ptr = src->data[1];
575 cr_ptr = src->data[2];
576 for(;height > 0; height --) {
578 for(w = width; w > 0; w--) {
579 YUV_TO_RGB1(cb_ptr[0], cr_ptr[0]);
581 YUV_TO_RGB2(r, g, b, y1_ptr[0]);
582 RGB_OUT(d1, r, g, b);
589 d += dst->linesize[0];
590 y1_ptr += src->linesize[0] - width;
591 cb_ptr += src->linesize[1] - width;
592 cr_ptr += src->linesize[2] - width;
596 static void rgb24_to_yuv444p(AVPicture *dst, AVPicture *src,
597 int width, int height)
601 uint8_t *lum, *cb, *cr;
608 src_wrap = src->linesize[0] - width * BPP;
610 for(y=0;y<height;y++) {
611 for(x=0;x<width;x++) {
613 lum[0] = RGB_TO_Y_CCIR(r, g, b);
614 cb[0] = RGB_TO_U_CCIR(r, g, b, 0);
615 cr[0] = RGB_TO_V_CCIR(r, g, b, 0);
622 lum += dst->linesize[0] - width;
623 cb += dst->linesize[1] - width;
624 cr += dst->linesize[2] - width;
628 static void rgb24_to_yuvj420p(AVPicture *dst, AVPicture *src,
629 int width, int height)
631 int wrap, wrap3, width2;
632 int r, g, b, r1, g1, b1, w;
633 uint8_t *lum, *cb, *cr;
640 width2 = (width + 1) >> 1;
641 wrap = dst->linesize[0];
642 wrap3 = src->linesize[0];
644 for(;height>=2;height -= 2) {
645 for(w = width; w >= 2; w -= 2) {
650 lum[0] = RGB_TO_Y(r, g, b);
652 RGB_IN(r, g, b, p + BPP);
656 lum[1] = RGB_TO_Y(r, g, b);
664 lum[0] = RGB_TO_Y(r, g, b);
666 RGB_IN(r, g, b, p + BPP);
670 lum[1] = RGB_TO_Y(r, g, b);
672 cb[0] = RGB_TO_U(r1, g1, b1, 2);
673 cr[0] = RGB_TO_V(r1, g1, b1, 2);
677 p += -wrap3 + 2 * BPP;
685 lum[0] = RGB_TO_Y(r, g, b);
692 lum[0] = RGB_TO_Y(r, g, b);
693 cb[0] = RGB_TO_U(r1, g1, b1, 1);
694 cr[0] = RGB_TO_V(r1, g1, b1, 1);
700 p += wrap3 + (wrap3 - width * BPP);
701 lum += wrap + (wrap - width);
702 cb += dst->linesize[1] - width2;
703 cr += dst->linesize[2] - width2;
705 /* handle odd height */
707 for(w = width; w >= 2; w -= 2) {
712 lum[0] = RGB_TO_Y(r, g, b);
714 RGB_IN(r, g, b, p + BPP);
718 lum[1] = RGB_TO_Y(r, g, b);
719 cb[0] = RGB_TO_U(r1, g1, b1, 1);
720 cr[0] = RGB_TO_V(r1, g1, b1, 1);
728 lum[0] = RGB_TO_Y(r, g, b);
729 cb[0] = RGB_TO_U(r, g, b, 0);
730 cr[0] = RGB_TO_V(r, g, b, 0);
735 static void rgb24_to_yuvj444p(AVPicture *dst, AVPicture *src,
736 int width, int height)
740 uint8_t *lum, *cb, *cr;
747 src_wrap = src->linesize[0] - width * BPP;
749 for(y=0;y<height;y++) {
750 for(x=0;x<width;x++) {
752 lum[0] = RGB_TO_Y(r, g, b);
753 cb[0] = RGB_TO_U(r, g, b, 0);
754 cr[0] = RGB_TO_V(r, g, b, 0);
761 lum += dst->linesize[0] - width;
762 cb += dst->linesize[1] - width;
763 cr += dst->linesize[2] - width;
767 #endif /* FMT_RGB24 */
769 #if defined(FMT_RGB24) || defined(FMT_RGBA32)
771 static void glue(RGB_NAME, _to_pal8)(AVPicture *dst, AVPicture *src,
772 int width, int height)
774 const unsigned char *p;
776 int dst_wrap, src_wrap;
778 unsigned int r, g, b;
781 src_wrap = src->linesize[0] - BPP * width;
784 dst_wrap = dst->linesize[0] - width;
787 for(y=0;y<height;y++) {
788 for(x=0;x<width;x++) {
792 RGBA_IN(r, g, b, a, p);
793 /* crude approximation for alpha ! */
798 q[0] = gif_clut_index(r, g, b);
803 q[0] = gif_clut_index(r, g, b);
812 build_rgb_palette(dst->data[1], has_alpha);
815 #endif /* defined(FMT_RGB24) || defined(FMT_RGBA32) */
819 static int glue(get_alpha_info_, RGB_NAME)(AVPicture *src, int width, int height)
821 const unsigned char *p;
822 int src_wrap, ret, x, y;
823 unsigned int r, g, b, a;
826 src_wrap = src->linesize[0] - BPP * width;
828 for(y=0;y<height;y++) {
829 for(x=0;x<width;x++) {
830 RGBA_IN(r, g, b, a, p);
832 ret |= FF_ALPHA_TRANSP;
833 } else if (a != 0xff) {
834 ret |= FF_ALPHA_SEMI_TRANSP;