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