07dbb654dc79b8429577c169cb4c3b12135aee93
[ffmpeg.git] / libavcodec / imgconvert_template.h
1 /*
2  * Templates for image convertion routines
3  * Copyright (c) 2001, 2002, 2003 Fabrice Bellard.
4  *
5  * This file is part of FFmpeg.
6  *
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.
11  *
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.
16  *
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
20  */
21
22 #ifndef RGB_OUT
23 #define RGB_OUT(d, r, g, b) RGBA_OUT(d, r, g, b, 0xff)
24 #endif
25
26 static void glue(yuv420p_to_, RGB_NAME)(AVPicture *dst, const AVPicture *src,
27                                         int width, int height)
28 {
29     const uint8_t *y1_ptr, *y2_ptr, *cb_ptr, *cr_ptr;
30     uint8_t *d, *d1, *d2;
31     int w, y, cb, cr, r_add, g_add, b_add, width2;
32     uint8_t *cm = ff_cropTbl + MAX_NEG_CROP;
33     unsigned int r, g, b;
34
35     d = dst->data[0];
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) {
41         d1 = d;
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]);
46             /* output 4 pixels */
47             YUV_TO_RGB2_CCIR(r, g, b, y1_ptr[0]);
48             RGB_OUT(d1, r, g, b);
49
50             YUV_TO_RGB2_CCIR(r, g, b, y1_ptr[1]);
51             RGB_OUT(d1 + BPP, r, g, b);
52
53             YUV_TO_RGB2_CCIR(r, g, b, y2_ptr[0]);
54             RGB_OUT(d2, r, g, b);
55
56             YUV_TO_RGB2_CCIR(r, g, b, y2_ptr[1]);
57             RGB_OUT(d2 + BPP, r, g, b);
58
59             d1 += 2 * BPP;
60             d2 += 2 * BPP;
61
62             y1_ptr += 2;
63             y2_ptr += 2;
64             cb_ptr++;
65             cr_ptr++;
66         }
67         /* handle odd width */
68         if (w) {
69             YUV_TO_RGB1_CCIR(cb_ptr[0], cr_ptr[0]);
70             YUV_TO_RGB2_CCIR(r, g, b, y1_ptr[0]);
71             RGB_OUT(d1, r, g, b);
72
73             YUV_TO_RGB2_CCIR(r, g, b, y2_ptr[0]);
74             RGB_OUT(d2, r, g, b);
75             d1 += BPP;
76             d2 += BPP;
77             y1_ptr++;
78             y2_ptr++;
79             cb_ptr++;
80             cr_ptr++;
81         }
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;
86     }
87     /* handle odd height */
88     if (height) {
89         d1 = d;
90         for(w = width; w >= 2; w -= 2) {
91             YUV_TO_RGB1_CCIR(cb_ptr[0], cr_ptr[0]);
92             /* output 2 pixels */
93             YUV_TO_RGB2_CCIR(r, g, b, y1_ptr[0]);
94             RGB_OUT(d1, r, g, b);
95
96             YUV_TO_RGB2_CCIR(r, g, b, y1_ptr[1]);
97             RGB_OUT(d1 + BPP, r, g, b);
98
99             d1 += 2 * BPP;
100
101             y1_ptr += 2;
102             cb_ptr++;
103             cr_ptr++;
104         }
105         /* handle width */
106         if (w) {
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);
111             d1 += BPP;
112
113             y1_ptr++;
114             cb_ptr++;
115             cr_ptr++;
116         }
117     }
118 }
119
120 static void glue(yuvj420p_to_, RGB_NAME)(AVPicture *dst, const AVPicture *src,
121                                          int width, int height)
122 {
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;
128
129     d = dst->data[0];
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) {
135         d1 = d;
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);
143
144             YUV_TO_RGB2(r, g, b, y1_ptr[1]);
145             RGB_OUT(d1 + BPP, r, g, b);
146
147             YUV_TO_RGB2(r, g, b, y2_ptr[0]);
148             RGB_OUT(d2, r, g, b);
149
150             YUV_TO_RGB2(r, g, b, y2_ptr[1]);
151             RGB_OUT(d2 + BPP, r, g, b);
152
153             d1 += 2 * BPP;
154             d2 += 2 * BPP;
155
156             y1_ptr += 2;
157             y2_ptr += 2;
158             cb_ptr++;
159             cr_ptr++;
160         }
161         /* handle odd width */
162         if (w) {
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);
166
167             YUV_TO_RGB2(r, g, b, y2_ptr[0]);
168             RGB_OUT(d2, r, g, b);
169             d1 += BPP;
170             d2 += BPP;
171             y1_ptr++;
172             y2_ptr++;
173             cb_ptr++;
174             cr_ptr++;
175         }
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;
180     }
181     /* handle odd height */
182     if (height) {
183         d1 = d;
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);
189
190             YUV_TO_RGB2(r, g, b, y1_ptr[1]);
191             RGB_OUT(d1 + BPP, r, g, b);
192
193             d1 += 2 * BPP;
194
195             y1_ptr += 2;
196             cb_ptr++;
197             cr_ptr++;
198         }
199         /* handle width */
200         if (w) {
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);
205             d1 += BPP;
206
207             y1_ptr++;
208             cb_ptr++;
209             cr_ptr++;
210         }
211     }
212 }
213
214 static void glue(RGB_NAME, _to_yuv420p)(AVPicture *dst, const AVPicture *src,
215                                         int width, int height)
216 {
217     int wrap, wrap3, width2;
218     int r, g, b, r1, g1, b1, w;
219     uint8_t *lum, *cb, *cr;
220     const uint8_t *p;
221
222     lum = dst->data[0];
223     cb = dst->data[1];
224     cr = dst->data[2];
225
226     width2 = (width + 1) >> 1;
227     wrap = dst->linesize[0];
228     wrap3 = src->linesize[0];
229     p = src->data[0];
230     for(;height>=2;height -= 2) {
231         for(w = width; w >= 2; w -= 2) {
232             RGB_IN(r, g, b, p);
233             r1 = r;
234             g1 = g;
235             b1 = b;
236             lum[0] = RGB_TO_Y_CCIR(r, g, b);
237
238             RGB_IN(r, g, b, p + BPP);
239             r1 += r;
240             g1 += g;
241             b1 += b;
242             lum[1] = RGB_TO_Y_CCIR(r, g, b);
243             p += wrap3;
244             lum += wrap;
245
246             RGB_IN(r, g, b, p);
247             r1 += r;
248             g1 += g;
249             b1 += b;
250             lum[0] = RGB_TO_Y_CCIR(r, g, b);
251
252             RGB_IN(r, g, b, p + BPP);
253             r1 += r;
254             g1 += g;
255             b1 += b;
256             lum[1] = RGB_TO_Y_CCIR(r, g, b);
257
258             cb[0] = RGB_TO_U_CCIR(r1, g1, b1, 2);
259             cr[0] = RGB_TO_V_CCIR(r1, g1, b1, 2);
260
261             cb++;
262             cr++;
263             p += -wrap3 + 2 * BPP;
264             lum += -wrap + 2;
265         }
266         if (w) {
267             RGB_IN(r, g, b, p);
268             r1 = r;
269             g1 = g;
270             b1 = b;
271             lum[0] = RGB_TO_Y_CCIR(r, g, b);
272             p += wrap3;
273             lum += wrap;
274             RGB_IN(r, g, b, p);
275             r1 += r;
276             g1 += g;
277             b1 += 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);
281             cb++;
282             cr++;
283             p += -wrap3 + BPP;
284             lum += -wrap + 1;
285         }
286         p += wrap3 + (wrap3 - width * BPP);
287         lum += wrap + (wrap - width);
288         cb += dst->linesize[1] - width2;
289         cr += dst->linesize[2] - width2;
290     }
291     /* handle odd height */
292     if (height) {
293         for(w = width; w >= 2; w -= 2) {
294             RGB_IN(r, g, b, p);
295             r1 = r;
296             g1 = g;
297             b1 = b;
298             lum[0] = RGB_TO_Y_CCIR(r, g, b);
299
300             RGB_IN(r, g, b, p + BPP);
301             r1 += r;
302             g1 += g;
303             b1 += b;
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);
307             cb++;
308             cr++;
309             p += 2 * BPP;
310            lum += 2;
311         }
312         if (w) {
313             RGB_IN(r, g, b, p);
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);
317         }
318     }
319 }
320
321 static void glue(RGB_NAME, _to_gray)(AVPicture *dst, const AVPicture *src,
322                                      int width, int height)
323 {
324     const unsigned char *p;
325     unsigned char *q;
326     int r, g, b, dst_wrap, src_wrap;
327     int x, y;
328
329     p = src->data[0];
330     src_wrap = src->linesize[0] - BPP * width;
331
332     q = dst->data[0];
333     dst_wrap = dst->linesize[0] - width;
334
335     for(y=0;y<height;y++) {
336         for(x=0;x<width;x++) {
337             RGB_IN(r, g, b, p);
338             q[0] = RGB_TO_Y(r, g, b);
339             q++;
340             p += BPP;
341         }
342         p += src_wrap;
343         q += dst_wrap;
344     }
345 }
346
347 static void glue(gray_to_, RGB_NAME)(AVPicture *dst, const AVPicture *src,
348                                      int width, int height)
349 {
350     const unsigned char *p;
351     unsigned char *q;
352     int r, dst_wrap, src_wrap;
353     int x, y;
354
355     p = src->data[0];
356     src_wrap = src->linesize[0] - width;
357
358     q = dst->data[0];
359     dst_wrap = dst->linesize[0] - BPP * width;
360
361     for(y=0;y<height;y++) {
362         for(x=0;x<width;x++) {
363             r = p[0];
364             RGB_OUT(q, r, r, r);
365             q += BPP;
366             p ++;
367         }
368         p += src_wrap;
369         q += dst_wrap;
370     }
371 }
372
373 static void glue(pal8_to_, RGB_NAME)(AVPicture *dst, const AVPicture *src,
374                                      int width, int height)
375 {
376     const unsigned char *p;
377     unsigned char *q;
378     int r, g, b, dst_wrap, src_wrap;
379     int x, y;
380     uint32_t v;
381     const uint32_t *palette;
382
383     p = src->data[0];
384     src_wrap = src->linesize[0] - width;
385     palette = (uint32_t *)src->data[1];
386
387     q = dst->data[0];
388     dst_wrap = dst->linesize[0] - BPP * width;
389
390     for(y=0;y<height;y++) {
391         for(x=0;x<width;x++) {
392             v = palette[p[0]];
393             r = (v >> 16) & 0xff;
394             g = (v >> 8) & 0xff;
395             b = (v) & 0xff;
396 #ifdef RGBA_OUT
397             {
398                 int a;
399                 a = (v >> 24) & 0xff;
400                 RGBA_OUT(q, r, g, b, a);
401             }
402 #else
403             RGB_OUT(q, r, g, b);
404 #endif
405             q += BPP;
406             p ++;
407         }
408         p += src_wrap;
409         q += dst_wrap;
410     }
411 }
412
413 #if !defined(FMT_RGBA32) && defined(RGBA_OUT)
414 /* alpha support */
415
416 static void glue(rgba32_to_, RGB_NAME)(AVPicture *dst, const AVPicture *src,
417                                       int width, int height)
418 {
419     const uint8_t *s;
420     uint8_t *d;
421     int src_wrap, dst_wrap, j, y;
422     unsigned int v, r, g, b, a;
423
424     s = src->data[0];
425     src_wrap = src->linesize[0] - width * 4;
426
427     d = dst->data[0];
428     dst_wrap = dst->linesize[0] - width * BPP;
429
430     for(y=0;y<height;y++) {
431         for(j = 0;j < width; j++) {
432             v = ((const uint32_t *)(s))[0];
433             a = (v >> 24) & 0xff;
434             r = (v >> 16) & 0xff;
435             g = (v >> 8) & 0xff;
436             b = v & 0xff;
437             RGBA_OUT(d, r, g, b, a);
438             s += 4;
439             d += BPP;
440         }
441         s += src_wrap;
442         d += dst_wrap;
443     }
444 }
445
446 static void glue(RGB_NAME, _to_rgba32)(AVPicture *dst, const AVPicture *src,
447                                        int width, int height)
448 {
449     const uint8_t *s;
450     uint8_t *d;
451     int src_wrap, dst_wrap, j, y;
452     unsigned int r, g, b, a;
453
454     s = src->data[0];
455     src_wrap = src->linesize[0] - width * BPP;
456
457     d = dst->data[0];
458     dst_wrap = dst->linesize[0] - width * 4;
459
460     for(y=0;y<height;y++) {
461         for(j = 0;j < width; j++) {
462             RGBA_IN(r, g, b, a, s);
463             ((uint32_t *)(d))[0] = (a << 24) | (r << 16) | (g << 8) | b;
464             d += 4;
465             s += BPP;
466         }
467         s += src_wrap;
468         d += dst_wrap;
469     }
470 }
471
472 #endif /* !defined(FMT_RGBA32) && defined(RGBA_IN) */
473
474 #ifndef FMT_RGB24
475
476 static void glue(rgb24_to_, RGB_NAME)(AVPicture *dst, const AVPicture *src,
477                                       int width, int height)
478 {
479     const uint8_t *s;
480     uint8_t *d;
481     int src_wrap, dst_wrap, j, y;
482     unsigned int r, g, b;
483
484     s = src->data[0];
485     src_wrap = src->linesize[0] - width * 3;
486
487     d = dst->data[0];
488     dst_wrap = dst->linesize[0] - width * BPP;
489
490     for(y=0;y<height;y++) {
491         for(j = 0;j < width; j++) {
492             r = s[0];
493             g = s[1];
494             b = s[2];
495             RGB_OUT(d, r, g, b);
496             s += 3;
497             d += BPP;
498         }
499         s += src_wrap;
500         d += dst_wrap;
501     }
502 }
503
504 static void glue(RGB_NAME, _to_rgb24)(AVPicture *dst, const AVPicture *src,
505                                       int width, int height)
506 {
507     const uint8_t *s;
508     uint8_t *d;
509     int src_wrap, dst_wrap, j, y;
510     unsigned int r, g , b;
511
512     s = src->data[0];
513     src_wrap = src->linesize[0] - width * BPP;
514
515     d = dst->data[0];
516     dst_wrap = dst->linesize[0] - width * 3;
517
518     for(y=0;y<height;y++) {
519         for(j = 0;j < width; j++) {
520             RGB_IN(r, g, b, s)
521             d[0] = r;
522             d[1] = g;
523             d[2] = b;
524             d += 3;
525             s += BPP;
526         }
527         s += src_wrap;
528         d += dst_wrap;
529     }
530 }
531
532 #endif /* !FMT_RGB24 */
533
534 #ifdef FMT_RGB24
535
536 static void yuv444p_to_rgb24(AVPicture *dst, const AVPicture *src,
537                              int width, int height)
538 {
539     const uint8_t *y1_ptr, *cb_ptr, *cr_ptr;
540     uint8_t *d, *d1;
541     int w, y, cb, cr, r_add, g_add, b_add;
542     uint8_t *cm = ff_cropTbl + MAX_NEG_CROP;
543     unsigned int r, g, b;
544
545     d = dst->data[0];
546     y1_ptr = src->data[0];
547     cb_ptr = src->data[1];
548     cr_ptr = src->data[2];
549     for(;height > 0; height --) {
550         d1 = d;
551         for(w = width; w > 0; w--) {
552             YUV_TO_RGB1_CCIR(cb_ptr[0], cr_ptr[0]);
553
554             YUV_TO_RGB2_CCIR(r, g, b, y1_ptr[0]);
555             RGB_OUT(d1, r, g, b);
556             d1 += BPP;
557
558             y1_ptr++;
559             cb_ptr++;
560             cr_ptr++;
561         }
562         d += dst->linesize[0];
563         y1_ptr += src->linesize[0] - width;
564         cb_ptr += src->linesize[1] - width;
565         cr_ptr += src->linesize[2] - width;
566     }
567 }
568
569 static void yuvj444p_to_rgb24(AVPicture *dst, const AVPicture *src,
570                               int width, int height)
571 {
572     const uint8_t *y1_ptr, *cb_ptr, *cr_ptr;
573     uint8_t *d, *d1;
574     int w, y, cb, cr, r_add, g_add, b_add;
575     uint8_t *cm = ff_cropTbl + MAX_NEG_CROP;
576     unsigned int r, g, b;
577
578     d = dst->data[0];
579     y1_ptr = src->data[0];
580     cb_ptr = src->data[1];
581     cr_ptr = src->data[2];
582     for(;height > 0; height --) {
583         d1 = d;
584         for(w = width; w > 0; w--) {
585             YUV_TO_RGB1(cb_ptr[0], cr_ptr[0]);
586
587             YUV_TO_RGB2(r, g, b, y1_ptr[0]);
588             RGB_OUT(d1, r, g, b);
589             d1 += BPP;
590
591             y1_ptr++;
592             cb_ptr++;
593             cr_ptr++;
594         }
595         d += dst->linesize[0];
596         y1_ptr += src->linesize[0] - width;
597         cb_ptr += src->linesize[1] - width;
598         cr_ptr += src->linesize[2] - width;
599     }
600 }
601
602 static void rgb24_to_yuv444p(AVPicture *dst, const AVPicture *src,
603                              int width, int height)
604 {
605     int src_wrap, x, y;
606     int r, g, b;
607     uint8_t *lum, *cb, *cr;
608     const uint8_t *p;
609
610     lum = dst->data[0];
611     cb = dst->data[1];
612     cr = dst->data[2];
613
614     src_wrap = src->linesize[0] - width * BPP;
615     p = src->data[0];
616     for(y=0;y<height;y++) {
617         for(x=0;x<width;x++) {
618             RGB_IN(r, g, b, p);
619             lum[0] = RGB_TO_Y_CCIR(r, g, b);
620             cb[0] = RGB_TO_U_CCIR(r, g, b, 0);
621             cr[0] = RGB_TO_V_CCIR(r, g, b, 0);
622             p += BPP;
623             cb++;
624             cr++;
625             lum++;
626         }
627         p += src_wrap;
628         lum += dst->linesize[0] - width;
629         cb += dst->linesize[1] - width;
630         cr += dst->linesize[2] - width;
631     }
632 }
633
634 static void rgb24_to_yuvj420p(AVPicture *dst, const AVPicture *src,
635                               int width, int height)
636 {
637     int wrap, wrap3, width2;
638     int r, g, b, r1, g1, b1, w;
639     uint8_t *lum, *cb, *cr;
640     const uint8_t *p;
641
642     lum = dst->data[0];
643     cb = dst->data[1];
644     cr = dst->data[2];
645
646     width2 = (width + 1) >> 1;
647     wrap = dst->linesize[0];
648     wrap3 = src->linesize[0];
649     p = src->data[0];
650     for(;height>=2;height -= 2) {
651         for(w = width; w >= 2; w -= 2) {
652             RGB_IN(r, g, b, p);
653             r1 = r;
654             g1 = g;
655             b1 = b;
656             lum[0] = RGB_TO_Y(r, g, b);
657
658             RGB_IN(r, g, b, p + BPP);
659             r1 += r;
660             g1 += g;
661             b1 += b;
662             lum[1] = RGB_TO_Y(r, g, b);
663             p += wrap3;
664             lum += wrap;
665
666             RGB_IN(r, g, b, p);
667             r1 += r;
668             g1 += g;
669             b1 += b;
670             lum[0] = RGB_TO_Y(r, g, b);
671
672             RGB_IN(r, g, b, p + BPP);
673             r1 += r;
674             g1 += g;
675             b1 += b;
676             lum[1] = RGB_TO_Y(r, g, b);
677
678             cb[0] = RGB_TO_U(r1, g1, b1, 2);
679             cr[0] = RGB_TO_V(r1, g1, b1, 2);
680
681             cb++;
682             cr++;
683             p += -wrap3 + 2 * BPP;
684             lum += -wrap + 2;
685         }
686         if (w) {
687             RGB_IN(r, g, b, p);
688             r1 = r;
689             g1 = g;
690             b1 = b;
691             lum[0] = RGB_TO_Y(r, g, b);
692             p += wrap3;
693             lum += wrap;
694             RGB_IN(r, g, b, p);
695             r1 += r;
696             g1 += g;
697             b1 += b;
698             lum[0] = RGB_TO_Y(r, g, b);
699             cb[0] = RGB_TO_U(r1, g1, b1, 1);
700             cr[0] = RGB_TO_V(r1, g1, b1, 1);
701             cb++;
702             cr++;
703             p += -wrap3 + BPP;
704             lum += -wrap + 1;
705         }
706         p += wrap3 + (wrap3 - width * BPP);
707         lum += wrap + (wrap - width);
708         cb += dst->linesize[1] - width2;
709         cr += dst->linesize[2] - width2;
710     }
711     /* handle odd height */
712     if (height) {
713         for(w = width; w >= 2; w -= 2) {
714             RGB_IN(r, g, b, p);
715             r1 = r;
716             g1 = g;
717             b1 = b;
718             lum[0] = RGB_TO_Y(r, g, b);
719
720             RGB_IN(r, g, b, p + BPP);
721             r1 += r;
722             g1 += g;
723             b1 += b;
724             lum[1] = RGB_TO_Y(r, g, b);
725             cb[0] = RGB_TO_U(r1, g1, b1, 1);
726             cr[0] = RGB_TO_V(r1, g1, b1, 1);
727             cb++;
728             cr++;
729             p += 2 * BPP;
730            lum += 2;
731         }
732         if (w) {
733             RGB_IN(r, g, b, p);
734             lum[0] = RGB_TO_Y(r, g, b);
735             cb[0] = RGB_TO_U(r, g, b, 0);
736             cr[0] = RGB_TO_V(r, g, b, 0);
737         }
738     }
739 }
740
741 static void rgb24_to_yuvj444p(AVPicture *dst, const AVPicture *src,
742                               int width, int height)
743 {
744     int src_wrap, x, y;
745     int r, g, b;
746     uint8_t *lum, *cb, *cr;
747     const uint8_t *p;
748
749     lum = dst->data[0];
750     cb = dst->data[1];
751     cr = dst->data[2];
752
753     src_wrap = src->linesize[0] - width * BPP;
754     p = src->data[0];
755     for(y=0;y<height;y++) {
756         for(x=0;x<width;x++) {
757             RGB_IN(r, g, b, p);
758             lum[0] = RGB_TO_Y(r, g, b);
759             cb[0] = RGB_TO_U(r, g, b, 0);
760             cr[0] = RGB_TO_V(r, g, b, 0);
761             p += BPP;
762             cb++;
763             cr++;
764             lum++;
765         }
766         p += src_wrap;
767         lum += dst->linesize[0] - width;
768         cb += dst->linesize[1] - width;
769         cr += dst->linesize[2] - width;
770     }
771 }
772
773 #endif /* FMT_RGB24 */
774
775 #if defined(FMT_RGB24) || defined(FMT_RGBA32)
776
777 static void glue(RGB_NAME, _to_pal8)(AVPicture *dst, const AVPicture *src,
778                                      int width, int height)
779 {
780     const unsigned char *p;
781     unsigned char *q;
782     int dst_wrap, src_wrap;
783     int x, y, has_alpha;
784     unsigned int r, g, b;
785
786     p = src->data[0];
787     src_wrap = src->linesize[0] - BPP * width;
788
789     q = dst->data[0];
790     dst_wrap = dst->linesize[0] - width;
791     has_alpha = 0;
792
793     for(y=0;y<height;y++) {
794         for(x=0;x<width;x++) {
795 #ifdef RGBA_IN
796             {
797                 unsigned int a;
798                 RGBA_IN(r, g, b, a, p);
799                 /* crude approximation for alpha ! */
800                 if (a < 0x80) {
801                     has_alpha = 1;
802                     q[0] = TRANSP_INDEX;
803                 } else {
804                     q[0] = gif_clut_index(r, g, b);
805                 }
806             }
807 #else
808             RGB_IN(r, g, b, p);
809             q[0] = gif_clut_index(r, g, b);
810 #endif
811             q++;
812             p += BPP;
813         }
814         p += src_wrap;
815         q += dst_wrap;
816     }
817
818     build_rgb_palette(dst->data[1], has_alpha);
819 }
820
821 #endif /* defined(FMT_RGB24) || defined(FMT_RGBA32) */
822
823 #ifdef RGBA_IN
824
825 static int glue(get_alpha_info_, RGB_NAME)(const AVPicture *src,
826                                            int width, int height)
827 {
828     const unsigned char *p;
829     int src_wrap, ret, x, y;
830     unsigned int r, g, b, a;
831
832     p = src->data[0];
833     src_wrap = src->linesize[0] - BPP * width;
834     ret = 0;
835     for(y=0;y<height;y++) {
836         for(x=0;x<width;x++) {
837             RGBA_IN(r, g, b, a, p);
838             if (a == 0x00) {
839                 ret |= FF_ALPHA_TRANSP;
840             } else if (a != 0xff) {
841                 ret |= FF_ALPHA_SEMI_TRANSP;
842             }
843             p += BPP;
844         }
845         p += src_wrap;
846     }
847     return ret;
848 }
849
850 #endif /* RGBA_IN */
851
852 #undef RGB_IN
853 #undef RGBA_IN
854 #undef RGB_OUT
855 #undef RGBA_OUT
856 #undef BPP
857 #undef RGB_NAME
858 #undef FMT_RGB24
859 #undef FMT_RGBA32