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);
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
;