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