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