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