7b4dbf94253dd5a64db9f3394510ac3222767ff3
[ffmpeg.git] / libavcodec / imgconvert_template.c
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 #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 // RGB24 has optimized routines
414 #if !defined(FMT_RGB32) && !defined(FMT_RGB24)
415 /* alpha support */
416
417 static void glue(rgb32_to_, RGB_NAME)(AVPicture *dst, const AVPicture *src,
418                                       int width, int height)
419 {
420     const uint8_t *s;
421     uint8_t *d;
422     int src_wrap, dst_wrap, j, y;
423     unsigned int v, r, g, b;
424 #ifdef RGBA_OUT
425     unsigned int a;
426 #endif
427
428     s = src->data[0];
429     src_wrap = src->linesize[0] - width * 4;
430
431     d = dst->data[0];
432     dst_wrap = dst->linesize[0] - width * BPP;
433
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;
438             g = (v >> 8) & 0xff;
439             b = v & 0xff;
440 #ifdef RGBA_OUT
441             a = (v >> 24) & 0xff;
442             RGBA_OUT(d, r, g, b, a);
443 #else
444             RGB_OUT(d, r, g, b);
445 #endif
446             s += 4;
447             d += BPP;
448         }
449         s += src_wrap;
450         d += dst_wrap;
451     }
452 }
453
454 static void glue(RGB_NAME, _to_rgb32)(AVPicture *dst, const AVPicture *src,
455                                        int width, int height)
456 {
457     const uint8_t *s;
458     uint8_t *d;
459     int src_wrap, dst_wrap, j, y;
460     unsigned int r, g, b;
461 #ifdef RGBA_IN
462     unsigned int a;
463 #endif
464
465     s = src->data[0];
466     src_wrap = src->linesize[0] - width * BPP;
467
468     d = dst->data[0];
469     dst_wrap = dst->linesize[0] - width * 4;
470
471     for(y=0;y<height;y++) {
472         for(j = 0;j < width; j++) {
473 #ifdef RGBA_IN
474             RGBA_IN(r, g, b, a, s);
475             ((uint32_t *)(d))[0] = (a << 24) | (r << 16) | (g << 8) | b;
476 #else
477             RGB_IN(r, g, b, s);
478             ((uint32_t *)(d))[0] = (0xff << 24) | (r << 16) | (g << 8) | b;
479 #endif
480             d += 4;
481             s += BPP;
482         }
483         s += src_wrap;
484         d += dst_wrap;
485     }
486 }
487
488 #endif /* !defined(FMT_RGB32) */
489
490 #ifndef FMT_RGB24
491
492 static void glue(rgb24_to_, RGB_NAME)(AVPicture *dst, const AVPicture *src,
493                                       int width, int height)
494 {
495     const uint8_t *s;
496     uint8_t *d;
497     int src_wrap, dst_wrap, j, y;
498     unsigned int r, g, b;
499
500     s = src->data[0];
501     src_wrap = src->linesize[0] - width * 3;
502
503     d = dst->data[0];
504     dst_wrap = dst->linesize[0] - width * BPP;
505
506     for(y=0;y<height;y++) {
507         for(j = 0;j < width; j++) {
508             r = s[0];
509             g = s[1];
510             b = s[2];
511             RGB_OUT(d, r, g, b);
512             s += 3;
513             d += BPP;
514         }
515         s += src_wrap;
516         d += dst_wrap;
517     }
518 }
519
520 static void glue(RGB_NAME, _to_rgb24)(AVPicture *dst, const AVPicture *src,
521                                       int width, int height)
522 {
523     const uint8_t *s;
524     uint8_t *d;
525     int src_wrap, dst_wrap, j, y;
526     unsigned int r, g , b;
527
528     s = src->data[0];
529     src_wrap = src->linesize[0] - width * BPP;
530
531     d = dst->data[0];
532     dst_wrap = dst->linesize[0] - width * 3;
533
534     for(y=0;y<height;y++) {
535         for(j = 0;j < width; j++) {
536             RGB_IN(r, g, b, s)
537             d[0] = r;
538             d[1] = g;
539             d[2] = b;
540             d += 3;
541             s += BPP;
542         }
543         s += src_wrap;
544         d += dst_wrap;
545     }
546 }
547
548 #endif /* !FMT_RGB24 */
549
550 #ifdef FMT_RGB24
551
552 static void yuv444p_to_rgb24(AVPicture *dst, const AVPicture *src,
553                              int width, int height)
554 {
555     const uint8_t *y1_ptr, *cb_ptr, *cr_ptr;
556     uint8_t *d, *d1;
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;
560
561     d = dst->data[0];
562     y1_ptr = src->data[0];
563     cb_ptr = src->data[1];
564     cr_ptr = src->data[2];
565     for(;height > 0; height --) {
566         d1 = d;
567         for(w = width; w > 0; w--) {
568             YUV_TO_RGB1_CCIR(cb_ptr[0], cr_ptr[0]);
569
570             YUV_TO_RGB2_CCIR(r, g, b, y1_ptr[0]);
571             RGB_OUT(d1, r, g, b);
572             d1 += BPP;
573
574             y1_ptr++;
575             cb_ptr++;
576             cr_ptr++;
577         }
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;
582     }
583 }
584
585 static void yuvj444p_to_rgb24(AVPicture *dst, const AVPicture *src,
586                               int width, int height)
587 {
588     const uint8_t *y1_ptr, *cb_ptr, *cr_ptr;
589     uint8_t *d, *d1;
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;
593
594     d = dst->data[0];
595     y1_ptr = src->data[0];
596     cb_ptr = src->data[1];
597     cr_ptr = src->data[2];
598     for(;height > 0; height --) {
599         d1 = d;
600         for(w = width; w > 0; w--) {
601             YUV_TO_RGB1(cb_ptr[0], cr_ptr[0]);
602
603             YUV_TO_RGB2(r, g, b, y1_ptr[0]);
604             RGB_OUT(d1, r, g, b);
605             d1 += BPP;
606
607             y1_ptr++;
608             cb_ptr++;
609             cr_ptr++;
610         }
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;
615     }
616 }
617
618 static void rgb24_to_yuv444p(AVPicture *dst, const AVPicture *src,
619                              int width, int height)
620 {
621     int src_wrap, x, y;
622     int r, g, b;
623     uint8_t *lum, *cb, *cr;
624     const uint8_t *p;
625
626     lum = dst->data[0];
627     cb = dst->data[1];
628     cr = dst->data[2];
629
630     src_wrap = src->linesize[0] - width * BPP;
631     p = src->data[0];
632     for(y=0;y<height;y++) {
633         for(x=0;x<width;x++) {
634             RGB_IN(r, g, b, p);
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);
638             p += BPP;
639             cb++;
640             cr++;
641             lum++;
642         }
643         p += src_wrap;
644         lum += dst->linesize[0] - width;
645         cb += dst->linesize[1] - width;
646         cr += dst->linesize[2] - width;
647     }
648 }
649
650 static void rgb24_to_yuvj420p(AVPicture *dst, const AVPicture *src,
651                               int width, int height)
652 {
653     int wrap, wrap3, width2;
654     int r, g, b, r1, g1, b1, w;
655     uint8_t *lum, *cb, *cr;
656     const uint8_t *p;
657
658     lum = dst->data[0];
659     cb = dst->data[1];
660     cr = dst->data[2];
661
662     width2 = (width + 1) >> 1;
663     wrap = dst->linesize[0];
664     wrap3 = src->linesize[0];
665     p = src->data[0];
666     for(;height>=2;height -= 2) {
667         for(w = width; w >= 2; w -= 2) {
668             RGB_IN(r, g, b, p);
669             r1 = r;
670             g1 = g;
671             b1 = b;
672             lum[0] = RGB_TO_Y(r, g, b);
673
674             RGB_IN(r, g, b, p + BPP);
675             r1 += r;
676             g1 += g;
677             b1 += b;
678             lum[1] = RGB_TO_Y(r, g, b);
679             p += wrap3;
680             lum += wrap;
681
682             RGB_IN(r, g, b, p);
683             r1 += r;
684             g1 += g;
685             b1 += b;
686             lum[0] = RGB_TO_Y(r, g, b);
687
688             RGB_IN(r, g, b, p + BPP);
689             r1 += r;
690             g1 += g;
691             b1 += b;
692             lum[1] = RGB_TO_Y(r, g, b);
693
694             cb[0] = RGB_TO_U(r1, g1, b1, 2);
695             cr[0] = RGB_TO_V(r1, g1, b1, 2);
696
697             cb++;
698             cr++;
699             p += -wrap3 + 2 * BPP;
700             lum += -wrap + 2;
701         }
702         if (w) {
703             RGB_IN(r, g, b, p);
704             r1 = r;
705             g1 = g;
706             b1 = b;
707             lum[0] = RGB_TO_Y(r, g, b);
708             p += wrap3;
709             lum += wrap;
710             RGB_IN(r, g, b, p);
711             r1 += r;
712             g1 += g;
713             b1 += 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);
717             cb++;
718             cr++;
719             p += -wrap3 + BPP;
720             lum += -wrap + 1;
721         }
722         p += wrap3 + (wrap3 - width * BPP);
723         lum += wrap + (wrap - width);
724         cb += dst->linesize[1] - width2;
725         cr += dst->linesize[2] - width2;
726     }
727     /* handle odd height */
728     if (height) {
729         for(w = width; w >= 2; w -= 2) {
730             RGB_IN(r, g, b, p);
731             r1 = r;
732             g1 = g;
733             b1 = b;
734             lum[0] = RGB_TO_Y(r, g, b);
735
736             RGB_IN(r, g, b, p + BPP);
737             r1 += r;
738             g1 += g;
739             b1 += b;
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);
743             cb++;
744             cr++;
745             p += 2 * BPP;
746            lum += 2;
747         }
748         if (w) {
749             RGB_IN(r, g, b, p);
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);
753         }
754     }
755 }
756
757 static void rgb24_to_yuvj444p(AVPicture *dst, const AVPicture *src,
758                               int width, int height)
759 {
760     int src_wrap, x, y;
761     int r, g, b;
762     uint8_t *lum, *cb, *cr;
763     const uint8_t *p;
764
765     lum = dst->data[0];
766     cb = dst->data[1];
767     cr = dst->data[2];
768
769     src_wrap = src->linesize[0] - width * BPP;
770     p = src->data[0];
771     for(y=0;y<height;y++) {
772         for(x=0;x<width;x++) {
773             RGB_IN(r, g, b, p);
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);
777             p += BPP;
778             cb++;
779             cr++;
780             lum++;
781         }
782         p += src_wrap;
783         lum += dst->linesize[0] - width;
784         cb += dst->linesize[1] - width;
785         cr += dst->linesize[2] - width;
786     }
787 }
788
789 #endif /* FMT_RGB24 */
790
791 #if defined(FMT_RGB24) || defined(FMT_RGB32)
792
793 static void glue(RGB_NAME, _to_pal8)(AVPicture *dst, const AVPicture *src,
794                                      int width, int height)
795 {
796     const unsigned char *p;
797     unsigned char *q;
798     int dst_wrap, src_wrap;
799     int x, y, has_alpha;
800     unsigned int r, g, b;
801
802     p = src->data[0];
803     src_wrap = src->linesize[0] - BPP * width;
804
805     q = dst->data[0];
806     dst_wrap = dst->linesize[0] - width;
807     has_alpha = 0;
808
809     for(y=0;y<height;y++) {
810         for(x=0;x<width;x++) {
811 #ifdef RGBA_IN
812             {
813                 unsigned int a;
814                 RGBA_IN(r, g, b, a, p);
815                 /* crude approximation for alpha ! */
816                 if (a < 0x80) {
817                     has_alpha = 1;
818                     q[0] = TRANSP_INDEX;
819                 } else {
820                     q[0] = gif_clut_index(r, g, b);
821                 }
822             }
823 #else
824             RGB_IN(r, g, b, p);
825             q[0] = gif_clut_index(r, g, b);
826 #endif
827             q++;
828             p += BPP;
829         }
830         p += src_wrap;
831         q += dst_wrap;
832     }
833
834     build_rgb_palette(dst->data[1], has_alpha);
835 }
836
837 #endif /* defined(FMT_RGB24) || defined(FMT_RGB32) */
838
839 #ifdef RGBA_IN
840
841 static int glue(get_alpha_info_, RGB_NAME)(const AVPicture *src,
842                                            int width, int height)
843 {
844     const unsigned char *p;
845     int src_wrap, ret, x, y;
846     unsigned int r, g, b, a;
847
848     p = src->data[0];
849     src_wrap = src->linesize[0] - BPP * width;
850     ret = 0;
851     for(y=0;y<height;y++) {
852         for(x=0;x<width;x++) {
853             RGBA_IN(r, g, b, a, p);
854             if (a == 0x00) {
855                 ret |= FF_ALPHA_TRANSP;
856             } else if (a != 0xff) {
857                 ret |= FF_ALPHA_SEMI_TRANSP;
858             }
859             p += BPP;
860         }
861         p += src_wrap;
862     }
863     return ret;
864 }
865
866 #endif /* RGBA_IN */
867
868 #undef RGB_IN
869 #undef RGBA_IN
870 #undef RGB_OUT
871 #undef RGBA_OUT
872 #undef BPP
873 #undef RGB_NAME
874 #undef FMT_RGB24
875 #undef FMT_RGB32