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