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