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