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