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