]> git.sesse.net Git - ffmpeg/blob - libavcodec/imgconvert.c
Move colorspace.h from libavcodec to libavutil.
[ffmpeg] / 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
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 "internal.h"
36 #include "imgconvert.h"
37 #include "libavutil/colorspace.h"
38 #include "libavutil/pixdesc.h"
39
40 #if HAVE_MMX
41 #include "x86/mmx.h"
42 #include "x86/dsputil_mmx.h"
43 #endif
44
45 #define xglue(x, y) x ## y
46 #define glue(x, y) xglue(x, y)
47
48 #define FF_COLOR_RGB      0 /**< RGB color space */
49 #define FF_COLOR_GRAY     1 /**< gray color space */
50 #define FF_COLOR_YUV      2 /**< YUV color space. 16 <= Y <= 235, 16 <= U, V <= 240 */
51 #define FF_COLOR_YUV_JPEG 3 /**< YUV color space. 0 <= Y <= 255, 0 <= U, V <= 255 */
52
53 #define FF_PIXEL_PLANAR   0 /**< each channel has one component in AVPicture */
54 #define FF_PIXEL_PACKED   1 /**< only one components containing all the channels */
55 #define FF_PIXEL_PALETTE  2  /**< one components containing indexes for a palette */
56
57 typedef struct PixFmtInfo {
58     uint8_t nb_channels;     /**< number of channels (including alpha) */
59     uint8_t color_type;      /**< color type (see FF_COLOR_xxx constants) */
60     uint8_t pixel_type;      /**< pixel storage type (see FF_PIXEL_xxx constants) */
61     uint8_t is_alpha : 1;    /**< true if alpha can be specified */
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         .nb_channels = 3,
70         .color_type = FF_COLOR_YUV,
71         .pixel_type = FF_PIXEL_PLANAR,
72         .depth = 8,
73     },
74     [PIX_FMT_YUV422P] = {
75         .nb_channels = 3,
76         .color_type = FF_COLOR_YUV,
77         .pixel_type = FF_PIXEL_PLANAR,
78         .depth = 8,
79     },
80     [PIX_FMT_YUV444P] = {
81         .nb_channels = 3,
82         .color_type = FF_COLOR_YUV,
83         .pixel_type = FF_PIXEL_PLANAR,
84         .depth = 8,
85     },
86     [PIX_FMT_YUYV422] = {
87         .nb_channels = 1,
88         .color_type = FF_COLOR_YUV,
89         .pixel_type = FF_PIXEL_PACKED,
90         .depth = 8,
91     },
92     [PIX_FMT_UYVY422] = {
93         .nb_channels = 1,
94         .color_type = FF_COLOR_YUV,
95         .pixel_type = FF_PIXEL_PACKED,
96         .depth = 8,
97     },
98     [PIX_FMT_YUV410P] = {
99         .nb_channels = 3,
100         .color_type = FF_COLOR_YUV,
101         .pixel_type = FF_PIXEL_PLANAR,
102         .depth = 8,
103     },
104     [PIX_FMT_YUV411P] = {
105         .nb_channels = 3,
106         .color_type = FF_COLOR_YUV,
107         .pixel_type = FF_PIXEL_PLANAR,
108         .depth = 8,
109     },
110     [PIX_FMT_YUV440P] = {
111         .nb_channels = 3,
112         .color_type = FF_COLOR_YUV,
113         .pixel_type = FF_PIXEL_PLANAR,
114         .depth = 8,
115     },
116     [PIX_FMT_YUV420P16LE] = {
117         .nb_channels = 3,
118         .color_type = FF_COLOR_YUV,
119         .pixel_type = FF_PIXEL_PLANAR,
120         .depth = 16,
121     },
122     [PIX_FMT_YUV422P16LE] = {
123         .nb_channels = 3,
124         .color_type = FF_COLOR_YUV,
125         .pixel_type = FF_PIXEL_PLANAR,
126         .depth = 16,
127     },
128     [PIX_FMT_YUV444P16LE] = {
129         .nb_channels = 3,
130         .color_type = FF_COLOR_YUV,
131         .pixel_type = FF_PIXEL_PLANAR,
132         .depth = 16,
133     },
134     [PIX_FMT_YUV420P16BE] = {
135         .nb_channels = 3,
136         .color_type = FF_COLOR_YUV,
137         .pixel_type = FF_PIXEL_PLANAR,
138         .depth = 16,
139     },
140     [PIX_FMT_YUV422P16BE] = {
141         .nb_channels = 3,
142         .color_type = FF_COLOR_YUV,
143         .pixel_type = FF_PIXEL_PLANAR,
144         .depth = 16,
145     },
146     [PIX_FMT_YUV444P16BE] = {
147         .nb_channels = 3,
148         .color_type = FF_COLOR_YUV,
149         .pixel_type = FF_PIXEL_PLANAR,
150         .depth = 16,
151     },
152
153
154     /* YUV formats with alpha plane */
155     [PIX_FMT_YUVA420P] = {
156         .nb_channels = 4,
157         .color_type = FF_COLOR_YUV,
158         .pixel_type = FF_PIXEL_PLANAR,
159         .depth = 8,
160     },
161
162     /* JPEG YUV */
163     [PIX_FMT_YUVJ420P] = {
164         .nb_channels = 3,
165         .color_type = FF_COLOR_YUV_JPEG,
166         .pixel_type = FF_PIXEL_PLANAR,
167         .depth = 8,
168     },
169     [PIX_FMT_YUVJ422P] = {
170         .nb_channels = 3,
171         .color_type = FF_COLOR_YUV_JPEG,
172         .pixel_type = FF_PIXEL_PLANAR,
173         .depth = 8,
174     },
175     [PIX_FMT_YUVJ444P] = {
176         .nb_channels = 3,
177         .color_type = FF_COLOR_YUV_JPEG,
178         .pixel_type = FF_PIXEL_PLANAR,
179         .depth = 8,
180     },
181     [PIX_FMT_YUVJ440P] = {
182         .nb_channels = 3,
183         .color_type = FF_COLOR_YUV_JPEG,
184         .pixel_type = FF_PIXEL_PLANAR,
185         .depth = 8,
186     },
187
188     /* RGB formats */
189     [PIX_FMT_RGB24] = {
190         .nb_channels = 3,
191         .color_type = FF_COLOR_RGB,
192         .pixel_type = FF_PIXEL_PACKED,
193         .depth = 8,
194     },
195     [PIX_FMT_BGR24] = {
196         .nb_channels = 3,
197         .color_type = FF_COLOR_RGB,
198         .pixel_type = FF_PIXEL_PACKED,
199         .depth = 8,
200     },
201     [PIX_FMT_ARGB] = {
202         .nb_channels = 4, .is_alpha = 1,
203         .color_type = FF_COLOR_RGB,
204         .pixel_type = FF_PIXEL_PACKED,
205         .depth = 8,
206     },
207     [PIX_FMT_RGB48BE] = {
208         .nb_channels = 3,
209         .color_type = FF_COLOR_RGB,
210         .pixel_type = FF_PIXEL_PACKED,
211         .depth = 16,
212     },
213     [PIX_FMT_RGB48LE] = {
214         .nb_channels = 3,
215         .color_type = FF_COLOR_RGB,
216         .pixel_type = FF_PIXEL_PACKED,
217         .depth = 16,
218     },
219     [PIX_FMT_RGB565BE] = {
220         .nb_channels = 3,
221         .color_type = FF_COLOR_RGB,
222         .pixel_type = FF_PIXEL_PACKED,
223         .depth = 5,
224     },
225     [PIX_FMT_RGB565LE] = {
226         .nb_channels = 3,
227         .color_type = FF_COLOR_RGB,
228         .pixel_type = FF_PIXEL_PACKED,
229         .depth = 5,
230     },
231     [PIX_FMT_RGB555BE] = {
232         .nb_channels = 3,
233         .color_type = FF_COLOR_RGB,
234         .pixel_type = FF_PIXEL_PACKED,
235         .depth = 5,
236     },
237     [PIX_FMT_RGB555LE] = {
238         .nb_channels = 3,
239         .color_type = FF_COLOR_RGB,
240         .pixel_type = FF_PIXEL_PACKED,
241         .depth = 5,
242     },
243     [PIX_FMT_RGB444BE] = {
244         .nb_channels = 3,
245         .color_type = FF_COLOR_RGB,
246         .pixel_type = FF_PIXEL_PACKED,
247         .depth = 4,
248     },
249     [PIX_FMT_RGB444LE] = {
250         .nb_channels = 3,
251         .color_type = FF_COLOR_RGB,
252         .pixel_type = FF_PIXEL_PACKED,
253         .depth = 4,
254     },
255
256     /* gray / mono formats */
257     [PIX_FMT_GRAY16BE] = {
258         .nb_channels = 1,
259         .color_type = FF_COLOR_GRAY,
260         .pixel_type = FF_PIXEL_PLANAR,
261         .depth = 16,
262     },
263     [PIX_FMT_GRAY16LE] = {
264         .nb_channels = 1,
265         .color_type = FF_COLOR_GRAY,
266         .pixel_type = FF_PIXEL_PLANAR,
267         .depth = 16,
268     },
269     [PIX_FMT_GRAY8] = {
270         .nb_channels = 1,
271         .color_type = FF_COLOR_GRAY,
272         .pixel_type = FF_PIXEL_PLANAR,
273         .depth = 8,
274     },
275     [PIX_FMT_MONOWHITE] = {
276         .nb_channels = 1,
277         .color_type = FF_COLOR_GRAY,
278         .pixel_type = FF_PIXEL_PLANAR,
279         .depth = 1,
280     },
281     [PIX_FMT_MONOBLACK] = {
282         .nb_channels = 1,
283         .color_type = FF_COLOR_GRAY,
284         .pixel_type = FF_PIXEL_PLANAR,
285         .depth = 1,
286     },
287
288     /* paletted formats */
289     [PIX_FMT_PAL8] = {
290         .nb_channels = 4, .is_alpha = 1,
291         .color_type = FF_COLOR_RGB,
292         .pixel_type = FF_PIXEL_PALETTE,
293         .depth = 8,
294     },
295     [PIX_FMT_UYYVYY411] = {
296         .nb_channels = 1,
297         .color_type = FF_COLOR_YUV,
298         .pixel_type = FF_PIXEL_PACKED,
299         .depth = 8,
300     },
301     [PIX_FMT_ABGR] = {
302         .nb_channels = 4, .is_alpha = 1,
303         .color_type = FF_COLOR_RGB,
304         .pixel_type = FF_PIXEL_PACKED,
305         .depth = 8,
306     },
307     [PIX_FMT_BGR565BE] = {
308         .nb_channels = 3,
309         .color_type = FF_COLOR_RGB,
310         .pixel_type = FF_PIXEL_PACKED,
311         .depth = 5,
312     },
313     [PIX_FMT_BGR565LE] = {
314         .nb_channels = 3,
315         .color_type = FF_COLOR_RGB,
316         .pixel_type = FF_PIXEL_PACKED,
317         .depth = 5,
318     },
319     [PIX_FMT_BGR555BE] = {
320         .nb_channels = 3,
321         .color_type = FF_COLOR_RGB,
322         .pixel_type = FF_PIXEL_PACKED,
323         .depth = 5,
324     },
325     [PIX_FMT_BGR555LE] = {
326         .nb_channels = 3,
327         .color_type = FF_COLOR_RGB,
328         .pixel_type = FF_PIXEL_PACKED,
329         .depth = 5,
330     },
331     [PIX_FMT_BGR444BE] = {
332         .nb_channels = 3,
333         .color_type = FF_COLOR_RGB,
334         .pixel_type = FF_PIXEL_PACKED,
335         .depth = 4,
336     },
337     [PIX_FMT_BGR444LE] = {
338         .nb_channels = 3,
339         .color_type = FF_COLOR_RGB,
340         .pixel_type = FF_PIXEL_PACKED,
341         .depth = 4,
342     },
343     [PIX_FMT_RGB8] = {
344         .nb_channels = 1,
345         .color_type = FF_COLOR_RGB,
346         .pixel_type = FF_PIXEL_PACKED,
347         .depth = 8,
348     },
349     [PIX_FMT_RGB4] = {
350         .nb_channels = 1,
351         .color_type = FF_COLOR_RGB,
352         .pixel_type = FF_PIXEL_PACKED,
353         .depth = 4,
354     },
355     [PIX_FMT_RGB4_BYTE] = {
356         .nb_channels = 1,
357         .color_type = FF_COLOR_RGB,
358         .pixel_type = FF_PIXEL_PACKED,
359         .depth = 8,
360     },
361     [PIX_FMT_BGR8] = {
362         .nb_channels = 1,
363         .color_type = FF_COLOR_RGB,
364         .pixel_type = FF_PIXEL_PACKED,
365         .depth = 8,
366     },
367     [PIX_FMT_BGR4] = {
368         .nb_channels = 1,
369         .color_type = FF_COLOR_RGB,
370         .pixel_type = FF_PIXEL_PACKED,
371         .depth = 4,
372     },
373     [PIX_FMT_BGR4_BYTE] = {
374         .nb_channels = 1,
375         .color_type = FF_COLOR_RGB,
376         .pixel_type = FF_PIXEL_PACKED,
377         .depth = 8,
378     },
379     [PIX_FMT_NV12] = {
380         .nb_channels = 2,
381         .color_type = FF_COLOR_YUV,
382         .pixel_type = FF_PIXEL_PLANAR,
383         .depth = 8,
384     },
385     [PIX_FMT_NV21] = {
386         .nb_channels = 2,
387         .color_type = FF_COLOR_YUV,
388         .pixel_type = FF_PIXEL_PLANAR,
389         .depth = 8,
390     },
391
392     [PIX_FMT_BGRA] = {
393         .nb_channels = 4, .is_alpha = 1,
394         .color_type = FF_COLOR_RGB,
395         .pixel_type = FF_PIXEL_PACKED,
396         .depth = 8,
397     },
398     [PIX_FMT_RGBA] = {
399         .nb_channels = 4, .is_alpha = 1,
400         .color_type = FF_COLOR_RGB,
401         .pixel_type = FF_PIXEL_PACKED,
402         .depth = 8,
403     },
404 };
405
406 void avcodec_get_chroma_sub_sample(enum PixelFormat pix_fmt, int *h_shift, int *v_shift)
407 {
408     *h_shift = av_pix_fmt_descriptors[pix_fmt].log2_chroma_w;
409     *v_shift = av_pix_fmt_descriptors[pix_fmt].log2_chroma_h;
410 }
411
412 const char *avcodec_get_pix_fmt_name(enum PixelFormat pix_fmt)
413 {
414     if (pix_fmt < 0 || pix_fmt >= PIX_FMT_NB)
415         return NULL;
416     else
417         return av_pix_fmt_descriptors[pix_fmt].name;
418 }
419
420 #if LIBAVCODEC_VERSION_MAJOR < 53
421 enum PixelFormat avcodec_get_pix_fmt(const char *name)
422 {
423     return av_get_pix_fmt(name);
424 }
425 #endif
426
427 void avcodec_pix_fmt_string (char *buf, int buf_size, enum PixelFormat pix_fmt)
428 {
429     /* print header */
430     if (pix_fmt < 0)
431         snprintf (buf, buf_size,
432                   "name      " " nb_channels" " depth" " is_alpha"
433             );
434     else{
435         PixFmtInfo info= pix_fmt_info[pix_fmt];
436
437         char is_alpha_char= info.is_alpha ? 'y' : 'n';
438
439         snprintf (buf, buf_size,
440                   "%-11s %5d %9d %6c",
441                   av_pix_fmt_descriptors[pix_fmt].name,
442                   info.nb_channels,
443                   info.depth,
444                   is_alpha_char
445             );
446     }
447 }
448
449 int ff_is_hwaccel_pix_fmt(enum PixelFormat pix_fmt)
450 {
451     return av_pix_fmt_descriptors[pix_fmt].flags & PIX_FMT_HWACCEL;
452 }
453
454 int ff_set_systematic_pal(uint32_t pal[256], enum PixelFormat pix_fmt){
455     int i;
456
457     for(i=0; i<256; i++){
458         int r,g,b;
459
460         switch(pix_fmt) {
461         case PIX_FMT_RGB8:
462             r= (i>>5    )*36;
463             g= ((i>>2)&7)*36;
464             b= (i&3     )*85;
465             break;
466         case PIX_FMT_BGR8:
467             b= (i>>6    )*85;
468             g= ((i>>3)&7)*36;
469             r= (i&7     )*36;
470             break;
471         case PIX_FMT_RGB4_BYTE:
472             r= (i>>3    )*255;
473             g= ((i>>1)&3)*85;
474             b= (i&1     )*255;
475             break;
476         case PIX_FMT_BGR4_BYTE:
477             b= (i>>3    )*255;
478             g= ((i>>1)&3)*85;
479             r= (i&1     )*255;
480             break;
481         case PIX_FMT_GRAY8:
482             r=b=g= i;
483             break;
484         default:
485             return -1;
486         }
487         pal[i] =  b + (g<<8) + (r<<16);
488     }
489
490     return 0;
491 }
492
493 int ff_fill_linesize(AVPicture *picture, enum PixelFormat pix_fmt, int width)
494 {
495     int i;
496     const AVPixFmtDescriptor *desc = &av_pix_fmt_descriptors[pix_fmt];
497     int max_plane_step     [4];
498     int max_plane_step_comp[4];
499
500     memset(picture->linesize, 0, sizeof(picture->linesize));
501
502     if (desc->flags & PIX_FMT_HWACCEL)
503         return -1;
504
505     if (desc->flags & PIX_FMT_BITSTREAM) {
506         picture->linesize[0] = (width * (desc->comp[0].step_minus1+1) + 7) >> 3;
507         return 0;
508     }
509
510     memset(max_plane_step     , 0, sizeof(max_plane_step     ));
511     memset(max_plane_step_comp, 0, sizeof(max_plane_step_comp));
512     for (i = 0; i < 4; i++) {
513         const AVComponentDescriptor *comp = &(desc->comp[i]);
514         if ((comp->step_minus1+1) > max_plane_step[comp->plane]) {
515             max_plane_step     [comp->plane] = comp->step_minus1+1;
516             max_plane_step_comp[comp->plane] = i;
517         }
518     }
519
520     for (i = 0; i < 4; i++) {
521         int s = (max_plane_step_comp[i] == 1 || max_plane_step_comp[i] == 2) ? desc->log2_chroma_w : 0;
522         picture->linesize[i] = max_plane_step[i] * (((width + (1 << s) - 1)) >> s);
523     }
524
525     return 0;
526 }
527
528 int ff_fill_pointer(AVPicture *picture, uint8_t *ptr, enum PixelFormat pix_fmt,
529                     int height)
530 {
531     int size, h2, size2;
532     const AVPixFmtDescriptor *desc = &av_pix_fmt_descriptors[pix_fmt];
533
534     size = picture->linesize[0] * height;
535     switch(pix_fmt) {
536     case PIX_FMT_YUV420P:
537     case PIX_FMT_YUV422P:
538     case PIX_FMT_YUV444P:
539     case PIX_FMT_YUV410P:
540     case PIX_FMT_YUV411P:
541     case PIX_FMT_YUV440P:
542     case PIX_FMT_YUVJ420P:
543     case PIX_FMT_YUVJ422P:
544     case PIX_FMT_YUVJ444P:
545     case PIX_FMT_YUVJ440P:
546     case PIX_FMT_YUV420P16LE:
547     case PIX_FMT_YUV422P16LE:
548     case PIX_FMT_YUV444P16LE:
549     case PIX_FMT_YUV420P16BE:
550     case PIX_FMT_YUV422P16BE:
551     case PIX_FMT_YUV444P16BE:
552         h2 = (height + (1 << desc->log2_chroma_h) - 1) >> desc->log2_chroma_h;
553         size2 = picture->linesize[1] * h2;
554         picture->data[0] = ptr;
555         picture->data[1] = picture->data[0] + size;
556         picture->data[2] = picture->data[1] + size2;
557         picture->data[3] = NULL;
558         return size + 2 * size2;
559     case PIX_FMT_YUVA420P:
560         h2 = (height + (1 << desc->log2_chroma_h) - 1) >> desc->log2_chroma_h;
561         size2 = picture->linesize[1] * h2;
562         picture->data[0] = ptr;
563         picture->data[1] = picture->data[0] + size;
564         picture->data[2] = picture->data[1] + size2;
565         picture->data[3] = picture->data[1] + size2 + size2;
566         return 2 * size + 2 * size2;
567     case PIX_FMT_NV12:
568     case PIX_FMT_NV21:
569         h2 = (height + (1 << desc->log2_chroma_h) - 1) >> desc->log2_chroma_h;
570         size2 = picture->linesize[1] * h2;
571         picture->data[0] = ptr;
572         picture->data[1] = picture->data[0] + size;
573         picture->data[2] = NULL;
574         picture->data[3] = NULL;
575         return size + size2;
576     case PIX_FMT_RGB24:
577     case PIX_FMT_BGR24:
578     case PIX_FMT_ARGB:
579     case PIX_FMT_ABGR:
580     case PIX_FMT_RGBA:
581     case PIX_FMT_BGRA:
582     case PIX_FMT_RGB48BE:
583     case PIX_FMT_RGB48LE:
584     case PIX_FMT_GRAY16BE:
585     case PIX_FMT_GRAY16LE:
586     case PIX_FMT_BGR444BE:
587     case PIX_FMT_BGR444LE:
588     case PIX_FMT_BGR555BE:
589     case PIX_FMT_BGR555LE:
590     case PIX_FMT_BGR565BE:
591     case PIX_FMT_BGR565LE:
592     case PIX_FMT_RGB444BE:
593     case PIX_FMT_RGB444LE:
594     case PIX_FMT_RGB555BE:
595     case PIX_FMT_RGB555LE:
596     case PIX_FMT_RGB565BE:
597     case PIX_FMT_RGB565LE:
598     case PIX_FMT_YUYV422:
599     case PIX_FMT_UYVY422:
600     case PIX_FMT_UYYVYY411:
601     case PIX_FMT_RGB4:
602     case PIX_FMT_BGR4:
603     case PIX_FMT_MONOWHITE:
604     case PIX_FMT_MONOBLACK:
605     case PIX_FMT_Y400A:
606         picture->data[0] = ptr;
607         picture->data[1] = NULL;
608         picture->data[2] = NULL;
609         picture->data[3] = NULL;
610         return size;
611     case PIX_FMT_PAL8:
612     case PIX_FMT_RGB8:
613     case PIX_FMT_BGR8:
614     case PIX_FMT_RGB4_BYTE:
615     case PIX_FMT_BGR4_BYTE:
616     case PIX_FMT_GRAY8:
617         size2 = (size + 3) & ~3;
618         picture->data[0] = ptr;
619         picture->data[1] = ptr + size2; /* palette is stored here as 256 32 bit words */
620         picture->data[2] = NULL;
621         picture->data[3] = NULL;
622         return size2 + 256 * 4;
623     default:
624         picture->data[0] = NULL;
625         picture->data[1] = NULL;
626         picture->data[2] = NULL;
627         picture->data[3] = NULL;
628         return -1;
629     }
630 }
631
632 int avpicture_fill(AVPicture *picture, uint8_t *ptr,
633                    enum PixelFormat pix_fmt, int width, int height)
634 {
635
636     if(avcodec_check_dimensions(NULL, width, height))
637         return -1;
638
639     if (ff_fill_linesize(picture, pix_fmt, width))
640         return -1;
641
642     return ff_fill_pointer(picture, ptr, pix_fmt, height);
643 }
644
645 int avpicture_layout(const AVPicture* src, enum PixelFormat pix_fmt, int width, int height,
646                      unsigned char *dest, int dest_size)
647 {
648     const PixFmtInfo* pf = &pix_fmt_info[pix_fmt];
649     const AVPixFmtDescriptor *desc = &av_pix_fmt_descriptors[pix_fmt];
650     int i, j, w, ow, h, oh, data_planes;
651     const unsigned char* s;
652     int size = avpicture_get_size(pix_fmt, width, height);
653
654     if (size > dest_size || size < 0)
655         return -1;
656
657     if (pf->pixel_type == FF_PIXEL_PACKED || pf->pixel_type == FF_PIXEL_PALETTE) {
658         if (pix_fmt == PIX_FMT_YUYV422 ||
659             pix_fmt == PIX_FMT_UYVY422 ||
660             pix_fmt == PIX_FMT_BGR565BE ||
661             pix_fmt == PIX_FMT_BGR565LE ||
662             pix_fmt == PIX_FMT_BGR555BE ||
663             pix_fmt == PIX_FMT_BGR555LE ||
664             pix_fmt == PIX_FMT_BGR444BE ||
665             pix_fmt == PIX_FMT_BGR444LE ||
666             pix_fmt == PIX_FMT_RGB565BE ||
667             pix_fmt == PIX_FMT_RGB565LE ||
668             pix_fmt == PIX_FMT_RGB555BE ||
669             pix_fmt == PIX_FMT_RGB555LE ||
670             pix_fmt == PIX_FMT_RGB444BE ||
671             pix_fmt == PIX_FMT_RGB444LE)
672             w = width * 2;
673         else if (pix_fmt == PIX_FMT_UYYVYY411)
674             w = width + width/2;
675         else if (pix_fmt == PIX_FMT_PAL8)
676             w = width;
677         else
678             w = width * (pf->depth * pf->nb_channels / 8);
679
680         data_planes = 1;
681         h = height;
682     } else {
683         data_planes = pf->nb_channels;
684         w = (width*pf->depth + 7)/8;
685         h = height;
686     }
687
688     ow = w;
689     oh = h;
690
691     for (i=0; i<data_planes; i++) {
692         if (i == 1) {
693             w = (- ((-width) >> desc->log2_chroma_w) * pf->depth + 7) / 8;
694             h = -((-height) >> desc->log2_chroma_h);
695             if (pix_fmt == PIX_FMT_NV12 || pix_fmt == PIX_FMT_NV21)
696                 w <<= 1;
697         } else if (i == 3) {
698             w = ow;
699             h = oh;
700         }
701         s = src->data[i];
702         for(j=0; j<h; j++) {
703             memcpy(dest, s, w);
704             dest += w;
705             s += src->linesize[i];
706         }
707     }
708
709     if (pf->pixel_type == FF_PIXEL_PALETTE)
710         memcpy((unsigned char *)(((size_t)dest + 3) & ~3), src->data[1], 256 * 4);
711
712     return size;
713 }
714
715 int avpicture_get_size(enum PixelFormat pix_fmt, int width, int height)
716 {
717     AVPicture dummy_pict;
718     if(avcodec_check_dimensions(NULL, width, height))
719         return -1;
720     switch (pix_fmt) {
721     case PIX_FMT_RGB8:
722     case PIX_FMT_BGR8:
723     case PIX_FMT_RGB4_BYTE:
724     case PIX_FMT_BGR4_BYTE:
725     case PIX_FMT_GRAY8:
726         // do not include palette for these pseudo-paletted formats
727         return width * height;
728     }
729     return avpicture_fill(&dummy_pict, NULL, pix_fmt, width, height);
730 }
731
732 int avcodec_get_pix_fmt_loss(enum PixelFormat dst_pix_fmt, enum PixelFormat src_pix_fmt,
733                              int has_alpha)
734 {
735     const PixFmtInfo *pf, *ps;
736     const AVPixFmtDescriptor *src_desc = &av_pix_fmt_descriptors[src_pix_fmt];
737     const AVPixFmtDescriptor *dst_desc = &av_pix_fmt_descriptors[dst_pix_fmt];
738     int loss;
739
740     ps = &pix_fmt_info[src_pix_fmt];
741
742     /* compute loss */
743     loss = 0;
744     pf = &pix_fmt_info[dst_pix_fmt];
745     if (pf->depth < ps->depth ||
746         ((dst_pix_fmt == PIX_FMT_RGB555BE || dst_pix_fmt == PIX_FMT_RGB555LE ||
747           dst_pix_fmt == PIX_FMT_BGR555BE || dst_pix_fmt == PIX_FMT_BGR555LE) &&
748          (src_pix_fmt == PIX_FMT_RGB565BE || src_pix_fmt == PIX_FMT_RGB565LE ||
749           src_pix_fmt == PIX_FMT_BGR565BE || src_pix_fmt == PIX_FMT_BGR565LE)))
750         loss |= FF_LOSS_DEPTH;
751     if (dst_desc->log2_chroma_w > src_desc->log2_chroma_w ||
752         dst_desc->log2_chroma_h > src_desc->log2_chroma_h)
753         loss |= FF_LOSS_RESOLUTION;
754     switch(pf->color_type) {
755     case FF_COLOR_RGB:
756         if (ps->color_type != FF_COLOR_RGB &&
757             ps->color_type != FF_COLOR_GRAY)
758             loss |= FF_LOSS_COLORSPACE;
759         break;
760     case FF_COLOR_GRAY:
761         if (ps->color_type != FF_COLOR_GRAY)
762             loss |= FF_LOSS_COLORSPACE;
763         break;
764     case FF_COLOR_YUV:
765         if (ps->color_type != FF_COLOR_YUV)
766             loss |= FF_LOSS_COLORSPACE;
767         break;
768     case FF_COLOR_YUV_JPEG:
769         if (ps->color_type != FF_COLOR_YUV_JPEG &&
770             ps->color_type != FF_COLOR_YUV &&
771             ps->color_type != FF_COLOR_GRAY)
772             loss |= FF_LOSS_COLORSPACE;
773         break;
774     default:
775         /* fail safe test */
776         if (ps->color_type != pf->color_type)
777             loss |= FF_LOSS_COLORSPACE;
778         break;
779     }
780     if (pf->color_type == FF_COLOR_GRAY &&
781         ps->color_type != FF_COLOR_GRAY)
782         loss |= FF_LOSS_CHROMA;
783     if (!pf->is_alpha && (ps->is_alpha && has_alpha))
784         loss |= FF_LOSS_ALPHA;
785     if (pf->pixel_type == FF_PIXEL_PALETTE &&
786         (ps->pixel_type != FF_PIXEL_PALETTE && ps->color_type != FF_COLOR_GRAY))
787         loss |= FF_LOSS_COLORQUANT;
788     return loss;
789 }
790
791 static int avg_bits_per_pixel(enum PixelFormat pix_fmt)
792 {
793     int bits;
794     const PixFmtInfo *pf;
795     const AVPixFmtDescriptor *desc = &av_pix_fmt_descriptors[pix_fmt];
796
797     pf = &pix_fmt_info[pix_fmt];
798     switch(pf->pixel_type) {
799     case FF_PIXEL_PACKED:
800         switch(pix_fmt) {
801         case PIX_FMT_YUYV422:
802         case PIX_FMT_UYVY422:
803         case PIX_FMT_RGB565BE:
804         case PIX_FMT_RGB565LE:
805         case PIX_FMT_RGB555BE:
806         case PIX_FMT_RGB555LE:
807         case PIX_FMT_RGB444BE:
808         case PIX_FMT_RGB444LE:
809         case PIX_FMT_BGR565BE:
810         case PIX_FMT_BGR565LE:
811         case PIX_FMT_BGR555BE:
812         case PIX_FMT_BGR555LE:
813         case PIX_FMT_BGR444BE:
814         case PIX_FMT_BGR444LE:
815             bits = 16;
816             break;
817         case PIX_FMT_UYYVYY411:
818             bits = 12;
819             break;
820         default:
821             bits = pf->depth * pf->nb_channels;
822             break;
823         }
824         break;
825     case FF_PIXEL_PLANAR:
826         if (desc->log2_chroma_w == 0 && desc->log2_chroma_h == 0) {
827             bits = pf->depth * pf->nb_channels;
828         } else {
829             bits = pf->depth + ((2 * pf->depth) >>
830                                 (desc->log2_chroma_w + desc->log2_chroma_h));
831         }
832         break;
833     case FF_PIXEL_PALETTE:
834         bits = 8;
835         break;
836     default:
837         bits = -1;
838         break;
839     }
840     return bits;
841 }
842
843 static enum PixelFormat avcodec_find_best_pix_fmt1(int64_t pix_fmt_mask,
844                                       enum PixelFormat src_pix_fmt,
845                                       int has_alpha,
846                                       int loss_mask)
847 {
848     int dist, i, loss, min_dist;
849     enum PixelFormat dst_pix_fmt;
850
851     /* find exact color match with smallest size */
852     dst_pix_fmt = PIX_FMT_NONE;
853     min_dist = 0x7fffffff;
854     for(i = 0;i < PIX_FMT_NB; i++) {
855         if (pix_fmt_mask & (1ULL << i)) {
856             loss = avcodec_get_pix_fmt_loss(i, src_pix_fmt, has_alpha) & loss_mask;
857             if (loss == 0) {
858                 dist = avg_bits_per_pixel(i);
859                 if (dist < min_dist) {
860                     min_dist = dist;
861                     dst_pix_fmt = i;
862                 }
863             }
864         }
865     }
866     return dst_pix_fmt;
867 }
868
869 enum PixelFormat avcodec_find_best_pix_fmt(int64_t pix_fmt_mask, enum PixelFormat src_pix_fmt,
870                               int has_alpha, int *loss_ptr)
871 {
872     enum PixelFormat dst_pix_fmt;
873     int loss_mask, i;
874     static const int loss_mask_order[] = {
875         ~0, /* no loss first */
876         ~FF_LOSS_ALPHA,
877         ~FF_LOSS_RESOLUTION,
878         ~(FF_LOSS_COLORSPACE | FF_LOSS_RESOLUTION),
879         ~FF_LOSS_COLORQUANT,
880         ~FF_LOSS_DEPTH,
881         0,
882     };
883
884     /* try with successive loss */
885     i = 0;
886     for(;;) {
887         loss_mask = loss_mask_order[i++];
888         dst_pix_fmt = avcodec_find_best_pix_fmt1(pix_fmt_mask, src_pix_fmt,
889                                                  has_alpha, loss_mask);
890         if (dst_pix_fmt >= 0)
891             goto found;
892         if (loss_mask == 0)
893             break;
894     }
895     return PIX_FMT_NONE;
896  found:
897     if (loss_ptr)
898         *loss_ptr = avcodec_get_pix_fmt_loss(dst_pix_fmt, src_pix_fmt, has_alpha);
899     return dst_pix_fmt;
900 }
901
902 void ff_img_copy_plane(uint8_t *dst, int dst_wrap,
903                            const uint8_t *src, int src_wrap,
904                            int width, int height)
905 {
906     if((!dst) || (!src))
907         return;
908     for(;height > 0; height--) {
909         memcpy(dst, src, width);
910         dst += dst_wrap;
911         src += src_wrap;
912     }
913 }
914
915 int ff_get_plane_bytewidth(enum PixelFormat pix_fmt, int width, int plane)
916 {
917     int bits;
918     const PixFmtInfo *pf = &pix_fmt_info[pix_fmt];
919     const AVPixFmtDescriptor *desc = &av_pix_fmt_descriptors[pix_fmt];
920
921     pf = &pix_fmt_info[pix_fmt];
922     switch(pf->pixel_type) {
923     case FF_PIXEL_PACKED:
924         switch(pix_fmt) {
925         case PIX_FMT_YUYV422:
926         case PIX_FMT_UYVY422:
927         case PIX_FMT_RGB565BE:
928         case PIX_FMT_RGB565LE:
929         case PIX_FMT_RGB555BE:
930         case PIX_FMT_RGB555LE:
931         case PIX_FMT_RGB444BE:
932         case PIX_FMT_RGB444LE:
933         case PIX_FMT_BGR565BE:
934         case PIX_FMT_BGR565LE:
935         case PIX_FMT_BGR555BE:
936         case PIX_FMT_BGR555LE:
937         case PIX_FMT_BGR444BE:
938         case PIX_FMT_BGR444LE:
939             bits = 16;
940             break;
941         case PIX_FMT_UYYVYY411:
942             bits = 12;
943             break;
944         default:
945             bits = pf->depth * pf->nb_channels;
946             break;
947         }
948         return (width * bits + 7) >> 3;
949         break;
950     case FF_PIXEL_PLANAR:
951             if ((pix_fmt != PIX_FMT_NV12 && pix_fmt != PIX_FMT_NV21) &&
952                 (plane == 1 || plane == 2))
953                 width= -((-width)>>desc->log2_chroma_w);
954
955             return (width * pf->depth + 7) >> 3;
956         break;
957     case FF_PIXEL_PALETTE:
958         if (plane == 0)
959             return width;
960         break;
961     }
962
963     return -1;
964 }
965
966 void av_picture_copy(AVPicture *dst, const AVPicture *src,
967                      enum PixelFormat pix_fmt, int width, int height)
968 {
969     int i;
970     const PixFmtInfo *pf = &pix_fmt_info[pix_fmt];
971     const AVPixFmtDescriptor *desc = &av_pix_fmt_descriptors[pix_fmt];
972
973     switch(pf->pixel_type) {
974     case FF_PIXEL_PACKED:
975     case FF_PIXEL_PLANAR:
976         for(i = 0; i < pf->nb_channels; i++) {
977             int h;
978             int bwidth = ff_get_plane_bytewidth(pix_fmt, width, i);
979             h = height;
980             if (i == 1 || i == 2) {
981                 h= -((-height)>>desc->log2_chroma_h);
982             }
983             ff_img_copy_plane(dst->data[i], dst->linesize[i],
984                            src->data[i], src->linesize[i],
985                            bwidth, h);
986         }
987         break;
988     case FF_PIXEL_PALETTE:
989         ff_img_copy_plane(dst->data[0], dst->linesize[0],
990                        src->data[0], src->linesize[0],
991                        width, height);
992         /* copy the palette */
993         memcpy(dst->data[1], src->data[1], 4*256);
994         break;
995     }
996 }
997
998 /* 2x2 -> 1x1 */
999 void ff_shrink22(uint8_t *dst, int dst_wrap,
1000                      const uint8_t *src, int src_wrap,
1001                      int width, int height)
1002 {
1003     int w;
1004     const uint8_t *s1, *s2;
1005     uint8_t *d;
1006
1007     for(;height > 0; height--) {
1008         s1 = src;
1009         s2 = s1 + src_wrap;
1010         d = dst;
1011         for(w = width;w >= 4; w-=4) {
1012             d[0] = (s1[0] + s1[1] + s2[0] + s2[1] + 2) >> 2;
1013             d[1] = (s1[2] + s1[3] + s2[2] + s2[3] + 2) >> 2;
1014             d[2] = (s1[4] + s1[5] + s2[4] + s2[5] + 2) >> 2;
1015             d[3] = (s1[6] + s1[7] + s2[6] + s2[7] + 2) >> 2;
1016             s1 += 8;
1017             s2 += 8;
1018             d += 4;
1019         }
1020         for(;w > 0; w--) {
1021             d[0] = (s1[0] + s1[1] + s2[0] + s2[1] + 2) >> 2;
1022             s1 += 2;
1023             s2 += 2;
1024             d++;
1025         }
1026         src += 2 * src_wrap;
1027         dst += dst_wrap;
1028     }
1029 }
1030
1031 /* 4x4 -> 1x1 */
1032 void ff_shrink44(uint8_t *dst, int dst_wrap,
1033                      const uint8_t *src, int src_wrap,
1034                      int width, int height)
1035 {
1036     int w;
1037     const uint8_t *s1, *s2, *s3, *s4;
1038     uint8_t *d;
1039
1040     for(;height > 0; height--) {
1041         s1 = src;
1042         s2 = s1 + src_wrap;
1043         s3 = s2 + src_wrap;
1044         s4 = s3 + src_wrap;
1045         d = dst;
1046         for(w = width;w > 0; w--) {
1047             d[0] = (s1[0] + s1[1] + s1[2] + s1[3] +
1048                     s2[0] + s2[1] + s2[2] + s2[3] +
1049                     s3[0] + s3[1] + s3[2] + s3[3] +
1050                     s4[0] + s4[1] + s4[2] + s4[3] + 8) >> 4;
1051             s1 += 4;
1052             s2 += 4;
1053             s3 += 4;
1054             s4 += 4;
1055             d++;
1056         }
1057         src += 4 * src_wrap;
1058         dst += dst_wrap;
1059     }
1060 }
1061
1062 /* 8x8 -> 1x1 */
1063 void ff_shrink88(uint8_t *dst, int dst_wrap,
1064                      const uint8_t *src, int src_wrap,
1065                      int width, int height)
1066 {
1067     int w, i;
1068
1069     for(;height > 0; height--) {
1070         for(w = width;w > 0; w--) {
1071             int tmp=0;
1072             for(i=0; i<8; i++){
1073                 tmp += src[0] + src[1] + src[2] + src[3] + src[4] + src[5] + src[6] + src[7];
1074                 src += src_wrap;
1075             }
1076             *(dst++) = (tmp + 32)>>6;
1077             src += 8 - 8*src_wrap;
1078         }
1079         src += 8*src_wrap - 8*width;
1080         dst += dst_wrap - width;
1081     }
1082 }
1083
1084
1085 int avpicture_alloc(AVPicture *picture,
1086                     enum PixelFormat pix_fmt, int width, int height)
1087 {
1088     int size;
1089     void *ptr;
1090
1091     size = avpicture_fill(picture, NULL, pix_fmt, width, height);
1092     if(size<0)
1093         goto fail;
1094     ptr = av_malloc(size);
1095     if (!ptr)
1096         goto fail;
1097     avpicture_fill(picture, ptr, pix_fmt, width, height);
1098     if(picture->data[1] && !picture->data[2])
1099         ff_set_systematic_pal((uint32_t*)picture->data[1], pix_fmt);
1100
1101     return 0;
1102  fail:
1103     memset(picture, 0, sizeof(AVPicture));
1104     return -1;
1105 }
1106
1107 void avpicture_free(AVPicture *picture)
1108 {
1109     av_free(picture->data[0]);
1110 }
1111
1112 /* return true if yuv planar */
1113 static inline int is_yuv_planar(const PixFmtInfo *ps)
1114 {
1115     return (ps->color_type == FF_COLOR_YUV ||
1116             ps->color_type == FF_COLOR_YUV_JPEG) &&
1117         ps->pixel_type == FF_PIXEL_PLANAR;
1118 }
1119
1120 int av_picture_crop(AVPicture *dst, const AVPicture *src,
1121                     enum PixelFormat pix_fmt, int top_band, int left_band)
1122 {
1123     int y_shift;
1124     int x_shift;
1125
1126     if (pix_fmt < 0 || pix_fmt >= PIX_FMT_NB || !is_yuv_planar(&pix_fmt_info[pix_fmt]))
1127         return -1;
1128
1129     y_shift = av_pix_fmt_descriptors[pix_fmt].log2_chroma_h;
1130     x_shift = av_pix_fmt_descriptors[pix_fmt].log2_chroma_w;
1131
1132     dst->data[0] = src->data[0] + (top_band * src->linesize[0]) + left_band;
1133     dst->data[1] = src->data[1] + ((top_band >> y_shift) * src->linesize[1]) + (left_band >> x_shift);
1134     dst->data[2] = src->data[2] + ((top_band >> y_shift) * src->linesize[2]) + (left_band >> x_shift);
1135
1136     dst->linesize[0] = src->linesize[0];
1137     dst->linesize[1] = src->linesize[1];
1138     dst->linesize[2] = src->linesize[2];
1139     return 0;
1140 }
1141
1142 int av_picture_pad(AVPicture *dst, const AVPicture *src, int height, int width,
1143                    enum PixelFormat pix_fmt, int padtop, int padbottom, int padleft, int padright,
1144             int *color)
1145 {
1146     uint8_t *optr;
1147     int y_shift;
1148     int x_shift;
1149     int yheight;
1150     int i, y;
1151
1152     if (pix_fmt < 0 || pix_fmt >= PIX_FMT_NB ||
1153         !is_yuv_planar(&pix_fmt_info[pix_fmt])) return -1;
1154
1155     for (i = 0; i < 3; i++) {
1156         x_shift = i ? av_pix_fmt_descriptors[pix_fmt].log2_chroma_w : 0;
1157         y_shift = i ? av_pix_fmt_descriptors[pix_fmt].log2_chroma_h : 0;
1158
1159         if (padtop || padleft) {
1160             memset(dst->data[i], color[i],
1161                 dst->linesize[i] * (padtop >> y_shift) + (padleft >> x_shift));
1162         }
1163
1164         if (padleft || padright) {
1165             optr = dst->data[i] + dst->linesize[i] * (padtop >> y_shift) +
1166                 (dst->linesize[i] - (padright >> x_shift));
1167             yheight = (height - 1 - (padtop + padbottom)) >> y_shift;
1168             for (y = 0; y < yheight; y++) {
1169                 memset(optr, color[i], (padleft + padright) >> x_shift);
1170                 optr += dst->linesize[i];
1171             }
1172         }
1173
1174         if (src) { /* first line */
1175             uint8_t *iptr = src->data[i];
1176             optr = dst->data[i] + dst->linesize[i] * (padtop >> y_shift) +
1177                     (padleft >> x_shift);
1178             memcpy(optr, iptr, (width - padleft - padright) >> x_shift);
1179             iptr += src->linesize[i];
1180             optr = dst->data[i] + dst->linesize[i] * (padtop >> y_shift) +
1181                 (dst->linesize[i] - (padright >> x_shift));
1182             yheight = (height - 1 - (padtop + padbottom)) >> y_shift;
1183             for (y = 0; y < yheight; y++) {
1184                 memset(optr, color[i], (padleft + padright) >> x_shift);
1185                 memcpy(optr + ((padleft + padright) >> x_shift), iptr,
1186                        (width - padleft - padright) >> x_shift);
1187                 iptr += src->linesize[i];
1188                 optr += dst->linesize[i];
1189             }
1190         }
1191
1192         if (padbottom || padright) {
1193             optr = dst->data[i] + dst->linesize[i] *
1194                 ((height - padbottom) >> y_shift) - (padright >> x_shift);
1195             memset(optr, color[i],dst->linesize[i] *
1196                 (padbottom >> y_shift) + (padright >> x_shift));
1197         }
1198     }
1199     return 0;
1200 }
1201
1202 /* NOTE: we scan all the pixels to have an exact information */
1203 static int get_alpha_info_pal8(const AVPicture *src, int width, int height)
1204 {
1205     const unsigned char *p;
1206     int src_wrap, ret, x, y;
1207     unsigned int a;
1208     uint32_t *palette = (uint32_t *)src->data[1];
1209
1210     p = src->data[0];
1211     src_wrap = src->linesize[0] - width;
1212     ret = 0;
1213     for(y=0;y<height;y++) {
1214         for(x=0;x<width;x++) {
1215             a = palette[p[0]] >> 24;
1216             if (a == 0x00) {
1217                 ret |= FF_ALPHA_TRANSP;
1218             } else if (a != 0xff) {
1219                 ret |= FF_ALPHA_SEMI_TRANSP;
1220             }
1221             p++;
1222         }
1223         p += src_wrap;
1224     }
1225     return ret;
1226 }
1227
1228 int img_get_alpha_info(const AVPicture *src,
1229                        enum PixelFormat pix_fmt, int width, int height)
1230 {
1231     const PixFmtInfo *pf = &pix_fmt_info[pix_fmt];
1232     int ret;
1233
1234     /* no alpha can be represented in format */
1235     if (!pf->is_alpha)
1236         return 0;
1237     switch(pix_fmt) {
1238     case PIX_FMT_PAL8:
1239         ret = get_alpha_info_pal8(src, width, height);
1240         break;
1241     default:
1242         /* we do not know, so everything is indicated */
1243         ret = FF_ALPHA_TRANSP | FF_ALPHA_SEMI_TRANSP;
1244         break;
1245     }
1246     return ret;
1247 }
1248
1249 #if HAVE_MMX
1250 #define DEINT_INPLACE_LINE_LUM \
1251                     movd_m2r(lum_m4[0],mm0);\
1252                     movd_m2r(lum_m3[0],mm1);\
1253                     movd_m2r(lum_m2[0],mm2);\
1254                     movd_m2r(lum_m1[0],mm3);\
1255                     movd_m2r(lum[0],mm4);\
1256                     punpcklbw_r2r(mm7,mm0);\
1257                     movd_r2m(mm2,lum_m4[0]);\
1258                     punpcklbw_r2r(mm7,mm1);\
1259                     punpcklbw_r2r(mm7,mm2);\
1260                     punpcklbw_r2r(mm7,mm3);\
1261                     punpcklbw_r2r(mm7,mm4);\
1262                     paddw_r2r(mm3,mm1);\
1263                     psllw_i2r(1,mm2);\
1264                     paddw_r2r(mm4,mm0);\
1265                     psllw_i2r(2,mm1);\
1266                     paddw_r2r(mm6,mm2);\
1267                     paddw_r2r(mm2,mm1);\
1268                     psubusw_r2r(mm0,mm1);\
1269                     psrlw_i2r(3,mm1);\
1270                     packuswb_r2r(mm7,mm1);\
1271                     movd_r2m(mm1,lum_m2[0]);
1272
1273 #define DEINT_LINE_LUM \
1274                     movd_m2r(lum_m4[0],mm0);\
1275                     movd_m2r(lum_m3[0],mm1);\
1276                     movd_m2r(lum_m2[0],mm2);\
1277                     movd_m2r(lum_m1[0],mm3);\
1278                     movd_m2r(lum[0],mm4);\
1279                     punpcklbw_r2r(mm7,mm0);\
1280                     punpcklbw_r2r(mm7,mm1);\
1281                     punpcklbw_r2r(mm7,mm2);\
1282                     punpcklbw_r2r(mm7,mm3);\
1283                     punpcklbw_r2r(mm7,mm4);\
1284                     paddw_r2r(mm3,mm1);\
1285                     psllw_i2r(1,mm2);\
1286                     paddw_r2r(mm4,mm0);\
1287                     psllw_i2r(2,mm1);\
1288                     paddw_r2r(mm6,mm2);\
1289                     paddw_r2r(mm2,mm1);\
1290                     psubusw_r2r(mm0,mm1);\
1291                     psrlw_i2r(3,mm1);\
1292                     packuswb_r2r(mm7,mm1);\
1293                     movd_r2m(mm1,dst[0]);
1294 #endif
1295
1296 /* filter parameters: [-1 4 2 4 -1] // 8 */
1297 static void deinterlace_line(uint8_t *dst,
1298                              const uint8_t *lum_m4, const uint8_t *lum_m3,
1299                              const uint8_t *lum_m2, const uint8_t *lum_m1,
1300                              const uint8_t *lum,
1301                              int size)
1302 {
1303 #if !HAVE_MMX
1304     uint8_t *cm = ff_cropTbl + MAX_NEG_CROP;
1305     int sum;
1306
1307     for(;size > 0;size--) {
1308         sum = -lum_m4[0];
1309         sum += lum_m3[0] << 2;
1310         sum += lum_m2[0] << 1;
1311         sum += lum_m1[0] << 2;
1312         sum += -lum[0];
1313         dst[0] = cm[(sum + 4) >> 3];
1314         lum_m4++;
1315         lum_m3++;
1316         lum_m2++;
1317         lum_m1++;
1318         lum++;
1319         dst++;
1320     }
1321 #else
1322
1323     {
1324         pxor_r2r(mm7,mm7);
1325         movq_m2r(ff_pw_4,mm6);
1326     }
1327     for (;size > 3; size-=4) {
1328         DEINT_LINE_LUM
1329         lum_m4+=4;
1330         lum_m3+=4;
1331         lum_m2+=4;
1332         lum_m1+=4;
1333         lum+=4;
1334         dst+=4;
1335     }
1336 #endif
1337 }
1338 static void deinterlace_line_inplace(uint8_t *lum_m4, uint8_t *lum_m3, uint8_t *lum_m2, uint8_t *lum_m1, uint8_t *lum,
1339                              int size)
1340 {
1341 #if !HAVE_MMX
1342     uint8_t *cm = ff_cropTbl + MAX_NEG_CROP;
1343     int sum;
1344
1345     for(;size > 0;size--) {
1346         sum = -lum_m4[0];
1347         sum += lum_m3[0] << 2;
1348         sum += lum_m2[0] << 1;
1349         lum_m4[0]=lum_m2[0];
1350         sum += lum_m1[0] << 2;
1351         sum += -lum[0];
1352         lum_m2[0] = cm[(sum + 4) >> 3];
1353         lum_m4++;
1354         lum_m3++;
1355         lum_m2++;
1356         lum_m1++;
1357         lum++;
1358     }
1359 #else
1360
1361     {
1362         pxor_r2r(mm7,mm7);
1363         movq_m2r(ff_pw_4,mm6);
1364     }
1365     for (;size > 3; size-=4) {
1366         DEINT_INPLACE_LINE_LUM
1367         lum_m4+=4;
1368         lum_m3+=4;
1369         lum_m2+=4;
1370         lum_m1+=4;
1371         lum+=4;
1372     }
1373 #endif
1374 }
1375
1376 /* deinterlacing : 2 temporal taps, 3 spatial taps linear filter. The
1377    top field is copied as is, but the bottom field is deinterlaced
1378    against the top field. */
1379 static void deinterlace_bottom_field(uint8_t *dst, int dst_wrap,
1380                                     const uint8_t *src1, int src_wrap,
1381                                     int width, int height)
1382 {
1383     const uint8_t *src_m2, *src_m1, *src_0, *src_p1, *src_p2;
1384     int y;
1385
1386     src_m2 = src1;
1387     src_m1 = src1;
1388     src_0=&src_m1[src_wrap];
1389     src_p1=&src_0[src_wrap];
1390     src_p2=&src_p1[src_wrap];
1391     for(y=0;y<(height-2);y+=2) {
1392         memcpy(dst,src_m1,width);
1393         dst += dst_wrap;
1394         deinterlace_line(dst,src_m2,src_m1,src_0,src_p1,src_p2,width);
1395         src_m2 = src_0;
1396         src_m1 = src_p1;
1397         src_0 = src_p2;
1398         src_p1 += 2*src_wrap;
1399         src_p2 += 2*src_wrap;
1400         dst += dst_wrap;
1401     }
1402     memcpy(dst,src_m1,width);
1403     dst += dst_wrap;
1404     /* do last line */
1405     deinterlace_line(dst,src_m2,src_m1,src_0,src_0,src_0,width);
1406 }
1407
1408 static void deinterlace_bottom_field_inplace(uint8_t *src1, int src_wrap,
1409                                              int width, int height)
1410 {
1411     uint8_t *src_m1, *src_0, *src_p1, *src_p2;
1412     int y;
1413     uint8_t *buf;
1414     buf = (uint8_t*)av_malloc(width);
1415
1416     src_m1 = src1;
1417     memcpy(buf,src_m1,width);
1418     src_0=&src_m1[src_wrap];
1419     src_p1=&src_0[src_wrap];
1420     src_p2=&src_p1[src_wrap];
1421     for(y=0;y<(height-2);y+=2) {
1422         deinterlace_line_inplace(buf,src_m1,src_0,src_p1,src_p2,width);
1423         src_m1 = src_p1;
1424         src_0 = src_p2;
1425         src_p1 += 2*src_wrap;
1426         src_p2 += 2*src_wrap;
1427     }
1428     /* do last line */
1429     deinterlace_line_inplace(buf,src_m1,src_0,src_0,src_0,width);
1430     av_free(buf);
1431 }
1432
1433 int avpicture_deinterlace(AVPicture *dst, const AVPicture *src,
1434                           enum PixelFormat pix_fmt, int width, int height)
1435 {
1436     int i;
1437
1438     if (pix_fmt != PIX_FMT_YUV420P &&
1439         pix_fmt != PIX_FMT_YUV422P &&
1440         pix_fmt != PIX_FMT_YUV444P &&
1441         pix_fmt != PIX_FMT_YUV411P &&
1442         pix_fmt != PIX_FMT_GRAY8)
1443         return -1;
1444     if ((width & 3) != 0 || (height & 3) != 0)
1445         return -1;
1446
1447     for(i=0;i<3;i++) {
1448         if (i == 1) {
1449             switch(pix_fmt) {
1450             case PIX_FMT_YUV420P:
1451                 width >>= 1;
1452                 height >>= 1;
1453                 break;
1454             case PIX_FMT_YUV422P:
1455                 width >>= 1;
1456                 break;
1457             case PIX_FMT_YUV411P:
1458                 width >>= 2;
1459                 break;
1460             default:
1461                 break;
1462             }
1463             if (pix_fmt == PIX_FMT_GRAY8) {
1464                 break;
1465             }
1466         }
1467         if (src == dst) {
1468             deinterlace_bottom_field_inplace(dst->data[i], dst->linesize[i],
1469                                  width, height);
1470         } else {
1471             deinterlace_bottom_field(dst->data[i],dst->linesize[i],
1472                                         src->data[i], src->linesize[i],
1473                                         width, height);
1474         }
1475     }
1476     emms_c();
1477     return 0;
1478 }
1479