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