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
26static 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
120static 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
214static 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
321static 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
347static 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
373static 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
417static 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
454static 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
492static 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
520static 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
552static 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
585static 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
618static 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
650static 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
757static 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
793static 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
841static 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
876