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