expand tabs
[platform/upstream/gstreamer.git] / gst / ffmpegcolorspace / imgconvert_template.h
1 /*
2  * Templates for image convertion routines
3  * Copyright (c) 2001, 2002, 2003 Fabrice Bellard.
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Lesser General Public
7  * License as published by the Free Software Foundation; either
8  * version 2 of the License, or (at your option) any later version.
9  *
10  * This library is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  * Lesser General Public License for more details.
14  *
15  * You should have received a copy of the GNU Lesser General Public
16  * License along with this library; if not, write to the Free Software
17  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
18  */
19
20 #ifndef RGB_OUT
21 #define RGB_OUT(d, r, g, b) RGBA_OUT(d, r, g, b, 0xff)
22 #endif
23
24 static void glue(yuv420p_to_, RGB_NAME)(AVPicture *dst, const AVPicture *src,
25                                         int width, int height)
26 {
27     const uint8_t *y1_ptr, *y2_ptr, *cb_ptr, *cr_ptr;
28     uint8_t *d, *d1, *d2;
29     int w, y, cb, cr, r_add, g_add, b_add, width2;
30     uint8_t *cm = cropTbl + MAX_NEG_CROP;
31     unsigned int r, g, b;
32
33     d = dst->data[0];
34     y1_ptr = src->data[0];
35     cb_ptr = src->data[1];
36     cr_ptr = src->data[2];
37     width2 = (width + 1) >> 1;
38     for(;height >= 2; height -= 2) {
39         d1 = d;
40         d2 = d + dst->linesize[0];
41         y2_ptr = y1_ptr + src->linesize[0];
42         for(w = width; w >= 2; w -= 2) {
43             YUV_TO_RGB1_CCIR(cb_ptr[0], cr_ptr[0]);
44             /* output 4 pixels */
45             YUV_TO_RGB2_CCIR(r, g, b, y1_ptr[0]);
46             RGB_OUT(d1, r, g, b);
47
48             YUV_TO_RGB2_CCIR(r, g, b, y1_ptr[1]);
49             RGB_OUT(d1 + BPP, r, g, b);
50
51             YUV_TO_RGB2_CCIR(r, g, b, y2_ptr[0]);
52             RGB_OUT(d2, r, g, b);
53
54             YUV_TO_RGB2_CCIR(r, g, b, y2_ptr[1]);
55             RGB_OUT(d2 + BPP, r, g, b);
56
57             d1 += 2 * BPP;
58             d2 += 2 * BPP;
59
60             y1_ptr += 2;
61             y2_ptr += 2;
62             cb_ptr++;
63             cr_ptr++;
64         }
65         /* handle odd width */
66         if (w) {
67             YUV_TO_RGB1_CCIR(cb_ptr[0], cr_ptr[0]);
68             YUV_TO_RGB2_CCIR(r, g, b, y1_ptr[0]);
69             RGB_OUT(d1, r, g, b);
70
71             YUV_TO_RGB2_CCIR(r, g, b, y2_ptr[0]);
72             RGB_OUT(d2, r, g, b);
73             d1 += BPP;
74             d2 += BPP;
75             y1_ptr++;
76             y2_ptr++;
77             cb_ptr++;
78             cr_ptr++;
79         }
80         d += 2 * dst->linesize[0];
81         y1_ptr += 2 * src->linesize[0] - width;
82         cb_ptr += src->linesize[1] - width2;
83         cr_ptr += src->linesize[2] - width2;
84     }
85     /* handle odd height */
86     if (height) {
87         d1 = d;
88         for(w = width; w >= 2; w -= 2) {
89             YUV_TO_RGB1_CCIR(cb_ptr[0], cr_ptr[0]);
90             /* output 2 pixels */
91             YUV_TO_RGB2_CCIR(r, g, b, y1_ptr[0]);
92             RGB_OUT(d1, r, g, b);
93
94             YUV_TO_RGB2_CCIR(r, g, b, y1_ptr[1]);
95             RGB_OUT(d1 + BPP, r, g, b);
96
97             d1 += 2 * BPP;
98
99             y1_ptr += 2;
100             cb_ptr++;
101             cr_ptr++;
102         }
103         /* handle width */
104         if (w) {
105             YUV_TO_RGB1_CCIR(cb_ptr[0], cr_ptr[0]);
106             /* output 2 pixels */
107             YUV_TO_RGB2_CCIR(r, g, b, y1_ptr[0]);
108             RGB_OUT(d1, r, g, b);
109             d1 += BPP;
110
111             y1_ptr++;
112             cb_ptr++;
113             cr_ptr++;
114         }
115     }
116 }
117
118 static void glue(yuvj420p_to_, RGB_NAME)(AVPicture *dst, const AVPicture *src,
119                                          int width, int height)
120 {
121     const uint8_t *y1_ptr, *y2_ptr, *cb_ptr, *cr_ptr;
122     uint8_t *d, *d1, *d2;
123     int w, y, cb, cr, r_add, g_add, b_add, width2;
124     uint8_t *cm = cropTbl + MAX_NEG_CROP;
125     unsigned int r, g, b;
126
127     d = dst->data[0];
128     y1_ptr = src->data[0];
129     cb_ptr = src->data[1];
130     cr_ptr = src->data[2];
131     width2 = (width + 1) >> 1;
132     for(;height >= 2; height -= 2) {
133         d1 = d;
134         d2 = d + dst->linesize[0];
135         y2_ptr = y1_ptr + src->linesize[0];
136         for(w = width; w >= 2; w -= 2) {
137             YUV_TO_RGB1(cb_ptr[0], cr_ptr[0]);
138             /* output 4 pixels */
139             YUV_TO_RGB2(r, g, b, y1_ptr[0]);
140             RGB_OUT(d1, r, g, b);
141
142             YUV_TO_RGB2(r, g, b, y1_ptr[1]);
143             RGB_OUT(d1 + BPP, r, g, b);
144
145             YUV_TO_RGB2(r, g, b, y2_ptr[0]);
146             RGB_OUT(d2, r, g, b);
147
148             YUV_TO_RGB2(r, g, b, y2_ptr[1]);
149             RGB_OUT(d2 + BPP, r, g, b);
150
151             d1 += 2 * BPP;
152             d2 += 2 * BPP;
153
154             y1_ptr += 2;
155             y2_ptr += 2;
156             cb_ptr++;
157             cr_ptr++;
158         }
159         /* handle odd width */
160         if (w) {
161             YUV_TO_RGB1(cb_ptr[0], cr_ptr[0]);
162             YUV_TO_RGB2(r, g, b, y1_ptr[0]);
163             RGB_OUT(d1, r, g, b);
164
165             YUV_TO_RGB2(r, g, b, y2_ptr[0]);
166             RGB_OUT(d2, r, g, b);
167             d1 += BPP;
168             d2 += BPP;
169             y1_ptr++;
170             y2_ptr++;
171             cb_ptr++;
172             cr_ptr++;
173         }
174         d += 2 * dst->linesize[0];
175         y1_ptr += 2 * src->linesize[0] - width;
176         cb_ptr += src->linesize[1] - width2;
177         cr_ptr += src->linesize[2] - width2;
178     }
179     /* handle odd height */
180     if (height) {
181         d1 = d;
182         for(w = width; w >= 2; w -= 2) {
183             YUV_TO_RGB1(cb_ptr[0], cr_ptr[0]);
184             /* output 2 pixels */
185             YUV_TO_RGB2(r, g, b, y1_ptr[0]);
186             RGB_OUT(d1, r, g, b);
187
188             YUV_TO_RGB2(r, g, b, y1_ptr[1]);
189             RGB_OUT(d1 + BPP, r, g, b);
190
191             d1 += 2 * BPP;
192
193             y1_ptr += 2;
194             cb_ptr++;
195             cr_ptr++;
196         }
197         /* handle width */
198         if (w) {
199             YUV_TO_RGB1(cb_ptr[0], cr_ptr[0]);
200             /* output 2 pixels */
201             YUV_TO_RGB2(r, g, b, y1_ptr[0]);
202             RGB_OUT(d1, r, g, b);
203             d1 += BPP;
204
205             y1_ptr++;
206             cb_ptr++;
207             cr_ptr++;
208         }
209     }
210 }
211
212 static void glue(RGB_NAME, _to_yuv420p)(AVPicture *dst, const AVPicture *src,
213                                         int width, int height)
214 {
215     int wrap, wrap3, width2;
216     int r, g, b, r1, g1, b1, w;
217     uint8_t *lum, *cb, *cr;
218     const uint8_t *p;
219
220     lum = dst->data[0];
221     cb = dst->data[1];
222     cr = dst->data[2];
223
224     width2 = (width + 1) >> 1;
225     wrap = dst->linesize[0];
226     wrap3 = src->linesize[0];
227     p = src->data[0];
228     for(;height>=2;height -= 2) {
229         for(w = width; w >= 2; w -= 2) {
230             RGB_IN(r, g, b, p);
231             r1 = r;
232             g1 = g;
233             b1 = b;
234             lum[0] = RGB_TO_Y_CCIR(r, g, b);
235
236             RGB_IN(r, g, b, p + BPP);
237             r1 += r;
238             g1 += g;
239             b1 += b;
240             lum[1] = RGB_TO_Y_CCIR(r, g, b);
241             p += wrap3;
242             lum += wrap;
243
244             RGB_IN(r, g, b, p);
245             r1 += r;
246             g1 += g;
247             b1 += b;
248             lum[0] = RGB_TO_Y_CCIR(r, g, b);
249
250             RGB_IN(r, g, b, p + BPP);
251             r1 += r;
252             g1 += g;
253             b1 += b;
254             lum[1] = RGB_TO_Y_CCIR(r, g, b);
255
256             cb[0] = RGB_TO_U_CCIR(r1, g1, b1, 2);
257             cr[0] = RGB_TO_V_CCIR(r1, g1, b1, 2);
258
259
260             cb++;
261             cr++;
262             p += -wrap3 + 2 * BPP;
263             lum += -wrap + 2;
264         }
265         if (w) {
266             RGB_IN(r, g, b, p);
267             r1 = r;
268             g1 = g;
269             b1 = b;
270             lum[0] = RGB_TO_Y_CCIR(r, g, b);
271             p += wrap3;
272             lum += wrap;
273             RGB_IN(r, g, b, p);
274             r1 += r;
275             g1 += g;
276             b1 += b;
277             lum[0] = RGB_TO_Y_CCIR(r, g, b);
278             cb[0] = RGB_TO_U_CCIR(r1, g1, b1, 1);
279             cr[0] = RGB_TO_V_CCIR(r1, g1, b1, 1);
280             cb++;
281             cr++;
282             p += -wrap3 + BPP;
283             lum += -wrap + 1;
284         }
285         p += wrap3 + (wrap3 - width * BPP);
286         lum += wrap + (wrap - width);
287         cb += dst->linesize[1] - width2;
288         cr += dst->linesize[2] - width2;
289     }
290     /* handle odd height */
291     if (height) {
292         for(w = width; w >= 2; w -= 2) {
293             RGB_IN(r, g, b, p);
294             r1 = r;
295             g1 = g;
296             b1 = b;
297             lum[0] = RGB_TO_Y_CCIR(r, g, b);
298
299             RGB_IN(r, g, b, p + BPP);
300             r1 += r;
301             g1 += g;
302             b1 += b;
303             lum[1] = RGB_TO_Y_CCIR(r, g, b);
304             cb[0] = RGB_TO_U_CCIR(r1, g1, b1, 1);
305             cr[0] = RGB_TO_V_CCIR(r1, g1, b1, 1);
306             cb++;
307             cr++;
308             p += 2 * BPP;
309            lum += 2;
310         }
311         if (w) {
312             RGB_IN(r, g, b, p);
313             lum[0] = RGB_TO_Y_CCIR(r, g, b);
314             cb[0] = RGB_TO_U_CCIR(r, g, b, 0);
315             cr[0] = RGB_TO_V_CCIR(r, g, b, 0);
316         }
317     }
318 }
319
320 static void glue(RGB_NAME, _to_gray)(AVPicture *dst, const AVPicture *src,
321                                      int width, int height)
322 {
323     const unsigned char *p;
324     unsigned char *q;
325     int r, g, b, dst_wrap, src_wrap;
326     int x, y;
327
328     p = src->data[0];
329     src_wrap = src->linesize[0] - BPP * width;
330
331     q = dst->data[0];
332     dst_wrap = dst->linesize[0] - width;
333
334     for(y=0;y<height;y++) {
335         for(x=0;x<width;x++) {
336             RGB_IN(r, g, b, p);
337             q[0] = RGB_TO_Y(r, g, b);
338             q++;
339             p += BPP;
340         }
341         p += src_wrap;
342         q += dst_wrap;
343     }
344 }
345
346 static void glue(gray_to_, RGB_NAME)(AVPicture *dst, const AVPicture *src,
347                                      int width, int height)
348 {
349     const unsigned char *p;
350     unsigned char *q;
351     int r, dst_wrap, src_wrap;
352     int x, y;
353
354     p = src->data[0];
355     src_wrap = src->linesize[0] - width;
356
357     q = dst->data[0];
358     dst_wrap = dst->linesize[0] - BPP * width;
359
360     for(y=0;y<height;y++) {
361         for(x=0;x<width;x++) {
362             r = p[0];
363             RGB_OUT(q, r, r, r);
364             q += BPP;
365             p ++;
366         }
367         p += src_wrap;
368         q += dst_wrap;
369     }
370 }
371
372 static void glue(pal8_to_, RGB_NAME)(AVPicture *dst, const AVPicture *src,
373                                      int width, int height)
374 {
375     const unsigned char *p;
376     unsigned char *q;
377     int r, g, b, dst_wrap, src_wrap;
378     int x, y;
379     uint32_t v;
380     const uint32_t *palette;
381
382     p = src->data[0];
383     src_wrap = src->linesize[0] - width;
384     palette = (uint32_t *)src->data[1];
385
386     q = dst->data[0];
387     dst_wrap = dst->linesize[0] - BPP * width;
388
389     for(y=0;y<height;y++) {
390         for(x=0;x<width;x++) {
391             v = palette[p[0]];
392             r = (v >> 16) & 0xff;
393             g = (v >> 8) & 0xff;
394             b = (v) & 0xff;
395 #ifdef RGBA_OUT
396             {
397                 int a;
398                 a = (v >> 24) & 0xff;
399                 RGBA_OUT(q, r, g, b, a);
400             }
401 #else
402             RGB_OUT(q, r, g, b);
403 #endif
404             q += BPP;
405             p ++;
406         }
407         p += src_wrap;
408         q += dst_wrap;
409     }
410 }
411
412 #if !defined(FMT_RGBA32) && defined(RGBA_OUT)
413 /* alpha support */
414
415 static void glue(rgba32_to_, RGB_NAME)(AVPicture *dst, const AVPicture *src,
416                                       int width, int height)
417 {
418     const uint8_t *s;
419     uint8_t *d;
420     int src_wrap, dst_wrap, j, y;
421     unsigned int v, r, g, b, a;
422
423     s = src->data[0];
424     src_wrap = src->linesize[0] - width * 4;
425
426     d = dst->data[0];
427     dst_wrap = dst->linesize[0] - width * BPP;
428
429     for(y=0;y<height;y++) {
430         for(j = 0;j < width; j++) {
431             v = ((const uint32_t *)(s))[0];
432             a = (v >> 24) & 0xff;
433             r = (v >> 16) & 0xff;
434             g = (v >> 8) & 0xff;
435             b = v & 0xff;
436             RGBA_OUT(d, r, g, b, a);
437             s += 4;
438             d += BPP;
439         }
440         s += src_wrap;
441         d += dst_wrap;
442     }
443 }
444
445 static void glue(RGB_NAME, _to_rgba32)(AVPicture *dst, const AVPicture *src,
446                                        int width, int height)
447 {
448     const uint8_t *s;
449     uint8_t *d;
450     int src_wrap, dst_wrap, j, y;
451     unsigned int r, g, b, a;
452
453     s = src->data[0];
454     src_wrap = src->linesize[0] - width * BPP;
455
456     d = dst->data[0];
457     dst_wrap = dst->linesize[0] - width * 4;
458
459     for(y=0;y<height;y++) {
460         for(j = 0;j < width; j++) {
461             RGBA_IN(r, g, b, a, s);
462             ((uint32_t *)(d))[0] = (a << 24) | (r << 16) | (g << 8) | b;
463             d += 4;
464             s += BPP;
465         }
466         s += src_wrap;
467         d += dst_wrap;
468     }
469 }
470 #endif /* !defined(FMT_RGBA32) && defined(RGBA_OUT) */
471
472 #if defined(FMT_RGBA32)
473
474 #if !defined(rgba32_fcts_done)
475 #define rgba32_fcts_done
476
477 static void ayuv4444_to_rgba32(AVPicture *dst, const AVPicture *src,
478                              int width, int height)
479 {
480     uint8_t *s, *d, *d1, *s1;
481     int w, y, cb, cr, r_add, g_add, b_add;
482     uint8_t *cm = cropTbl + MAX_NEG_CROP;
483     unsigned int r, g, b, a;
484
485     d = dst->data[0];
486     s = src->data[0];
487     for(;height > 0; height --) {
488         d1 = d;
489         s1 = s;
490         for(w = width; w > 0; w--) {
491             a = s1[0];
492             YUV_TO_RGB1_CCIR(s1[2], s1[3]);
493
494             YUV_TO_RGB2_CCIR(r, g, b, s1[1]);
495             RGBA_OUT(d1, r, g, b, a);
496             d1 += BPP;
497             s1 += 4;
498         }
499         d += dst->linesize[0];
500         s += src->linesize[0];
501     }
502 }
503
504 static void rgba32_to_ayuv4444(AVPicture *dst, const AVPicture *src,
505                              int width, int height)
506 {
507     int src_wrap, dst_wrap, x, y;
508     int r, g, b, a;
509     uint8_t *d;
510     const uint8_t *p;
511
512     src_wrap = src->linesize[0] - width * BPP;
513     dst_wrap = dst->linesize[0] - width * 4;
514     d = dst->data[0];
515     p = src->data[0];
516     for(y=0;y<height;y++) {
517         for(x=0;x<width;x++) {
518             RGBA_IN(r, g, b, a, p);
519             d[0] = a;
520             d[1] = RGB_TO_Y_CCIR(r, g, b);
521             d[2] = RGB_TO_U_CCIR(r, g, b, 0);
522             d[3] = RGB_TO_V_CCIR(r, g, b, 0);
523             p += BPP;
524             d += 4;
525         }
526         p += src_wrap;
527         d += dst_wrap;
528     }
529 }
530
531 #endif /* !defined(rgba32_fcts_done) */
532
533 #endif /* defined(FMT_RGBA32) */
534
535 #if defined(FMT_BGRA32)
536 #if !defined(bgra32_fcts_done)
537 #define bgra32_fcts_done
538
539 static void bgra32_to_ayuv4444(AVPicture *dst, const AVPicture *src,
540                                int width, int height)
541 {
542   int src_wrap, dst_wrap, x, y;
543   int r, g, b, a;
544   uint8_t *d;
545   const uint8_t *p;
546   
547   src_wrap = src->linesize[0] - width * BPP;
548   dst_wrap = dst->linesize[0] - width * 4;
549   d = dst->data[0];
550   p = src->data[0];
551   for(y=0;y<height;y++) {
552     for(x=0;x<width;x++) {
553       RGBA_IN(r, g, b, a, p);
554       d[0] = a;
555       d[1] = RGB_TO_Y_CCIR(r, g, b);
556       d[2] = RGB_TO_U_CCIR(r, g, b, 0);
557       d[3] = RGB_TO_V_CCIR(r, g, b, 0);
558       p += BPP;
559       d += 4;
560     }
561     p += src_wrap;
562     d += dst_wrap;
563   }
564 }
565
566 #endif /* !defined(bgra32_fcts_done) */
567
568 #endif /* defined(FMT_BGRA32) */
569
570 #ifndef FMT_RGB24
571
572 static void glue(rgb24_to_, RGB_NAME)(AVPicture *dst, const AVPicture *src,
573                                       int width, int height)
574 {
575     const uint8_t *s;
576     uint8_t *d;
577     int src_wrap, dst_wrap, j, y;
578     unsigned int r, g, b;
579
580     s = src->data[0];
581     src_wrap = src->linesize[0] - width * 3;
582
583     d = dst->data[0];
584     dst_wrap = dst->linesize[0] - width * BPP;
585
586     for(y=0;y<height;y++) {
587         for(j = 0;j < width; j++) {
588             r = s[0];
589             g = s[1];
590             b = s[2];
591             RGB_OUT(d, r, g, b);
592             s += 3;
593             d += BPP;
594         }
595         s += src_wrap;
596         d += dst_wrap;
597     }
598 }
599
600 static void glue(RGB_NAME, _to_rgb24)(AVPicture *dst, const AVPicture *src,
601                                       int width, int height)
602 {
603     const uint8_t *s;
604     uint8_t *d;
605     int src_wrap, dst_wrap, j, y;
606     unsigned int r, g , b;
607
608     s = src->data[0];
609     src_wrap = src->linesize[0] - width * BPP;
610
611     d = dst->data[0];
612     dst_wrap = dst->linesize[0] - width * 3;
613
614     for(y=0;y<height;y++) {
615         for(j = 0;j < width; j++) {
616             RGB_IN(r, g, b, s)
617             d[0] = r;
618             d[1] = g;
619             d[2] = b;
620             d += 3;
621             s += BPP;
622         }
623         s += src_wrap;
624         d += dst_wrap;
625     }
626 }
627
628 #endif /* !FMT_RGB24 */
629
630 #ifdef FMT_RGB24
631
632 static void yuv444p_to_rgb24(AVPicture *dst, const AVPicture *src,
633                              int width, int height)
634 {
635     const uint8_t *y1_ptr, *cb_ptr, *cr_ptr;
636     uint8_t *d, *d1;
637     int w, y, cb, cr, r_add, g_add, b_add;
638     uint8_t *cm = cropTbl + MAX_NEG_CROP;
639     unsigned int r, g, b;
640
641     d = dst->data[0];
642     y1_ptr = src->data[0];
643     cb_ptr = src->data[1];
644     cr_ptr = src->data[2];
645     for(;height > 0; height --) {
646         d1 = d;
647         for(w = width; w > 0; w--) {
648             YUV_TO_RGB1_CCIR(cb_ptr[0], cr_ptr[0]);
649
650             YUV_TO_RGB2_CCIR(r, g, b, y1_ptr[0]);
651             RGB_OUT(d1, r, g, b);
652             d1 += BPP;
653
654             y1_ptr++;
655             cb_ptr++;
656             cr_ptr++;
657         }
658         d += dst->linesize[0];
659         y1_ptr += src->linesize[0] - width;
660         cb_ptr += src->linesize[1] - width;
661         cr_ptr += src->linesize[2] - width;
662     }
663 }
664
665 static void yuvj444p_to_rgb24(AVPicture *dst, const AVPicture *src,
666                               int width, int height)
667 {
668     const uint8_t *y1_ptr, *cb_ptr, *cr_ptr;
669     uint8_t *d, *d1;
670     int w, y, cb, cr, r_add, g_add, b_add;
671     uint8_t *cm = cropTbl + MAX_NEG_CROP;
672     unsigned int r, g, b;
673
674     d = dst->data[0];
675     y1_ptr = src->data[0];
676     cb_ptr = src->data[1];
677     cr_ptr = src->data[2];
678     for(;height > 0; height --) {
679         d1 = d;
680         for(w = width; w > 0; w--) {
681             YUV_TO_RGB1(cb_ptr[0], cr_ptr[0]);
682
683             YUV_TO_RGB2(r, g, b, y1_ptr[0]);
684             RGB_OUT(d1, r, g, b);
685             d1 += BPP;
686
687             y1_ptr++;
688             cb_ptr++;
689             cr_ptr++;
690         }
691         d += dst->linesize[0];
692         y1_ptr += src->linesize[0] - width;
693         cb_ptr += src->linesize[1] - width;
694         cr_ptr += src->linesize[2] - width;
695     }
696 }
697
698 static void rgb24_to_yuv444p(AVPicture *dst, const AVPicture *src,
699                              int width, int height)
700 {
701     int src_wrap, x, y;
702     int r, g, b;
703     uint8_t *lum, *cb, *cr;
704     const uint8_t *p;
705
706     lum = dst->data[0];
707     cb = dst->data[1];
708     cr = dst->data[2];
709
710     src_wrap = src->linesize[0] - width * BPP;
711     p = src->data[0];
712     for(y=0;y<height;y++) {
713         for(x=0;x<width;x++) {
714             RGB_IN(r, g, b, p);
715             lum[0] = RGB_TO_Y_CCIR(r, g, b);
716             cb[0] = RGB_TO_U_CCIR(r, g, b, 0);
717             cr[0] = RGB_TO_V_CCIR(r, g, b, 0);
718             p += BPP;
719             cb++;
720             cr++;
721             lum++;
722         }
723         p += src_wrap;
724         lum += dst->linesize[0] - width;
725         cb += dst->linesize[1] - width;
726         cr += dst->linesize[2] - width;
727     }
728 }
729
730 static void rgb24_to_yuvj420p(AVPicture *dst, const AVPicture *src,
731                               int width, int height)
732 {
733     int wrap, wrap3, width2;
734     int r, g, b, r1, g1, b1, w;
735     uint8_t *lum, *cb, *cr;
736     const uint8_t *p;
737
738     lum = dst->data[0];
739     cb = dst->data[1];
740     cr = dst->data[2];
741
742     width2 = (width + 1) >> 1;
743     wrap = dst->linesize[0];
744     wrap3 = src->linesize[0];
745     p = src->data[0];
746     for(;height>=2;height -= 2) {
747         for(w = width; w >= 2; w -= 2) {
748             RGB_IN(r, g, b, p);
749             r1 = r;
750             g1 = g;
751             b1 = b;
752             lum[0] = RGB_TO_Y(r, g, b);
753
754             RGB_IN(r, g, b, p + BPP);
755             r1 += r;
756             g1 += g;
757             b1 += b;
758             lum[1] = RGB_TO_Y(r, g, b);
759             p += wrap3;
760             lum += wrap;
761
762             RGB_IN(r, g, b, p);
763             r1 += r;
764             g1 += g;
765             b1 += b;
766             lum[0] = RGB_TO_Y(r, g, b);
767
768             RGB_IN(r, g, b, p + BPP);
769             r1 += r;
770             g1 += g;
771             b1 += b;
772             lum[1] = RGB_TO_Y(r, g, b);
773
774             cb[0] = RGB_TO_U(r1, g1, b1, 2);
775             cr[0] = RGB_TO_V(r1, g1, b1, 2);
776
777             cb++;
778             cr++;
779             p += -wrap3 + 2 * BPP;
780             lum += -wrap + 2;
781         }
782         if (w) {
783             RGB_IN(r, g, b, p);
784             r1 = r;
785             g1 = g;
786             b1 = b;
787             lum[0] = RGB_TO_Y(r, g, b);
788             p += wrap3;
789             lum += wrap;
790             RGB_IN(r, g, b, p);
791             r1 += r;
792             g1 += g;
793             b1 += b;
794             lum[0] = RGB_TO_Y(r, g, b);
795             cb[0] = RGB_TO_U(r1, g1, b1, 1);
796             cr[0] = RGB_TO_V(r1, g1, b1, 1);
797             cb++;
798             cr++;
799             p += -wrap3 + BPP;
800             lum += -wrap + 1;
801         }
802         p += wrap3 + (wrap3 - width * BPP);
803         lum += wrap + (wrap - width);
804         cb += dst->linesize[1] - width2;
805         cr += dst->linesize[2] - width2;
806     }
807     /* handle odd height */
808     if (height) {
809         for(w = width; w >= 2; w -= 2) {
810             RGB_IN(r, g, b, p);
811             r1 = r;
812             g1 = g;
813             b1 = b;
814             lum[0] = RGB_TO_Y(r, g, b);
815
816             RGB_IN(r, g, b, p + BPP);
817             r1 += r;
818             g1 += g;
819             b1 += b;
820             lum[1] = RGB_TO_Y(r, g, b);
821             cb[0] = RGB_TO_U(r1, g1, b1, 1);
822             cr[0] = RGB_TO_V(r1, g1, b1, 1);
823             cb++;
824             cr++;
825             p += 2 * BPP;
826            lum += 2;
827         }
828         if (w) {
829             RGB_IN(r, g, b, p);
830             lum[0] = RGB_TO_Y(r, g, b);
831             cb[0] = RGB_TO_U(r, g, b, 0);
832             cr[0] = RGB_TO_V(r, g, b, 0);
833         }
834     }
835 }
836
837 static void rgb24_to_yuvj444p(AVPicture *dst, const AVPicture *src,
838                               int width, int height)
839 {
840     int src_wrap, x, y;
841     int r, g, b;
842     uint8_t *lum, *cb, *cr;
843     const uint8_t *p;
844
845     lum = dst->data[0];
846     cb = dst->data[1];
847     cr = dst->data[2];
848
849     src_wrap = src->linesize[0] - width * BPP;
850     p = src->data[0];
851     for(y=0;y<height;y++) {
852         for(x=0;x<width;x++) {
853             RGB_IN(r, g, b, p);
854             lum[0] = RGB_TO_Y(r, g, b);
855             cb[0] = RGB_TO_U(r, g, b, 0);
856             cr[0] = RGB_TO_V(r, g, b, 0);
857             p += BPP;
858             cb++;
859             cr++;
860             lum++;
861         }
862         p += src_wrap;
863         lum += dst->linesize[0] - width;
864         cb += dst->linesize[1] - width;
865         cr += dst->linesize[2] - width;
866     }
867 }
868
869 static void ayuv4444_to_rgb24(AVPicture *dst, const AVPicture *src,
870                              int width, int height)
871 {
872     uint8_t *s, *d, *d1, *s1;
873     int w, y, cb, cr, r_add, g_add, b_add;
874     uint8_t *cm = cropTbl + MAX_NEG_CROP;
875     unsigned int r, g, b;
876
877     d = dst->data[0];
878     s = src->data[0];
879     for(;height > 0; height --) {
880         d1 = d;
881         s1 = s;
882         for(w = width; w > 0; w--) {
883             YUV_TO_RGB1_CCIR(s1[2], s1[3]);
884
885             YUV_TO_RGB2_CCIR(r, g, b, s1[1]);
886             RGB_OUT(d1, r, g, b);
887             d1 += BPP;
888             s1 += 4;
889         }
890         d += dst->linesize[0];
891         s += src->linesize[0];
892     }
893 }
894
895 static void rgb24_to_ayuv4444(AVPicture *dst, const AVPicture *src,
896                              int width, int height)
897 {
898     int src_wrap, dst_wrap, x, y;
899     int r, g, b;
900     uint8_t *d;
901     const uint8_t *p;
902
903     src_wrap = src->linesize[0] - width * BPP;
904     dst_wrap = dst->linesize[0] - width * 4;
905     d = dst->data[0];
906     p = src->data[0];
907     for(y=0;y<height;y++) {
908         for(x=0;x<width;x++) {
909             RGB_IN(r, g, b, p);
910             d[0] = 0xff;
911             d[1] = RGB_TO_Y_CCIR(r, g, b);
912             d[2] = RGB_TO_U_CCIR(r, g, b, 0);
913             d[3] = RGB_TO_V_CCIR(r, g, b, 0);
914             p += BPP;
915             d += 4;
916         }
917         p += src_wrap;
918         d += dst_wrap;
919     }
920 }
921 #endif /* FMT_RGB24 */
922
923 #if defined(FMT_RGB24) || defined(FMT_RGBA32)
924
925 static void glue(RGB_NAME, _to_pal8)(AVPicture *dst, const AVPicture *src,
926                                      int width, int height)
927 {
928     const unsigned char *p;
929     unsigned char *q;
930     int dst_wrap, src_wrap;
931     int x, y, has_alpha;
932     unsigned int r, g, b;
933
934     p = src->data[0];
935     src_wrap = src->linesize[0] - BPP * width;
936
937     q = dst->data[0];
938     dst_wrap = dst->linesize[0] - width;
939     has_alpha = 0;
940     
941     for(y=0;y<height;y++) {
942         for(x=0;x<width;x++) {
943 #ifdef RGBA_IN
944             {
945                 unsigned int a;
946                 RGBA_IN(r, g, b, a, p);
947                 /* crude approximation for alpha ! */
948                 if (a < 0x80) {
949                     has_alpha = 1;
950                     q[0] = TRANSP_INDEX;
951                 } else {
952                     q[0] = gif_clut_index(r, g, b);
953                 }
954             }
955 #else
956             RGB_IN(r, g, b, p);
957             q[0] = gif_clut_index(r, g, b);
958 #endif
959             q++;
960             p += BPP;
961         }
962         p += src_wrap;
963         q += dst_wrap;
964     }
965
966     build_rgb_palette(dst->data[1], has_alpha);
967 }
968
969 #endif /* defined(FMT_RGB24) || defined(FMT_RGBA32) */
970         
971 #ifdef RGBA_IN
972
973 static int glue(get_alpha_info_, RGB_NAME)(const AVPicture *src,
974                                            int width, int height)
975 {
976     const unsigned char *p;
977     int src_wrap, ret, x, y;
978     unsigned int r, g, b, a;
979
980     p = src->data[0];
981     src_wrap = src->linesize[0] - BPP * width;
982     ret = 0;
983     for(y=0;y<height;y++) {
984         for(x=0;x<width;x++) {
985             RGBA_IN(r, g, b, a, p);
986             if (a == 0x00) {
987                 ret |= FF_ALPHA_TRANSP;
988             } else if (a != 0xff) {
989                 ret |= FF_ALPHA_SEMI_TRANSP;
990             }
991             p += BPP;
992         }
993         p += src_wrap;
994     }
995     return ret;
996 }
997
998 #endif /* RGBA_IN */
999
1000 #undef RGB_IN
1001 #undef RGBA_IN
1002 #undef RGB_OUT
1003 #undef RGBA_OUT
1004 #undef BPP
1005 #undef RGB_NAME
1006 #undef FMT_RGB24
1007 #undef FMT_RGBA32