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