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