Convert deinterlacing MMX code to YASM
[libav.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
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 "internal.h"
36 #include "imgconvert.h"
37 #include "libavutil/colorspace.h"
38 #include "libavutil/pixdesc.h"
39 #include "libavcore/imgutils.h"
40
41 #if HAVE_MMX
42 #include "x86/dsputil_mmx.h"
43 #endif
44
45 #define xglue(x, y) x ## y
46 #define glue(x, y) xglue(x, y)
47
48 #define FF_COLOR_RGB 0 /**< RGB color space */
49 #define FF_COLOR_GRAY 1 /**< gray color space */
50 #define FF_COLOR_YUV 2 /**< YUV color space. 16 <= Y <= 235, 16 <= U, V <= 240 */
51 #define FF_COLOR_YUV_JPEG 3 /**< YUV color space. 0 <= Y <= 255, 0 <= U, V <= 255 */
52
53 #define FF_PIXEL_PLANAR 0 /**< each channel has one component in AVPicture */
54 #define FF_PIXEL_PACKED 1 /**< only one components containing all the channels */
55 #define FF_PIXEL_PALETTE 2 /**< one components containing indexes for a palette */
56
57 #if HAVE_MMX
58 #define deinterlace_line_inplace ff_deinterlace_line_inplace_mmx
59 #define deinterlace_line ff_deinterlace_line_mmx
60 #else
61 #define deinterlace_line_inplace deinterlace_line_inplace_c
62 #define deinterlace_line deinterlace_line_c
63 #endif
64
65 typedef struct PixFmtInfo {
66 uint8_t nb_channels; /**< number of channels (including alpha) */
67 uint8_t color_type; /**< color type (see FF_COLOR_xxx constants) */
68 uint8_t pixel_type; /**< pixel storage type (see FF_PIXEL_xxx constants) */
69 uint8_t is_alpha : 1; /**< true if alpha can be specified */
70 uint8_t depth; /**< bit depth of the color components */
71 } PixFmtInfo;
72
73 /* this table gives more information about formats */
74 static const PixFmtInfo pix_fmt_info[PIX_FMT_NB] = {
75 /* YUV formats */
76 [PIX_FMT_YUV420P] = {
77 .nb_channels = 3,
78 .color_type = FF_COLOR_YUV,
79 .pixel_type = FF_PIXEL_PLANAR,
80 .depth = 8,
81 },
82 [PIX_FMT_YUV422P] = {
83 .nb_channels = 3,
84 .color_type = FF_COLOR_YUV,
85 .pixel_type = FF_PIXEL_PLANAR,
86 .depth = 8,
87 },
88 [PIX_FMT_YUV444P] = {
89 .nb_channels = 3,
90 .color_type = FF_COLOR_YUV,
91 .pixel_type = FF_PIXEL_PLANAR,
92 .depth = 8,
93 },
94 [PIX_FMT_YUYV422] = {
95 .nb_channels = 1,
96 .color_type = FF_COLOR_YUV,
97 .pixel_type = FF_PIXEL_PACKED,
98 .depth = 8,
99 },
100 [PIX_FMT_UYVY422] = {
101 .nb_channels = 1,
102 .color_type = FF_COLOR_YUV,
103 .pixel_type = FF_PIXEL_PACKED,
104 .depth = 8,
105 },
106 [PIX_FMT_YUV410P] = {
107 .nb_channels = 3,
108 .color_type = FF_COLOR_YUV,
109 .pixel_type = FF_PIXEL_PLANAR,
110 .depth = 8,
111 },
112 [PIX_FMT_YUV411P] = {
113 .nb_channels = 3,
114 .color_type = FF_COLOR_YUV,
115 .pixel_type = FF_PIXEL_PLANAR,
116 .depth = 8,
117 },
118 [PIX_FMT_YUV440P] = {
119 .nb_channels = 3,
120 .color_type = FF_COLOR_YUV,
121 .pixel_type = FF_PIXEL_PLANAR,
122 .depth = 8,
123 },
124 [PIX_FMT_YUV420P16LE] = {
125 .nb_channels = 3,
126 .color_type = FF_COLOR_YUV,
127 .pixel_type = FF_PIXEL_PLANAR,
128 .depth = 16,
129 },
130 [PIX_FMT_YUV422P16LE] = {
131 .nb_channels = 3,
132 .color_type = FF_COLOR_YUV,
133 .pixel_type = FF_PIXEL_PLANAR,
134 .depth = 16,
135 },
136 [PIX_FMT_YUV444P16LE] = {
137 .nb_channels = 3,
138 .color_type = FF_COLOR_YUV,
139 .pixel_type = FF_PIXEL_PLANAR,
140 .depth = 16,
141 },
142 [PIX_FMT_YUV420P16BE] = {
143 .nb_channels = 3,
144 .color_type = FF_COLOR_YUV,
145 .pixel_type = FF_PIXEL_PLANAR,
146 .depth = 16,
147 },
148 [PIX_FMT_YUV422P16BE] = {
149 .nb_channels = 3,
150 .color_type = FF_COLOR_YUV,
151 .pixel_type = FF_PIXEL_PLANAR,
152 .depth = 16,
153 },
154 [PIX_FMT_YUV444P16BE] = {
155 .nb_channels = 3,
156 .color_type = FF_COLOR_YUV,
157 .pixel_type = FF_PIXEL_PLANAR,
158 .depth = 16,
159 },
160
161
162 /* YUV formats with alpha plane */
163 [PIX_FMT_YUVA420P] = {
164 .nb_channels = 4,
165 .color_type = FF_COLOR_YUV,
166 .pixel_type = FF_PIXEL_PLANAR,
167 .depth = 8,
168 },
169
170 /* JPEG YUV */
171 [PIX_FMT_YUVJ420P] = {
172 .nb_channels = 3,
173 .color_type = FF_COLOR_YUV_JPEG,
174 .pixel_type = FF_PIXEL_PLANAR,
175 .depth = 8,
176 },
177 [PIX_FMT_YUVJ422P] = {
178 .nb_channels = 3,
179 .color_type = FF_COLOR_YUV_JPEG,
180 .pixel_type = FF_PIXEL_PLANAR,
181 .depth = 8,
182 },
183 [PIX_FMT_YUVJ444P] = {
184 .nb_channels = 3,
185 .color_type = FF_COLOR_YUV_JPEG,
186 .pixel_type = FF_PIXEL_PLANAR,
187 .depth = 8,
188 },
189 [PIX_FMT_YUVJ440P] = {
190 .nb_channels = 3,
191 .color_type = FF_COLOR_YUV_JPEG,
192 .pixel_type = FF_PIXEL_PLANAR,
193 .depth = 8,
194 },
195
196 /* RGB formats */
197 [PIX_FMT_RGB24] = {
198 .nb_channels = 3,
199 .color_type = FF_COLOR_RGB,
200 .pixel_type = FF_PIXEL_PACKED,
201 .depth = 8,
202 },
203 [PIX_FMT_BGR24] = {
204 .nb_channels = 3,
205 .color_type = FF_COLOR_RGB,
206 .pixel_type = FF_PIXEL_PACKED,
207 .depth = 8,
208 },
209 [PIX_FMT_ARGB] = {
210 .nb_channels = 4, .is_alpha = 1,
211 .color_type = FF_COLOR_RGB,
212 .pixel_type = FF_PIXEL_PACKED,
213 .depth = 8,
214 },
215 [PIX_FMT_RGB48BE] = {
216 .nb_channels = 3,
217 .color_type = FF_COLOR_RGB,
218 .pixel_type = FF_PIXEL_PACKED,
219 .depth = 16,
220 },
221 [PIX_FMT_RGB48LE] = {
222 .nb_channels = 3,
223 .color_type = FF_COLOR_RGB,
224 .pixel_type = FF_PIXEL_PACKED,
225 .depth = 16,
226 },
227 [PIX_FMT_RGB565BE] = {
228 .nb_channels = 3,
229 .color_type = FF_COLOR_RGB,
230 .pixel_type = FF_PIXEL_PACKED,
231 .depth = 5,
232 },
233 [PIX_FMT_RGB565LE] = {
234 .nb_channels = 3,
235 .color_type = FF_COLOR_RGB,
236 .pixel_type = FF_PIXEL_PACKED,
237 .depth = 5,
238 },
239 [PIX_FMT_RGB555BE] = {
240 .nb_channels = 3,
241 .color_type = FF_COLOR_RGB,
242 .pixel_type = FF_PIXEL_PACKED,
243 .depth = 5,
244 },
245 [PIX_FMT_RGB555LE] = {
246 .nb_channels = 3,
247 .color_type = FF_COLOR_RGB,
248 .pixel_type = FF_PIXEL_PACKED,
249 .depth = 5,
250 },
251 [PIX_FMT_RGB444BE] = {
252 .nb_channels = 3,
253 .color_type = FF_COLOR_RGB,
254 .pixel_type = FF_PIXEL_PACKED,
255 .depth = 4,
256 },
257 [PIX_FMT_RGB444LE] = {
258 .nb_channels = 3,
259 .color_type = FF_COLOR_RGB,
260 .pixel_type = FF_PIXEL_PACKED,
261 .depth = 4,
262 },
263
264 /* gray / mono formats */
265 [PIX_FMT_GRAY16BE] = {
266 .nb_channels = 1,
267 .color_type = FF_COLOR_GRAY,
268 .pixel_type = FF_PIXEL_PLANAR,
269 .depth = 16,
270 },
271 [PIX_FMT_GRAY16LE] = {
272 .nb_channels = 1,
273 .color_type = FF_COLOR_GRAY,
274 .pixel_type = FF_PIXEL_PLANAR,
275 .depth = 16,
276 },
277 [PIX_FMT_GRAY8] = {
278 .nb_channels = 1,
279 .color_type = FF_COLOR_GRAY,
280 .pixel_type = FF_PIXEL_PLANAR,
281 .depth = 8,
282 },
283 [PIX_FMT_MONOWHITE] = {
284 .nb_channels = 1,
285 .color_type = FF_COLOR_GRAY,
286 .pixel_type = FF_PIXEL_PLANAR,
287 .depth = 1,
288 },
289 [PIX_FMT_MONOBLACK] = {
290 .nb_channels = 1,
291 .color_type = FF_COLOR_GRAY,
292 .pixel_type = FF_PIXEL_PLANAR,
293 .depth = 1,
294 },
295
296 /* paletted formats */
297 [PIX_FMT_PAL8] = {
298 .nb_channels = 4, .is_alpha = 1,
299 .color_type = FF_COLOR_RGB,
300 .pixel_type = FF_PIXEL_PALETTE,
301 .depth = 8,
302 },
303 [PIX_FMT_UYYVYY411] = {
304 .nb_channels = 1,
305 .color_type = FF_COLOR_YUV,
306 .pixel_type = FF_PIXEL_PACKED,
307 .depth = 8,
308 },
309 [PIX_FMT_ABGR] = {
310 .nb_channels = 4, .is_alpha = 1,
311 .color_type = FF_COLOR_RGB,
312 .pixel_type = FF_PIXEL_PACKED,
313 .depth = 8,
314 },
315 [PIX_FMT_BGR565BE] = {
316 .nb_channels = 3,
317 .color_type = FF_COLOR_RGB,
318 .pixel_type = FF_PIXEL_PACKED,
319 .depth = 5,
320 },
321 [PIX_FMT_BGR565LE] = {
322 .nb_channels = 3,
323 .color_type = FF_COLOR_RGB,
324 .pixel_type = FF_PIXEL_PACKED,
325 .depth = 5,
326 },
327 [PIX_FMT_BGR555BE] = {
328 .nb_channels = 3,
329 .color_type = FF_COLOR_RGB,
330 .pixel_type = FF_PIXEL_PACKED,
331 .depth = 5,
332 },
333 [PIX_FMT_BGR555LE] = {
334 .nb_channels = 3,
335 .color_type = FF_COLOR_RGB,
336 .pixel_type = FF_PIXEL_PACKED,
337 .depth = 5,
338 },
339 [PIX_FMT_BGR444BE] = {
340 .nb_channels = 3,
341 .color_type = FF_COLOR_RGB,
342 .pixel_type = FF_PIXEL_PACKED,
343 .depth = 4,
344 },
345 [PIX_FMT_BGR444LE] = {
346 .nb_channels = 3,
347 .color_type = FF_COLOR_RGB,
348 .pixel_type = FF_PIXEL_PACKED,
349 .depth = 4,
350 },
351 [PIX_FMT_RGB8] = {
352 .nb_channels = 1,
353 .color_type = FF_COLOR_RGB,
354 .pixel_type = FF_PIXEL_PACKED,
355 .depth = 8,
356 },
357 [PIX_FMT_RGB4] = {
358 .nb_channels = 1,
359 .color_type = FF_COLOR_RGB,
360 .pixel_type = FF_PIXEL_PACKED,
361 .depth = 4,
362 },
363 [PIX_FMT_RGB4_BYTE] = {
364 .nb_channels = 1,
365 .color_type = FF_COLOR_RGB,
366 .pixel_type = FF_PIXEL_PACKED,
367 .depth = 8,
368 },
369 [PIX_FMT_BGR8] = {
370 .nb_channels = 1,
371 .color_type = FF_COLOR_RGB,
372 .pixel_type = FF_PIXEL_PACKED,
373 .depth = 8,
374 },
375 [PIX_FMT_BGR4] = {
376 .nb_channels = 1,
377 .color_type = FF_COLOR_RGB,
378 .pixel_type = FF_PIXEL_PACKED,
379 .depth = 4,
380 },
381 [PIX_FMT_BGR4_BYTE] = {
382 .nb_channels = 1,
383 .color_type = FF_COLOR_RGB,
384 .pixel_type = FF_PIXEL_PACKED,
385 .depth = 8,
386 },
387 [PIX_FMT_NV12] = {
388 .nb_channels = 2,
389 .color_type = FF_COLOR_YUV,
390 .pixel_type = FF_PIXEL_PLANAR,
391 .depth = 8,
392 },
393 [PIX_FMT_NV21] = {
394 .nb_channels = 2,
395 .color_type = FF_COLOR_YUV,
396 .pixel_type = FF_PIXEL_PLANAR,
397 .depth = 8,
398 },
399
400 [PIX_FMT_BGRA] = {
401 .nb_channels = 4, .is_alpha = 1,
402 .color_type = FF_COLOR_RGB,
403 .pixel_type = FF_PIXEL_PACKED,
404 .depth = 8,
405 },
406 [PIX_FMT_RGBA] = {
407 .nb_channels = 4, .is_alpha = 1,
408 .color_type = FF_COLOR_RGB,
409 .pixel_type = FF_PIXEL_PACKED,
410 .depth = 8,
411 },
412 };
413
414 void avcodec_get_chroma_sub_sample(enum PixelFormat pix_fmt, int *h_shift, int *v_shift)
415 {
416 *h_shift = av_pix_fmt_descriptors[pix_fmt].log2_chroma_w;
417 *v_shift = av_pix_fmt_descriptors[pix_fmt].log2_chroma_h;
418 }
419
420 const char *avcodec_get_pix_fmt_name(enum PixelFormat pix_fmt)
421 {
422 if (pix_fmt < 0 || pix_fmt >= PIX_FMT_NB)
423 return NULL;
424 else
425 return av_pix_fmt_descriptors[pix_fmt].name;
426 }
427
428 #if LIBAVCODEC_VERSION_MAJOR < 53
429 enum PixelFormat avcodec_get_pix_fmt(const char *name)
430 {
431 return av_get_pix_fmt(name);
432 }
433 #endif
434
435 void avcodec_pix_fmt_string (char *buf, int buf_size, enum PixelFormat pix_fmt)
436 {
437 /* print header */
438 if (pix_fmt < 0)
439 snprintf (buf, buf_size,
440 "name " " nb_channels" " depth" " is_alpha"
441 );
442 else{
443 PixFmtInfo info= pix_fmt_info[pix_fmt];
444
445 char is_alpha_char= info.is_alpha ? 'y' : 'n';
446
447 snprintf (buf, buf_size,
448 "%-11s %5d %9d %6c",
449 av_pix_fmt_descriptors[pix_fmt].name,
450 info.nb_channels,
451 info.depth,
452 is_alpha_char
453 );
454 }
455 }
456
457 int ff_is_hwaccel_pix_fmt(enum PixelFormat pix_fmt)
458 {
459 return av_pix_fmt_descriptors[pix_fmt].flags & PIX_FMT_HWACCEL;
460 }
461
462 int ff_set_systematic_pal(uint32_t pal[256], enum PixelFormat pix_fmt){
463 int i;
464
465 for(i=0; i<256; i++){
466 int r,g,b;
467
468 switch(pix_fmt) {
469 case PIX_FMT_RGB8:
470 r= (i>>5 )*36;
471 g= ((i>>2)&7)*36;
472 b= (i&3 )*85;
473 break;
474 case PIX_FMT_BGR8:
475 b= (i>>6 )*85;
476 g= ((i>>3)&7)*36;
477 r= (i&7 )*36;
478 break;
479 case PIX_FMT_RGB4_BYTE:
480 r= (i>>3 )*255;
481 g= ((i>>1)&3)*85;
482 b= (i&1 )*255;
483 break;
484 case PIX_FMT_BGR4_BYTE:
485 b= (i>>3 )*255;
486 g= ((i>>1)&3)*85;
487 r= (i&1 )*255;
488 break;
489 case PIX_FMT_GRAY8:
490 r=b=g= i;
491 break;
492 default:
493 return -1;
494 }
495 pal[i] = b + (g<<8) + (r<<16);
496 }
497
498 return 0;
499 }
500
501 int ff_fill_linesize(AVPicture *picture, enum PixelFormat pix_fmt, int width)
502 {
503 return av_fill_image_linesizes(picture->linesize, pix_fmt, width);
504 }
505
506 int ff_fill_pointer(AVPicture *picture, uint8_t *ptr, enum PixelFormat pix_fmt,
507 int height)
508 {
509 return av_fill_image_pointers(picture->data, pix_fmt, height, ptr, picture->linesize);
510 }
511
512 int avpicture_fill(AVPicture *picture, uint8_t *ptr,
513 enum PixelFormat pix_fmt, int width, int height)
514 {
515
516 if(avcodec_check_dimensions(NULL, width, height))
517 return -1;
518
519 if (av_fill_image_linesizes(picture->linesize, pix_fmt, width))
520 return -1;
521
522 return av_fill_image_pointers(picture->data, pix_fmt, height, ptr, picture->linesize);
523 }
524
525 int avpicture_layout(const AVPicture* src, enum PixelFormat pix_fmt, int width, int height,
526 unsigned char *dest, int dest_size)
527 {
528 const PixFmtInfo* pf = &pix_fmt_info[pix_fmt];
529 const AVPixFmtDescriptor *desc = &av_pix_fmt_descriptors[pix_fmt];
530 int i, j, w, ow, h, oh, data_planes;
531 const unsigned char* s;
532 int size = avpicture_get_size(pix_fmt, width, height);
533
534 if (size > dest_size || size < 0)
535 return -1;
536
537 if (pf->pixel_type == FF_PIXEL_PACKED || pf->pixel_type == FF_PIXEL_PALETTE) {
538 if (pix_fmt == PIX_FMT_YUYV422 ||
539 pix_fmt == PIX_FMT_UYVY422 ||
540 pix_fmt == PIX_FMT_BGR565BE ||
541 pix_fmt == PIX_FMT_BGR565LE ||
542 pix_fmt == PIX_FMT_BGR555BE ||
543 pix_fmt == PIX_FMT_BGR555LE ||
544 pix_fmt == PIX_FMT_BGR444BE ||
545 pix_fmt == PIX_FMT_BGR444LE ||
546 pix_fmt == PIX_FMT_RGB565BE ||
547 pix_fmt == PIX_FMT_RGB565LE ||
548 pix_fmt == PIX_FMT_RGB555BE ||
549 pix_fmt == PIX_FMT_RGB555LE ||
550 pix_fmt == PIX_FMT_RGB444BE ||
551 pix_fmt == PIX_FMT_RGB444LE)
552 w = width * 2;
553 else if (pix_fmt == PIX_FMT_UYYVYY411)
554 w = width + width/2;
555 else if (pix_fmt == PIX_FMT_PAL8)
556 w = width;
557 else
558 w = width * (pf->depth * pf->nb_channels / 8);
559
560 data_planes = 1;
561 h = height;
562 } else {
563 data_planes = pf->nb_channels;
564 w = (width*pf->depth + 7)/8;
565 h = height;
566 }
567
568 ow = w;
569 oh = h;
570
571 for (i=0; i<data_planes; i++) {
572 if (i == 1) {
573 w = (- ((-width) >> desc->log2_chroma_w) * pf->depth + 7) / 8;
574 h = -((-height) >> desc->log2_chroma_h);
575 if (pix_fmt == PIX_FMT_NV12 || pix_fmt == PIX_FMT_NV21)
576 w <<= 1;
577 } else if (i == 3) {
578 w = ow;
579 h = oh;
580 }
581 s = src->data[i];
582 for(j=0; j<h; j++) {
583 memcpy(dest, s, w);
584 dest += w;
585 s += src->linesize[i];
586 }
587 }
588
589 if (pf->pixel_type == FF_PIXEL_PALETTE)
590 memcpy((unsigned char *)(((size_t)dest + 3) & ~3), src->data[1], 256 * 4);
591
592 return size;
593 }
594
595 int avpicture_get_size(enum PixelFormat pix_fmt, int width, int height)
596 {
597 AVPicture dummy_pict;
598 if(avcodec_check_dimensions(NULL, width, height))
599 return -1;
600 switch (pix_fmt) {
601 case PIX_FMT_RGB8:
602 case PIX_FMT_BGR8:
603 case PIX_FMT_RGB4_BYTE:
604 case PIX_FMT_BGR4_BYTE:
605 case PIX_FMT_GRAY8:
606 // do not include palette for these pseudo-paletted formats
607 return width * height;
608 }
609 return avpicture_fill(&dummy_pict, NULL, pix_fmt, width, height);
610 }
611
612 int avcodec_get_pix_fmt_loss(enum PixelFormat dst_pix_fmt, enum PixelFormat src_pix_fmt,
613 int has_alpha)
614 {
615 const PixFmtInfo *pf, *ps;
616 const AVPixFmtDescriptor *src_desc = &av_pix_fmt_descriptors[src_pix_fmt];
617 const AVPixFmtDescriptor *dst_desc = &av_pix_fmt_descriptors[dst_pix_fmt];
618 int loss;
619
620 ps = &pix_fmt_info[src_pix_fmt];
621
622 /* compute loss */
623 loss = 0;
624 pf = &pix_fmt_info[dst_pix_fmt];
625 if (pf->depth < ps->depth ||
626 ((dst_pix_fmt == PIX_FMT_RGB555BE || dst_pix_fmt == PIX_FMT_RGB555LE ||
627 dst_pix_fmt == PIX_FMT_BGR555BE || dst_pix_fmt == PIX_FMT_BGR555LE) &&
628 (src_pix_fmt == PIX_FMT_RGB565BE || src_pix_fmt == PIX_FMT_RGB565LE ||
629 src_pix_fmt == PIX_FMT_BGR565BE || src_pix_fmt == PIX_FMT_BGR565LE)))
630 loss |= FF_LOSS_DEPTH;
631 if (dst_desc->log2_chroma_w > src_desc->log2_chroma_w ||
632 dst_desc->log2_chroma_h > src_desc->log2_chroma_h)
633 loss |= FF_LOSS_RESOLUTION;
634 switch(pf->color_type) {
635 case FF_COLOR_RGB:
636 if (ps->color_type != FF_COLOR_RGB &&
637 ps->color_type != FF_COLOR_GRAY)
638 loss |= FF_LOSS_COLORSPACE;
639 break;
640 case FF_COLOR_GRAY:
641 if (ps->color_type != FF_COLOR_GRAY)
642 loss |= FF_LOSS_COLORSPACE;
643 break;
644 case FF_COLOR_YUV:
645 if (ps->color_type != FF_COLOR_YUV)
646 loss |= FF_LOSS_COLORSPACE;
647 break;
648 case FF_COLOR_YUV_JPEG:
649 if (ps->color_type != FF_COLOR_YUV_JPEG &&
650 ps->color_type != FF_COLOR_YUV &&
651 ps->color_type != FF_COLOR_GRAY)
652 loss |= FF_LOSS_COLORSPACE;
653 break;
654 default:
655 /* fail safe test */
656 if (ps->color_type != pf->color_type)
657 loss |= FF_LOSS_COLORSPACE;
658 break;
659 }
660 if (pf->color_type == FF_COLOR_GRAY &&
661 ps->color_type != FF_COLOR_GRAY)
662 loss |= FF_LOSS_CHROMA;
663 if (!pf->is_alpha && (ps->is_alpha && has_alpha))
664 loss |= FF_LOSS_ALPHA;
665 if (pf->pixel_type == FF_PIXEL_PALETTE &&
666 (ps->pixel_type != FF_PIXEL_PALETTE && ps->color_type != FF_COLOR_GRAY))
667 loss |= FF_LOSS_COLORQUANT;
668 return loss;
669 }
670
671 static int avg_bits_per_pixel(enum PixelFormat pix_fmt)
672 {
673 int bits;
674 const PixFmtInfo *pf;
675 const AVPixFmtDescriptor *desc = &av_pix_fmt_descriptors[pix_fmt];
676
677 pf = &pix_fmt_info[pix_fmt];
678 switch(pf->pixel_type) {
679 case FF_PIXEL_PACKED:
680 switch(pix_fmt) {
681 case PIX_FMT_YUYV422:
682 case PIX_FMT_UYVY422:
683 case PIX_FMT_RGB565BE:
684 case PIX_FMT_RGB565LE:
685 case PIX_FMT_RGB555BE:
686 case PIX_FMT_RGB555LE:
687 case PIX_FMT_RGB444BE:
688 case PIX_FMT_RGB444LE:
689 case PIX_FMT_BGR565BE:
690 case PIX_FMT_BGR565LE:
691 case PIX_FMT_BGR555BE:
692 case PIX_FMT_BGR555LE:
693 case PIX_FMT_BGR444BE:
694 case PIX_FMT_BGR444LE:
695 bits = 16;
696 break;
697 case PIX_FMT_UYYVYY411:
698 bits = 12;
699 break;
700 default:
701 bits = pf->depth * pf->nb_channels;
702 break;
703 }
704 break;
705 case FF_PIXEL_PLANAR:
706 if (desc->log2_chroma_w == 0 && desc->log2_chroma_h == 0) {
707 bits = pf->depth * pf->nb_channels;
708 } else {
709 bits = pf->depth + ((2 * pf->depth) >>
710 (desc->log2_chroma_w + desc->log2_chroma_h));
711 }
712 break;
713 case FF_PIXEL_PALETTE:
714 bits = 8;
715 break;
716 default:
717 bits = -1;
718 break;
719 }
720 return bits;
721 }
722
723 static enum PixelFormat avcodec_find_best_pix_fmt1(int64_t pix_fmt_mask,
724 enum PixelFormat src_pix_fmt,
725 int has_alpha,
726 int loss_mask)
727 {
728 int dist, i, loss, min_dist;
729 enum PixelFormat dst_pix_fmt;
730
731 /* find exact color match with smallest size */
732 dst_pix_fmt = PIX_FMT_NONE;
733 min_dist = 0x7fffffff;
734 for(i = 0;i < PIX_FMT_NB; i++) {
735 if (pix_fmt_mask & (1ULL << i)) {
736 loss = avcodec_get_pix_fmt_loss(i, src_pix_fmt, has_alpha) & loss_mask;
737 if (loss == 0) {
738 dist = avg_bits_per_pixel(i);
739 if (dist < min_dist) {
740 min_dist = dist;
741 dst_pix_fmt = i;
742 }
743 }
744 }
745 }
746 return dst_pix_fmt;
747 }
748
749 enum PixelFormat avcodec_find_best_pix_fmt(int64_t pix_fmt_mask, enum PixelFormat src_pix_fmt,
750 int has_alpha, int *loss_ptr)
751 {
752 enum PixelFormat dst_pix_fmt;
753 int loss_mask, i;
754 static const int loss_mask_order[] = {
755 ~0, /* no loss first */
756 ~FF_LOSS_ALPHA,
757 ~FF_LOSS_RESOLUTION,
758 ~(FF_LOSS_COLORSPACE | FF_LOSS_RESOLUTION),
759 ~FF_LOSS_COLORQUANT,
760 ~FF_LOSS_DEPTH,
761 0,
762 };
763
764 /* try with successive loss */
765 i = 0;
766 for(;;) {
767 loss_mask = loss_mask_order[i++];
768 dst_pix_fmt = avcodec_find_best_pix_fmt1(pix_fmt_mask, src_pix_fmt,
769 has_alpha, loss_mask);
770 if (dst_pix_fmt >= 0)
771 goto found;
772 if (loss_mask == 0)
773 break;
774 }
775 return PIX_FMT_NONE;
776 found:
777 if (loss_ptr)
778 *loss_ptr = avcodec_get_pix_fmt_loss(dst_pix_fmt, src_pix_fmt, has_alpha);
779 return dst_pix_fmt;
780 }
781
782 void ff_img_copy_plane(uint8_t *dst, int dst_wrap,
783 const uint8_t *src, int src_wrap,
784 int width, int height)
785 {
786 if((!dst) || (!src))
787 return;
788 for(;height > 0; height--) {
789 memcpy(dst, src, width);
790 dst += dst_wrap;
791 src += src_wrap;
792 }
793 }
794
795 int ff_get_plane_bytewidth(enum PixelFormat pix_fmt, int width, int plane)
796 {
797 int bits;
798 const PixFmtInfo *pf = &pix_fmt_info[pix_fmt];
799 const AVPixFmtDescriptor *desc = &av_pix_fmt_descriptors[pix_fmt];
800
801 pf = &pix_fmt_info[pix_fmt];
802 switch(pf->pixel_type) {
803 case FF_PIXEL_PACKED:
804 switch(pix_fmt) {
805 case PIX_FMT_YUYV422:
806 case PIX_FMT_UYVY422:
807 case PIX_FMT_RGB565BE:
808 case PIX_FMT_RGB565LE:
809 case PIX_FMT_RGB555BE:
810 case PIX_FMT_RGB555LE:
811 case PIX_FMT_RGB444BE:
812 case PIX_FMT_RGB444LE:
813 case PIX_FMT_BGR565BE:
814 case PIX_FMT_BGR565LE:
815 case PIX_FMT_BGR555BE:
816 case PIX_FMT_BGR555LE:
817 case PIX_FMT_BGR444BE:
818 case PIX_FMT_BGR444LE:
819 bits = 16;
820 break;
821 case PIX_FMT_UYYVYY411:
822 bits = 12;
823 break;
824 default:
825 bits = pf->depth * pf->nb_channels;
826 break;
827 }
828 return (width * bits + 7) >> 3;
829 break;
830 case FF_PIXEL_PLANAR:
831 if ((pix_fmt != PIX_FMT_NV12 && pix_fmt != PIX_FMT_NV21) &&
832 (plane == 1 || plane == 2))
833 width= -((-width)>>desc->log2_chroma_w);
834
835 return (width * pf->depth + 7) >> 3;
836 break;
837 case FF_PIXEL_PALETTE:
838 if (plane == 0)
839 return width;
840 break;
841 }
842
843 return -1;
844 }
845
846 void av_picture_copy(AVPicture *dst, const AVPicture *src,
847 enum PixelFormat pix_fmt, int width, int height)
848 {
849 int i;
850 const PixFmtInfo *pf = &pix_fmt_info[pix_fmt];
851 const AVPixFmtDescriptor *desc = &av_pix_fmt_descriptors[pix_fmt];
852
853 switch(pf->pixel_type) {
854 case FF_PIXEL_PACKED:
855 case FF_PIXEL_PLANAR:
856 for(i = 0; i < pf->nb_channels; i++) {
857 int h;
858 int bwidth = ff_get_plane_bytewidth(pix_fmt, width, i);
859 h = height;
860 if (i == 1 || i == 2) {
861 h= -((-height)>>desc->log2_chroma_h);
862 }
863 ff_img_copy_plane(dst->data[i], dst->linesize[i],
864 src->data[i], src->linesize[i],
865 bwidth, h);
866 }
867 break;
868 case FF_PIXEL_PALETTE:
869 ff_img_copy_plane(dst->data[0], dst->linesize[0],
870 src->data[0], src->linesize[0],
871 width, height);
872 /* copy the palette */
873 memcpy(dst->data[1], src->data[1], 4*256);
874 break;
875 }
876 }
877
878 /* 2x2 -> 1x1 */
879 void ff_shrink22(uint8_t *dst, int dst_wrap,
880 const uint8_t *src, int src_wrap,
881 int width, int height)
882 {
883 int w;
884 const uint8_t *s1, *s2;
885 uint8_t *d;
886
887 for(;height > 0; height--) {
888 s1 = src;
889 s2 = s1 + src_wrap;
890 d = dst;
891 for(w = width;w >= 4; w-=4) {
892 d[0] = (s1[0] + s1[1] + s2[0] + s2[1] + 2) >> 2;
893 d[1] = (s1[2] + s1[3] + s2[2] + s2[3] + 2) >> 2;
894 d[2] = (s1[4] + s1[5] + s2[4] + s2[5] + 2) >> 2;
895 d[3] = (s1[6] + s1[7] + s2[6] + s2[7] + 2) >> 2;
896 s1 += 8;
897 s2 += 8;
898 d += 4;
899 }
900 for(;w > 0; w--) {
901 d[0] = (s1[0] + s1[1] + s2[0] + s2[1] + 2) >> 2;
902 s1 += 2;
903 s2 += 2;
904 d++;
905 }
906 src += 2 * src_wrap;
907 dst += dst_wrap;
908 }
909 }
910
911 /* 4x4 -> 1x1 */
912 void ff_shrink44(uint8_t *dst, int dst_wrap,
913 const uint8_t *src, int src_wrap,
914 int width, int height)
915 {
916 int w;
917 const uint8_t *s1, *s2, *s3, *s4;
918 uint8_t *d;
919
920 for(;height > 0; height--) {
921 s1 = src;
922 s2 = s1 + src_wrap;
923 s3 = s2 + src_wrap;
924 s4 = s3 + src_wrap;
925 d = dst;
926 for(w = width;w > 0; w--) {
927 d[0] = (s1[0] + s1[1] + s1[2] + s1[3] +
928 s2[0] + s2[1] + s2[2] + s2[3] +
929 s3[0] + s3[1] + s3[2] + s3[3] +
930 s4[0] + s4[1] + s4[2] + s4[3] + 8) >> 4;
931 s1 += 4;
932 s2 += 4;
933 s3 += 4;
934 s4 += 4;
935 d++;
936 }
937 src += 4 * src_wrap;
938 dst += dst_wrap;
939 }
940 }
941
942 /* 8x8 -> 1x1 */
943 void ff_shrink88(uint8_t *dst, int dst_wrap,
944 const uint8_t *src, int src_wrap,
945 int width, int height)
946 {
947 int w, i;
948
949 for(;height > 0; height--) {
950 for(w = width;w > 0; w--) {
951 int tmp=0;
952 for(i=0; i<8; i++){
953 tmp += src[0] + src[1] + src[2] + src[3] + src[4] + src[5] + src[6] + src[7];
954 src += src_wrap;
955 }
956 *(dst++) = (tmp + 32)>>6;
957 src += 8 - 8*src_wrap;
958 }
959 src += 8*src_wrap - 8*width;
960 dst += dst_wrap - width;
961 }
962 }
963
964
965 int avpicture_alloc(AVPicture *picture,
966 enum PixelFormat pix_fmt, int width, int height)
967 {
968 int size;
969 void *ptr;
970
971 size = avpicture_fill(picture, NULL, pix_fmt, width, height);
972 if(size<0)
973 goto fail;
974 ptr = av_malloc(size);
975 if (!ptr)
976 goto fail;
977 avpicture_fill(picture, ptr, pix_fmt, width, height);
978 if(picture->data[1] && !picture->data[2])
979 ff_set_systematic_pal((uint32_t*)picture->data[1], pix_fmt);
980
981 return 0;
982 fail:
983 memset(picture, 0, sizeof(AVPicture));
984 return -1;
985 }
986
987 void avpicture_free(AVPicture *picture)
988 {
989 av_free(picture->data[0]);
990 }
991
992 /* return true if yuv planar */
993 static inline int is_yuv_planar(const PixFmtInfo *ps)
994 {
995 return (ps->color_type == FF_COLOR_YUV ||
996 ps->color_type == FF_COLOR_YUV_JPEG) &&
997 ps->pixel_type == FF_PIXEL_PLANAR;
998 }
999
1000 int av_picture_crop(AVPicture *dst, const AVPicture *src,
1001 enum PixelFormat pix_fmt, int top_band, int left_band)
1002 {
1003 int y_shift;
1004 int x_shift;
1005
1006 if (pix_fmt < 0 || pix_fmt >= PIX_FMT_NB || !is_yuv_planar(&pix_fmt_info[pix_fmt]))
1007 return -1;
1008
1009 y_shift = av_pix_fmt_descriptors[pix_fmt].log2_chroma_h;
1010 x_shift = av_pix_fmt_descriptors[pix_fmt].log2_chroma_w;
1011
1012 dst->data[0] = src->data[0] + (top_band * src->linesize[0]) + left_band;
1013 dst->data[1] = src->data[1] + ((top_band >> y_shift) * src->linesize[1]) + (left_band >> x_shift);
1014 dst->data[2] = src->data[2] + ((top_band >> y_shift) * src->linesize[2]) + (left_band >> x_shift);
1015
1016 dst->linesize[0] = src->linesize[0];
1017 dst->linesize[1] = src->linesize[1];
1018 dst->linesize[2] = src->linesize[2];
1019 return 0;
1020 }
1021
1022 int av_picture_pad(AVPicture *dst, const AVPicture *src, int height, int width,
1023 enum PixelFormat pix_fmt, int padtop, int padbottom, int padleft, int padright,
1024 int *color)
1025 {
1026 uint8_t *optr;
1027 int y_shift;
1028 int x_shift;
1029 int yheight;
1030 int i, y;
1031
1032 if (pix_fmt < 0 || pix_fmt >= PIX_FMT_NB ||
1033 !is_yuv_planar(&pix_fmt_info[pix_fmt])) return -1;
1034
1035 for (i = 0; i < 3; i++) {
1036 x_shift = i ? av_pix_fmt_descriptors[pix_fmt].log2_chroma_w : 0;
1037 y_shift = i ? av_pix_fmt_descriptors[pix_fmt].log2_chroma_h : 0;
1038
1039 if (padtop || padleft) {
1040 memset(dst->data[i], color[i],
1041 dst->linesize[i] * (padtop >> y_shift) + (padleft >> x_shift));
1042 }
1043
1044 if (padleft || padright) {
1045 optr = dst->data[i] + dst->linesize[i] * (padtop >> y_shift) +
1046 (dst->linesize[i] - (padright >> x_shift));
1047 yheight = (height - 1 - (padtop + padbottom)) >> y_shift;
1048 for (y = 0; y < yheight; y++) {
1049 memset(optr, color[i], (padleft + padright) >> x_shift);
1050 optr += dst->linesize[i];
1051 }
1052 }
1053
1054 if (src) { /* first line */
1055 uint8_t *iptr = src->data[i];
1056 optr = dst->data[i] + dst->linesize[i] * (padtop >> y_shift) +
1057 (padleft >> x_shift);
1058 memcpy(optr, iptr, (width - padleft - padright) >> x_shift);
1059 iptr += src->linesize[i];
1060 optr = dst->data[i] + dst->linesize[i] * (padtop >> y_shift) +
1061 (dst->linesize[i] - (padright >> x_shift));
1062 yheight = (height - 1 - (padtop + padbottom)) >> y_shift;
1063 for (y = 0; y < yheight; y++) {
1064 memset(optr, color[i], (padleft + padright) >> x_shift);
1065 memcpy(optr + ((padleft + padright) >> x_shift), iptr,
1066 (width - padleft - padright) >> x_shift);
1067 iptr += src->linesize[i];
1068 optr += dst->linesize[i];
1069 }
1070 }
1071
1072 if (padbottom || padright) {
1073 optr = dst->data[i] + dst->linesize[i] *
1074 ((height - padbottom) >> y_shift) - (padright >> x_shift);
1075 memset(optr, color[i],dst->linesize[i] *
1076 (padbottom >> y_shift) + (padright >> x_shift));
1077 }
1078 }
1079 return 0;
1080 }
1081
1082 /* NOTE: we scan all the pixels to have an exact information */
1083 static int get_alpha_info_pal8(const AVPicture *src, int width, int height)
1084 {
1085 const unsigned char *p;
1086 int src_wrap, ret, x, y;
1087 unsigned int a;
1088 uint32_t *palette = (uint32_t *)src->data[1];
1089
1090 p = src->data[0];
1091 src_wrap = src->linesize[0] - width;
1092 ret = 0;
1093 for(y=0;y<height;y++) {
1094 for(x=0;x<width;x++) {
1095 a = palette[p[0]] >> 24;
1096 if (a == 0x00) {
1097 ret |= FF_ALPHA_TRANSP;
1098 } else if (a != 0xff) {
1099 ret |= FF_ALPHA_SEMI_TRANSP;
1100 }
1101 p++;
1102 }
1103 p += src_wrap;
1104 }
1105 return ret;
1106 }
1107
1108 int img_get_alpha_info(const AVPicture *src,
1109 enum PixelFormat pix_fmt, int width, int height)
1110 {
1111 const PixFmtInfo *pf = &pix_fmt_info[pix_fmt];
1112 int ret;
1113
1114 /* no alpha can be represented in format */
1115 if (!pf->is_alpha)
1116 return 0;
1117 switch(pix_fmt) {
1118 case PIX_FMT_PAL8:
1119 ret = get_alpha_info_pal8(src, width, height);
1120 break;
1121 default:
1122 /* we do not know, so everything is indicated */
1123 ret = FF_ALPHA_TRANSP | FF_ALPHA_SEMI_TRANSP;
1124 break;
1125 }
1126 return ret;
1127 }
1128
1129 #if !HAVE_MMX
1130 /* filter parameters: [-1 4 2 4 -1] // 8 */
1131 static void deinterlace_line_c(uint8_t *dst,
1132 const uint8_t *lum_m4, const uint8_t *lum_m3,
1133 const uint8_t *lum_m2, const uint8_t *lum_m1,
1134 const uint8_t *lum,
1135 int size)
1136 {
1137 uint8_t *cm = ff_cropTbl + MAX_NEG_CROP;
1138 int sum;
1139
1140 for(;size > 0;size--) {
1141 sum = -lum_m4[0];
1142 sum += lum_m3[0] << 2;
1143 sum += lum_m2[0] << 1;
1144 sum += lum_m1[0] << 2;
1145 sum += -lum[0];
1146 dst[0] = cm[(sum + 4) >> 3];
1147 lum_m4++;
1148 lum_m3++;
1149 lum_m2++;
1150 lum_m1++;
1151 lum++;
1152 dst++;
1153 }
1154 }
1155
1156 static void deinterlace_line_inplace_c(uint8_t *lum_m4, uint8_t *lum_m3,
1157 uint8_t *lum_m2, uint8_t *lum_m1,
1158 uint8_t *lum, int size)
1159 {
1160 uint8_t *cm = ff_cropTbl + MAX_NEG_CROP;
1161 int sum;
1162
1163 for(;size > 0;size--) {
1164 sum = -lum_m4[0];
1165 sum += lum_m3[0] << 2;
1166 sum += lum_m2[0] << 1;
1167 lum_m4[0]=lum_m2[0];
1168 sum += lum_m1[0] << 2;
1169 sum += -lum[0];
1170 lum_m2[0] = cm[(sum + 4) >> 3];
1171 lum_m4++;
1172 lum_m3++;
1173 lum_m2++;
1174 lum_m1++;
1175 lum++;
1176 }
1177 }
1178 #endif
1179
1180 /* deinterlacing : 2 temporal taps, 3 spatial taps linear filter. The
1181 top field is copied as is, but the bottom field is deinterlaced
1182 against the top field. */
1183 static void deinterlace_bottom_field(uint8_t *dst, int dst_wrap,
1184 const uint8_t *src1, int src_wrap,
1185 int width, int height)
1186 {
1187 const uint8_t *src_m2, *src_m1, *src_0, *src_p1, *src_p2;
1188 int y;
1189
1190 src_m2 = src1;
1191 src_m1 = src1;
1192 src_0=&src_m1[src_wrap];
1193 src_p1=&src_0[src_wrap];
1194 src_p2=&src_p1[src_wrap];
1195 for(y=0;y<(height-2);y+=2) {
1196 memcpy(dst,src_m1,width);
1197 dst += dst_wrap;
1198 deinterlace_line(dst,src_m2,src_m1,src_0,src_p1,src_p2,width);
1199 src_m2 = src_0;
1200 src_m1 = src_p1;
1201 src_0 = src_p2;
1202 src_p1 += 2*src_wrap;
1203 src_p2 += 2*src_wrap;
1204 dst += dst_wrap;
1205 }
1206 memcpy(dst,src_m1,width);
1207 dst += dst_wrap;
1208 /* do last line */
1209 deinterlace_line(dst,src_m2,src_m1,src_0,src_0,src_0,width);
1210 }
1211
1212 static void deinterlace_bottom_field_inplace(uint8_t *src1, int src_wrap,
1213 int width, int height)
1214 {
1215 uint8_t *src_m1, *src_0, *src_p1, *src_p2;
1216 int y;
1217 uint8_t *buf;
1218 buf = (uint8_t*)av_malloc(width);
1219
1220 src_m1 = src1;
1221 memcpy(buf,src_m1,width);
1222 src_0=&src_m1[src_wrap];
1223 src_p1=&src_0[src_wrap];
1224 src_p2=&src_p1[src_wrap];
1225 for(y=0;y<(height-2);y+=2) {
1226 deinterlace_line_inplace(buf,src_m1,src_0,src_p1,src_p2,width);
1227 src_m1 = src_p1;
1228 src_0 = src_p2;
1229 src_p1 += 2*src_wrap;
1230 src_p2 += 2*src_wrap;
1231 }
1232 /* do last line */
1233 deinterlace_line_inplace(buf,src_m1,src_0,src_0,src_0,width);
1234 av_free(buf);
1235 }
1236
1237 int avpicture_deinterlace(AVPicture *dst, const AVPicture *src,
1238 enum PixelFormat pix_fmt, int width, int height)
1239 {
1240 int i;
1241
1242 if (pix_fmt != PIX_FMT_YUV420P &&
1243 pix_fmt != PIX_FMT_YUV422P &&
1244 pix_fmt != PIX_FMT_YUV444P &&
1245 pix_fmt != PIX_FMT_YUV411P &&
1246 pix_fmt != PIX_FMT_GRAY8)
1247 return -1;
1248 if ((width & 3) != 0 || (height & 3) != 0)
1249 return -1;
1250
1251 for(i=0;i<3;i++) {
1252 if (i == 1) {
1253 switch(pix_fmt) {
1254 case PIX_FMT_YUV420P:
1255 width >>= 1;
1256 height >>= 1;
1257 break;
1258 case PIX_FMT_YUV422P:
1259 width >>= 1;
1260 break;
1261 case PIX_FMT_YUV411P:
1262 width >>= 2;
1263 break;
1264 default:
1265 break;
1266 }
1267 if (pix_fmt == PIX_FMT_GRAY8) {
1268 break;
1269 }
1270 }
1271 if (src == dst) {
1272 deinterlace_bottom_field_inplace(dst->data[i], dst->linesize[i],
1273 width, height);
1274 } else {
1275 deinterlace_bottom_field(dst->data[i],dst->linesize[i],
1276 src->data[i], src->linesize[i],
1277 width, height);
1278 }
1279 }
1280 emms_c();
1281 return 0;
1282 }
1283