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