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