380fe71732a6248b8c76f867c69f28b09473c873
[ffmpeg.git] / libavcodec / imgconvert.c
1 /*
2  * Misc image convertion routines
3  * Copyright (c) 2001, 2002, 2003 Fabrice Bellard.
4  *
5  * This file is part of FFmpeg.
6  *
7  * FFmpeg is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public
9  * License as published by the Free Software Foundation; either
10  * version 2.1 of the License, or (at your option) any later version.
11  *
12  * FFmpeg is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  * Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public
18  * License along with FFmpeg; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20  */
21
22 /**
23  * @file imgconvert.c
24  * Misc image convertion routines.
25  */
26
27 /* TODO:
28  * - write 'ffimg' program to test all the image related stuff
29  * - move all api to slice based system
30  * - integrate deinterlacing, postprocessing and scaling in the conversion process
31  */
32
33 #include "avcodec.h"
34 #include "dsputil.h"
35
36 #ifdef USE_FASTMEMCPY
37 #include "libvo/fastmemcpy.h"
38 #endif
39
40 #ifdef HAVE_MMX
41 #include "i386/mmx.h"
42 #endif
43
44 #define xglue(x, y) x ## y
45 #define glue(x, y) xglue(x, y)
46
47 #define FF_COLOR_RGB      0 /**< RGB color space */
48 #define FF_COLOR_GRAY     1 /**< gray color space */
49 #define FF_COLOR_YUV      2 /**< YUV color space. 16 <= Y <= 235, 16 <= U, V <= 240 */
50 #define FF_COLOR_YUV_JPEG 3 /**< YUV color space. 0 <= Y <= 255, 0 <= U, V <= 255 */
51
52 #define FF_PIXEL_PLANAR   0 /**< each channel has one component in AVPicture */
53 #define FF_PIXEL_PACKED   1 /**< only one components containing all the channels */
54 #define FF_PIXEL_PALETTE  2  /**< one components containing indexes for a palette */
55
56 typedef struct PixFmtInfo {
57     const char *name;
58     uint8_t nb_channels;     /**< number of channels (including alpha) */
59     uint8_t color_type;      /**< color type (see FF_COLOR_xxx constants) */
60     uint8_t pixel_type;      /**< pixel storage type (see FF_PIXEL_xxx constants) */
61     uint8_t is_alpha : 1;    /**< true if alpha can be specified */
62     uint8_t x_chroma_shift;  /**< X chroma subsampling factor is 2 ^ shift */
63     uint8_t y_chroma_shift;  /**< Y chroma subsampling factor is 2 ^ shift */
64     uint8_t depth;           /**< bit depth of the color components */
65 } PixFmtInfo;
66
67 /* this table gives more information about formats */
68 static const PixFmtInfo pix_fmt_info[PIX_FMT_NB] = {
69     /* YUV formats */
70     [PIX_FMT_YUV420P] = {
71         .name = "yuv420p",
72         .nb_channels = 3,
73         .color_type = FF_COLOR_YUV,
74         .pixel_type = FF_PIXEL_PLANAR,
75         .depth = 8,
76         .x_chroma_shift = 1, .y_chroma_shift = 1,
77     },
78     [PIX_FMT_YUV422P] = {
79         .name = "yuv422p",
80         .nb_channels = 3,
81         .color_type = FF_COLOR_YUV,
82         .pixel_type = FF_PIXEL_PLANAR,
83         .depth = 8,
84         .x_chroma_shift = 1, .y_chroma_shift = 0,
85     },
86     [PIX_FMT_YUV444P] = {
87         .name = "yuv444p",
88         .nb_channels = 3,
89         .color_type = FF_COLOR_YUV,
90         .pixel_type = FF_PIXEL_PLANAR,
91         .depth = 8,
92         .x_chroma_shift = 0, .y_chroma_shift = 0,
93     },
94     [PIX_FMT_YUYV422] = {
95         .name = "yuyv422",
96         .nb_channels = 1,
97         .color_type = FF_COLOR_YUV,
98         .pixel_type = FF_PIXEL_PACKED,
99         .depth = 8,
100         .x_chroma_shift = 1, .y_chroma_shift = 0,
101     },
102     [PIX_FMT_UYVY422] = {
103         .name = "uyvy422",
104         .nb_channels = 1,
105         .color_type = FF_COLOR_YUV,
106         .pixel_type = FF_PIXEL_PACKED,
107         .depth = 8,
108         .x_chroma_shift = 1, .y_chroma_shift = 0,
109     },
110     [PIX_FMT_YUV410P] = {
111         .name = "yuv410p",
112         .nb_channels = 3,
113         .color_type = FF_COLOR_YUV,
114         .pixel_type = FF_PIXEL_PLANAR,
115         .depth = 8,
116         .x_chroma_shift = 2, .y_chroma_shift = 2,
117     },
118     [PIX_FMT_YUV411P] = {
119         .name = "yuv411p",
120         .nb_channels = 3,
121         .color_type = FF_COLOR_YUV,
122         .pixel_type = FF_PIXEL_PLANAR,
123         .depth = 8,
124         .x_chroma_shift = 2, .y_chroma_shift = 0,
125     },
126
127     /* JPEG YUV */
128     [PIX_FMT_YUVJ420P] = {
129         .name = "yuvj420p",
130         .nb_channels = 3,
131         .color_type = FF_COLOR_YUV_JPEG,
132         .pixel_type = FF_PIXEL_PLANAR,
133         .depth = 8,
134         .x_chroma_shift = 1, .y_chroma_shift = 1,
135     },
136     [PIX_FMT_YUVJ422P] = {
137         .name = "yuvj422p",
138         .nb_channels = 3,
139         .color_type = FF_COLOR_YUV_JPEG,
140         .pixel_type = FF_PIXEL_PLANAR,
141         .depth = 8,
142         .x_chroma_shift = 1, .y_chroma_shift = 0,
143     },
144     [PIX_FMT_YUVJ444P] = {
145         .name = "yuvj444p",
146         .nb_channels = 3,
147         .color_type = FF_COLOR_YUV_JPEG,
148         .pixel_type = FF_PIXEL_PLANAR,
149         .depth = 8,
150         .x_chroma_shift = 0, .y_chroma_shift = 0,
151     },
152
153     /* RGB formats */
154     [PIX_FMT_RGB24] = {
155         .name = "rgb24",
156         .nb_channels = 3,
157         .color_type = FF_COLOR_RGB,
158         .pixel_type = FF_PIXEL_PACKED,
159         .depth = 8,
160         .x_chroma_shift = 0, .y_chroma_shift = 0,
161     },
162     [PIX_FMT_BGR24] = {
163         .name = "bgr24",
164         .nb_channels = 3,
165         .color_type = FF_COLOR_RGB,
166         .pixel_type = FF_PIXEL_PACKED,
167         .depth = 8,
168         .x_chroma_shift = 0, .y_chroma_shift = 0,
169     },
170     [PIX_FMT_RGB32] = {
171         .name = "rgb32",
172         .nb_channels = 4, .is_alpha = 1,
173         .color_type = FF_COLOR_RGB,
174         .pixel_type = FF_PIXEL_PACKED,
175         .depth = 8,
176         .x_chroma_shift = 0, .y_chroma_shift = 0,
177     },
178     [PIX_FMT_RGB565] = {
179         .name = "rgb565",
180         .nb_channels = 3,
181         .color_type = FF_COLOR_RGB,
182         .pixel_type = FF_PIXEL_PACKED,
183         .depth = 5,
184         .x_chroma_shift = 0, .y_chroma_shift = 0,
185     },
186     [PIX_FMT_RGB555] = {
187         .name = "rgb555",
188         .nb_channels = 3,
189         .color_type = FF_COLOR_RGB,
190         .pixel_type = FF_PIXEL_PACKED,
191         .depth = 5,
192         .x_chroma_shift = 0, .y_chroma_shift = 0,
193     },
194
195     /* gray / mono formats */
196     [PIX_FMT_GRAY16BE] = {
197         .name = "gray16be",
198         .nb_channels = 1,
199         .color_type = FF_COLOR_GRAY,
200         .pixel_type = FF_PIXEL_PLANAR,
201         .depth = 16,
202     },
203     [PIX_FMT_GRAY16LE] = {
204         .name = "gray16le",
205         .nb_channels = 1,
206         .color_type = FF_COLOR_GRAY,
207         .pixel_type = FF_PIXEL_PLANAR,
208         .depth = 16,
209     },
210     [PIX_FMT_GRAY8] = {
211         .name = "gray",
212         .nb_channels = 1,
213         .color_type = FF_COLOR_GRAY,
214         .pixel_type = FF_PIXEL_PLANAR,
215         .depth = 8,
216     },
217     [PIX_FMT_MONOWHITE] = {
218         .name = "monow",
219         .nb_channels = 1,
220         .color_type = FF_COLOR_GRAY,
221         .pixel_type = FF_PIXEL_PLANAR,
222         .depth = 1,
223     },
224     [PIX_FMT_MONOBLACK] = {
225         .name = "monob",
226         .nb_channels = 1,
227         .color_type = FF_COLOR_GRAY,
228         .pixel_type = FF_PIXEL_PLANAR,
229         .depth = 1,
230     },
231
232     /* paletted formats */
233     [PIX_FMT_PAL8] = {
234         .name = "pal8",
235         .nb_channels = 4, .is_alpha = 1,
236         .color_type = FF_COLOR_RGB,
237         .pixel_type = FF_PIXEL_PALETTE,
238         .depth = 8,
239     },
240     [PIX_FMT_XVMC_MPEG2_MC] = {
241         .name = "xvmcmc",
242     },
243     [PIX_FMT_XVMC_MPEG2_IDCT] = {
244         .name = "xvmcidct",
245     },
246     [PIX_FMT_UYYVYY411] = {
247         .name = "uyyvyy411",
248         .nb_channels = 1,
249         .color_type = FF_COLOR_YUV,
250         .pixel_type = FF_PIXEL_PACKED,
251         .depth = 8,
252         .x_chroma_shift = 2, .y_chroma_shift = 0,
253     },
254     [PIX_FMT_BGR32] = {
255         .name = "bgr32",
256         .nb_channels = 4, .is_alpha = 1,
257         .color_type = FF_COLOR_RGB,
258         .pixel_type = FF_PIXEL_PACKED,
259         .depth = 8,
260         .x_chroma_shift = 0, .y_chroma_shift = 0,
261     },
262     [PIX_FMT_BGR565] = {
263         .name = "bgr565",
264         .nb_channels = 3,
265         .color_type = FF_COLOR_RGB,
266         .pixel_type = FF_PIXEL_PACKED,
267         .depth = 5,
268         .x_chroma_shift = 0, .y_chroma_shift = 0,
269     },
270     [PIX_FMT_BGR555] = {
271         .name = "bgr555",
272         .nb_channels = 3,
273         .color_type = FF_COLOR_RGB,
274         .pixel_type = FF_PIXEL_PACKED,
275         .depth = 5,
276         .x_chroma_shift = 0, .y_chroma_shift = 0,
277     },
278     [PIX_FMT_RGB8] = {
279         .name = "rgb8",
280         .nb_channels = 1,
281         .color_type = FF_COLOR_RGB,
282         .pixel_type = FF_PIXEL_PACKED,
283         .depth = 8,
284         .x_chroma_shift = 0, .y_chroma_shift = 0,
285     },
286     [PIX_FMT_RGB4] = {
287         .name = "rgb4",
288         .nb_channels = 1,
289         .color_type = FF_COLOR_RGB,
290         .pixel_type = FF_PIXEL_PACKED,
291         .depth = 4,
292         .x_chroma_shift = 0, .y_chroma_shift = 0,
293     },
294     [PIX_FMT_RGB4_BYTE] = {
295         .name = "rgb4_byte",
296         .nb_channels = 1,
297         .color_type = FF_COLOR_RGB,
298         .pixel_type = FF_PIXEL_PACKED,
299         .depth = 8,
300         .x_chroma_shift = 0, .y_chroma_shift = 0,
301     },
302     [PIX_FMT_BGR8] = {
303         .name = "bgr8",
304         .nb_channels = 1,
305         .color_type = FF_COLOR_RGB,
306         .pixel_type = FF_PIXEL_PACKED,
307         .depth = 8,
308         .x_chroma_shift = 0, .y_chroma_shift = 0,
309     },
310     [PIX_FMT_BGR4] = {
311         .name = "bgr4",
312         .nb_channels = 1,
313         .color_type = FF_COLOR_RGB,
314         .pixel_type = FF_PIXEL_PACKED,
315         .depth = 4,
316         .x_chroma_shift = 0, .y_chroma_shift = 0,
317     },
318     [PIX_FMT_BGR4_BYTE] = {
319         .name = "bgr4_byte",
320         .nb_channels = 1,
321         .color_type = FF_COLOR_RGB,
322         .pixel_type = FF_PIXEL_PACKED,
323         .depth = 8,
324         .x_chroma_shift = 0, .y_chroma_shift = 0,
325     },
326     [PIX_FMT_NV12] = {
327         .name = "nv12",
328         .nb_channels = 2,
329         .color_type = FF_COLOR_YUV,
330         .pixel_type = FF_PIXEL_PLANAR,
331         .depth = 8,
332         .x_chroma_shift = 1, .y_chroma_shift = 1,
333     },
334     [PIX_FMT_NV21] = {
335         .name = "nv12",
336         .nb_channels = 2,
337         .color_type = FF_COLOR_YUV,
338         .pixel_type = FF_PIXEL_PLANAR,
339         .depth = 8,
340         .x_chroma_shift = 1, .y_chroma_shift = 1,
341     },
342
343     [PIX_FMT_BGR32_1] = {
344         .name = "bgr32_1",
345         .nb_channels = 4, .is_alpha = 1,
346         .color_type = FF_COLOR_RGB,
347         .pixel_type = FF_PIXEL_PACKED,
348         .depth = 8,
349         .x_chroma_shift = 0, .y_chroma_shift = 0,
350     },
351     [PIX_FMT_RGB32_1] = {
352         .name = "rgb32_1",
353         .nb_channels = 4, .is_alpha = 1,
354         .color_type = FF_COLOR_RGB,
355         .pixel_type = FF_PIXEL_PACKED,
356         .depth = 8,
357         .x_chroma_shift = 0, .y_chroma_shift = 0,
358     },
359 };
360
361 void avcodec_get_chroma_sub_sample(int pix_fmt, int *h_shift, int *v_shift)
362 {
363     *h_shift = pix_fmt_info[pix_fmt].x_chroma_shift;
364     *v_shift = pix_fmt_info[pix_fmt].y_chroma_shift;
365 }
366
367 const char *avcodec_get_pix_fmt_name(int pix_fmt)
368 {
369     if (pix_fmt < 0 || pix_fmt >= PIX_FMT_NB)
370         return "???";
371     else
372         return pix_fmt_info[pix_fmt].name;
373 }
374
375 enum PixelFormat avcodec_get_pix_fmt(const char* name)
376 {
377     int i;
378
379     for (i=0; i < PIX_FMT_NB; i++)
380          if (!strcmp(pix_fmt_info[i].name, name))
381              break;
382     return i;
383 }
384
385 /**
386  * Fill in AVPicture's fields.
387  * The fields of the given AVPicture are filled in by using the 'ptr' address
388  * which points to the image data buffer. Depending on the specified picture
389  * format, one or multiple image data pointers and line sizes will be set.
390  * If a planar format is specified, several pointers will be set pointing to
391  * the different picture planes and the line sizes of the different planes
392  * will be stored in the lines_sizes array.
393  *
394  * @param picture AVPicture who's fields are to be filled in
395  * @param ptr Buffer which will contain or contains the actual image data
396  * @param pix_fmt The format in which the picture data is stored
397  * @param width The width of the image in pixels
398  * @param height The height of the image in pixels
399  * @return Size of the image data in bytes.
400  */
401 int avpicture_fill(AVPicture *picture, uint8_t *ptr,
402                    int pix_fmt, int width, int height)
403 {
404     int size, w2, h2, size2;
405     const PixFmtInfo *pinfo;
406
407     if(avcodec_check_dimensions(NULL, width, height))
408         goto fail;
409
410     pinfo = &pix_fmt_info[pix_fmt];
411     size = width * height;
412     switch(pix_fmt) {
413     case PIX_FMT_YUV420P:
414     case PIX_FMT_YUV422P:
415     case PIX_FMT_YUV444P:
416     case PIX_FMT_YUV410P:
417     case PIX_FMT_YUV411P:
418     case PIX_FMT_YUVJ420P:
419     case PIX_FMT_YUVJ422P:
420     case PIX_FMT_YUVJ444P:
421         w2 = (width + (1 << pinfo->x_chroma_shift) - 1) >> pinfo->x_chroma_shift;
422         h2 = (height + (1 << pinfo->y_chroma_shift) - 1) >> pinfo->y_chroma_shift;
423         size2 = w2 * h2;
424         picture->data[0] = ptr;
425         picture->data[1] = picture->data[0] + size;
426         picture->data[2] = picture->data[1] + size2;
427         picture->linesize[0] = width;
428         picture->linesize[1] = w2;
429         picture->linesize[2] = w2;
430         return size + 2 * size2;
431     case PIX_FMT_NV12:
432     case PIX_FMT_NV21:
433         w2 = (width + (1 << pinfo->x_chroma_shift) - 1) >> pinfo->x_chroma_shift;
434         h2 = (height + (1 << pinfo->y_chroma_shift) - 1) >> pinfo->y_chroma_shift;
435         size2 = w2 * h2 * 2;
436         picture->data[0] = ptr;
437         picture->data[1] = picture->data[0] + size;
438         picture->data[2] = NULL;
439         picture->linesize[0] = width;
440         picture->linesize[1] = w2;
441         picture->linesize[2] = 0;
442         return size + 2 * size2;
443     case PIX_FMT_RGB24:
444     case PIX_FMT_BGR24:
445         picture->data[0] = ptr;
446         picture->data[1] = NULL;
447         picture->data[2] = NULL;
448         picture->linesize[0] = width * 3;
449         return size * 3;
450     case PIX_FMT_RGB32:
451     case PIX_FMT_BGR32:
452     case PIX_FMT_RGB32_1:
453     case PIX_FMT_BGR32_1:
454         picture->data[0] = ptr;
455         picture->data[1] = NULL;
456         picture->data[2] = NULL;
457         picture->linesize[0] = width * 4;
458         return size * 4;
459     case PIX_FMT_GRAY16BE:
460     case PIX_FMT_GRAY16LE:
461     case PIX_FMT_BGR555:
462     case PIX_FMT_BGR565:
463     case PIX_FMT_RGB555:
464     case PIX_FMT_RGB565:
465     case PIX_FMT_YUYV422:
466         picture->data[0] = ptr;
467         picture->data[1] = NULL;
468         picture->data[2] = NULL;
469         picture->linesize[0] = width * 2;
470         return size * 2;
471     case PIX_FMT_UYVY422:
472         picture->data[0] = ptr;
473         picture->data[1] = NULL;
474         picture->data[2] = NULL;
475         picture->linesize[0] = width * 2;
476         return size * 2;
477     case PIX_FMT_UYYVYY411:
478         picture->data[0] = ptr;
479         picture->data[1] = NULL;
480         picture->data[2] = NULL;
481         picture->linesize[0] = width + width/2;
482         return size + size/2;
483     case PIX_FMT_RGB8:
484     case PIX_FMT_BGR8:
485     case PIX_FMT_RGB4_BYTE:
486     case PIX_FMT_BGR4_BYTE:
487     case PIX_FMT_GRAY8:
488         picture->data[0] = ptr;
489         picture->data[1] = NULL;
490         picture->data[2] = NULL;
491         picture->linesize[0] = width;
492         return size;
493     case PIX_FMT_RGB4:
494     case PIX_FMT_BGR4:
495         picture->data[0] = ptr;
496         picture->data[1] = NULL;
497         picture->data[2] = NULL;
498         picture->linesize[0] = width / 2;
499         return size / 2;
500     case PIX_FMT_MONOWHITE:
501     case PIX_FMT_MONOBLACK:
502         picture->data[0] = ptr;
503         picture->data[1] = NULL;
504         picture->data[2] = NULL;
505         picture->linesize[0] = (width + 7) >> 3;
506         return picture->linesize[0] * height;
507     case PIX_FMT_PAL8:
508         size2 = (size + 3) & ~3;
509         picture->data[0] = ptr;
510         picture->data[1] = ptr + size2; /* palette is stored here as 256 32 bit words */
511         picture->data[2] = NULL;
512         picture->linesize[0] = width;
513         picture->linesize[1] = 4;
514         return size2 + 256 * 4;
515     default:
516 fail:
517         picture->data[0] = NULL;
518         picture->data[1] = NULL;
519         picture->data[2] = NULL;
520         picture->data[3] = NULL;
521         return -1;
522     }
523 }
524
525 int avpicture_layout(const AVPicture* src, int pix_fmt, int width, int height,
526                      unsigned char *dest, int dest_size)
527 {
528     const PixFmtInfo* pf = &pix_fmt_info[pix_fmt];
529     int i, j, w, h, data_planes;
530     const unsigned char* s;
531     int size = avpicture_get_size(pix_fmt, width, height);
532
533     if (size > dest_size || size < 0)
534         return -1;
535
536     if (pf->pixel_type == FF_PIXEL_PACKED || pf->pixel_type == FF_PIXEL_PALETTE) {
537         if (pix_fmt == PIX_FMT_YUYV422 ||
538             pix_fmt == PIX_FMT_UYVY422 ||
539             pix_fmt == PIX_FMT_BGR565 ||
540             pix_fmt == PIX_FMT_BGR555 ||
541             pix_fmt == PIX_FMT_RGB565 ||
542             pix_fmt == PIX_FMT_RGB555)
543             w = width * 2;
544         else if (pix_fmt == PIX_FMT_UYYVYY411)
545           w = width + width/2;
546         else if (pix_fmt == PIX_FMT_PAL8)
547           w = width;
548         else
549           w = width * (pf->depth * pf->nb_channels / 8);
550
551         data_planes = 1;
552         h = height;
553     } else {
554         data_planes = pf->nb_channels;
555         w = (width*pf->depth + 7)/8;
556         h = height;
557     }
558
559     for (i=0; i<data_planes; i++) {
560          if (i == 1) {
561              w = width >> pf->x_chroma_shift;
562              h = height >> pf->y_chroma_shift;
563          }
564          s = src->data[i];
565          for(j=0; j<h; j++) {
566              memcpy(dest, s, w);
567              dest += w;
568              s += src->linesize[i];
569          }
570     }
571
572     if (pf->pixel_type == FF_PIXEL_PALETTE)
573         memcpy((unsigned char *)(((size_t)dest + 3) & ~3), src->data[1], 256 * 4);
574
575     return size;
576 }
577
578 /**
579  * Calculate the size in bytes that a picture of the given width and height
580  * would occupy if stored in the given picture format.
581  *
582  * @param pix_fmt The given picture format
583  * @param width The width of the image
584  * @param height The height of the image
585  * @return Image data size in bytes
586  */
587 int avpicture_get_size(int pix_fmt, int width, int height)
588 {
589     AVPicture dummy_pict;
590     return avpicture_fill(&dummy_pict, NULL, pix_fmt, width, height);
591 }
592
593 /**
594  * compute the loss when converting from a pixel format to another
595  */
596 int avcodec_get_pix_fmt_loss(int dst_pix_fmt, int src_pix_fmt,
597                              int has_alpha)
598 {
599     const PixFmtInfo *pf, *ps;
600     int loss;
601
602     ps = &pix_fmt_info[src_pix_fmt];
603     pf = &pix_fmt_info[dst_pix_fmt];
604
605     /* compute loss */
606     loss = 0;
607     pf = &pix_fmt_info[dst_pix_fmt];
608     if (pf->depth < ps->depth ||
609         (dst_pix_fmt == PIX_FMT_RGB555 && src_pix_fmt == PIX_FMT_RGB565))
610         loss |= FF_LOSS_DEPTH;
611     if (pf->x_chroma_shift > ps->x_chroma_shift ||
612         pf->y_chroma_shift > ps->y_chroma_shift)
613         loss |= FF_LOSS_RESOLUTION;
614     switch(pf->color_type) {
615     case FF_COLOR_RGB:
616         if (ps->color_type != FF_COLOR_RGB &&
617             ps->color_type != FF_COLOR_GRAY)
618             loss |= FF_LOSS_COLORSPACE;
619         break;
620     case FF_COLOR_GRAY:
621         if (ps->color_type != FF_COLOR_GRAY)
622             loss |= FF_LOSS_COLORSPACE;
623         break;
624     case FF_COLOR_YUV:
625         if (ps->color_type != FF_COLOR_YUV)
626             loss |= FF_LOSS_COLORSPACE;
627         break;
628     case FF_COLOR_YUV_JPEG:
629         if (ps->color_type != FF_COLOR_YUV_JPEG &&
630             ps->color_type != FF_COLOR_YUV &&
631             ps->color_type != FF_COLOR_GRAY)
632             loss |= FF_LOSS_COLORSPACE;
633         break;
634     default:
635         /* fail safe test */
636         if (ps->color_type != pf->color_type)
637             loss |= FF_LOSS_COLORSPACE;
638         break;
639     }
640     if (pf->color_type == FF_COLOR_GRAY &&
641         ps->color_type != FF_COLOR_GRAY)
642         loss |= FF_LOSS_CHROMA;
643     if (!pf->is_alpha && (ps->is_alpha && has_alpha))
644         loss |= FF_LOSS_ALPHA;
645     if (pf->pixel_type == FF_PIXEL_PALETTE &&
646         (ps->pixel_type != FF_PIXEL_PALETTE && ps->color_type != FF_COLOR_GRAY))
647         loss |= FF_LOSS_COLORQUANT;
648     return loss;
649 }
650
651 static int avg_bits_per_pixel(int pix_fmt)
652 {
653     int bits;
654     const PixFmtInfo *pf;
655
656     pf = &pix_fmt_info[pix_fmt];
657     switch(pf->pixel_type) {
658     case FF_PIXEL_PACKED:
659         switch(pix_fmt) {
660         case PIX_FMT_YUYV422:
661         case PIX_FMT_UYVY422:
662         case PIX_FMT_RGB565:
663         case PIX_FMT_RGB555:
664         case PIX_FMT_BGR565:
665         case PIX_FMT_BGR555:
666             bits = 16;
667             break;
668         case PIX_FMT_UYYVYY411:
669             bits = 12;
670             break;
671         default:
672             bits = pf->depth * pf->nb_channels;
673             break;
674         }
675         break;
676     case FF_PIXEL_PLANAR:
677         if (pf->x_chroma_shift == 0 && pf->y_chroma_shift == 0) {
678             bits = pf->depth * pf->nb_channels;
679         } else {
680             bits = pf->depth + ((2 * pf->depth) >>
681                                 (pf->x_chroma_shift + pf->y_chroma_shift));
682         }
683         break;
684     case FF_PIXEL_PALETTE:
685         bits = 8;
686         break;
687     default:
688         bits = -1;
689         break;
690     }
691     return bits;
692 }
693
694 static int avcodec_find_best_pix_fmt1(int pix_fmt_mask,
695                                       int src_pix_fmt,
696                                       int has_alpha,
697                                       int loss_mask)
698 {
699     int dist, i, loss, min_dist, dst_pix_fmt;
700
701     /* find exact color match with smallest size */
702     dst_pix_fmt = -1;
703     min_dist = 0x7fffffff;
704     for(i = 0;i < PIX_FMT_NB; i++) {
705         if (pix_fmt_mask & (1 << i)) {
706             loss = avcodec_get_pix_fmt_loss(i, src_pix_fmt, has_alpha) & loss_mask;
707             if (loss == 0) {
708                 dist = avg_bits_per_pixel(i);
709                 if (dist < min_dist) {
710                     min_dist = dist;
711                     dst_pix_fmt = i;
712                 }
713             }
714         }
715     }
716     return dst_pix_fmt;
717 }
718
719 /**
720  * find best pixel format to convert to. Return -1 if none found
721  */
722 int avcodec_find_best_pix_fmt(int pix_fmt_mask, int src_pix_fmt,
723                               int has_alpha, int *loss_ptr)
724 {
725     int dst_pix_fmt, loss_mask, i;
726     static const int loss_mask_order[] = {
727         ~0, /* no loss first */
728         ~FF_LOSS_ALPHA,
729         ~FF_LOSS_RESOLUTION,
730         ~(FF_LOSS_COLORSPACE | FF_LOSS_RESOLUTION),
731         ~FF_LOSS_COLORQUANT,
732         ~FF_LOSS_DEPTH,
733         0,
734     };
735
736     /* try with successive loss */
737     i = 0;
738     for(;;) {
739         loss_mask = loss_mask_order[i++];
740         dst_pix_fmt = avcodec_find_best_pix_fmt1(pix_fmt_mask, src_pix_fmt,
741                                                  has_alpha, loss_mask);
742         if (dst_pix_fmt >= 0)
743             goto found;
744         if (loss_mask == 0)
745             break;
746     }
747     return -1;
748  found:
749     if (loss_ptr)
750         *loss_ptr = avcodec_get_pix_fmt_loss(dst_pix_fmt, src_pix_fmt, has_alpha);
751     return dst_pix_fmt;
752 }
753
754 void ff_img_copy_plane(uint8_t *dst, int dst_wrap,
755                            const uint8_t *src, int src_wrap,
756                            int width, int height)
757 {
758     if((!dst) || (!src))
759         return;
760     for(;height > 0; height--) {
761         memcpy(dst, src, width);
762         dst += dst_wrap;
763         src += src_wrap;
764     }
765 }
766
767 /**
768  * Copy image 'src' to 'dst'.
769  */
770 void img_copy(AVPicture *dst, const AVPicture *src,
771               int pix_fmt, int width, int height)
772 {
773     int bwidth, bits, i;
774     const PixFmtInfo *pf = &pix_fmt_info[pix_fmt];
775
776     pf = &pix_fmt_info[pix_fmt];
777     switch(pf->pixel_type) {
778     case FF_PIXEL_PACKED:
779         switch(pix_fmt) {
780         case PIX_FMT_YUYV422:
781         case PIX_FMT_UYVY422:
782         case PIX_FMT_RGB565:
783         case PIX_FMT_RGB555:
784         case PIX_FMT_BGR565:
785         case PIX_FMT_BGR555:
786             bits = 16;
787             break;
788         case PIX_FMT_UYYVYY411:
789             bits = 12;
790             break;
791         default:
792             bits = pf->depth * pf->nb_channels;
793             break;
794         }
795         bwidth = (width * bits + 7) >> 3;
796         ff_img_copy_plane(dst->data[0], dst->linesize[0],
797                        src->data[0], src->linesize[0],
798                        bwidth, height);
799         break;
800     case FF_PIXEL_PLANAR:
801         for(i = 0; i < pf->nb_channels; i++) {
802             int w, h;
803             w = width;
804             h = height;
805             if (i == 1 || i == 2) {
806                 w >>= pf->x_chroma_shift;
807                 h >>= pf->y_chroma_shift;
808             }
809             bwidth = (w * pf->depth + 7) >> 3;
810             ff_img_copy_plane(dst->data[i], dst->linesize[i],
811                            src->data[i], src->linesize[i],
812                            bwidth, h);
813         }
814         break;
815     case FF_PIXEL_PALETTE:
816         ff_img_copy_plane(dst->data[0], dst->linesize[0],
817                        src->data[0], src->linesize[0],
818                        width, height);
819         /* copy the palette */
820         ff_img_copy_plane(dst->data[1], dst->linesize[1],
821                        src->data[1], src->linesize[1],
822                        4, 256);
823         break;
824     }
825 }
826
827 /* XXX: totally non optimized */
828
829 static void yuyv422_to_yuv420p(AVPicture *dst, const AVPicture *src,
830                               int width, int height)
831 {
832     const uint8_t *p, *p1;
833     uint8_t *lum, *cr, *cb, *lum1, *cr1, *cb1;
834     int w;
835
836     p1 = src->data[0];
837     lum1 = dst->data[0];
838     cb1 = dst->data[1];
839     cr1 = dst->data[2];
840
841     for(;height >= 1; height -= 2) {
842         p = p1;
843         lum = lum1;
844         cb = cb1;
845         cr = cr1;
846         for(w = width; w >= 2; w -= 2) {
847             lum[0] = p[0];
848             cb[0] = p[1];
849             lum[1] = p[2];
850             cr[0] = p[3];
851             p += 4;
852             lum += 2;
853             cb++;
854             cr++;
855         }
856         if (w) {
857             lum[0] = p[0];
858             cb[0] = p[1];
859             cr[0] = p[3];
860             cb++;
861             cr++;
862         }
863         p1 += src->linesize[0];
864         lum1 += dst->linesize[0];
865         if (height>1) {
866             p = p1;
867             lum = lum1;
868             for(w = width; w >= 2; w -= 2) {
869                 lum[0] = p[0];
870                 lum[1] = p[2];
871                 p += 4;
872                 lum += 2;
873             }
874             if (w) {
875                 lum[0] = p[0];
876             }
877             p1 += src->linesize[0];
878             lum1 += dst->linesize[0];
879         }
880         cb1 += dst->linesize[1];
881         cr1 += dst->linesize[2];
882     }
883 }
884
885 static void uyvy422_to_yuv420p(AVPicture *dst, const AVPicture *src,
886                               int width, int height)
887 {
888     const uint8_t *p, *p1;
889     uint8_t *lum, *cr, *cb, *lum1, *cr1, *cb1;
890     int w;
891
892     p1 = src->data[0];
893
894     lum1 = dst->data[0];
895     cb1 = dst->data[1];
896     cr1 = dst->data[2];
897
898     for(;height >= 1; height -= 2) {
899         p = p1;
900         lum = lum1;
901         cb = cb1;
902         cr = cr1;
903         for(w = width; w >= 2; w -= 2) {
904             lum[0] = p[1];
905             cb[0] = p[0];
906             lum[1] = p[3];
907             cr[0] = p[2];
908             p += 4;
909             lum += 2;
910             cb++;
911             cr++;
912         }
913         if (w) {
914             lum[0] = p[1];
915             cb[0] = p[0];
916             cr[0] = p[2];
917             cb++;
918             cr++;
919         }
920         p1 += src->linesize[0];
921         lum1 += dst->linesize[0];
922         if (height>1) {
923             p = p1;
924             lum = lum1;
925             for(w = width; w >= 2; w -= 2) {
926                 lum[0] = p[1];
927                 lum[1] = p[3];
928                 p += 4;
929                 lum += 2;
930             }
931             if (w) {
932                 lum[0] = p[1];
933             }
934             p1 += src->linesize[0];
935             lum1 += dst->linesize[0];
936         }
937         cb1 += dst->linesize[1];
938         cr1 += dst->linesize[2];
939     }
940 }
941
942
943 static void uyvy422_to_yuv422p(AVPicture *dst, const AVPicture *src,
944                               int width, int height)
945 {
946     const uint8_t *p, *p1;
947     uint8_t *lum, *cr, *cb, *lum1, *cr1, *cb1;
948     int w;
949
950     p1 = src->data[0];
951     lum1 = dst->data[0];
952     cb1 = dst->data[1];
953     cr1 = dst->data[2];
954     for(;height > 0; height--) {
955         p = p1;
956         lum = lum1;
957         cb = cb1;
958         cr = cr1;
959         for(w = width; w >= 2; w -= 2) {
960             lum[0] = p[1];
961             cb[0] = p[0];
962             lum[1] = p[3];
963             cr[0] = p[2];
964             p += 4;
965             lum += 2;
966             cb++;
967             cr++;
968         }
969         p1 += src->linesize[0];
970         lum1 += dst->linesize[0];
971         cb1 += dst->linesize[1];
972         cr1 += dst->linesize[2];
973     }
974 }
975
976
977 static void yuyv422_to_yuv422p(AVPicture *dst, const AVPicture *src,
978                               int width, int height)
979 {
980     const uint8_t *p, *p1;
981     uint8_t *lum, *cr, *cb, *lum1, *cr1, *cb1;
982     int w;
983
984     p1 = src->data[0];
985     lum1 = dst->data[0];
986     cb1 = dst->data[1];
987     cr1 = dst->data[2];
988     for(;height > 0; height--) {
989         p = p1;
990         lum = lum1;
991         cb = cb1;
992         cr = cr1;
993         for(w = width; w >= 2; w -= 2) {
994             lum[0] = p[0];
995             cb[0] = p[1];
996             lum[1] = p[2];
997             cr[0] = p[3];
998             p += 4;
999             lum += 2;
1000             cb++;
1001             cr++;
1002         }
1003         p1 += src->linesize[0];
1004         lum1 += dst->linesize[0];
1005         cb1 += dst->linesize[1];
1006         cr1 += dst->linesize[2];
1007     }
1008 }
1009
1010 static void yuv422p_to_yuyv422(AVPicture *dst, const AVPicture *src,
1011                               int width, int height)
1012 {
1013     uint8_t *p, *p1;
1014     const uint8_t *lum, *cr, *cb, *lum1, *cr1, *cb1;
1015     int w;
1016
1017     p1 = dst->data[0];
1018     lum1 = src->data[0];
1019     cb1 = src->data[1];
1020     cr1 = src->data[2];
1021     for(;height > 0; height--) {
1022         p = p1;
1023         lum = lum1;
1024         cb = cb1;
1025         cr = cr1;
1026         for(w = width; w >= 2; w -= 2) {
1027             p[0] = lum[0];
1028             p[1] = cb[0];
1029             p[2] = lum[1];
1030             p[3] = cr[0];
1031             p += 4;
1032             lum += 2;
1033             cb++;
1034             cr++;
1035         }
1036         p1 += dst->linesize[0];
1037         lum1 += src->linesize[0];
1038         cb1 += src->linesize[1];
1039         cr1 += src->linesize[2];
1040     }
1041 }
1042
1043 static void yuv422p_to_uyvy422(AVPicture *dst, const AVPicture *src,
1044                               int width, int height)
1045 {
1046     uint8_t *p, *p1;
1047     const uint8_t *lum, *cr, *cb, *lum1, *cr1, *cb1;
1048     int w;
1049
1050     p1 = dst->data[0];
1051     lum1 = src->data[0];
1052     cb1 = src->data[1];
1053     cr1 = src->data[2];
1054     for(;height > 0; height--) {
1055         p = p1;
1056         lum = lum1;
1057         cb = cb1;
1058         cr = cr1;
1059         for(w = width; w >= 2; w -= 2) {
1060             p[1] = lum[0];
1061             p[0] = cb[0];
1062             p[3] = lum[1];
1063             p[2] = cr[0];
1064             p += 4;
1065             lum += 2;
1066             cb++;
1067             cr++;
1068         }
1069         p1 += dst->linesize[0];
1070         lum1 += src->linesize[0];
1071         cb1 += src->linesize[1];
1072         cr1 += src->linesize[2];
1073     }
1074 }
1075
1076 static void uyyvyy411_to_yuv411p(AVPicture *dst, const AVPicture *src,
1077                               int width, int height)
1078 {
1079     const uint8_t *p, *p1;
1080     uint8_t *lum, *cr, *cb, *lum1, *cr1, *cb1;
1081     int w;
1082
1083     p1 = src->data[0];
1084     lum1 = dst->data[0];
1085     cb1 = dst->data[1];
1086     cr1 = dst->data[2];
1087     for(;height > 0; height--) {
1088         p = p1;
1089         lum = lum1;
1090         cb = cb1;
1091         cr = cr1;
1092         for(w = width; w >= 4; w -= 4) {
1093             cb[0] = p[0];
1094             lum[0] = p[1];
1095             lum[1] = p[2];
1096             cr[0] = p[3];
1097             lum[2] = p[4];
1098             lum[3] = p[5];
1099             p += 6;
1100             lum += 4;
1101             cb++;
1102             cr++;
1103         }
1104         p1 += src->linesize[0];
1105         lum1 += dst->linesize[0];
1106         cb1 += dst->linesize[1];
1107         cr1 += dst->linesize[2];
1108     }
1109 }
1110
1111
1112 static void yuv420p_to_yuyv422(AVPicture *dst, const AVPicture *src,
1113                               int width, int height)
1114 {
1115     int w, h;
1116     uint8_t *line1, *line2, *linesrc = dst->data[0];
1117     uint8_t *lum1, *lum2, *lumsrc = src->data[0];
1118     uint8_t *cb1, *cb2 = src->data[1];
1119     uint8_t *cr1, *cr2 = src->data[2];
1120
1121     for(h = height / 2; h--;) {
1122         line1 = linesrc;
1123         line2 = linesrc + dst->linesize[0];
1124
1125         lum1 = lumsrc;
1126         lum2 = lumsrc + src->linesize[0];
1127
1128         cb1 = cb2;
1129         cr1 = cr2;
1130
1131         for(w = width / 2; w--;) {
1132                 *line1++ = *lum1++; *line2++ = *lum2++;
1133                 *line1++ =          *line2++ = *cb1++;
1134                 *line1++ = *lum1++; *line2++ = *lum2++;
1135                 *line1++ =          *line2++ = *cr1++;
1136         }
1137
1138         linesrc += dst->linesize[0] * 2;
1139         lumsrc += src->linesize[0] * 2;
1140         cb2 += src->linesize[1];
1141         cr2 += src->linesize[2];
1142     }
1143 }
1144
1145 static void yuv420p_to_uyvy422(AVPicture *dst, const AVPicture *src,
1146                               int width, int height)
1147 {
1148     int w, h;
1149     uint8_t *line1, *line2, *linesrc = dst->data[0];
1150     uint8_t *lum1, *lum2, *lumsrc = src->data[0];
1151     uint8_t *cb1, *cb2 = src->data[1];
1152     uint8_t *cr1, *cr2 = src->data[2];
1153
1154     for(h = height / 2; h--;) {
1155         line1 = linesrc;
1156         line2 = linesrc + dst->linesize[0];
1157
1158         lum1 = lumsrc;
1159         lum2 = lumsrc + src->linesize[0];
1160
1161         cb1 = cb2;
1162         cr1 = cr2;
1163
1164         for(w = width / 2; w--;) {
1165                 *line1++ =          *line2++ = *cb1++;
1166                 *line1++ = *lum1++; *line2++ = *lum2++;
1167                 *line1++ =          *line2++ = *cr1++;
1168                 *line1++ = *lum1++; *line2++ = *lum2++;
1169         }
1170
1171         linesrc += dst->linesize[0] * 2;
1172         lumsrc += src->linesize[0] * 2;
1173         cb2 += src->linesize[1];
1174         cr2 += src->linesize[2];
1175     }
1176 }
1177
1178 #define SCALEBITS 10
1179 #define ONE_HALF  (1 << (SCALEBITS - 1))
1180 #define FIX(x)    ((int) ((x) * (1<<SCALEBITS) + 0.5))
1181
1182 #define YUV_TO_RGB1_CCIR(cb1, cr1)\
1183 {\
1184     cb = (cb1) - 128;\
1185     cr = (cr1) - 128;\
1186     r_add = FIX(1.40200*255.0/224.0) * cr + ONE_HALF;\
1187     g_add = - FIX(0.34414*255.0/224.0) * cb - FIX(0.71414*255.0/224.0) * cr + \
1188             ONE_HALF;\
1189     b_add = FIX(1.77200*255.0/224.0) * cb + ONE_HALF;\
1190 }
1191
1192 #define YUV_TO_RGB2_CCIR(r, g, b, y1)\
1193 {\
1194     y = ((y1) - 16) * FIX(255.0/219.0);\
1195     r = cm[(y + r_add) >> SCALEBITS];\
1196     g = cm[(y + g_add) >> SCALEBITS];\
1197     b = cm[(y + b_add) >> SCALEBITS];\
1198 }
1199
1200 #define YUV_TO_RGB1(cb1, cr1)\
1201 {\
1202     cb = (cb1) - 128;\
1203     cr = (cr1) - 128;\
1204     r_add = FIX(1.40200) * cr + ONE_HALF;\
1205     g_add = - FIX(0.34414) * cb - FIX(0.71414) * cr + ONE_HALF;\
1206     b_add = FIX(1.77200) * cb + ONE_HALF;\
1207 }
1208
1209 #define YUV_TO_RGB2(r, g, b, y1)\
1210 {\
1211     y = (y1) << SCALEBITS;\
1212     r = cm[(y + r_add) >> SCALEBITS];\
1213     g = cm[(y + g_add) >> SCALEBITS];\
1214     b = cm[(y + b_add) >> SCALEBITS];\
1215 }
1216
1217 #define Y_CCIR_TO_JPEG(y)\
1218  cm[((y) * FIX(255.0/219.0) + (ONE_HALF - 16 * FIX(255.0/219.0))) >> SCALEBITS]
1219
1220 #define Y_JPEG_TO_CCIR(y)\
1221  (((y) * FIX(219.0/255.0) + (ONE_HALF + (16 << SCALEBITS))) >> SCALEBITS)
1222
1223 #define C_CCIR_TO_JPEG(y)\
1224  cm[(((y) - 128) * FIX(127.0/112.0) + (ONE_HALF + (128 << SCALEBITS))) >> SCALEBITS]
1225
1226 /* NOTE: the clamp is really necessary! */
1227 static inline int C_JPEG_TO_CCIR(int y) {
1228     y = (((y - 128) * FIX(112.0/127.0) + (ONE_HALF + (128 << SCALEBITS))) >> SCALEBITS);
1229     if (y < 16)
1230         y = 16;
1231     return y;
1232 }
1233
1234
1235 #define RGB_TO_Y(r, g, b) \
1236 ((FIX(0.29900) * (r) + FIX(0.58700) * (g) + \
1237   FIX(0.11400) * (b) + ONE_HALF) >> SCALEBITS)
1238
1239 #define RGB_TO_U(r1, g1, b1, shift)\
1240 (((- FIX(0.16874) * r1 - FIX(0.33126) * g1 +         \
1241      FIX(0.50000) * b1 + (ONE_HALF << shift) - 1) >> (SCALEBITS + shift)) + 128)
1242
1243 #define RGB_TO_V(r1, g1, b1, shift)\
1244 (((FIX(0.50000) * r1 - FIX(0.41869) * g1 -           \
1245    FIX(0.08131) * b1 + (ONE_HALF << shift) - 1) >> (SCALEBITS + shift)) + 128)
1246
1247 #define RGB_TO_Y_CCIR(r, g, b) \
1248 ((FIX(0.29900*219.0/255.0) * (r) + FIX(0.58700*219.0/255.0) * (g) + \
1249   FIX(0.11400*219.0/255.0) * (b) + (ONE_HALF + (16 << SCALEBITS))) >> SCALEBITS)
1250
1251 #define RGB_TO_U_CCIR(r1, g1, b1, shift)\
1252 (((- FIX(0.16874*224.0/255.0) * r1 - FIX(0.33126*224.0/255.0) * g1 +         \
1253      FIX(0.50000*224.0/255.0) * b1 + (ONE_HALF << shift) - 1) >> (SCALEBITS + shift)) + 128)
1254
1255 #define RGB_TO_V_CCIR(r1, g1, b1, shift)\
1256 (((FIX(0.50000*224.0/255.0) * r1 - FIX(0.41869*224.0/255.0) * g1 -           \
1257    FIX(0.08131*224.0/255.0) * b1 + (ONE_HALF << shift) - 1) >> (SCALEBITS + shift)) + 128)
1258
1259 static uint8_t y_ccir_to_jpeg[256];
1260 static uint8_t y_jpeg_to_ccir[256];
1261 static uint8_t c_ccir_to_jpeg[256];
1262 static uint8_t c_jpeg_to_ccir[256];
1263
1264 /* init various conversion tables */
1265 static void img_convert_init(void)
1266 {
1267     int i;
1268     uint8_t *cm = ff_cropTbl + MAX_NEG_CROP;
1269
1270     for(i = 0;i < 256; i++) {
1271         y_ccir_to_jpeg[i] = Y_CCIR_TO_JPEG(i);
1272         y_jpeg_to_ccir[i] = Y_JPEG_TO_CCIR(i);
1273         c_ccir_to_jpeg[i] = C_CCIR_TO_JPEG(i);
1274         c_jpeg_to_ccir[i] = C_JPEG_TO_CCIR(i);
1275     }
1276 }
1277
1278 /* apply to each pixel the given table */
1279 static void img_apply_table(uint8_t *dst, int dst_wrap,
1280                             const uint8_t *src, int src_wrap,
1281                             int width, int height, const uint8_t *table1)
1282 {
1283     int n;
1284     const uint8_t *s;
1285     uint8_t *d;
1286     const uint8_t *table;
1287
1288     table = table1;
1289     for(;height > 0; height--) {
1290         s = src;
1291         d = dst;
1292         n = width;
1293         while (n >= 4) {
1294             d[0] = table[s[0]];
1295             d[1] = table[s[1]];
1296             d[2] = table[s[2]];
1297             d[3] = table[s[3]];
1298             d += 4;
1299             s += 4;
1300             n -= 4;
1301         }
1302         while (n > 0) {
1303             d[0] = table[s[0]];
1304             d++;
1305             s++;
1306             n--;
1307         }
1308         dst += dst_wrap;
1309         src += src_wrap;
1310     }
1311 }
1312
1313 /* XXX: use generic filter ? */
1314 /* XXX: in most cases, the sampling position is incorrect */
1315
1316 /* 4x1 -> 1x1 */
1317 static void shrink41(uint8_t *dst, int dst_wrap,
1318                      const uint8_t *src, int src_wrap,
1319                      int width, int height)
1320 {
1321     int w;
1322     const uint8_t *s;
1323     uint8_t *d;
1324
1325     for(;height > 0; height--) {
1326         s = src;
1327         d = dst;
1328         for(w = width;w > 0; w--) {
1329             d[0] = (s[0] + s[1] + s[2] + s[3] + 2) >> 2;
1330             s += 4;
1331             d++;
1332         }
1333         src += src_wrap;
1334         dst += dst_wrap;
1335     }
1336 }
1337
1338 /* 2x1 -> 1x1 */
1339 static void shrink21(uint8_t *dst, int dst_wrap,
1340                      const uint8_t *src, int src_wrap,
1341                      int width, int height)
1342 {
1343     int w;
1344     const uint8_t *s;
1345     uint8_t *d;
1346
1347     for(;height > 0; height--) {
1348         s = src;
1349         d = dst;
1350         for(w = width;w > 0; w--) {
1351             d[0] = (s[0] + s[1]) >> 1;
1352             s += 2;
1353             d++;
1354         }
1355         src += src_wrap;
1356         dst += dst_wrap;
1357     }
1358 }
1359
1360 /* 1x2 -> 1x1 */
1361 static void shrink12(uint8_t *dst, int dst_wrap,
1362                      const uint8_t *src, int src_wrap,
1363                      int width, int height)
1364 {
1365     int w;
1366     uint8_t *d;
1367     const uint8_t *s1, *s2;
1368
1369     for(;height > 0; height--) {
1370         s1 = src;
1371         s2 = s1 + src_wrap;
1372         d = dst;
1373         for(w = width;w >= 4; w-=4) {
1374             d[0] = (s1[0] + s2[0]) >> 1;
1375             d[1] = (s1[1] + s2[1]) >> 1;
1376             d[2] = (s1[2] + s2[2]) >> 1;
1377             d[3] = (s1[3] + s2[3]) >> 1;
1378             s1 += 4;
1379             s2 += 4;
1380             d += 4;
1381         }
1382         for(;w > 0; w--) {
1383             d[0] = (s1[0] + s2[0]) >> 1;
1384             s1++;
1385             s2++;
1386             d++;
1387         }
1388         src += 2 * src_wrap;
1389         dst += dst_wrap;
1390     }
1391 }
1392
1393 /* 2x2 -> 1x1 */
1394 void ff_shrink22(uint8_t *dst, int dst_wrap,
1395                      const uint8_t *src, int src_wrap,
1396                      int width, int height)
1397 {
1398     int w;
1399     const uint8_t *s1, *s2;
1400     uint8_t *d;
1401
1402     for(;height > 0; height--) {
1403         s1 = src;
1404         s2 = s1 + src_wrap;
1405         d = dst;
1406         for(w = width;w >= 4; w-=4) {
1407             d[0] = (s1[0] + s1[1] + s2[0] + s2[1] + 2) >> 2;
1408             d[1] = (s1[2] + s1[3] + s2[2] + s2[3] + 2) >> 2;
1409             d[2] = (s1[4] + s1[5] + s2[4] + s2[5] + 2) >> 2;
1410             d[3] = (s1[6] + s1[7] + s2[6] + s2[7] + 2) >> 2;
1411             s1 += 8;
1412             s2 += 8;
1413             d += 4;
1414         }
1415         for(;w > 0; w--) {
1416             d[0] = (s1[0] + s1[1] + s2[0] + s2[1] + 2) >> 2;
1417             s1 += 2;
1418             s2 += 2;
1419             d++;
1420         }
1421         src += 2 * src_wrap;
1422         dst += dst_wrap;
1423     }
1424 }
1425
1426 /* 4x4 -> 1x1 */
1427 void ff_shrink44(uint8_t *dst, int dst_wrap,
1428                      const uint8_t *src, int src_wrap,
1429                      int width, int height)
1430 {
1431     int w;
1432     const uint8_t *s1, *s2, *s3, *s4;
1433     uint8_t *d;
1434
1435     for(;height > 0; height--) {
1436         s1 = src;
1437         s2 = s1 + src_wrap;
1438         s3 = s2 + src_wrap;
1439         s4 = s3 + src_wrap;
1440         d = dst;
1441         for(w = width;w > 0; w--) {
1442             d[0] = (s1[0] + s1[1] + s1[2] + s1[3] +
1443                     s2[0] + s2[1] + s2[2] + s2[3] +
1444                     s3[0] + s3[1] + s3[2] + s3[3] +
1445                     s4[0] + s4[1] + s4[2] + s4[3] + 8) >> 4;
1446             s1 += 4;
1447             s2 += 4;
1448             s3 += 4;
1449             s4 += 4;
1450             d++;
1451         }
1452         src += 4 * src_wrap;
1453         dst += dst_wrap;
1454     }
1455 }
1456
1457 /* 8x8 -> 1x1 */
1458 void ff_shrink88(uint8_t *dst, int dst_wrap,
1459                      const uint8_t *src, int src_wrap,
1460                      int width, int height)
1461 {
1462     int w, i;
1463
1464     for(;height > 0; height--) {
1465         for(w = width;w > 0; w--) {
1466             int tmp=0;
1467             for(i=0; i<8; i++){
1468                 tmp += src[0] + src[1] + src[2] + src[3] + src[4] + src[5] + src[6] + src[7];
1469                 src += src_wrap;
1470             }
1471             *(dst++) = (tmp + 32)>>6;
1472             src += 8 - 8*src_wrap;
1473         }
1474         src += 8*src_wrap - 8*width;
1475         dst += dst_wrap - width;
1476     }
1477 }
1478
1479 static void grow21_line(uint8_t *dst, const uint8_t *src,
1480                         int width)
1481 {
1482     int w;
1483     const uint8_t *s1;
1484     uint8_t *d;
1485
1486     s1 = src;
1487     d = dst;
1488     for(w = width;w >= 4; w-=4) {
1489         d[1] = d[0] = s1[0];
1490         d[3] = d[2] = s1[1];
1491         s1 += 2;
1492         d += 4;
1493     }
1494     for(;w >= 2; w -= 2) {
1495         d[1] = d[0] = s1[0];
1496         s1 ++;
1497         d += 2;
1498     }
1499     /* only needed if width is not a multiple of two */
1500     /* XXX: veryfy that */
1501     if (w) {
1502         d[0] = s1[0];
1503     }
1504 }
1505
1506 static void grow41_line(uint8_t *dst, const uint8_t *src,
1507                         int width)
1508 {
1509     int w, v;
1510     const uint8_t *s1;
1511     uint8_t *d;
1512
1513     s1 = src;
1514     d = dst;
1515     for(w = width;w >= 4; w-=4) {
1516         v = s1[0];
1517         d[0] = v;
1518         d[1] = v;
1519         d[2] = v;
1520         d[3] = v;
1521         s1 ++;
1522         d += 4;
1523     }
1524 }
1525
1526 /* 1x1 -> 2x1 */
1527 static void grow21(uint8_t *dst, int dst_wrap,
1528                    const uint8_t *src, int src_wrap,
1529                    int width, int height)
1530 {
1531     for(;height > 0; height--) {
1532         grow21_line(dst, src, width);
1533         src += src_wrap;
1534         dst += dst_wrap;
1535     }
1536 }
1537
1538 /* 1x1 -> 2x2 */
1539 static void grow22(uint8_t *dst, int dst_wrap,
1540                    const uint8_t *src, int src_wrap,
1541                    int width, int height)
1542 {
1543     for(;height > 0; height--) {
1544         grow21_line(dst, src, width);
1545         if (height%2)
1546             src += src_wrap;
1547         dst += dst_wrap;
1548     }
1549 }
1550
1551 /* 1x1 -> 4x1 */
1552 static void grow41(uint8_t *dst, int dst_wrap,
1553                    const uint8_t *src, int src_wrap,
1554                    int width, int height)
1555 {
1556     for(;height > 0; height--) {
1557         grow41_line(dst, src, width);
1558         src += src_wrap;
1559         dst += dst_wrap;
1560     }
1561 }
1562
1563 /* 1x1 -> 4x4 */
1564 static void grow44(uint8_t *dst, int dst_wrap,
1565                    const uint8_t *src, int src_wrap,
1566                    int width, int height)
1567 {
1568     for(;height > 0; height--) {
1569         grow41_line(dst, src, width);
1570         if ((height & 3) == 1)
1571             src += src_wrap;
1572         dst += dst_wrap;
1573     }
1574 }
1575
1576 /* 1x2 -> 2x1 */
1577 static void conv411(uint8_t *dst, int dst_wrap,
1578                     const uint8_t *src, int src_wrap,
1579                     int width, int height)
1580 {
1581     int w, c;
1582     const uint8_t *s1, *s2;
1583     uint8_t *d;
1584
1585     width>>=1;
1586
1587     for(;height > 0; height--) {
1588         s1 = src;
1589         s2 = src + src_wrap;
1590         d = dst;
1591         for(w = width;w > 0; w--) {
1592             c = (s1[0] + s2[0]) >> 1;
1593             d[0] = c;
1594             d[1] = c;
1595             s1++;
1596             s2++;
1597             d += 2;
1598         }
1599         src += src_wrap * 2;
1600         dst += dst_wrap;
1601     }
1602 }
1603
1604 /* XXX: add jpeg quantize code */
1605
1606 #define TRANSP_INDEX (6*6*6)
1607
1608 /* this is maybe slow, but allows for extensions */
1609 static inline unsigned char gif_clut_index(uint8_t r, uint8_t g, uint8_t b)
1610 {
1611     return ((((r)/47)%6)*6*6+(((g)/47)%6)*6+(((b)/47)%6));
1612 }
1613
1614 static void build_rgb_palette(uint8_t *palette, int has_alpha)
1615 {
1616     uint32_t *pal;
1617     static const uint8_t pal_value[6] = { 0x00, 0x33, 0x66, 0x99, 0xcc, 0xff };
1618     int i, r, g, b;
1619
1620     pal = (uint32_t *)palette;
1621     i = 0;
1622     for(r = 0; r < 6; r++) {
1623         for(g = 0; g < 6; g++) {
1624             for(b = 0; b < 6; b++) {
1625                 pal[i++] = (0xff << 24) | (pal_value[r] << 16) |
1626                     (pal_value[g] << 8) | pal_value[b];
1627             }
1628         }
1629     }
1630     if (has_alpha)
1631         pal[i++] = 0;
1632     while (i < 256)
1633         pal[i++] = 0xff000000;
1634 }
1635
1636 /* copy bit n to bits 0 ... n - 1 */
1637 static inline unsigned int bitcopy_n(unsigned int a, int n)
1638 {
1639     int mask;
1640     mask = (1 << n) - 1;
1641     return (a & (0xff & ~mask)) | ((-((a >> n) & 1)) & mask);
1642 }
1643
1644 /* rgb555 handling */
1645
1646 #define RGB_NAME rgb555
1647
1648 #define RGB_IN(r, g, b, s)\
1649 {\
1650     unsigned int v = ((const uint16_t *)(s))[0];\
1651     r = bitcopy_n(v >> (10 - 3), 3);\
1652     g = bitcopy_n(v >> (5 - 3), 3);\
1653     b = bitcopy_n(v << 3, 3);\
1654 }
1655
1656
1657 #define RGB_OUT(d, r, g, b)\
1658 {\
1659     ((uint16_t *)(d))[0] = ((r >> 3) << 10) | ((g >> 3) << 5) | (b >> 3);\
1660 }
1661
1662 #define BPP 2
1663
1664 #include "imgconvert_template.h"
1665
1666 /* rgb565 handling */
1667
1668 #define RGB_NAME rgb565
1669
1670 #define RGB_IN(r, g, b, s)\
1671 {\
1672     unsigned int v = ((const uint16_t *)(s))[0];\
1673     r = bitcopy_n(v >> (11 - 3), 3);\
1674     g = bitcopy_n(v >> (5 - 2), 2);\
1675     b = bitcopy_n(v << 3, 3);\
1676 }
1677
1678 #define RGB_OUT(d, r, g, b)\
1679 {\
1680     ((uint16_t *)(d))[0] = ((r >> 3) << 11) | ((g >> 2) << 5) | (b >> 3);\
1681 }
1682
1683 #define BPP 2
1684
1685 #include "imgconvert_template.h"
1686
1687 /* bgr24 handling */
1688
1689 #define RGB_NAME bgr24
1690
1691 #define RGB_IN(r, g, b, s)\
1692 {\
1693     b = (s)[0];\
1694     g = (s)[1];\
1695     r = (s)[2];\
1696 }
1697
1698 #define RGB_OUT(d, r, g, b)\
1699 {\
1700     (d)[0] = b;\
1701     (d)[1] = g;\
1702     (d)[2] = r;\
1703 }
1704
1705 #define BPP 3
1706
1707 #include "imgconvert_template.h"
1708
1709 #undef RGB_IN
1710 #undef RGB_OUT
1711 #undef BPP
1712
1713 /* rgb24 handling */
1714
1715 #define RGB_NAME rgb24
1716 #define FMT_RGB24
1717
1718 #define RGB_IN(r, g, b, s)\
1719 {\
1720     r = (s)[0];\
1721     g = (s)[1];\
1722     b = (s)[2];\
1723 }
1724
1725 #define RGB_OUT(d, r, g, b)\
1726 {\
1727     (d)[0] = r;\
1728     (d)[1] = g;\
1729     (d)[2] = b;\
1730 }
1731
1732 #define BPP 3
1733
1734 #include "imgconvert_template.h"
1735
1736 /* rgb32 handling */
1737
1738 #define RGB_NAME rgb32
1739 #define FMT_RGB32
1740
1741 #define RGB_IN(r, g, b, s)\
1742 {\
1743     unsigned int v = ((const uint32_t *)(s))[0];\
1744     r = (v >> 16) & 0xff;\
1745     g = (v >> 8) & 0xff;\
1746     b = v & 0xff;\
1747 }
1748
1749 #define RGBA_IN(r, g, b, a, s)\
1750 {\
1751     unsigned int v = ((const uint32_t *)(s))[0];\
1752     a = (v >> 24) & 0xff;\
1753     r = (v >> 16) & 0xff;\
1754     g = (v >> 8) & 0xff;\
1755     b = v & 0xff;\
1756 }
1757
1758 #define RGBA_OUT(d, r, g, b, a)\
1759 {\
1760     ((uint32_t *)(d))[0] = (a << 24) | (r << 16) | (g << 8) | b;\
1761 }
1762
1763 #define BPP 4
1764
1765 #include "imgconvert_template.h"
1766
1767 static void mono_to_gray(AVPicture *dst, const AVPicture *src,
1768                          int width, int height, int xor_mask)
1769 {
1770     const unsigned char *p;
1771     unsigned char *q;
1772     int v, dst_wrap, src_wrap;
1773     int y, w;
1774
1775     p = src->data[0];
1776     src_wrap = src->linesize[0] - ((width + 7) >> 3);
1777
1778     q = dst->data[0];
1779     dst_wrap = dst->linesize[0] - width;
1780     for(y=0;y<height;y++) {
1781         w = width;
1782         while (w >= 8) {
1783             v = *p++ ^ xor_mask;
1784             q[0] = -(v >> 7);
1785             q[1] = -((v >> 6) & 1);
1786             q[2] = -((v >> 5) & 1);
1787             q[3] = -((v >> 4) & 1);
1788             q[4] = -((v >> 3) & 1);
1789             q[5] = -((v >> 2) & 1);
1790             q[6] = -((v >> 1) & 1);
1791             q[7] = -((v >> 0) & 1);
1792             w -= 8;
1793             q += 8;
1794         }
1795         if (w > 0) {
1796             v = *p++ ^ xor_mask;
1797             do {
1798                 q[0] = -((v >> 7) & 1);
1799                 q++;
1800                 v <<= 1;
1801             } while (--w);
1802         }
1803         p += src_wrap;
1804         q += dst_wrap;
1805     }
1806 }
1807
1808 static void monowhite_to_gray(AVPicture *dst, const AVPicture *src,
1809                                int width, int height)
1810 {
1811     mono_to_gray(dst, src, width, height, 0xff);
1812 }
1813
1814 static void monoblack_to_gray(AVPicture *dst, const AVPicture *src,
1815                                int width, int height)
1816 {
1817     mono_to_gray(dst, src, width, height, 0x00);
1818 }
1819
1820 static void gray_to_mono(AVPicture *dst, const AVPicture *src,
1821                          int width, int height, int xor_mask)
1822 {
1823     int n;
1824     const uint8_t *s;
1825     uint8_t *d;
1826     int j, b, v, n1, src_wrap, dst_wrap, y;
1827
1828     s = src->data[0];
1829     src_wrap = src->linesize[0] - width;
1830
1831     d = dst->data[0];
1832     dst_wrap = dst->linesize[0] - ((width + 7) >> 3);
1833
1834     for(y=0;y<height;y++) {
1835         n = width;
1836         while (n >= 8) {
1837             v = 0;
1838             for(j=0;j<8;j++) {
1839                 b = s[0];
1840                 s++;
1841                 v = (v << 1) | (b >> 7);
1842             }
1843             d[0] = v ^ xor_mask;
1844             d++;
1845             n -= 8;
1846         }
1847         if (n > 0) {
1848             n1 = n;
1849             v = 0;
1850             while (n > 0) {
1851                 b = s[0];
1852                 s++;
1853                 v = (v << 1) | (b >> 7);
1854                 n--;
1855             }
1856             d[0] = (v << (8 - (n1 & 7))) ^ xor_mask;
1857             d++;
1858         }
1859         s += src_wrap;
1860         d += dst_wrap;
1861     }
1862 }
1863
1864 static void gray_to_monowhite(AVPicture *dst, const AVPicture *src,
1865                               int width, int height)
1866 {
1867     gray_to_mono(dst, src, width, height, 0xff);
1868 }
1869
1870 static void gray_to_monoblack(AVPicture *dst, const AVPicture *src,
1871                               int width, int height)
1872 {
1873     gray_to_mono(dst, src, width, height, 0x00);
1874 }
1875
1876 static void gray_to_gray16(AVPicture *dst, const AVPicture *src,
1877                               int width, int height)
1878 {
1879     int x, y, src_wrap, dst_wrap;
1880     uint8_t *s, *d;
1881     s = src->data[0];
1882     src_wrap = src->linesize[0] - width;
1883     d = dst->data[0];
1884     dst_wrap = dst->linesize[0] - width * 2;
1885     for(y=0; y<height; y++){
1886         for(x=0; x<width; x++){
1887             *d++ = *s;
1888             *d++ = *s++;
1889         }
1890         s += src_wrap;
1891         d += dst_wrap;
1892     }
1893 }
1894
1895 static void gray16_to_gray(AVPicture *dst, const AVPicture *src,
1896                               int width, int height)
1897 {
1898     int x, y, src_wrap, dst_wrap;
1899     uint8_t *s, *d;
1900     s = src->data[0];
1901     src_wrap = src->linesize[0] - width * 2;
1902     d = dst->data[0];
1903     dst_wrap = dst->linesize[0] - width;
1904     for(y=0; y<height; y++){
1905         for(x=0; x<width; x++){
1906             *d++ = *s;
1907             s += 2;
1908         }
1909         s += src_wrap;
1910         d += dst_wrap;
1911     }
1912 }
1913
1914 static void gray16be_to_gray(AVPicture *dst, const AVPicture *src,
1915                               int width, int height)
1916 {
1917     gray16_to_gray(dst, src, width, height);
1918 }
1919
1920 static void gray16le_to_gray(AVPicture *dst, const AVPicture *src,
1921                               int width, int height)
1922 {
1923     gray16_to_gray(dst, src + 1, width, height);
1924 }
1925
1926 static void gray16_to_gray16(AVPicture *dst, const AVPicture *src,
1927                               int width, int height)
1928 {
1929     int x, y, src_wrap, dst_wrap;
1930     uint16_t *s, *d;
1931     s = src->data[0];
1932     src_wrap = (src->linesize[0] - width * 2)/2;
1933     d = dst->data[0];
1934     dst_wrap = (dst->linesize[0] - width * 2)/2;
1935     for(y=0; y<height; y++){
1936         for(x=0; x<width; x++){
1937             *d++ = bswap_16(*s++);
1938         }
1939         s += src_wrap;
1940         d += dst_wrap;
1941     }
1942 }
1943
1944
1945 typedef struct ConvertEntry {
1946     void (*convert)(AVPicture *dst,
1947                     const AVPicture *src, int width, int height);
1948 } ConvertEntry;
1949
1950 /* Add each new convertion function in this table. In order to be able
1951    to convert from any format to any format, the following constraints
1952    must be satisfied:
1953
1954    - all FF_COLOR_RGB formats must convert to and from PIX_FMT_RGB24
1955
1956    - all FF_COLOR_GRAY formats must convert to and from PIX_FMT_GRAY8
1957
1958    - all FF_COLOR_RGB formats with alpha must convert to and from PIX_FMT_RGB32
1959
1960    - PIX_FMT_YUV444P and PIX_FMT_YUVJ444P must convert to and from
1961      PIX_FMT_RGB24.
1962
1963    - PIX_FMT_422 must convert to and from PIX_FMT_422P.
1964
1965    The other conversion functions are just optimisations for common cases.
1966 */
1967 static const ConvertEntry convert_table[PIX_FMT_NB][PIX_FMT_NB] = {
1968     [PIX_FMT_YUV420P] = {
1969         [PIX_FMT_YUYV422] = {
1970             .convert = yuv420p_to_yuyv422,
1971         },
1972         [PIX_FMT_RGB555] = {
1973             .convert = yuv420p_to_rgb555
1974         },
1975         [PIX_FMT_RGB565] = {
1976             .convert = yuv420p_to_rgb565
1977         },
1978         [PIX_FMT_BGR24] = {
1979             .convert = yuv420p_to_bgr24
1980         },
1981         [PIX_FMT_RGB24] = {
1982             .convert = yuv420p_to_rgb24
1983         },
1984         [PIX_FMT_RGB32] = {
1985             .convert = yuv420p_to_rgb32
1986         },
1987         [PIX_FMT_UYVY422] = {
1988             .convert = yuv420p_to_uyvy422,
1989         },
1990     },
1991     [PIX_FMT_YUV422P] = {
1992         [PIX_FMT_YUYV422] = {
1993             .convert = yuv422p_to_yuyv422,
1994         },
1995         [PIX_FMT_UYVY422] = {
1996             .convert = yuv422p_to_uyvy422,
1997         },
1998     },
1999     [PIX_FMT_YUV444P] = {
2000         [PIX_FMT_RGB24] = {
2001             .convert = yuv444p_to_rgb24
2002         },
2003     },
2004     [PIX_FMT_YUVJ420P] = {
2005         [PIX_FMT_RGB555] = {
2006             .convert = yuvj420p_to_rgb555
2007         },
2008         [PIX_FMT_RGB565] = {
2009             .convert = yuvj420p_to_rgb565
2010         },
2011         [PIX_FMT_BGR24] = {
2012             .convert = yuvj420p_to_bgr24
2013         },
2014         [PIX_FMT_RGB24] = {
2015             .convert = yuvj420p_to_rgb24
2016         },
2017         [PIX_FMT_RGB32] = {
2018             .convert = yuvj420p_to_rgb32
2019         },
2020     },
2021     [PIX_FMT_YUVJ444P] = {
2022         [PIX_FMT_RGB24] = {
2023             .convert = yuvj444p_to_rgb24
2024         },
2025     },
2026     [PIX_FMT_YUYV422] = {
2027         [PIX_FMT_YUV420P] = {
2028             .convert = yuyv422_to_yuv420p,
2029         },
2030         [PIX_FMT_YUV422P] = {
2031             .convert = yuyv422_to_yuv422p,
2032         },
2033     },
2034     [PIX_FMT_UYVY422] = {
2035         [PIX_FMT_YUV420P] = {
2036             .convert = uyvy422_to_yuv420p,
2037         },
2038         [PIX_FMT_YUV422P] = {
2039             .convert = uyvy422_to_yuv422p,
2040         },
2041     },
2042     [PIX_FMT_RGB24] = {
2043         [PIX_FMT_YUV420P] = {
2044             .convert = rgb24_to_yuv420p
2045         },
2046         [PIX_FMT_RGB565] = {
2047             .convert = rgb24_to_rgb565
2048         },
2049         [PIX_FMT_RGB555] = {
2050             .convert = rgb24_to_rgb555
2051         },
2052         [PIX_FMT_RGB32] = {
2053             .convert = rgb24_to_rgb32
2054         },
2055         [PIX_FMT_BGR24] = {
2056             .convert = rgb24_to_bgr24
2057         },
2058         [PIX_FMT_GRAY8] = {
2059             .convert = rgb24_to_gray
2060         },
2061         [PIX_FMT_PAL8] = {
2062             .convert = rgb24_to_pal8
2063         },
2064         [PIX_FMT_YUV444P] = {
2065             .convert = rgb24_to_yuv444p
2066         },
2067         [PIX_FMT_YUVJ420P] = {
2068             .convert = rgb24_to_yuvj420p
2069         },
2070         [PIX_FMT_YUVJ444P] = {
2071             .convert = rgb24_to_yuvj444p
2072         },
2073     },
2074     [PIX_FMT_RGB32] = {
2075         [PIX_FMT_RGB24] = {
2076             .convert = rgb32_to_rgb24
2077         },
2078         [PIX_FMT_BGR24] = {
2079             .convert = rgb32_to_bgr24
2080         },
2081         [PIX_FMT_RGB565] = {
2082             .convert = rgb32_to_rgb565
2083         },
2084         [PIX_FMT_RGB555] = {
2085             .convert = rgb32_to_rgb555
2086         },
2087         [PIX_FMT_PAL8] = {
2088             .convert = rgb32_to_pal8
2089         },
2090         [PIX_FMT_YUV420P] = {
2091             .convert = rgb32_to_yuv420p
2092         },
2093         [PIX_FMT_GRAY8] = {
2094             .convert = rgb32_to_gray
2095         },
2096     },
2097     [PIX_FMT_BGR24] = {
2098         [PIX_FMT_RGB32] = {
2099             .convert = bgr24_to_rgb32
2100         },
2101         [PIX_FMT_RGB24] = {
2102             .convert = bgr24_to_rgb24
2103         },
2104         [PIX_FMT_YUV420P] = {
2105             .convert = bgr24_to_yuv420p
2106         },
2107         [PIX_FMT_GRAY8] = {
2108             .convert = bgr24_to_gray
2109         },
2110     },
2111     [PIX_FMT_RGB555] = {
2112         [PIX_FMT_RGB24] = {
2113             .convert = rgb555_to_rgb24
2114         },
2115         [PIX_FMT_RGB32] = {
2116             .convert = rgb555_to_rgb32
2117         },
2118         [PIX_FMT_YUV420P] = {
2119             .convert = rgb555_to_yuv420p
2120         },
2121         [PIX_FMT_GRAY8] = {
2122             .convert = rgb555_to_gray
2123         },
2124     },
2125     [PIX_FMT_RGB565] = {
2126         [PIX_FMT_RGB32] = {
2127             .convert = rgb565_to_rgb32
2128         },
2129         [PIX_FMT_RGB24] = {
2130             .convert = rgb565_to_rgb24
2131         },
2132         [PIX_FMT_YUV420P] = {
2133             .convert = rgb565_to_yuv420p
2134         },
2135         [PIX_FMT_GRAY8] = {
2136             .convert = rgb565_to_gray
2137         },
2138     },
2139     [PIX_FMT_GRAY16BE] = {
2140         [PIX_FMT_GRAY8] = {
2141             .convert = gray16be_to_gray
2142         },
2143         [PIX_FMT_GRAY16LE] = {
2144             .convert = gray16_to_gray16
2145         },
2146     },
2147     [PIX_FMT_GRAY16LE] = {
2148         [PIX_FMT_GRAY8] = {
2149             .convert = gray16le_to_gray
2150         },
2151         [PIX_FMT_GRAY16BE] = {
2152             .convert = gray16_to_gray16
2153         },
2154     },
2155     [PIX_FMT_GRAY8] = {
2156         [PIX_FMT_RGB555] = {
2157             .convert = gray_to_rgb555
2158         },
2159         [PIX_FMT_RGB565] = {
2160             .convert = gray_to_rgb565
2161         },
2162         [PIX_FMT_RGB24] = {
2163             .convert = gray_to_rgb24
2164         },
2165         [PIX_FMT_BGR24] = {
2166             .convert = gray_to_bgr24
2167         },
2168         [PIX_FMT_RGB32] = {
2169             .convert = gray_to_rgb32
2170         },
2171         [PIX_FMT_MONOWHITE] = {
2172             .convert = gray_to_monowhite
2173         },
2174         [PIX_FMT_MONOBLACK] = {
2175             .convert = gray_to_monoblack
2176         },
2177         [PIX_FMT_GRAY16LE] = {
2178             .convert = gray_to_gray16
2179         },
2180         [PIX_FMT_GRAY16BE] = {
2181             .convert = gray_to_gray16
2182         },
2183     },
2184     [PIX_FMT_MONOWHITE] = {
2185         [PIX_FMT_GRAY8] = {
2186             .convert = monowhite_to_gray
2187         },
2188     },
2189     [PIX_FMT_MONOBLACK] = {
2190         [PIX_FMT_GRAY8] = {
2191             .convert = monoblack_to_gray
2192         },
2193     },
2194     [PIX_FMT_PAL8] = {
2195         [PIX_FMT_RGB555] = {
2196             .convert = pal8_to_rgb555
2197         },
2198         [PIX_FMT_RGB565] = {
2199             .convert = pal8_to_rgb565
2200         },
2201         [PIX_FMT_BGR24] = {
2202             .convert = pal8_to_bgr24
2203         },
2204         [PIX_FMT_RGB24] = {
2205             .convert = pal8_to_rgb24
2206         },
2207         [PIX_FMT_RGB32] = {
2208             .convert = pal8_to_rgb32
2209         },
2210     },
2211     [PIX_FMT_UYYVYY411] = {
2212         [PIX_FMT_YUV411P] = {
2213             .convert = uyyvyy411_to_yuv411p,
2214         },
2215     },
2216
2217 };
2218
2219 int avpicture_alloc(AVPicture *picture,
2220                            int pix_fmt, int width, int height)
2221 {
2222     int size;
2223     void *ptr;
2224
2225     size = avpicture_get_size(pix_fmt, width, height);
2226     if(size<0)
2227         goto fail;
2228     ptr = av_malloc(size);
2229     if (!ptr)
2230         goto fail;
2231     avpicture_fill(picture, ptr, pix_fmt, width, height);
2232     return 0;
2233  fail:
2234     memset(picture, 0, sizeof(AVPicture));
2235     return -1;
2236 }
2237
2238 void avpicture_free(AVPicture *picture)
2239 {
2240     av_free(picture->data[0]);
2241 }
2242
2243 /* return true if yuv planar */
2244 static inline int is_yuv_planar(const PixFmtInfo *ps)
2245 {
2246     return (ps->color_type == FF_COLOR_YUV ||
2247             ps->color_type == FF_COLOR_YUV_JPEG) &&
2248         ps->pixel_type == FF_PIXEL_PLANAR;
2249 }
2250
2251 /**
2252  * Crop image top and left side
2253  */
2254 int img_crop(AVPicture *dst, const AVPicture *src,
2255               int pix_fmt, int top_band, int left_band)
2256 {
2257     int y_shift;
2258     int x_shift;
2259
2260     if (pix_fmt < 0 || pix_fmt >= PIX_FMT_NB || !is_yuv_planar(&pix_fmt_info[pix_fmt]))
2261         return -1;
2262
2263     y_shift = pix_fmt_info[pix_fmt].y_chroma_shift;
2264     x_shift = pix_fmt_info[pix_fmt].x_chroma_shift;
2265
2266     dst->data[0] = src->data[0] + (top_band * src->linesize[0]) + left_band;
2267     dst->data[1] = src->data[1] + ((top_band >> y_shift) * src->linesize[1]) + (left_band >> x_shift);
2268     dst->data[2] = src->data[2] + ((top_band >> y_shift) * src->linesize[2]) + (left_band >> x_shift);
2269
2270     dst->linesize[0] = src->linesize[0];
2271     dst->linesize[1] = src->linesize[1];
2272     dst->linesize[2] = src->linesize[2];
2273     return 0;
2274 }
2275
2276 /**
2277  * Pad image
2278  */
2279 int img_pad(AVPicture *dst, const AVPicture *src, int height, int width,
2280             int pix_fmt, int padtop, int padbottom, int padleft, int padright,
2281             int *color)
2282 {
2283     uint8_t *optr;
2284     int y_shift;
2285     int x_shift;
2286     int yheight;
2287     int i, y;
2288
2289     if (pix_fmt < 0 || pix_fmt >= PIX_FMT_NB ||
2290         !is_yuv_planar(&pix_fmt_info[pix_fmt])) return -1;
2291
2292     for (i = 0; i < 3; i++) {
2293         x_shift = i ? pix_fmt_info[pix_fmt].x_chroma_shift : 0;
2294         y_shift = i ? pix_fmt_info[pix_fmt].y_chroma_shift : 0;
2295
2296         if (padtop || padleft) {
2297             memset(dst->data[i], color[i],
2298                 dst->linesize[i] * (padtop >> y_shift) + (padleft >> x_shift));
2299         }
2300
2301         if (padleft || padright) {
2302             optr = dst->data[i] + dst->linesize[i] * (padtop >> y_shift) +
2303                 (dst->linesize[i] - (padright >> x_shift));
2304             yheight = (height - 1 - (padtop + padbottom)) >> y_shift;
2305             for (y = 0; y < yheight; y++) {
2306                 memset(optr, color[i], (padleft + padright) >> x_shift);
2307                 optr += dst->linesize[i];
2308             }
2309         }
2310
2311         if (src) { /* first line */
2312             uint8_t *iptr = src->data[i];
2313             optr = dst->data[i] + dst->linesize[i] * (padtop >> y_shift) +
2314                     (padleft >> x_shift);
2315             memcpy(optr, iptr, src->linesize[i]);
2316             iptr += src->linesize[i];
2317             optr = dst->data[i] + dst->linesize[i] * (padtop >> y_shift) +
2318                 (dst->linesize[i] - (padright >> x_shift));
2319             yheight = (height - 1 - (padtop + padbottom)) >> y_shift;
2320             for (y = 0; y < yheight; y++) {
2321                 memset(optr, color[i], (padleft + padright) >> x_shift);
2322                 memcpy(optr + ((padleft + padright) >> x_shift), iptr,
2323                     src->linesize[i]);
2324                 iptr += src->linesize[i];
2325                 optr += dst->linesize[i];
2326             }
2327         }
2328
2329         if (padbottom || padright) {
2330             optr = dst->data[i] + dst->linesize[i] *
2331                 ((height - padbottom) >> y_shift) - (padright >> x_shift);
2332             memset(optr, color[i],dst->linesize[i] *
2333                 (padbottom >> y_shift) + (padright >> x_shift));
2334         }
2335     }
2336     return 0;
2337 }
2338
2339 #ifndef CONFIG_SWSCALER
2340 /* XXX: always use linesize. Return -1 if not supported */
2341 int img_convert(AVPicture *dst, int dst_pix_fmt,
2342                 const AVPicture *src, int src_pix_fmt,
2343                 int src_width, int src_height)
2344 {
2345     static int inited;
2346     int i, ret, dst_width, dst_height, int_pix_fmt;
2347     const PixFmtInfo *src_pix, *dst_pix;
2348     const ConvertEntry *ce;
2349     AVPicture tmp1, *tmp = &tmp1;
2350
2351     if (src_pix_fmt < 0 || src_pix_fmt >= PIX_FMT_NB ||
2352         dst_pix_fmt < 0 || dst_pix_fmt >= PIX_FMT_NB)
2353         return -1;
2354     if (src_width <= 0 || src_height <= 0)
2355         return 0;
2356
2357     if (!inited) {
2358         inited = 1;
2359         img_convert_init();
2360     }
2361
2362     dst_width = src_width;
2363     dst_height = src_height;
2364
2365     dst_pix = &pix_fmt_info[dst_pix_fmt];
2366     src_pix = &pix_fmt_info[src_pix_fmt];
2367     if (src_pix_fmt == dst_pix_fmt) {
2368         /* no conversion needed: just copy */
2369         img_copy(dst, src, dst_pix_fmt, dst_width, dst_height);
2370         return 0;
2371     }
2372
2373     ce = &convert_table[src_pix_fmt][dst_pix_fmt];
2374     if (ce->convert) {
2375         /* specific conversion routine */
2376         ce->convert(dst, src, dst_width, dst_height);
2377         return 0;
2378     }
2379
2380     /* gray to YUV */
2381     if (is_yuv_planar(dst_pix) &&
2382         src_pix_fmt == PIX_FMT_GRAY8) {
2383         int w, h, y;
2384         uint8_t *d;
2385
2386         if (dst_pix->color_type == FF_COLOR_YUV_JPEG) {
2387             ff_img_copy_plane(dst->data[0], dst->linesize[0],
2388                      src->data[0], src->linesize[0],
2389                      dst_width, dst_height);
2390         } else {
2391             img_apply_table(dst->data[0], dst->linesize[0],
2392                             src->data[0], src->linesize[0],
2393                             dst_width, dst_height,
2394                             y_jpeg_to_ccir);
2395         }
2396         /* fill U and V with 128 */
2397         w = dst_width;
2398         h = dst_height;
2399         w >>= dst_pix->x_chroma_shift;
2400         h >>= dst_pix->y_chroma_shift;
2401         for(i = 1; i <= 2; i++) {
2402             d = dst->data[i];
2403             for(y = 0; y< h; y++) {
2404                 memset(d, 128, w);
2405                 d += dst->linesize[i];
2406             }
2407         }
2408         return 0;
2409     }
2410
2411     /* YUV to gray */
2412     if (is_yuv_planar(src_pix) &&
2413         dst_pix_fmt == PIX_FMT_GRAY8) {
2414         if (src_pix->color_type == FF_COLOR_YUV_JPEG) {
2415             ff_img_copy_plane(dst->data[0], dst->linesize[0],
2416                      src->data[0], src->linesize[0],
2417                      dst_width, dst_height);
2418         } else {
2419             img_apply_table(dst->data[0], dst->linesize[0],
2420                             src->data[0], src->linesize[0],
2421                             dst_width, dst_height,
2422                             y_ccir_to_jpeg);
2423         }
2424         return 0;
2425     }
2426
2427     /* YUV to YUV planar */
2428     if (is_yuv_planar(dst_pix) && is_yuv_planar(src_pix)) {
2429         int x_shift, y_shift, w, h, xy_shift;
2430         void (*resize_func)(uint8_t *dst, int dst_wrap,
2431                             const uint8_t *src, int src_wrap,
2432                             int width, int height);
2433
2434         /* compute chroma size of the smallest dimensions */
2435         w = dst_width;
2436         h = dst_height;
2437         if (dst_pix->x_chroma_shift >= src_pix->x_chroma_shift)
2438             w >>= dst_pix->x_chroma_shift;
2439         else
2440             w >>= src_pix->x_chroma_shift;
2441         if (dst_pix->y_chroma_shift >= src_pix->y_chroma_shift)
2442             h >>= dst_pix->y_chroma_shift;
2443         else
2444             h >>= src_pix->y_chroma_shift;
2445
2446         x_shift = (dst_pix->x_chroma_shift - src_pix->x_chroma_shift);
2447         y_shift = (dst_pix->y_chroma_shift - src_pix->y_chroma_shift);
2448         xy_shift = ((x_shift & 0xf) << 4) | (y_shift & 0xf);
2449         /* there must be filters for conversion at least from and to
2450            YUV444 format */
2451         switch(xy_shift) {
2452         case 0x00:
2453             resize_func = ff_img_copy_plane;
2454             break;
2455         case 0x10:
2456             resize_func = shrink21;
2457             break;
2458         case 0x20:
2459             resize_func = shrink41;
2460             break;
2461         case 0x01:
2462             resize_func = shrink12;
2463             break;
2464         case 0x11:
2465             resize_func = ff_shrink22;
2466             break;
2467         case 0x22:
2468             resize_func = ff_shrink44;
2469             break;
2470         case 0xf0:
2471             resize_func = grow21;
2472             break;
2473         case 0xe0:
2474             resize_func = grow41;
2475             break;
2476         case 0xff:
2477             resize_func = grow22;
2478             break;
2479         case 0xee:
2480             resize_func = grow44;
2481             break;
2482         case 0xf1:
2483             resize_func = conv411;
2484             break;
2485         default:
2486             /* currently not handled */
2487             goto no_chroma_filter;
2488         }
2489
2490         ff_img_copy_plane(dst->data[0], dst->linesize[0],
2491                        src->data[0], src->linesize[0],
2492                        dst_width, dst_height);
2493
2494         for(i = 1;i <= 2; i++)
2495             resize_func(dst->data[i], dst->linesize[i],
2496                         src->data[i], src->linesize[i],
2497                         dst_width>>dst_pix->x_chroma_shift, dst_height>>dst_pix->y_chroma_shift);
2498         /* if yuv color space conversion is needed, we do it here on
2499            the destination image */
2500         if (dst_pix->color_type != src_pix->color_type) {
2501             const uint8_t *y_table, *c_table;
2502             if (dst_pix->color_type == FF_COLOR_YUV) {
2503                 y_table = y_jpeg_to_ccir;
2504                 c_table = c_jpeg_to_ccir;
2505             } else {
2506                 y_table = y_ccir_to_jpeg;
2507                 c_table = c_ccir_to_jpeg;
2508             }
2509             img_apply_table(dst->data[0], dst->linesize[0],
2510                             dst->data[0], dst->linesize[0],
2511                             dst_width, dst_height,
2512                             y_table);
2513
2514             for(i = 1;i <= 2; i++)
2515                 img_apply_table(dst->data[i], dst->linesize[i],
2516                                 dst->data[i], dst->linesize[i],
2517                                 dst_width>>dst_pix->x_chroma_shift,
2518                                 dst_height>>dst_pix->y_chroma_shift,
2519                                 c_table);
2520         }
2521         return 0;
2522     }
2523  no_chroma_filter:
2524
2525     /* try to use an intermediate format */
2526     if (src_pix_fmt == PIX_FMT_YUYV422 ||
2527         dst_pix_fmt == PIX_FMT_YUYV422) {
2528         /* specific case: convert to YUV422P first */
2529         int_pix_fmt = PIX_FMT_YUV422P;
2530     } else if (src_pix_fmt == PIX_FMT_UYVY422 ||
2531         dst_pix_fmt == PIX_FMT_UYVY422) {
2532         /* specific case: convert to YUV422P first */
2533         int_pix_fmt = PIX_FMT_YUV422P;
2534     } else if (src_pix_fmt == PIX_FMT_UYYVYY411 ||
2535         dst_pix_fmt == PIX_FMT_UYYVYY411) {
2536         /* specific case: convert to YUV411P first */
2537         int_pix_fmt = PIX_FMT_YUV411P;
2538     } else if ((src_pix->color_type == FF_COLOR_GRAY &&
2539                 src_pix_fmt != PIX_FMT_GRAY8) ||
2540                (dst_pix->color_type == FF_COLOR_GRAY &&
2541                 dst_pix_fmt != PIX_FMT_GRAY8)) {
2542         /* gray8 is the normalized format */
2543         int_pix_fmt = PIX_FMT_GRAY8;
2544     } else if ((is_yuv_planar(src_pix) &&
2545                 src_pix_fmt != PIX_FMT_YUV444P &&
2546                 src_pix_fmt != PIX_FMT_YUVJ444P)) {
2547         /* yuv444 is the normalized format */
2548         if (src_pix->color_type == FF_COLOR_YUV_JPEG)
2549             int_pix_fmt = PIX_FMT_YUVJ444P;
2550         else
2551             int_pix_fmt = PIX_FMT_YUV444P;
2552     } else if ((is_yuv_planar(dst_pix) &&
2553                 dst_pix_fmt != PIX_FMT_YUV444P &&
2554                 dst_pix_fmt != PIX_FMT_YUVJ444P)) {
2555         /* yuv444 is the normalized format */
2556         if (dst_pix->color_type == FF_COLOR_YUV_JPEG)
2557             int_pix_fmt = PIX_FMT_YUVJ444P;
2558         else
2559             int_pix_fmt = PIX_FMT_YUV444P;
2560     } else {
2561         /* the two formats are rgb or gray8 or yuv[j]444p */
2562         if (src_pix->is_alpha && dst_pix->is_alpha)
2563             int_pix_fmt = PIX_FMT_RGB32;
2564         else
2565             int_pix_fmt = PIX_FMT_RGB24;
2566     }
2567     if (avpicture_alloc(tmp, int_pix_fmt, dst_width, dst_height) < 0)
2568         return -1;
2569     ret = -1;
2570     if (img_convert(tmp, int_pix_fmt,
2571                     src, src_pix_fmt, src_width, src_height) < 0)
2572         goto fail1;
2573     if (img_convert(dst, dst_pix_fmt,
2574                     tmp, int_pix_fmt, dst_width, dst_height) < 0)
2575         goto fail1;
2576     ret = 0;
2577  fail1:
2578     avpicture_free(tmp);
2579     return ret;
2580 }
2581 #endif
2582
2583 /* NOTE: we scan all the pixels to have an exact information */
2584 static int get_alpha_info_pal8(const AVPicture *src, int width, int height)
2585 {
2586     const unsigned char *p;
2587     int src_wrap, ret, x, y;
2588     unsigned int a;
2589     uint32_t *palette = (uint32_t *)src->data[1];
2590
2591     p = src->data[0];
2592     src_wrap = src->linesize[0] - width;
2593     ret = 0;
2594     for(y=0;y<height;y++) {
2595         for(x=0;x<width;x++) {
2596             a = palette[p[0]] >> 24;
2597             if (a == 0x00) {
2598                 ret |= FF_ALPHA_TRANSP;
2599             } else if (a != 0xff) {
2600                 ret |= FF_ALPHA_SEMI_TRANSP;
2601             }
2602             p++;
2603         }
2604         p += src_wrap;
2605     }
2606     return ret;
2607 }
2608
2609 /**
2610  * Tell if an image really has transparent alpha values.
2611  * @return ored mask of FF_ALPHA_xxx constants
2612  */
2613 int img_get_alpha_info(const AVPicture *src,
2614                        int pix_fmt, int width, int height)
2615 {
2616     const PixFmtInfo *pf = &pix_fmt_info[pix_fmt];
2617     int ret;
2618
2619     pf = &pix_fmt_info[pix_fmt];
2620     /* no alpha can be represented in format */
2621     if (!pf->is_alpha)
2622         return 0;
2623     switch(pix_fmt) {
2624     case PIX_FMT_RGB32:
2625         ret = get_alpha_info_rgb32(src, width, height);
2626         break;
2627     case PIX_FMT_PAL8:
2628         ret = get_alpha_info_pal8(src, width, height);
2629         break;
2630     default:
2631         /* we do not know, so everything is indicated */
2632         ret = FF_ALPHA_TRANSP | FF_ALPHA_SEMI_TRANSP;
2633         break;
2634     }
2635     return ret;
2636 }
2637
2638 #ifdef HAVE_MMX
2639 #define DEINT_INPLACE_LINE_LUM \
2640                     movd_m2r(lum_m4[0],mm0);\
2641                     movd_m2r(lum_m3[0],mm1);\
2642                     movd_m2r(lum_m2[0],mm2);\
2643                     movd_m2r(lum_m1[0],mm3);\
2644                     movd_m2r(lum[0],mm4);\
2645                     punpcklbw_r2r(mm7,mm0);\
2646                     movd_r2m(mm2,lum_m4[0]);\
2647                     punpcklbw_r2r(mm7,mm1);\
2648                     punpcklbw_r2r(mm7,mm2);\
2649                     punpcklbw_r2r(mm7,mm3);\
2650                     punpcklbw_r2r(mm7,mm4);\
2651                     paddw_r2r(mm3,mm1);\
2652                     psllw_i2r(1,mm2);\
2653                     paddw_r2r(mm4,mm0);\
2654                     psllw_i2r(2,mm1);\
2655                     paddw_r2r(mm6,mm2);\
2656                     paddw_r2r(mm2,mm1);\
2657                     psubusw_r2r(mm0,mm1);\
2658                     psrlw_i2r(3,mm1);\
2659                     packuswb_r2r(mm7,mm1);\
2660                     movd_r2m(mm1,lum_m2[0]);
2661
2662 #define DEINT_LINE_LUM \
2663                     movd_m2r(lum_m4[0],mm0);\
2664                     movd_m2r(lum_m3[0],mm1);\
2665                     movd_m2r(lum_m2[0],mm2);\
2666                     movd_m2r(lum_m1[0],mm3);\
2667                     movd_m2r(lum[0],mm4);\
2668                     punpcklbw_r2r(mm7,mm0);\
2669                     punpcklbw_r2r(mm7,mm1);\
2670                     punpcklbw_r2r(mm7,mm2);\
2671                     punpcklbw_r2r(mm7,mm3);\
2672                     punpcklbw_r2r(mm7,mm4);\
2673                     paddw_r2r(mm3,mm1);\
2674                     psllw_i2r(1,mm2);\
2675                     paddw_r2r(mm4,mm0);\
2676                     psllw_i2r(2,mm1);\
2677                     paddw_r2r(mm6,mm2);\
2678                     paddw_r2r(mm2,mm1);\
2679                     psubusw_r2r(mm0,mm1);\
2680                     psrlw_i2r(3,mm1);\
2681                     packuswb_r2r(mm7,mm1);\
2682                     movd_r2m(mm1,dst[0]);
2683 #endif
2684
2685 /* filter parameters: [-1 4 2 4 -1] // 8 */
2686 static void deinterlace_line(uint8_t *dst,
2687                              const uint8_t *lum_m4, const uint8_t *lum_m3,
2688                              const uint8_t *lum_m2, const uint8_t *lum_m1,
2689                              const uint8_t *lum,
2690                              int size)
2691 {
2692 #ifndef HAVE_MMX
2693     uint8_t *cm = ff_cropTbl + MAX_NEG_CROP;
2694     int sum;
2695
2696     for(;size > 0;size--) {
2697         sum = -lum_m4[0];
2698         sum += lum_m3[0] << 2;
2699         sum += lum_m2[0] << 1;
2700         sum += lum_m1[0] << 2;
2701         sum += -lum[0];
2702         dst[0] = cm[(sum + 4) >> 3];
2703         lum_m4++;
2704         lum_m3++;
2705         lum_m2++;
2706         lum_m1++;
2707         lum++;
2708         dst++;
2709     }
2710 #else
2711
2712     {
2713         mmx_t rounder;
2714         rounder.uw[0]=4;
2715         rounder.uw[1]=4;
2716         rounder.uw[2]=4;
2717         rounder.uw[3]=4;
2718         pxor_r2r(mm7,mm7);
2719         movq_m2r(rounder,mm6);
2720     }
2721     for (;size > 3; size-=4) {
2722         DEINT_LINE_LUM
2723         lum_m4+=4;
2724         lum_m3+=4;
2725         lum_m2+=4;
2726         lum_m1+=4;
2727         lum+=4;
2728         dst+=4;
2729     }
2730 #endif
2731 }
2732 static void deinterlace_line_inplace(uint8_t *lum_m4, uint8_t *lum_m3, uint8_t *lum_m2, uint8_t *lum_m1, uint8_t *lum,
2733                              int size)
2734 {
2735 #ifndef HAVE_MMX
2736     uint8_t *cm = ff_cropTbl + MAX_NEG_CROP;
2737     int sum;
2738
2739     for(;size > 0;size--) {
2740         sum = -lum_m4[0];
2741         sum += lum_m3[0] << 2;
2742         sum += lum_m2[0] << 1;
2743         lum_m4[0]=lum_m2[0];
2744         sum += lum_m1[0] << 2;
2745         sum += -lum[0];
2746         lum_m2[0] = cm[(sum + 4) >> 3];
2747         lum_m4++;
2748         lum_m3++;
2749         lum_m2++;
2750         lum_m1++;
2751         lum++;
2752     }
2753 #else
2754
2755     {
2756         mmx_t rounder;
2757         rounder.uw[0]=4;
2758         rounder.uw[1]=4;
2759         rounder.uw[2]=4;
2760         rounder.uw[3]=4;
2761         pxor_r2r(mm7,mm7);
2762         movq_m2r(rounder,mm6);
2763     }
2764     for (;size > 3; size-=4) {
2765         DEINT_INPLACE_LINE_LUM
2766         lum_m4+=4;
2767         lum_m3+=4;
2768         lum_m2+=4;
2769         lum_m1+=4;
2770         lum+=4;
2771     }
2772 #endif
2773 }
2774
2775 /* deinterlacing : 2 temporal taps, 3 spatial taps linear filter. The
2776    top field is copied as is, but the bottom field is deinterlaced
2777    against the top field. */
2778 static void deinterlace_bottom_field(uint8_t *dst, int dst_wrap,
2779                                     const uint8_t *src1, int src_wrap,
2780                                     int width, int height)
2781 {
2782     const uint8_t *src_m2, *src_m1, *src_0, *src_p1, *src_p2;
2783     int y;
2784
2785     src_m2 = src1;
2786     src_m1 = src1;
2787     src_0=&src_m1[src_wrap];
2788     src_p1=&src_0[src_wrap];
2789     src_p2=&src_p1[src_wrap];
2790     for(y=0;y<(height-2);y+=2) {
2791         memcpy(dst,src_m1,width);
2792         dst += dst_wrap;
2793         deinterlace_line(dst,src_m2,src_m1,src_0,src_p1,src_p2,width);
2794         src_m2 = src_0;
2795         src_m1 = src_p1;
2796         src_0 = src_p2;
2797         src_p1 += 2*src_wrap;
2798         src_p2 += 2*src_wrap;
2799         dst += dst_wrap;
2800     }
2801     memcpy(dst,src_m1,width);
2802     dst += dst_wrap;
2803     /* do last line */
2804     deinterlace_line(dst,src_m2,src_m1,src_0,src_0,src_0,width);
2805 }
2806
2807 static void deinterlace_bottom_field_inplace(uint8_t *src1, int src_wrap,
2808                                              int width, int height)
2809 {
2810     uint8_t *src_m1, *src_0, *src_p1, *src_p2;
2811     int y;
2812     uint8_t *buf;
2813     buf = (uint8_t*)av_malloc(width);
2814
2815     src_m1 = src1;
2816     memcpy(buf,src_m1,width);
2817     src_0=&src_m1[src_wrap];
2818     src_p1=&src_0[src_wrap];
2819     src_p2=&src_p1[src_wrap];
2820     for(y=0;y<(height-2);y+=2) {
2821         deinterlace_line_inplace(buf,src_m1,src_0,src_p1,src_p2,width);
2822         src_m1 = src_p1;
2823         src_0 = src_p2;
2824         src_p1 += 2*src_wrap;
2825         src_p2 += 2*src_wrap;
2826     }
2827     /* do last line */
2828     deinterlace_line_inplace(buf,src_m1,src_0,src_0,src_0,width);
2829     av_free(buf);
2830 }
2831
2832
2833 /* deinterlace - if not supported return -1 */
2834 int avpicture_deinterlace(AVPicture *dst, const AVPicture *src,
2835                           int pix_fmt, int width, int height)
2836 {
2837     int i;
2838
2839     if (pix_fmt != PIX_FMT_YUV420P &&
2840         pix_fmt != PIX_FMT_YUV422P &&
2841         pix_fmt != PIX_FMT_YUV444P &&
2842         pix_fmt != PIX_FMT_YUV411P)
2843         return -1;
2844     if ((width & 3) != 0 || (height & 3) != 0)
2845         return -1;
2846
2847     for(i=0;i<3;i++) {
2848         if (i == 1) {
2849             switch(pix_fmt) {
2850             case PIX_FMT_YUV420P:
2851                 width >>= 1;
2852                 height >>= 1;
2853                 break;
2854             case PIX_FMT_YUV422P:
2855                 width >>= 1;
2856                 break;
2857             case PIX_FMT_YUV411P:
2858                 width >>= 2;
2859                 break;
2860             default:
2861                 break;
2862             }
2863         }
2864         if (src == dst) {
2865             deinterlace_bottom_field_inplace(dst->data[i], dst->linesize[i],
2866                                  width, height);
2867         } else {
2868             deinterlace_bottom_field(dst->data[i],dst->linesize[i],
2869                                         src->data[i], src->linesize[i],
2870                                         width, height);
2871         }
2872     }
2873 #ifdef HAVE_MMX
2874     emms();
2875 #endif
2876     return 0;
2877 }
2878
2879 #undef FIX