]> git.sesse.net Git - ffmpeg/blob - libavcodec/imgconvert.c
10l
[ffmpeg] / libavcodec / imgconvert.c
1 /*
2  * Misc 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 /**
21  * @file imgconvert.c
22  * Misc image convertion routines.
23  */
24
25 /* TODO:
26  * - write 'ffimg' program to test all the image related stuff
27  * - move all api to slice based system
28  * - integrate deinterlacing, postprocessing and scaling in the conversion process
29  */
30
31 #include "avcodec.h"
32 #include "dsputil.h"
33
34 #ifdef USE_FASTMEMCPY
35 #include "fastmemcpy.h"
36 #endif
37
38 #ifdef HAVE_MMX
39 #include "i386/mmx.h"
40 #endif
41
42 #define xglue(x, y) x ## y
43 #define glue(x, y) xglue(x, y)
44
45 #define FF_COLOR_RGB      0 /* RGB color space */
46 #define FF_COLOR_GRAY     1 /* gray color space */
47 #define FF_COLOR_YUV      2 /* YUV color space. 16 <= Y <= 235, 16 <= U, V <= 240 */
48 #define FF_COLOR_YUV_JPEG 3 /* YUV color space. 0 <= Y <= 255, 0 <= U, V <= 255 */
49
50 #define FF_PIXEL_PLANAR   0 /* each channel has one component in AVPicture */
51 #define FF_PIXEL_PACKED   1 /* only one components containing all the channels */
52 #define FF_PIXEL_PALETTE  2  /* one components containing indexes for a palette */
53
54 typedef struct PixFmtInfo {
55     const char *name;
56     uint8_t nb_channels;     /* number of channels (including alpha) */
57     uint8_t color_type;      /* color type (see FF_COLOR_xxx constants) */
58     uint8_t pixel_type;      /* pixel storage type (see FF_PIXEL_xxx constants) */
59     uint8_t is_alpha : 1;    /* true if alpha can be specified */
60     uint8_t x_chroma_shift;  /* X chroma subsampling factor is 2 ^ shift */
61     uint8_t y_chroma_shift;  /* Y chroma subsampling factor is 2 ^ shift */
62     uint8_t depth;           /* bit depth of the color components */
63 } PixFmtInfo;
64
65 /* this table gives more information about formats */
66 static PixFmtInfo pix_fmt_info[PIX_FMT_NB] = {
67     /* YUV formats */
68     [PIX_FMT_YUV420P] = {
69         .name = "yuv420p",
70         .nb_channels = 3,
71         .color_type = FF_COLOR_YUV,
72         .pixel_type = FF_PIXEL_PLANAR,
73         .depth = 8,
74         .x_chroma_shift = 1, .y_chroma_shift = 1, 
75     },
76     [PIX_FMT_YUV422P] = {
77         .name = "yuv422p",
78         .nb_channels = 3,
79         .color_type = FF_COLOR_YUV,
80         .pixel_type = FF_PIXEL_PLANAR,
81         .depth = 8,
82         .x_chroma_shift = 1, .y_chroma_shift = 0, 
83     },
84     [PIX_FMT_YUV444P] = {
85         .name = "yuv444p",
86         .nb_channels = 3,
87         .color_type = FF_COLOR_YUV,
88         .pixel_type = FF_PIXEL_PLANAR,
89         .depth = 8,
90         .x_chroma_shift = 0, .y_chroma_shift = 0, 
91     },
92     [PIX_FMT_YUV422] = {
93         .name = "yuv422",
94         .nb_channels = 1,
95         .color_type = FF_COLOR_YUV,
96         .pixel_type = FF_PIXEL_PACKED,
97         .depth = 8,
98         .x_chroma_shift = 1, .y_chroma_shift = 0,
99     },
100     [PIX_FMT_YUV410P] = {
101         .name = "yuv410p",
102         .nb_channels = 3,
103         .color_type = FF_COLOR_YUV,
104         .pixel_type = FF_PIXEL_PLANAR,
105         .depth = 8,
106         .x_chroma_shift = 2, .y_chroma_shift = 2,
107     },
108     [PIX_FMT_YUV411P] = {
109         .name = "yuv411p",
110         .nb_channels = 3,
111         .color_type = FF_COLOR_YUV,
112         .pixel_type = FF_PIXEL_PLANAR,
113         .depth = 8,
114         .x_chroma_shift = 2, .y_chroma_shift = 0,
115     },
116
117     /* JPEG YUV */
118     [PIX_FMT_YUVJ420P] = {
119         .name = "yuvj420p",
120         .nb_channels = 3,
121         .color_type = FF_COLOR_YUV_JPEG,
122         .pixel_type = FF_PIXEL_PLANAR,
123         .depth = 8,
124         .x_chroma_shift = 1, .y_chroma_shift = 1, 
125     },
126     [PIX_FMT_YUVJ422P] = {
127         .name = "yuvj422p",
128         .nb_channels = 3,
129         .color_type = FF_COLOR_YUV_JPEG,
130         .pixel_type = FF_PIXEL_PLANAR,
131         .depth = 8,
132         .x_chroma_shift = 1, .y_chroma_shift = 0, 
133     },
134     [PIX_FMT_YUVJ444P] = {
135         .name = "yuvj444p",
136         .nb_channels = 3,
137         .color_type = FF_COLOR_YUV_JPEG,
138         .pixel_type = FF_PIXEL_PLANAR,
139         .depth = 8,
140         .x_chroma_shift = 0, .y_chroma_shift = 0, 
141     },
142
143     /* RGB formats */
144     [PIX_FMT_RGB24] = {
145         .name = "rgb24",
146         .nb_channels = 3,
147         .color_type = FF_COLOR_RGB,
148         .pixel_type = FF_PIXEL_PACKED,
149         .depth = 8,
150     },
151     [PIX_FMT_BGR24] = {
152         .name = "bgr24",
153         .nb_channels = 3,
154         .color_type = FF_COLOR_RGB,
155         .pixel_type = FF_PIXEL_PACKED,
156         .depth = 8,
157     },
158     [PIX_FMT_RGBA32] = {
159         .name = "rgba32",
160         .nb_channels = 4, .is_alpha = 1,
161         .color_type = FF_COLOR_RGB,
162         .pixel_type = FF_PIXEL_PACKED,
163         .depth = 8,
164     },
165     [PIX_FMT_RGB565] = {
166         .name = "rgb565",
167         .nb_channels = 3,
168         .color_type = FF_COLOR_RGB,
169         .pixel_type = FF_PIXEL_PACKED,
170         .depth = 5,
171     },
172     [PIX_FMT_RGB555] = {
173         .name = "rgb555",
174         .nb_channels = 4, .is_alpha = 1,
175         .color_type = FF_COLOR_RGB,
176         .pixel_type = FF_PIXEL_PACKED,
177         .depth = 5,
178     },
179
180     /* gray / mono formats */
181     [PIX_FMT_GRAY8] = {
182         .name = "gray",
183         .nb_channels = 1,
184         .color_type = FF_COLOR_GRAY,
185         .pixel_type = FF_PIXEL_PLANAR,
186         .depth = 8,
187     },
188     [PIX_FMT_MONOWHITE] = {
189         .name = "monow",
190         .nb_channels = 1,
191         .color_type = FF_COLOR_GRAY,
192         .pixel_type = FF_PIXEL_PLANAR,
193         .depth = 1,
194     },
195     [PIX_FMT_MONOBLACK] = {
196         .name = "monob",
197         .nb_channels = 1,
198         .color_type = FF_COLOR_GRAY,
199         .pixel_type = FF_PIXEL_PLANAR,
200         .depth = 1,
201     },
202
203     /* paletted formats */
204     [PIX_FMT_PAL8] = {
205         .name = "pal8",
206         .nb_channels = 4, .is_alpha = 1,
207         .color_type = FF_COLOR_RGB,
208         .pixel_type = FF_PIXEL_PALETTE,
209         .depth = 8,
210     },
211 };
212
213 void avcodec_get_chroma_sub_sample(int pix_fmt, int *h_shift, int *v_shift)
214 {
215     *h_shift = pix_fmt_info[pix_fmt].x_chroma_shift;
216     *v_shift = pix_fmt_info[pix_fmt].y_chroma_shift;
217 }
218
219 const char *avcodec_get_pix_fmt_name(int pix_fmt)
220 {
221     if (pix_fmt < 0 || pix_fmt >= PIX_FMT_NB)
222         return "???";
223     else
224         return pix_fmt_info[pix_fmt].name;
225 }
226
227 /* Picture field are filled with 'ptr' addresses. Also return size */
228 int avpicture_fill(AVPicture *picture, uint8_t *ptr,
229                    int pix_fmt, int width, int height)
230 {
231     int size, w2, h2, size2;
232     PixFmtInfo *pinfo;
233     
234     pinfo = &pix_fmt_info[pix_fmt];
235     size = width * height;
236     switch(pix_fmt) {
237     case PIX_FMT_YUV420P:
238     case PIX_FMT_YUV422P:
239     case PIX_FMT_YUV444P:
240     case PIX_FMT_YUV410P:
241     case PIX_FMT_YUV411P:
242     case PIX_FMT_YUVJ420P:
243     case PIX_FMT_YUVJ422P:
244     case PIX_FMT_YUVJ444P:
245         w2 = (width + (1 << pinfo->x_chroma_shift) - 1) >> pinfo->x_chroma_shift;
246         h2 = (height + (1 << pinfo->y_chroma_shift) - 1) >> pinfo->y_chroma_shift;
247         size2 = w2 * h2;
248         picture->data[0] = ptr;
249         picture->data[1] = picture->data[0] + size;
250         picture->data[2] = picture->data[1] + size2;
251         picture->linesize[0] = width;
252         picture->linesize[1] = w2;
253         picture->linesize[2] = w2;
254         return size + 2 * size2;
255     case PIX_FMT_RGB24:
256     case PIX_FMT_BGR24:
257         picture->data[0] = ptr;
258         picture->data[1] = NULL;
259         picture->data[2] = NULL;
260         picture->linesize[0] = width * 3;
261         return size * 3;
262     case PIX_FMT_RGBA32:
263         picture->data[0] = ptr;
264         picture->data[1] = NULL;
265         picture->data[2] = NULL;
266         picture->linesize[0] = width * 4;
267         return size * 4;
268     case PIX_FMT_RGB555:
269     case PIX_FMT_RGB565:
270     case PIX_FMT_YUV422:
271         picture->data[0] = ptr;
272         picture->data[1] = NULL;
273         picture->data[2] = NULL;
274         picture->linesize[0] = width * 2;
275         return size * 2;
276     case PIX_FMT_GRAY8:
277         picture->data[0] = ptr;
278         picture->data[1] = NULL;
279         picture->data[2] = NULL;
280         picture->linesize[0] = width;
281         return size;
282     case PIX_FMT_MONOWHITE:
283     case PIX_FMT_MONOBLACK:
284         picture->data[0] = ptr;
285         picture->data[1] = NULL;
286         picture->data[2] = NULL;
287         picture->linesize[0] = (width + 7) >> 3;
288         return picture->linesize[0] * height;
289     case PIX_FMT_PAL8:
290         size2 = (size + 3) & ~3;
291         picture->data[0] = ptr;
292         picture->data[1] = ptr + size2; /* palette is stored here as 256 32 bit words */
293         picture->data[2] = NULL;
294         picture->linesize[0] = width;
295         picture->linesize[1] = 4;
296         return size2 + 256 * 4;
297     default:
298         picture->data[0] = NULL;
299         picture->data[1] = NULL;
300         picture->data[2] = NULL;
301         picture->data[3] = NULL;
302         return -1;
303     }
304 }
305
306 int avpicture_get_size(int pix_fmt, int width, int height)
307 {
308     AVPicture dummy_pict;
309     return avpicture_fill(&dummy_pict, NULL, pix_fmt, width, height);
310 }
311
312 /**
313  * compute the loss when converting from a pixel format to another 
314  */
315 int avcodec_get_pix_fmt_loss(int dst_pix_fmt, int src_pix_fmt,
316                              int has_alpha)
317 {
318     const PixFmtInfo *pf, *ps;
319     int loss;
320
321     ps = &pix_fmt_info[src_pix_fmt];
322     pf = &pix_fmt_info[dst_pix_fmt];
323
324     /* compute loss */
325     loss = 0;
326     pf = &pix_fmt_info[dst_pix_fmt];
327     if (pf->depth < ps->depth ||
328         (dst_pix_fmt == PIX_FMT_RGB555 && src_pix_fmt == PIX_FMT_RGB565))
329         loss |= FF_LOSS_DEPTH;
330     if (pf->x_chroma_shift > ps->x_chroma_shift ||
331         pf->y_chroma_shift > ps->y_chroma_shift)
332         loss |= FF_LOSS_RESOLUTION;
333     switch(pf->color_type) {
334     case FF_COLOR_RGB:
335         if (ps->color_type != FF_COLOR_RGB &&
336             ps->color_type != FF_COLOR_GRAY)
337             loss |= FF_LOSS_COLORSPACE;
338         break;
339     case FF_COLOR_GRAY:
340         if (ps->color_type != FF_COLOR_GRAY)
341             loss |= FF_LOSS_COLORSPACE;
342         break;
343     case FF_COLOR_YUV:
344         if (ps->color_type != FF_COLOR_YUV)
345             loss |= FF_LOSS_COLORSPACE;
346         break;
347     case FF_COLOR_YUV_JPEG:
348         if (ps->color_type != FF_COLOR_YUV_JPEG &&
349             ps->color_type != FF_COLOR_YUV && 
350             ps->color_type != FF_COLOR_GRAY)
351             loss |= FF_LOSS_COLORSPACE;
352         break;
353     default:
354         /* fail safe test */
355         if (ps->color_type != pf->color_type)
356             loss |= FF_LOSS_COLORSPACE;
357         break;
358     }
359     if (pf->color_type == FF_COLOR_GRAY &&
360         ps->color_type != FF_COLOR_GRAY)
361         loss |= FF_LOSS_CHROMA;
362     if (!pf->is_alpha && (ps->is_alpha && has_alpha))
363         loss |= FF_LOSS_ALPHA;
364     if (pf->pixel_type == FF_PIXEL_PALETTE && 
365         (ps->pixel_type != FF_PIXEL_PALETTE && ps->color_type != FF_COLOR_GRAY))
366         loss |= FF_LOSS_COLORQUANT;
367     return loss;
368 }
369
370 static int avg_bits_per_pixel(int pix_fmt)
371 {
372     int bits;
373     const PixFmtInfo *pf;
374
375     pf = &pix_fmt_info[pix_fmt];
376     switch(pf->pixel_type) {
377     case FF_PIXEL_PACKED:
378         switch(pix_fmt) {
379         case PIX_FMT_YUV422:
380         case PIX_FMT_RGB565:
381         case PIX_FMT_RGB555:
382             bits = 16;
383             break;
384         default:
385             bits = pf->depth * pf->nb_channels;
386             break;
387         }
388         break;
389     case FF_PIXEL_PLANAR:
390         if (pf->x_chroma_shift == 0 && pf->y_chroma_shift == 0) {
391             bits = pf->depth * pf->nb_channels;
392         } else {
393             bits = pf->depth + ((2 * pf->depth) >> 
394                                 (pf->x_chroma_shift + pf->y_chroma_shift));
395         }
396         break;
397     case FF_PIXEL_PALETTE:
398         bits = 8;
399         break;
400     default:
401         bits = -1;
402         break;
403     }
404     return bits;
405 }
406
407 static int avcodec_find_best_pix_fmt1(int pix_fmt_mask, 
408                                       int src_pix_fmt,
409                                       int has_alpha,
410                                       int loss_mask)
411 {
412     int dist, i, loss, min_dist, dst_pix_fmt;
413
414     /* find exact color match with smallest size */
415     dst_pix_fmt = -1;
416     min_dist = 0x7fffffff;
417     for(i = 0;i < PIX_FMT_NB; i++) {
418         if (pix_fmt_mask & (1 << i)) {
419             loss = avcodec_get_pix_fmt_loss(i, src_pix_fmt, has_alpha) & loss_mask;
420             if (loss == 0) {
421                 dist = avg_bits_per_pixel(i);
422                 if (dist < min_dist) {
423                     min_dist = dist;
424                     dst_pix_fmt = i;
425                 }
426             }
427         }
428     }
429     return dst_pix_fmt;
430 }
431
432 /** 
433  * find best pixel format to convert to. Return -1 if none found 
434  */
435 int avcodec_find_best_pix_fmt(int pix_fmt_mask, int src_pix_fmt,
436                               int has_alpha, int *loss_ptr)
437 {
438     int dst_pix_fmt, loss_mask, i;
439     static const int loss_mask_order[] = {
440         ~0, /* no loss first */
441         ~FF_LOSS_ALPHA,
442         ~FF_LOSS_RESOLUTION,
443         ~(FF_LOSS_COLORSPACE | FF_LOSS_RESOLUTION),
444         ~FF_LOSS_COLORQUANT,
445         ~FF_LOSS_DEPTH,
446         0,
447     };
448
449     /* try with successive loss */
450     i = 0;
451     for(;;) {
452         loss_mask = loss_mask_order[i++];
453         dst_pix_fmt = avcodec_find_best_pix_fmt1(pix_fmt_mask, src_pix_fmt, 
454                                                  has_alpha, loss_mask);
455         if (dst_pix_fmt >= 0)
456             goto found;
457         if (loss_mask == 0)
458             break;
459     }
460     return -1;
461  found:
462     if (loss_ptr)
463         *loss_ptr = avcodec_get_pix_fmt_loss(dst_pix_fmt, src_pix_fmt, has_alpha);
464     return dst_pix_fmt;
465 }
466
467 static void img_copy_plane(uint8_t *dst, int dst_wrap, 
468                            const uint8_t *src, int src_wrap,
469                            int width, int height)
470 {
471     for(;height > 0; height--) {
472         memcpy(dst, src, width);
473         dst += dst_wrap;
474         src += src_wrap;
475     }
476 }
477
478 /**
479  * Copy image 'src' to 'dst'.
480  */
481 void img_copy(AVPicture *dst, AVPicture *src,
482               int pix_fmt, int width, int height)
483 {
484     int bwidth, bits, i;
485     PixFmtInfo *pf = &pix_fmt_info[pix_fmt];
486     
487     pf = &pix_fmt_info[pix_fmt];
488     switch(pf->pixel_type) {
489     case FF_PIXEL_PACKED:
490         switch(pix_fmt) {
491         case PIX_FMT_YUV422:
492         case PIX_FMT_RGB565:
493         case PIX_FMT_RGB555:
494             bits = 16;
495             break;
496         default:
497             bits = pf->depth * pf->nb_channels;
498             break;
499         }
500         bwidth = (width * bits + 7) >> 3;
501         img_copy_plane(dst->data[0], dst->linesize[0],
502                        src->data[0], src->linesize[0],
503                        bwidth, height);
504         break;
505     case FF_PIXEL_PLANAR:
506         for(i = 0; i < pf->nb_channels; i++) {
507             int w, h;
508             w = width;
509             h = height;
510             if (i == 1 || i == 2) {
511                 w >>= pf->x_chroma_shift;
512                 h >>= pf->y_chroma_shift;
513             }
514             bwidth = (w * pf->depth + 7) >> 3;
515             img_copy_plane(dst->data[i], dst->linesize[i],
516                            src->data[i], src->linesize[i],
517                            bwidth, h);
518         }
519         break;
520     case FF_PIXEL_PALETTE:
521         img_copy_plane(dst->data[0], dst->linesize[0],
522                        src->data[0], src->linesize[0],
523                        width, height);
524         /* copy the palette */
525         img_copy_plane(dst->data[1], dst->linesize[1],
526                        src->data[1], src->linesize[1],
527                        4, 256);
528         break;
529     }
530 }
531
532 /* XXX: totally non optimized */
533
534 static void yuv422_to_yuv420p(AVPicture *dst, AVPicture *src,
535                               int width, int height)
536 {
537     const uint8_t *p, *p1;
538     uint8_t *lum, *cr, *cb, *lum1, *cr1, *cb1;
539     int x;
540  
541     p1 = src->data[0];
542     lum1 = dst->data[0];
543     cb1 = dst->data[1];
544     cr1 = dst->data[2];
545
546     for(;height >= 2; height -= 2) {
547         p = p1;
548         lum = lum1;
549         cb = cb1;
550         cr = cr1;
551         for(x=0;x<width;x+=2) {
552             lum[0] = p[0];
553             cb[0] = p[1];
554             lum[1] = p[2];
555             cr[0] = p[3];
556             p += 4;
557             lum += 2;
558             cb++;
559             cr++;
560         }
561         p1 += src->linesize[0];
562         lum1 += dst->linesize[0];
563         p = p1;
564         lum = lum1;
565         for(x=0;x<width;x+=2) {
566             lum[0] = p[0];
567             lum[1] = p[2];
568             p += 4;
569             lum += 2;
570         }
571         p1 += src->linesize[0];
572         lum1 += dst->linesize[0];
573         cb1 += dst->linesize[1];
574         cr1 += dst->linesize[2];
575     }
576 }
577
578 static void yuv422_to_yuv422p(AVPicture *dst, AVPicture *src,
579                               int width, int height)
580 {
581     const uint8_t *p, *p1;
582     uint8_t *lum, *cr, *cb, *lum1, *cr1, *cb1;
583     int w;
584
585     p1 = src->data[0];
586     lum1 = dst->data[0];
587     cb1 = dst->data[1];
588     cr1 = dst->data[2];
589     for(;height > 0; height--) {
590         p = p1;
591         lum = lum1;
592         cb = cb1;
593         cr = cr1;
594         for(w = width; w >= 2; w -= 2) {
595             lum[0] = p[0];
596             cb[0] = p[1];
597             lum[1] = p[2];
598             cr[0] = p[3];
599             p += 4;
600             lum += 2;
601             cb++;
602             cr++;
603         }
604         p1 += src->linesize[0];
605         lum1 += dst->linesize[0];
606         cb1 += dst->linesize[1];
607         cr1 += dst->linesize[2];
608     }
609 }
610
611 static void yuv422p_to_yuv422(AVPicture *dst, AVPicture *src,
612                               int width, int height)
613 {
614     uint8_t *p, *p1;
615     const uint8_t *lum, *cr, *cb, *lum1, *cr1, *cb1;
616     int w;
617
618     p1 = dst->data[0];
619     lum1 = src->data[0];
620     cb1 = src->data[1];
621     cr1 = src->data[2];
622     for(;height > 0; height--) {
623         p = p1;
624         lum = lum1;
625         cb = cb1;
626         cr = cr1;
627         for(w = width; w >= 2; w -= 2) {
628             p[0] = lum[0];
629             p[1] = cb[0];
630             p[2] = lum[1];
631             p[3] = cr[0];
632             p += 4;
633             lum += 2;
634             cb++;
635             cr++;
636         }
637         p1 += dst->linesize[0];
638         lum1 += src->linesize[0];
639         cb1 += src->linesize[1];
640         cr1 += src->linesize[2];
641     }
642 }
643
644 #define SCALEBITS 10
645 #define ONE_HALF  (1 << (SCALEBITS - 1))
646 #define FIX(x)    ((int) ((x) * (1<<SCALEBITS) + 0.5))
647
648 #define YUV_TO_RGB1_CCIR(cb1, cr1)\
649 {\
650     cb = (cb1) - 128;\
651     cr = (cr1) - 128;\
652     r_add = FIX(1.40200*255.0/224.0) * cr + ONE_HALF;\
653     g_add = - FIX(0.34414*255.0/224.0) * cb - FIX(0.71414*255.0/224.0) * cr + \
654             ONE_HALF;\
655     b_add = FIX(1.77200*255.0/224.0) * cb + ONE_HALF;\
656 }
657
658 #define YUV_TO_RGB2_CCIR(r, g, b, y1)\
659 {\
660     y = ((y1) - 16) * FIX(255.0/219.0);\
661     r = cm[(y + r_add) >> SCALEBITS];\
662     g = cm[(y + g_add) >> SCALEBITS];\
663     b = cm[(y + b_add) >> SCALEBITS];\
664 }
665
666 #define YUV_TO_RGB1(cb1, cr1)\
667 {\
668     cb = (cb1) - 128;\
669     cr = (cr1) - 128;\
670     r_add = FIX(1.40200) * cr + ONE_HALF;\
671     g_add = - FIX(0.34414) * cb - FIX(0.71414) * cr + ONE_HALF;\
672     b_add = FIX(1.77200) * cb + ONE_HALF;\
673 }
674
675 #define YUV_TO_RGB2(r, g, b, y1)\
676 {\
677     y = (y1) << SCALEBITS;\
678     r = cm[(y + r_add) >> SCALEBITS];\
679     g = cm[(y + g_add) >> SCALEBITS];\
680     b = cm[(y + b_add) >> SCALEBITS];\
681 }
682
683 #define Y_CCIR_TO_JPEG(y)\
684  cm[((y) * FIX(255.0/219.0) + (ONE_HALF - 16 * FIX(255.0/219.0))) >> SCALEBITS]
685
686 #define Y_JPEG_TO_CCIR(y)\
687  (((y) * FIX(219.0/255.0) + (ONE_HALF + (16 << SCALEBITS))) >> SCALEBITS)
688
689 #define C_CCIR_TO_JPEG(y)\
690  cm[(((y) - 128) * FIX(127.0/112.0) + (ONE_HALF + (128 << SCALEBITS))) >> SCALEBITS]
691
692 /* NOTE: the clamp is really necessary! */
693 #define C_JPEG_TO_CCIR(y)\
694 ({\
695     int __y;\
696     __y = ((((y) - 128) * FIX(112.0/127.0) + (ONE_HALF + (128 << SCALEBITS))) >> SCALEBITS);\
697     if (__y < 16)\
698          __y = 16;\
699     __y;\
700 })
701
702 #define RGB_TO_Y(r, g, b) \
703 ((FIX(0.29900) * (r) + FIX(0.58700) * (g) + \
704   FIX(0.11400) * (b) + ONE_HALF) >> SCALEBITS)
705
706 #define RGB_TO_U(r1, g1, b1, shift)\
707 (((- FIX(0.16874) * r1 - FIX(0.33126) * g1 +         \
708      FIX(0.50000) * b1 + (ONE_HALF << shift) - 1) >> (SCALEBITS + shift)) + 128)
709
710 #define RGB_TO_V(r1, g1, b1, shift)\
711 (((FIX(0.50000) * r1 - FIX(0.41869) * g1 -           \
712    FIX(0.08131) * b1 + (ONE_HALF << shift) - 1) >> (SCALEBITS + shift)) + 128)
713
714 #define RGB_TO_Y_CCIR(r, g, b) \
715 ((FIX(0.29900*219.0/255.0) * (r) + FIX(0.58700*219.0/255.0) * (g) + \
716   FIX(0.11400*219.0/255.0) * (b) + (ONE_HALF + (16 << SCALEBITS))) >> SCALEBITS)
717
718 #define RGB_TO_U_CCIR(r1, g1, b1, shift)\
719 (((- FIX(0.16874*224.0/255.0) * r1 - FIX(0.33126*224.0/255.0) * g1 +         \
720      FIX(0.50000*224.0/255.0) * b1 + (ONE_HALF << shift) - 1) >> (SCALEBITS + shift)) + 128)
721
722 #define RGB_TO_V_CCIR(r1, g1, b1, shift)\
723 (((FIX(0.50000*224.0/255.0) * r1 - FIX(0.41869*224.0/255.0) * g1 -           \
724    FIX(0.08131*224.0/255.0) * b1 + (ONE_HALF << shift) - 1) >> (SCALEBITS + shift)) + 128)
725
726 static uint8_t y_ccir_to_jpeg[256];
727 static uint8_t y_jpeg_to_ccir[256];
728 static uint8_t c_ccir_to_jpeg[256];
729 static uint8_t c_jpeg_to_ccir[256];
730
731 /* init various conversion tables */
732 static void img_convert_init(void)
733 {
734     int i;
735     uint8_t *cm = cropTbl + MAX_NEG_CROP;
736
737     for(i = 0;i < 256; i++) {
738         y_ccir_to_jpeg[i] = Y_CCIR_TO_JPEG(i);
739         y_jpeg_to_ccir[i] = Y_JPEG_TO_CCIR(i);
740         c_ccir_to_jpeg[i] = C_CCIR_TO_JPEG(i);
741         c_jpeg_to_ccir[i] = C_JPEG_TO_CCIR(i);
742     }
743 }
744
745 /* apply to each pixel the given table */
746 static void img_apply_table(uint8_t *dst, int dst_wrap, 
747                             const uint8_t *src, int src_wrap,
748                             int width, int height, const uint8_t *table1)
749 {
750     int n;
751     const uint8_t *s;
752     uint8_t *d;
753     const uint8_t *table;
754
755     table = table1;
756     for(;height > 0; height--) {
757         s = src;
758         d = dst;
759         n = width;
760         while (n >= 4) {
761             d[0] = table[s[0]];
762             d[1] = table[s[1]];
763             d[2] = table[s[2]];
764             d[3] = table[s[3]];
765             d += 4;
766             s += 4;
767             n -= 4;
768         }
769         while (n > 0) {
770             d[0] = table[s[0]];
771             d++;
772             s++;
773             n--;
774         }
775         dst += dst_wrap;
776         src += src_wrap;
777     }
778 }
779
780 /* XXX: use generic filter ? */
781 /* XXX: in most cases, the sampling position is incorrect */
782
783 /* 4x1 -> 1x1 */
784 static void shrink41(uint8_t *dst, int dst_wrap, 
785                      const uint8_t *src, int src_wrap,
786                      int width, int height)
787 {
788     int w;
789     const uint8_t *s;
790     uint8_t *d;
791
792     for(;height > 0; height--) {
793         s = src;
794         d = dst;
795         for(w = width;w > 0; w--) {
796             d[0] = (s[0] + s[1] + s[2] + s[3] + 2) >> 2;
797             s += 4;
798             d++;
799         }
800         src += src_wrap;
801         dst += dst_wrap;
802     }
803 }
804
805 /* 2x1 -> 1x1 */
806 static void shrink21(uint8_t *dst, int dst_wrap, 
807                      const uint8_t *src, int src_wrap,
808                      int width, int height)
809 {
810     int w;
811     const uint8_t *s;
812     uint8_t *d;
813
814     for(;height > 0; height--) {
815         s = src;
816         d = dst;
817         for(w = width;w > 0; w--) {
818             d[0] = (s[0] + s[1]) >> 1;
819             s += 2;
820             d++;
821         }
822         src += src_wrap;
823         dst += dst_wrap;
824     }
825 }
826
827 /* 1x2 -> 1x1 */
828 static void shrink12(uint8_t *dst, int dst_wrap, 
829                      const uint8_t *src, int src_wrap,
830                      int width, int height)
831 {
832     int w;
833     uint8_t *d;
834     const uint8_t *s1, *s2;
835
836     for(;height > 0; height--) {
837         s1 = src;
838         s2 = s1 + src_wrap;
839         d = dst;
840         for(w = width;w >= 4; w-=4) {
841             d[0] = (s1[0] + s2[0]) >> 1;
842             d[1] = (s1[1] + s2[1]) >> 1;
843             d[2] = (s1[2] + s2[2]) >> 1;
844             d[3] = (s1[3] + s2[3]) >> 1;
845             s1 += 4;
846             s2 += 4;
847             d += 4;
848         }
849         for(;w > 0; w--) {
850             d[0] = (s1[0] + s2[0]) >> 1;
851             s1++;
852             s2++;
853             d++;
854         }
855         src += 2 * src_wrap;
856         dst += dst_wrap;
857     }
858 }
859
860 /* 2x2 -> 1x1 */
861 static void shrink22(uint8_t *dst, int dst_wrap, 
862                      const uint8_t *src, int src_wrap,
863                      int width, int height)
864 {
865     int w;
866     const uint8_t *s1, *s2;
867     uint8_t *d;
868
869     for(;height > 0; height--) {
870         s1 = src;
871         s2 = s1 + src_wrap;
872         d = dst;
873         for(w = width;w >= 4; w-=4) {
874             d[0] = (s1[0] + s1[1] + s2[0] + s2[1] + 2) >> 2;
875             d[1] = (s1[2] + s1[3] + s2[2] + s2[3] + 2) >> 2;
876             d[2] = (s1[4] + s1[5] + s2[4] + s2[5] + 2) >> 2;
877             d[3] = (s1[6] + s1[7] + s2[6] + s2[7] + 2) >> 2;
878             s1 += 8;
879             s2 += 8;
880             d += 4;
881         }
882         for(;w > 0; w--) {
883             d[0] = (s1[0] + s1[1] + s2[0] + s2[1] + 2) >> 2;
884             s1 += 2;
885             s2 += 2;
886             d++;
887         }
888         src += 2 * src_wrap;
889         dst += dst_wrap;
890     }
891 }
892
893 /* 4x4 -> 1x1 */
894 static void shrink44(uint8_t *dst, int dst_wrap, 
895                      const uint8_t *src, int src_wrap,
896                      int width, int height)
897 {
898     int w;
899     const uint8_t *s1, *s2, *s3, *s4;
900     uint8_t *d;
901
902     for(;height > 0; height--) {
903         s1 = src;
904         s2 = s1 + src_wrap;
905         s3 = s2 + src_wrap;
906         s4 = s3 + src_wrap;
907         d = dst;
908         for(w = width;w > 0; w--) {
909             d[0] = (s1[0] + s1[1] + s1[2] + s1[3] +
910                     s2[0] + s2[1] + s2[2] + s2[3] +
911                     s3[0] + s3[1] + s3[2] + s3[3] +
912                     s4[0] + s4[1] + s4[2] + s4[3] + 8) >> 4;
913             s1 += 4;
914             s2 += 4;
915             s3 += 4;
916             s4 += 4;
917             d++;
918         }
919         src += 4 * src_wrap;
920         dst += dst_wrap;
921     }
922 }
923
924 static void grow21_line(uint8_t *dst, const uint8_t *src,
925                         int width)
926 {
927     int w;
928     const uint8_t *s1;
929     uint8_t *d;
930
931     s1 = src;
932     d = dst;
933     for(w = width;w >= 4; w-=4) {
934         d[1] = d[0] = s1[0];
935         d[3] = d[2] = s1[1];
936         s1 += 2;
937         d += 4;
938     }
939     for(;w >= 2; w -= 2) {
940         d[1] = d[0] = s1[0];
941         s1 ++;
942         d += 2;
943     }
944     /* only needed if width is not a multiple of two */
945     /* XXX: veryfy that */
946     if (w) {
947         d[0] = s1[0];
948     }
949 }
950
951 static void grow41_line(uint8_t *dst, const uint8_t *src,
952                         int width)
953 {
954     int w, v;
955     const uint8_t *s1;
956     uint8_t *d;
957
958     s1 = src;
959     d = dst;
960     for(w = width;w >= 4; w-=4) {
961         v = s1[0];
962         d[0] = v;
963         d[1] = v;
964         d[2] = v;
965         d[3] = v;
966         s1 ++;
967         d += 4;
968     }
969 }
970
971 /* 1x1 -> 2x1 */
972 static void grow21(uint8_t *dst, int dst_wrap,
973                    const uint8_t *src, int src_wrap,
974                    int width, int height)
975 {
976     for(;height > 0; height--) {
977         grow21_line(dst, src, width);
978         src += src_wrap;
979         dst += dst_wrap;
980     }
981 }
982
983 /* 1x1 -> 2x2 */
984 static void grow22(uint8_t *dst, int dst_wrap,
985                    const uint8_t *src, int src_wrap,
986                    int width, int height)
987 {
988     for(;height > 0; height--) {
989         grow21_line(dst, src, width);
990         if (height%2)
991             src += src_wrap;
992         dst += dst_wrap;
993     }
994 }
995
996 /* 1x1 -> 4x1 */
997 static void grow41(uint8_t *dst, int dst_wrap,
998                    const uint8_t *src, int src_wrap,
999                    int width, int height)
1000 {
1001     for(;height > 0; height--) {
1002         grow41_line(dst, src, width);
1003         src += src_wrap;
1004         dst += dst_wrap;
1005     }
1006 }
1007
1008 /* 1x1 -> 4x4 */
1009 static void grow44(uint8_t *dst, int dst_wrap,
1010                    const uint8_t *src, int src_wrap,
1011                    int width, int height)
1012 {
1013     for(;height > 0; height--) {
1014         grow41_line(dst, src, width);
1015         if ((height & 3) == 1)
1016             src += src_wrap;
1017         dst += dst_wrap;
1018     }
1019 }
1020
1021 /* 1x2 -> 2x1 */
1022 static void conv411(uint8_t *dst, int dst_wrap, 
1023                     const uint8_t *src, int src_wrap,
1024                     int width, int height)
1025 {
1026     int w, c;
1027     const uint8_t *s1, *s2;
1028     uint8_t *d;
1029
1030     width>>=1;
1031
1032     for(;height > 0; height--) {
1033         s1 = src;
1034         s2 = src + src_wrap;
1035         d = dst;
1036         for(w = width;w > 0; w--) {
1037             c = (s1[0] + s2[0]) >> 1;
1038             d[0] = c;
1039             d[1] = c;
1040             s1++;
1041             s2++;
1042             d += 2;
1043         }
1044         src += src_wrap * 2;
1045         dst += dst_wrap;
1046     }
1047 }
1048
1049 /* XXX: add jpeg quantize code */
1050
1051 #define TRANSP_INDEX (6*6*6)
1052
1053 /* this is maybe slow, but allows for extensions */
1054 static inline unsigned char gif_clut_index(uint8_t r, uint8_t g, uint8_t b)
1055 {
1056     return ((((r)/47)%6)*6*6+(((g)/47)%6)*6+(((b)/47)%6));
1057 }
1058
1059 static void build_rgb_palette(uint8_t *palette, int has_alpha)
1060 {
1061     uint32_t *pal;
1062     static const uint8_t pal_value[6] = { 0x00, 0x33, 0x66, 0x99, 0xcc, 0xff };
1063     int i, r, g, b;
1064
1065     pal = (uint32_t *)palette;
1066     i = 0;
1067     for(r = 0; r < 6; r++) {
1068         for(g = 0; g < 6; g++) {
1069             for(b = 0; b < 6; b++) {
1070                 pal[i++] = (0xff << 24) | (pal_value[r] << 16) | 
1071                     (pal_value[g] << 8) | pal_value[b];
1072             }
1073         }
1074     }
1075     if (has_alpha)
1076         pal[i++] = 0;
1077     while (i < 256)
1078         pal[i++] = 0xff000000;
1079 }
1080
1081 /* copy bit n to bits 0 ... n - 1 */
1082 static inline unsigned int bitcopy_n(unsigned int a, int n)
1083 {
1084     int mask;
1085     mask = (1 << n) - 1;
1086     return (a & (0xff & ~mask)) | ((-((a >> n) & 1)) & mask);
1087 }
1088
1089 /* rgb555 handling */
1090
1091 #define RGB_NAME rgb555
1092
1093 #define RGB_IN(r, g, b, s)\
1094 {\
1095     unsigned int v = ((const uint16_t *)(s))[0];\
1096     r = bitcopy_n(v >> (10 - 3), 3);\
1097     g = bitcopy_n(v >> (5 - 3), 3);\
1098     b = bitcopy_n(v << 3, 3);\
1099 }
1100
1101 #define RGBA_IN(r, g, b, a, s)\
1102 {\
1103     unsigned int v = ((const uint16_t *)(s))[0];\
1104     r = bitcopy_n(v >> (10 - 3), 3);\
1105     g = bitcopy_n(v >> (5 - 3), 3);\
1106     b = bitcopy_n(v << 3, 3);\
1107     a = (-(v >> 15)) & 0xff;\
1108 }
1109
1110 #define RGBA_OUT(d, r, g, b, a)\
1111 {\
1112     ((uint16_t *)(d))[0] = ((r >> 3) << 10) | ((g >> 3) << 5) | (b >> 3) | \
1113                            ((a << 8) & 0x8000);\
1114 }
1115
1116 #define BPP 2
1117
1118 #include "imgconvert_template.h"
1119
1120 /* rgb565 handling */
1121
1122 #define RGB_NAME rgb565
1123
1124 #define RGB_IN(r, g, b, s)\
1125 {\
1126     unsigned int v = ((const uint16_t *)(s))[0];\
1127     r = bitcopy_n(v >> (11 - 3), 3);\
1128     g = bitcopy_n(v >> (5 - 2), 2);\
1129     b = bitcopy_n(v << 3, 3);\
1130 }
1131
1132 #define RGB_OUT(d, r, g, b)\
1133 {\
1134     ((uint16_t *)(d))[0] = ((r >> 3) << 11) | ((g >> 2) << 5) | (b >> 3);\
1135 }
1136
1137 #define BPP 2
1138
1139 #include "imgconvert_template.h"
1140
1141 /* bgr24 handling */
1142
1143 #define RGB_NAME bgr24
1144
1145 #define RGB_IN(r, g, b, s)\
1146 {\
1147     b = (s)[0];\
1148     g = (s)[1];\
1149     r = (s)[2];\
1150 }
1151
1152 #define RGB_OUT(d, r, g, b)\
1153 {\
1154     (d)[0] = b;\
1155     (d)[1] = g;\
1156     (d)[2] = r;\
1157 }
1158
1159 #define BPP 3
1160
1161 #include "imgconvert_template.h"
1162
1163 #undef RGB_IN
1164 #undef RGB_OUT
1165 #undef BPP
1166
1167 /* rgb24 handling */
1168
1169 #define RGB_NAME rgb24
1170 #define FMT_RGB24
1171
1172 #define RGB_IN(r, g, b, s)\
1173 {\
1174     r = (s)[0];\
1175     g = (s)[1];\
1176     b = (s)[2];\
1177 }
1178
1179 #define RGB_OUT(d, r, g, b)\
1180 {\
1181     (d)[0] = r;\
1182     (d)[1] = g;\
1183     (d)[2] = b;\
1184 }
1185
1186 #define BPP 3
1187
1188 #include "imgconvert_template.h"
1189
1190 /* rgba32 handling */
1191
1192 #define RGB_NAME rgba32
1193 #define FMT_RGBA32
1194
1195 #define RGB_IN(r, g, b, s)\
1196 {\
1197     unsigned int v = ((const uint32_t *)(s))[0];\
1198     r = (v >> 16) & 0xff;\
1199     g = (v >> 8) & 0xff;\
1200     b = v & 0xff;\
1201 }
1202
1203 #define RGBA_IN(r, g, b, a, s)\
1204 {\
1205     unsigned int v = ((const uint32_t *)(s))[0];\
1206     a = (v >> 24) & 0xff;\
1207     r = (v >> 16) & 0xff;\
1208     g = (v >> 8) & 0xff;\
1209     b = v & 0xff;\
1210 }
1211
1212 #define RGBA_OUT(d, r, g, b, a)\
1213 {\
1214     ((uint32_t *)(d))[0] = (a << 24) | (r << 16) | (g << 8) | b;\
1215 }
1216
1217 #define BPP 4
1218
1219 #include "imgconvert_template.h"
1220
1221 static void mono_to_gray(AVPicture *dst, AVPicture *src,
1222                          int width, int height, int xor_mask)
1223 {
1224     const unsigned char *p;
1225     unsigned char *q;
1226     int v, dst_wrap, src_wrap;
1227     int y, w;
1228
1229     p = src->data[0];
1230     src_wrap = src->linesize[0] - ((width + 7) >> 3);
1231
1232     q = dst->data[0];
1233     dst_wrap = dst->linesize[0] - width;
1234     for(y=0;y<height;y++) {
1235         w = width; 
1236         while (w >= 8) {
1237             v = *p++ ^ xor_mask;
1238             q[0] = -(v >> 7);
1239             q[1] = -((v >> 6) & 1);
1240             q[2] = -((v >> 5) & 1);
1241             q[3] = -((v >> 4) & 1);
1242             q[4] = -((v >> 3) & 1);
1243             q[5] = -((v >> 2) & 1);
1244             q[6] = -((v >> 1) & 1);
1245             q[7] = -((v >> 0) & 1);
1246             w -= 8;
1247             q += 8;
1248         }
1249         if (w > 0) {
1250             v = *p++ ^ xor_mask;
1251             do {
1252                 q[0] = -((v >> 7) & 1);
1253                 q++;
1254                 v <<= 1;
1255             } while (--w);
1256         }
1257         p += src_wrap;
1258         q += dst_wrap;
1259     }
1260 }
1261
1262 static void monowhite_to_gray(AVPicture *dst, AVPicture *src,
1263                                int width, int height)
1264 {
1265     mono_to_gray(dst, src, width, height, 0xff);
1266 }
1267
1268 static void monoblack_to_gray(AVPicture *dst, AVPicture *src,
1269                                int width, int height)
1270 {
1271     mono_to_gray(dst, src, width, height, 0x00);
1272 }
1273
1274 static void gray_to_mono(AVPicture *dst, AVPicture *src,
1275                          int width, int height, int xor_mask)
1276 {
1277     int n;
1278     const uint8_t *s;
1279     uint8_t *d;
1280     int j, b, v, n1, src_wrap, dst_wrap, y;
1281
1282     s = src->data[0];
1283     src_wrap = src->linesize[0] - width;
1284
1285     d = dst->data[0];
1286     dst_wrap = dst->linesize[0] - ((width + 7) >> 3);
1287
1288     for(y=0;y<height;y++) {
1289         n = width;
1290         while (n >= 8) {
1291             v = 0;
1292             for(j=0;j<8;j++) {
1293                 b = s[0];
1294                 s++;
1295                 v = (v << 1) | (b >> 7);
1296             }
1297             d[0] = v ^ xor_mask;
1298             d++;
1299             n -= 8;
1300         }
1301         if (n > 0) {
1302             n1 = n;
1303             v = 0;
1304             while (n > 0) {
1305                 b = s[0];
1306                 s++;
1307                 v = (v << 1) | (b >> 7);
1308                 n--;
1309             }
1310             d[0] = (v << (8 - (n1 & 7))) ^ xor_mask;
1311             d++;
1312         }
1313         s += src_wrap;
1314         d += dst_wrap;
1315     }
1316 }
1317
1318 static void gray_to_monowhite(AVPicture *dst, AVPicture *src,
1319                               int width, int height)
1320 {
1321     gray_to_mono(dst, src, width, height, 0xff);
1322 }
1323
1324 static void gray_to_monoblack(AVPicture *dst, AVPicture *src,
1325                               int width, int height)
1326 {
1327     gray_to_mono(dst, src, width, height, 0x00);
1328 }
1329
1330 typedef struct ConvertEntry {
1331     void (*convert)(AVPicture *dst, AVPicture *src, int width, int height);
1332 } ConvertEntry;
1333
1334 /* Add each new convertion function in this table. In order to be able
1335    to convert from any format to any format, the following constraints
1336    must be satisfied:
1337
1338    - all FF_COLOR_RGB formats must convert to and from PIX_FMT_RGB24 
1339
1340    - all FF_COLOR_GRAY formats must convert to and from PIX_FMT_GRAY8
1341
1342    - all FF_COLOR_RGB formats with alpha must convert to and from PIX_FMT_RGBA32
1343
1344    - PIX_FMT_YUV444P and PIX_FMT_YUVJ444P must convert to and from
1345      PIX_FMT_RGB24.
1346
1347    - PIX_FMT_422 must convert to and from PIX_FMT_422P.
1348
1349    The other conversion functions are just optimisations for common cases.
1350 */
1351 static ConvertEntry convert_table[PIX_FMT_NB][PIX_FMT_NB] = {
1352     [PIX_FMT_YUV420P] = {
1353         [PIX_FMT_RGB555] = { 
1354             .convert = yuv420p_to_rgb555
1355         },
1356         [PIX_FMT_RGB565] = { 
1357             .convert = yuv420p_to_rgb565
1358         },
1359         [PIX_FMT_BGR24] = { 
1360             .convert = yuv420p_to_bgr24
1361         },
1362         [PIX_FMT_RGB24] = { 
1363             .convert = yuv420p_to_rgb24
1364         },
1365         [PIX_FMT_RGBA32] = { 
1366             .convert = yuv420p_to_rgba32
1367         },
1368     },
1369     [PIX_FMT_YUV422P] = { 
1370         [PIX_FMT_YUV422] = { 
1371             .convert = yuv422p_to_yuv422,
1372         },
1373     },
1374     [PIX_FMT_YUV444P] = { 
1375         [PIX_FMT_RGB24] = { 
1376             .convert = yuv444p_to_rgb24
1377         },
1378     },
1379     [PIX_FMT_YUVJ420P] = {
1380         [PIX_FMT_RGB555] = { 
1381             .convert = yuvj420p_to_rgb555
1382         },
1383         [PIX_FMT_RGB565] = { 
1384             .convert = yuvj420p_to_rgb565
1385         },
1386         [PIX_FMT_BGR24] = { 
1387             .convert = yuvj420p_to_bgr24
1388         },
1389         [PIX_FMT_RGB24] = { 
1390             .convert = yuvj420p_to_rgb24
1391         },
1392         [PIX_FMT_RGBA32] = { 
1393             .convert = yuvj420p_to_rgba32
1394         },
1395     },
1396     [PIX_FMT_YUVJ444P] = { 
1397         [PIX_FMT_RGB24] = { 
1398             .convert = yuvj444p_to_rgb24
1399         },
1400     },
1401     [PIX_FMT_YUV422] = { 
1402         [PIX_FMT_YUV420P] = { 
1403             .convert = yuv422_to_yuv420p,
1404         },
1405         [PIX_FMT_YUV422P] = { 
1406             .convert = yuv422_to_yuv422p,
1407         },
1408     },
1409
1410     [PIX_FMT_RGB24] = {
1411         [PIX_FMT_YUV420P] = { 
1412             .convert = rgb24_to_yuv420p
1413         },
1414         [PIX_FMT_RGB565] = { 
1415             .convert = rgb24_to_rgb565
1416         },
1417         [PIX_FMT_RGB555] = { 
1418             .convert = rgb24_to_rgb555
1419         },
1420         [PIX_FMT_RGBA32] = { 
1421             .convert = rgb24_to_rgba32
1422         },
1423         [PIX_FMT_BGR24] = { 
1424             .convert = rgb24_to_bgr24
1425         },
1426         [PIX_FMT_GRAY8] = { 
1427             .convert = rgb24_to_gray
1428         },
1429         [PIX_FMT_PAL8] = {
1430             .convert = rgb24_to_pal8
1431         },
1432         [PIX_FMT_YUV444P] = { 
1433             .convert = rgb24_to_yuv444p
1434         },
1435         [PIX_FMT_YUVJ420P] = { 
1436             .convert = rgb24_to_yuvj420p
1437         },
1438         [PIX_FMT_YUVJ444P] = { 
1439             .convert = rgb24_to_yuvj444p
1440         },
1441     },
1442     [PIX_FMT_RGBA32] = {
1443         [PIX_FMT_RGB24] = { 
1444             .convert = rgba32_to_rgb24
1445         },
1446         [PIX_FMT_RGB555] = { 
1447             .convert = rgba32_to_rgb555
1448         },
1449         [PIX_FMT_PAL8] = { 
1450             .convert = rgba32_to_pal8
1451         },
1452         [PIX_FMT_YUV420P] = { 
1453             .convert = rgba32_to_yuv420p
1454         },
1455         [PIX_FMT_GRAY8] = { 
1456             .convert = rgba32_to_gray
1457         },
1458     },
1459     [PIX_FMT_BGR24] = {
1460         [PIX_FMT_RGB24] = { 
1461             .convert = bgr24_to_rgb24
1462         },
1463         [PIX_FMT_YUV420P] = { 
1464             .convert = bgr24_to_yuv420p
1465         },
1466         [PIX_FMT_GRAY8] = { 
1467             .convert = bgr24_to_gray
1468         },
1469     },
1470     [PIX_FMT_RGB555] = {
1471         [PIX_FMT_RGB24] = { 
1472             .convert = rgb555_to_rgb24
1473         },
1474         [PIX_FMT_RGBA32] = { 
1475             .convert = rgb555_to_rgba32
1476         },
1477         [PIX_FMT_YUV420P] = { 
1478             .convert = rgb555_to_yuv420p
1479         },
1480         [PIX_FMT_GRAY8] = { 
1481             .convert = rgb555_to_gray
1482         },
1483     },
1484     [PIX_FMT_RGB565] = {
1485         [PIX_FMT_RGB24] = { 
1486             .convert = rgb565_to_rgb24
1487         },
1488         [PIX_FMT_YUV420P] = { 
1489             .convert = rgb565_to_yuv420p
1490         },
1491         [PIX_FMT_GRAY8] = { 
1492             .convert = rgb565_to_gray
1493         },
1494     },
1495     [PIX_FMT_GRAY8] = {
1496         [PIX_FMT_RGB555] = { 
1497             .convert = gray_to_rgb555
1498         },
1499         [PIX_FMT_RGB565] = { 
1500             .convert = gray_to_rgb565
1501         },
1502         [PIX_FMT_RGB24] = { 
1503             .convert = gray_to_rgb24
1504         },
1505         [PIX_FMT_BGR24] = { 
1506             .convert = gray_to_bgr24
1507         },
1508         [PIX_FMT_RGBA32] = { 
1509             .convert = gray_to_rgba32
1510         },
1511         [PIX_FMT_MONOWHITE] = { 
1512             .convert = gray_to_monowhite
1513         },
1514         [PIX_FMT_MONOBLACK] = { 
1515             .convert = gray_to_monoblack
1516         },
1517     },
1518     [PIX_FMT_MONOWHITE] = {
1519         [PIX_FMT_GRAY8] = { 
1520             .convert = monowhite_to_gray
1521         },
1522     },
1523     [PIX_FMT_MONOBLACK] = {
1524         [PIX_FMT_GRAY8] = { 
1525             .convert = monoblack_to_gray
1526         },
1527     },
1528     [PIX_FMT_PAL8] = {
1529         [PIX_FMT_RGB555] = { 
1530             .convert = pal8_to_rgb555
1531         },
1532         [PIX_FMT_RGB565] = { 
1533             .convert = pal8_to_rgb565
1534         },
1535         [PIX_FMT_BGR24] = { 
1536             .convert = pal8_to_bgr24
1537         },
1538         [PIX_FMT_RGB24] = { 
1539             .convert = pal8_to_rgb24
1540         },
1541         [PIX_FMT_RGBA32] = { 
1542             .convert = pal8_to_rgba32
1543         },
1544     },
1545 };
1546
1547 static int avpicture_alloc(AVPicture *picture,
1548                            int pix_fmt, int width, int height)
1549 {
1550     unsigned int size;
1551     void *ptr;
1552
1553     size = avpicture_get_size(pix_fmt, width, height);
1554     if (size < 0)
1555         goto fail;
1556     ptr = av_malloc(size);
1557     if (!ptr)
1558         goto fail;
1559     avpicture_fill(picture, ptr, pix_fmt, width, height);
1560     return 0;
1561  fail:
1562     memset(picture, 0, sizeof(AVPicture));
1563     return -1;
1564 }
1565
1566 static void avpicture_free(AVPicture *picture)
1567 {
1568     av_free(picture->data[0]);
1569 }
1570
1571 /* return true if yuv planar */
1572 static inline int is_yuv_planar(PixFmtInfo *ps)
1573 {
1574     return (ps->color_type == FF_COLOR_YUV ||
1575             ps->color_type == FF_COLOR_YUV_JPEG) && 
1576         ps->pixel_type == FF_PIXEL_PLANAR;
1577 }
1578
1579 /* XXX: always use linesize. Return -1 if not supported */
1580 int img_convert(AVPicture *dst, int dst_pix_fmt,
1581                 AVPicture *src, int src_pix_fmt, 
1582                 int src_width, int src_height)
1583 {
1584     static int inited;
1585     int i, ret, dst_width, dst_height, int_pix_fmt;
1586     PixFmtInfo *src_pix, *dst_pix;
1587     ConvertEntry *ce;
1588     AVPicture tmp1, *tmp = &tmp1;
1589
1590     if (src_pix_fmt < 0 || src_pix_fmt >= PIX_FMT_NB ||
1591         dst_pix_fmt < 0 || dst_pix_fmt >= PIX_FMT_NB)
1592         return -1;
1593     if (src_width <= 0 || src_height <= 0)
1594         return 0;
1595
1596     if (!inited) {
1597         inited = 1;
1598         img_convert_init();
1599     }
1600
1601     dst_width = src_width;
1602     dst_height = src_height;
1603
1604     dst_pix = &pix_fmt_info[dst_pix_fmt];
1605     src_pix = &pix_fmt_info[src_pix_fmt];
1606     if (src_pix_fmt == dst_pix_fmt) {
1607         /* no conversion needed: just copy */
1608         img_copy(dst, src, dst_pix_fmt, dst_width, dst_height);
1609         return 0;
1610     }
1611
1612     ce = &convert_table[src_pix_fmt][dst_pix_fmt];
1613     if (ce->convert) {
1614         /* specific convertion routine */
1615         ce->convert(dst, src, dst_width, dst_height);
1616         return 0;
1617     }
1618
1619     /* gray to YUV */
1620     if (is_yuv_planar(dst_pix) &&
1621         src_pix_fmt == PIX_FMT_GRAY8) {
1622         int w, h, y;
1623         uint8_t *d;
1624
1625         if (dst_pix->color_type == FF_COLOR_YUV_JPEG) {
1626             img_copy_plane(dst->data[0], dst->linesize[0],
1627                      src->data[0], src->linesize[0],
1628                      dst_width, dst_height);
1629         } else {
1630             img_apply_table(dst->data[0], dst->linesize[0],
1631                             src->data[0], src->linesize[0],
1632                             dst_width, dst_height,
1633                             y_jpeg_to_ccir);
1634         }
1635         /* fill U and V with 128 */
1636         w = dst_width;
1637         h = dst_height;
1638         w >>= dst_pix->x_chroma_shift;
1639         h >>= dst_pix->y_chroma_shift;
1640         for(i = 1; i <= 2; i++) {
1641             d = dst->data[i];
1642             for(y = 0; y< h; y++) {
1643                 memset(d, 128, w);
1644                 d += dst->linesize[i];
1645             }
1646         }
1647         return 0;
1648     }
1649
1650     /* YUV to gray */
1651     if (is_yuv_planar(src_pix) && 
1652         dst_pix_fmt == PIX_FMT_GRAY8) {
1653         if (src_pix->color_type == FF_COLOR_YUV_JPEG) {
1654             img_copy_plane(dst->data[0], dst->linesize[0],
1655                      src->data[0], src->linesize[0],
1656                      dst_width, dst_height);
1657         } else {
1658             img_apply_table(dst->data[0], dst->linesize[0],
1659                             src->data[0], src->linesize[0],
1660                             dst_width, dst_height,
1661                             y_ccir_to_jpeg);
1662         }
1663         return 0;
1664     }
1665
1666     /* YUV to YUV planar */
1667     if (is_yuv_planar(dst_pix) && is_yuv_planar(src_pix)) {
1668         int x_shift, y_shift, w, h, xy_shift;
1669         void (*resize_func)(uint8_t *dst, int dst_wrap, 
1670                             const uint8_t *src, int src_wrap,
1671                             int width, int height);
1672
1673         /* compute chroma size of the smallest dimensions */
1674         w = dst_width;
1675         h = dst_height;
1676         if (dst_pix->x_chroma_shift >= src_pix->x_chroma_shift)
1677             w >>= dst_pix->x_chroma_shift;
1678         else
1679             w >>= src_pix->x_chroma_shift;
1680         if (dst_pix->y_chroma_shift >= src_pix->y_chroma_shift)
1681             h >>= dst_pix->y_chroma_shift;
1682         else
1683             h >>= src_pix->y_chroma_shift;
1684
1685         x_shift = (dst_pix->x_chroma_shift - src_pix->x_chroma_shift);
1686         y_shift = (dst_pix->y_chroma_shift - src_pix->y_chroma_shift);
1687         xy_shift = ((x_shift & 0xf) << 4) | (y_shift & 0xf);
1688         /* there must be filters for conversion at least from and to
1689            YUV444 format */
1690         switch(xy_shift) {
1691         case 0x00:
1692             resize_func = img_copy_plane;
1693             break;
1694         case 0x10:
1695             resize_func = shrink21;
1696             break;
1697         case 0x20:
1698             resize_func = shrink41;
1699             break;
1700         case 0x01:
1701             resize_func = shrink12;
1702             break;
1703         case 0x11:
1704             resize_func = shrink22;
1705             break;
1706         case 0x22:
1707             resize_func = shrink44;
1708             break;
1709         case 0xf0:
1710             resize_func = grow21;
1711             break;
1712         case 0xe0:
1713             resize_func = grow41;
1714             break;
1715         case 0xff:
1716             resize_func = grow22;
1717             break;
1718         case 0xee:
1719             resize_func = grow44;
1720             break;
1721         case 0xf1:
1722             resize_func = conv411;
1723             break;
1724         default:
1725             /* currently not handled */
1726             goto no_chroma_filter;
1727         }
1728
1729         img_copy_plane(dst->data[0], dst->linesize[0],
1730                        src->data[0], src->linesize[0],
1731                        dst_width, dst_height);
1732
1733         for(i = 1;i <= 2; i++)
1734             resize_func(dst->data[i], dst->linesize[i],
1735                         src->data[i], src->linesize[i],
1736                         dst_width>>dst_pix->x_chroma_shift, dst_height>>dst_pix->y_chroma_shift);
1737         /* if yuv color space conversion is needed, we do it here on
1738            the destination image */
1739         if (dst_pix->color_type != src_pix->color_type) {
1740             const uint8_t *y_table, *c_table;
1741             if (dst_pix->color_type == FF_COLOR_YUV) {
1742                 y_table = y_jpeg_to_ccir;
1743                 c_table = c_jpeg_to_ccir;
1744             } else {
1745                 y_table = y_ccir_to_jpeg;
1746                 c_table = c_ccir_to_jpeg;
1747             }
1748             img_apply_table(dst->data[0], dst->linesize[0],
1749                             dst->data[0], dst->linesize[0],
1750                             dst_width, dst_height,
1751                             y_table);
1752
1753             for(i = 1;i <= 2; i++)
1754                 img_apply_table(dst->data[i], dst->linesize[i],
1755                                 dst->data[i], dst->linesize[i],
1756                                 dst_width>>dst_pix->x_chroma_shift, 
1757                                 dst_height>>dst_pix->y_chroma_shift,
1758                                 c_table);
1759         }
1760         return 0;
1761     }
1762  no_chroma_filter:
1763
1764     /* try to use an intermediate format */
1765     if (src_pix_fmt == PIX_FMT_YUV422 ||
1766         dst_pix_fmt == PIX_FMT_YUV422) {
1767         /* specific case: convert to YUV422P first */
1768         int_pix_fmt = PIX_FMT_YUV422P;
1769     } else if ((src_pix->color_type == FF_COLOR_GRAY &&
1770                 src_pix_fmt != PIX_FMT_GRAY8) || 
1771                (dst_pix->color_type == FF_COLOR_GRAY &&
1772                 dst_pix_fmt != PIX_FMT_GRAY8)) {
1773         /* gray8 is the normalized format */
1774         int_pix_fmt = PIX_FMT_GRAY8;
1775     } else if ((is_yuv_planar(src_pix) && 
1776                 src_pix_fmt != PIX_FMT_YUV444P &&
1777                 src_pix_fmt != PIX_FMT_YUVJ444P)) {
1778         /* yuv444 is the normalized format */
1779         if (src_pix->color_type == FF_COLOR_YUV_JPEG)
1780             int_pix_fmt = PIX_FMT_YUVJ444P;
1781         else
1782             int_pix_fmt = PIX_FMT_YUV444P;
1783     } else if ((is_yuv_planar(dst_pix) && 
1784                 dst_pix_fmt != PIX_FMT_YUV444P &&
1785                 dst_pix_fmt != PIX_FMT_YUVJ444P)) {
1786         /* yuv444 is the normalized format */
1787         if (dst_pix->color_type == FF_COLOR_YUV_JPEG)
1788             int_pix_fmt = PIX_FMT_YUVJ444P;
1789         else
1790             int_pix_fmt = PIX_FMT_YUV444P;
1791     } else {
1792         /* the two formats are rgb or gray8 or yuv[j]444p */
1793         if (src_pix->is_alpha && dst_pix->is_alpha)
1794             int_pix_fmt = PIX_FMT_RGBA32;
1795         else
1796             int_pix_fmt = PIX_FMT_RGB24;
1797     }
1798     if (avpicture_alloc(tmp, int_pix_fmt, dst_width, dst_height) < 0)
1799         return -1;
1800     ret = -1;
1801     if (img_convert(tmp, int_pix_fmt,
1802                     src, src_pix_fmt, src_width, src_height) < 0)
1803         goto fail1;
1804     if (img_convert(dst, dst_pix_fmt,
1805                     tmp, int_pix_fmt, dst_width, dst_height) < 0)
1806         goto fail1;
1807     ret = 0;
1808  fail1:
1809     avpicture_free(tmp);
1810     return ret;
1811 }
1812
1813 /* NOTE: we scan all the pixels to have an exact information */
1814 static int get_alpha_info_pal8(AVPicture *src, int width, int height)
1815 {
1816     const unsigned char *p;
1817     int src_wrap, ret, x, y;
1818     unsigned int a;
1819     uint32_t *palette = (uint32_t *)src->data[1];
1820     
1821     p = src->data[0];
1822     src_wrap = src->linesize[0] - width;
1823     ret = 0;
1824     for(y=0;y<height;y++) {
1825         for(x=0;x<width;x++) {
1826             a = palette[p[0]] >> 24;
1827             if (a == 0x00) {
1828                 ret |= FF_ALPHA_TRANSP;
1829             } else if (a != 0xff) {
1830                 ret |= FF_ALPHA_SEMI_TRANSP;
1831             }
1832             p++;
1833         }
1834         p += src_wrap;
1835     }
1836     return ret;
1837 }
1838
1839 /**
1840  * Tell if an image really has transparent alpha values.
1841  * @return ored mask of FF_ALPHA_xxx constants
1842  */
1843 int img_get_alpha_info(AVPicture *src, int pix_fmt, int width, int height)
1844 {
1845     PixFmtInfo *pf = &pix_fmt_info[pix_fmt];
1846     int ret;
1847
1848     pf = &pix_fmt_info[pix_fmt];
1849     /* no alpha can be represented in format */
1850     if (!pf->is_alpha)
1851         return 0;
1852     switch(pix_fmt) {
1853     case PIX_FMT_RGBA32:
1854         ret = get_alpha_info_rgba32(src, width, height);
1855         break;
1856     case PIX_FMT_RGB555:
1857         ret = get_alpha_info_rgb555(src, width, height);
1858         break;
1859     case PIX_FMT_PAL8:
1860         ret = get_alpha_info_pal8(src, width, height);
1861         break;
1862     default:
1863         /* we do not know, so everything is indicated */
1864         ret = FF_ALPHA_TRANSP | FF_ALPHA_SEMI_TRANSP;
1865         break;
1866     }
1867     return ret;
1868 }
1869
1870 #ifdef HAVE_MMX
1871 #define DEINT_INPLACE_LINE_LUM \
1872                     movd_m2r(lum_m4[0],mm0);\
1873                     movd_m2r(lum_m3[0],mm1);\
1874                     movd_m2r(lum_m2[0],mm2);\
1875                     movd_m2r(lum_m1[0],mm3);\
1876                     movd_m2r(lum[0],mm4);\
1877                     punpcklbw_r2r(mm7,mm0);\
1878                     movd_r2m(mm2,lum_m4[0]);\
1879                     punpcklbw_r2r(mm7,mm1);\
1880                     punpcklbw_r2r(mm7,mm2);\
1881                     punpcklbw_r2r(mm7,mm3);\
1882                     punpcklbw_r2r(mm7,mm4);\
1883                     paddw_r2r(mm3,mm1);\
1884                     psllw_i2r(1,mm2);\
1885                     paddw_r2r(mm4,mm0);\
1886                     psllw_i2r(2,mm1);\
1887                     paddw_r2r(mm6,mm2);\
1888                     paddw_r2r(mm2,mm1);\
1889                     psubusw_r2r(mm0,mm1);\
1890                     psrlw_i2r(3,mm1);\
1891                     packuswb_r2r(mm7,mm1);\
1892                     movd_r2m(mm1,lum_m2[0]);
1893
1894 #define DEINT_LINE_LUM \
1895                     movd_m2r(lum_m4[0],mm0);\
1896                     movd_m2r(lum_m3[0],mm1);\
1897                     movd_m2r(lum_m2[0],mm2);\
1898                     movd_m2r(lum_m1[0],mm3);\
1899                     movd_m2r(lum[0],mm4);\
1900                     punpcklbw_r2r(mm7,mm0);\
1901                     punpcklbw_r2r(mm7,mm1);\
1902                     punpcklbw_r2r(mm7,mm2);\
1903                     punpcklbw_r2r(mm7,mm3);\
1904                     punpcklbw_r2r(mm7,mm4);\
1905                     paddw_r2r(mm3,mm1);\
1906                     psllw_i2r(1,mm2);\
1907                     paddw_r2r(mm4,mm0);\
1908                     psllw_i2r(2,mm1);\
1909                     paddw_r2r(mm6,mm2);\
1910                     paddw_r2r(mm2,mm1);\
1911                     psubusw_r2r(mm0,mm1);\
1912                     psrlw_i2r(3,mm1);\
1913                     packuswb_r2r(mm7,mm1);\
1914                     movd_r2m(mm1,dst[0]);
1915 #endif
1916
1917 /* filter parameters: [-1 4 2 4 -1] // 8 */
1918 static void deinterlace_line(uint8_t *dst, uint8_t *lum_m4, uint8_t *lum_m3, uint8_t *lum_m2, uint8_t *lum_m1, uint8_t *lum,
1919                                 int size)
1920 {
1921 #ifndef HAVE_MMX
1922     uint8_t *cm = cropTbl + MAX_NEG_CROP;
1923     int sum;
1924
1925     for(;size > 0;size--) {
1926         sum = -lum_m4[0];
1927         sum += lum_m3[0] << 2;
1928         sum += lum_m2[0] << 1;
1929         sum += lum_m1[0] << 2;
1930         sum += -lum[0];
1931         dst[0] = cm[(sum + 4) >> 3];
1932         lum_m4++;
1933         lum_m3++;
1934         lum_m2++;
1935         lum_m1++;
1936         lum++;
1937         dst++;
1938     }
1939 #else
1940
1941     {
1942         mmx_t rounder;
1943         rounder.uw[0]=4;
1944         rounder.uw[1]=4;
1945         rounder.uw[2]=4;
1946         rounder.uw[3]=4;
1947         pxor_r2r(mm7,mm7);
1948         movq_m2r(rounder,mm6);
1949     }
1950     for (;size > 3; size-=4) {
1951         DEINT_LINE_LUM
1952         lum_m4+=4;
1953         lum_m3+=4;
1954         lum_m2+=4;
1955         lum_m1+=4;
1956         lum+=4;
1957         dst+=4;
1958     }
1959 #endif
1960 }
1961 static void deinterlace_line_inplace(uint8_t *lum_m4, uint8_t *lum_m3, uint8_t *lum_m2, uint8_t *lum_m1, uint8_t *lum,
1962                              int size)
1963 {
1964 #ifndef HAVE_MMX
1965     uint8_t *cm = cropTbl + MAX_NEG_CROP;
1966     int sum;
1967
1968     for(;size > 0;size--) {
1969         sum = -lum_m4[0];
1970         sum += lum_m3[0] << 2;
1971         sum += lum_m2[0] << 1;
1972         lum_m4[0]=lum_m2[0];
1973         sum += lum_m1[0] << 2;
1974         sum += -lum[0];
1975         lum_m2[0] = cm[(sum + 4) >> 3];
1976         lum_m4++;
1977         lum_m3++;
1978         lum_m2++;
1979         lum_m1++;
1980         lum++;
1981     }
1982 #else
1983
1984     {
1985         mmx_t rounder;
1986         rounder.uw[0]=4;
1987         rounder.uw[1]=4;
1988         rounder.uw[2]=4;
1989         rounder.uw[3]=4;
1990         pxor_r2r(mm7,mm7);
1991         movq_m2r(rounder,mm6);
1992     }
1993     for (;size > 3; size-=4) {
1994         DEINT_INPLACE_LINE_LUM
1995         lum_m4+=4;
1996         lum_m3+=4;
1997         lum_m2+=4;
1998         lum_m1+=4;
1999         lum+=4;
2000     }
2001 #endif
2002 }
2003
2004 /* deinterlacing : 2 temporal taps, 3 spatial taps linear filter. The
2005    top field is copied as is, but the bottom field is deinterlaced
2006    against the top field. */
2007 static void deinterlace_bottom_field(uint8_t *dst, int dst_wrap,
2008                                     uint8_t *src1, int src_wrap,
2009                                     int width, int height)
2010 {
2011     uint8_t *src_m2, *src_m1, *src_0, *src_p1, *src_p2;
2012     int y;
2013
2014     src_m2 = src1;
2015     src_m1 = src1;
2016     src_0=&src_m1[src_wrap];
2017     src_p1=&src_0[src_wrap];
2018     src_p2=&src_p1[src_wrap];
2019     for(y=0;y<(height-2);y+=2) {
2020         memcpy(dst,src_m1,width);
2021         dst += dst_wrap;
2022         deinterlace_line(dst,src_m2,src_m1,src_0,src_p1,src_p2,width);
2023         src_m2 = src_0;
2024         src_m1 = src_p1;
2025         src_0 = src_p2;
2026         src_p1 += 2*src_wrap;
2027         src_p2 += 2*src_wrap;
2028         dst += dst_wrap;
2029     }
2030     memcpy(dst,src_m1,width);
2031     dst += dst_wrap;
2032     /* do last line */
2033     deinterlace_line(dst,src_m2,src_m1,src_0,src_0,src_0,width);
2034 }
2035
2036 static void deinterlace_bottom_field_inplace(uint8_t *src1, int src_wrap,
2037                                      int width, int height)
2038 {
2039     uint8_t *src_m1, *src_0, *src_p1, *src_p2;
2040     int y;
2041     uint8_t *buf;
2042     buf = (uint8_t*)av_malloc(width);
2043
2044     src_m1 = src1;
2045     memcpy(buf,src_m1,width);
2046     src_0=&src_m1[src_wrap];
2047     src_p1=&src_0[src_wrap];
2048     src_p2=&src_p1[src_wrap];
2049     for(y=0;y<(height-2);y+=2) {
2050         deinterlace_line_inplace(buf,src_m1,src_0,src_p1,src_p2,width);
2051         src_m1 = src_p1;
2052         src_0 = src_p2;
2053         src_p1 += 2*src_wrap;
2054         src_p2 += 2*src_wrap;
2055     }
2056     /* do last line */
2057     deinterlace_line_inplace(buf,src_m1,src_0,src_0,src_0,width);
2058     av_free(buf);
2059 }
2060
2061
2062 /* deinterlace - if not supported return -1 */
2063 int avpicture_deinterlace(AVPicture *dst, AVPicture *src,
2064                           int pix_fmt, int width, int height)
2065 {
2066     int i;
2067
2068     if (pix_fmt != PIX_FMT_YUV420P &&
2069         pix_fmt != PIX_FMT_YUV422P &&
2070         pix_fmt != PIX_FMT_YUV444P)
2071         return -1;
2072     if ((width & 3) != 0 || (height & 3) != 0)
2073         return -1;
2074
2075     for(i=0;i<3;i++) {
2076         if (i == 1) {
2077             switch(pix_fmt) {
2078             case PIX_FMT_YUV420P:
2079                 width >>= 1;
2080                 height >>= 1;
2081                 break;
2082             case PIX_FMT_YUV422P:
2083                 width >>= 1;
2084                 break;
2085             default:
2086                 break;
2087             }
2088         }
2089         if (src == dst) {
2090             deinterlace_bottom_field_inplace(src->data[i], src->linesize[i],
2091                                  width, height);
2092         } else {
2093             deinterlace_bottom_field(dst->data[i],dst->linesize[i],
2094                                         src->data[i], src->linesize[i],
2095                                         width, height);
2096         }
2097     }
2098 #ifdef HAVE_MMX
2099     emms();
2100 #endif
2101     return 0;
2102 }
2103
2104 #undef FIX