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