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