2 * templates for image conversion 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
= ff_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
= ff_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 // RGB24 has optimized routines
414 #if !defined(FMT_RGB32) && !defined(FMT_RGB24)
417 static void glue(rgb32_to_
, RGB_NAME
)(AVPicture
*dst
, const AVPicture
*src
,
418 int width
, int height
)
422 int src_wrap
, dst_wrap
, j
, y
;
423 unsigned int v
, r
, g
, b
;
429 src_wrap
= src
->linesize
[0] - width
* 4;
432 dst_wrap
= dst
->linesize
[0] - width
* BPP
;
434 for(y
=0;y
<height
;y
++) {
435 for(j
= 0;j
< width
; j
++) {
436 v
= ((const uint32_t *)(s
))[0];
437 r
= (v
>> 16) & 0xff;
441 a
= (v
>> 24) & 0xff;
442 RGBA_OUT(d
, r
, g
, b
, a
);
454 static void glue(RGB_NAME
, _to_rgb32
)(AVPicture
*dst
, const AVPicture
*src
,
455 int width
, int height
)
459 int src_wrap
, dst_wrap
, j
, y
;
460 unsigned int r
, g
, b
;
466 src_wrap
= src
->linesize
[0] - width
* BPP
;
469 dst_wrap
= dst
->linesize
[0] - width
* 4;
471 for(y
=0;y
<height
;y
++) {
472 for(j
= 0;j
< width
; j
++) {
474 RGBA_IN(r
, g
, b
, a
, s
);
475 ((uint32_t *)(d
))[0] = (a
<< 24) | (r
<< 16) | (g
<< 8) | b
;
478 ((uint32_t *)(d
))[0] = (0xff << 24) | (r
<< 16) | (g
<< 8) | b
;
488 #endif /* !defined(FMT_RGB32) */
492 static void glue(rgb24_to_
, RGB_NAME
)(AVPicture
*dst
, const AVPicture
*src
,
493 int width
, int height
)
497 int src_wrap
, dst_wrap
, j
, y
;
498 unsigned int r
, g
, b
;
501 src_wrap
= src
->linesize
[0] - width
* 3;
504 dst_wrap
= dst
->linesize
[0] - width
* BPP
;
506 for(y
=0;y
<height
;y
++) {
507 for(j
= 0;j
< width
; j
++) {
520 static void glue(RGB_NAME
, _to_rgb24
)(AVPicture
*dst
, const AVPicture
*src
,
521 int width
, int height
)
525 int src_wrap
, dst_wrap
, j
, y
;
526 unsigned int r
, g
, b
;
529 src_wrap
= src
->linesize
[0] - width
* BPP
;
532 dst_wrap
= dst
->linesize
[0] - width
* 3;
534 for(y
=0;y
<height
;y
++) {
535 for(j
= 0;j
< width
; j
++) {
548 #endif /* !FMT_RGB24 */
552 static void yuv444p_to_rgb24(AVPicture
*dst
, const AVPicture
*src
,
553 int width
, int height
)
555 const uint8_t *y1_ptr
, *cb_ptr
, *cr_ptr
;
557 int w
, y
, cb
, cr
, r_add
, g_add
, b_add
;
558 uint8_t *cm
= ff_cropTbl
+ MAX_NEG_CROP
;
559 unsigned int r
, g
, b
;
562 y1_ptr
= src
->data
[0];
563 cb_ptr
= src
->data
[1];
564 cr_ptr
= src
->data
[2];
565 for(;height
> 0; height
--) {
567 for(w
= width
; w
> 0; w
--) {
568 YUV_TO_RGB1_CCIR(cb_ptr
[0], cr_ptr
[0]);
570 YUV_TO_RGB2_CCIR(r
, g
, b
, y1_ptr
[0]);
571 RGB_OUT(d1
, r
, g
, b
);
578 d
+= dst
->linesize
[0];
579 y1_ptr
+= src
->linesize
[0] - width
;
580 cb_ptr
+= src
->linesize
[1] - width
;
581 cr_ptr
+= src
->linesize
[2] - width
;
585 static void yuvj444p_to_rgb24(AVPicture
*dst
, const AVPicture
*src
,
586 int width
, int height
)
588 const uint8_t *y1_ptr
, *cb_ptr
, *cr_ptr
;
590 int w
, y
, cb
, cr
, r_add
, g_add
, b_add
;
591 uint8_t *cm
= ff_cropTbl
+ MAX_NEG_CROP
;
592 unsigned int r
, g
, b
;
595 y1_ptr
= src
->data
[0];
596 cb_ptr
= src
->data
[1];
597 cr_ptr
= src
->data
[2];
598 for(;height
> 0; height
--) {
600 for(w
= width
; w
> 0; w
--) {
601 YUV_TO_RGB1(cb_ptr
[0], cr_ptr
[0]);
603 YUV_TO_RGB2(r
, g
, b
, y1_ptr
[0]);
604 RGB_OUT(d1
, r
, g
, b
);
611 d
+= dst
->linesize
[0];
612 y1_ptr
+= src
->linesize
[0] - width
;
613 cb_ptr
+= src
->linesize
[1] - width
;
614 cr_ptr
+= src
->linesize
[2] - width
;
618 static void rgb24_to_yuv444p(AVPicture
*dst
, const AVPicture
*src
,
619 int width
, int height
)
623 uint8_t *lum
, *cb
, *cr
;
630 src_wrap
= src
->linesize
[0] - width
* BPP
;
632 for(y
=0;y
<height
;y
++) {
633 for(x
=0;x
<width
;x
++) {
635 lum
[0] = RGB_TO_Y_CCIR(r
, g
, b
);
636 cb
[0] = RGB_TO_U_CCIR(r
, g
, b
, 0);
637 cr
[0] = RGB_TO_V_CCIR(r
, g
, b
, 0);
644 lum
+= dst
->linesize
[0] - width
;
645 cb
+= dst
->linesize
[1] - width
;
646 cr
+= dst
->linesize
[2] - width
;
650 static void rgb24_to_yuvj420p(AVPicture
*dst
, const AVPicture
*src
,
651 int width
, int height
)
653 int wrap
, wrap3
, width2
;
654 int r
, g
, b
, r1
, g1
, b1
, w
;
655 uint8_t *lum
, *cb
, *cr
;
662 width2
= (width
+ 1) >> 1;
663 wrap
= dst
->linesize
[0];
664 wrap3
= src
->linesize
[0];
666 for(;height
>=2;height
-= 2) {
667 for(w
= width
; w
>= 2; w
-= 2) {
672 lum
[0] = RGB_TO_Y(r
, g
, b
);
674 RGB_IN(r
, g
, b
, p
+ BPP
);
678 lum
[1] = RGB_TO_Y(r
, g
, b
);
686 lum
[0] = RGB_TO_Y(r
, g
, b
);
688 RGB_IN(r
, g
, b
, p
+ BPP
);
692 lum
[1] = RGB_TO_Y(r
, g
, b
);
694 cb
[0] = RGB_TO_U(r1
, g1
, b1
, 2);
695 cr
[0] = RGB_TO_V(r1
, g1
, b1
, 2);
699 p
+= -wrap3
+ 2 * BPP
;
707 lum
[0] = RGB_TO_Y(r
, g
, b
);
714 lum
[0] = RGB_TO_Y(r
, g
, b
);
715 cb
[0] = RGB_TO_U(r1
, g1
, b1
, 1);
716 cr
[0] = RGB_TO_V(r1
, g1
, b1
, 1);
722 p
+= wrap3
+ (wrap3
- width
* BPP
);
723 lum
+= wrap
+ (wrap
- width
);
724 cb
+= dst
->linesize
[1] - width2
;
725 cr
+= dst
->linesize
[2] - width2
;
727 /* handle odd height */
729 for(w
= width
; w
>= 2; w
-= 2) {
734 lum
[0] = RGB_TO_Y(r
, g
, b
);
736 RGB_IN(r
, g
, b
, p
+ BPP
);
740 lum
[1] = RGB_TO_Y(r
, g
, b
);
741 cb
[0] = RGB_TO_U(r1
, g1
, b1
, 1);
742 cr
[0] = RGB_TO_V(r1
, g1
, b1
, 1);
750 lum
[0] = RGB_TO_Y(r
, g
, b
);
751 cb
[0] = RGB_TO_U(r
, g
, b
, 0);
752 cr
[0] = RGB_TO_V(r
, g
, b
, 0);
757 static void rgb24_to_yuvj444p(AVPicture
*dst
, const AVPicture
*src
,
758 int width
, int height
)
762 uint8_t *lum
, *cb
, *cr
;
769 src_wrap
= src
->linesize
[0] - width
* BPP
;
771 for(y
=0;y
<height
;y
++) {
772 for(x
=0;x
<width
;x
++) {
774 lum
[0] = RGB_TO_Y(r
, g
, b
);
775 cb
[0] = RGB_TO_U(r
, g
, b
, 0);
776 cr
[0] = RGB_TO_V(r
, g
, b
, 0);
783 lum
+= dst
->linesize
[0] - width
;
784 cb
+= dst
->linesize
[1] - width
;
785 cr
+= dst
->linesize
[2] - width
;
789 #endif /* FMT_RGB24 */
791 #if defined(FMT_RGB24) || defined(FMT_RGB32)
793 static void glue(RGB_NAME
, _to_pal8
)(AVPicture
*dst
, const AVPicture
*src
,
794 int width
, int height
)
796 const unsigned char *p
;
798 int dst_wrap
, src_wrap
;
800 unsigned int r
, g
, b
;
803 src_wrap
= src
->linesize
[0] - BPP
* width
;
806 dst_wrap
= dst
->linesize
[0] - width
;
809 for(y
=0;y
<height
;y
++) {
810 for(x
=0;x
<width
;x
++) {
814 RGBA_IN(r
, g
, b
, a
, p
);
815 /* crude approximation for alpha ! */
820 q
[0] = gif_clut_index(r
, g
, b
);
825 q
[0] = gif_clut_index(r
, g
, b
);
834 build_rgb_palette(dst
->data
[1], has_alpha
);
837 #endif /* defined(FMT_RGB24) || defined(FMT_RGB32) */
841 static int glue(get_alpha_info_
, RGB_NAME
)(const AVPicture
*src
,
842 int width
, int height
)
844 const unsigned char *p
;
845 int src_wrap
, ret
, x
, y
;
846 unsigned int r
, g
, b
, a
;
849 src_wrap
= src
->linesize
[0] - BPP
* width
;
851 for(y
=0;y
<height
;y
++) {
852 for(x
=0;x
<width
;x
++) {
853 RGBA_IN(r
, g
, b
, a
, p
);
855 ret
|= FF_ALPHA_TRANSP
;
856 } else if (a
!= 0xff) {
857 ret
|= FF_ALPHA_SEMI_TRANSP
;