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