Use av_fill_image_pointers/linesizes in place of ff_fill_pointer/linesize,
[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 && HAVE_YASM
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 && HAVE_YASM
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 #if LIBAVCODEC_VERSION_MAJOR < 53
502 int ff_fill_linesize(AVPicture *picture, enum PixelFormat pix_fmt, int width)
503 {
504 return av_fill_image_linesizes(picture->linesize, pix_fmt, width);
505 }
506
507 int ff_fill_pointer(AVPicture *picture, uint8_t *ptr, enum PixelFormat pix_fmt,
508 int height)
509 {
510 return av_fill_image_pointers(picture->data, pix_fmt, height, ptr, picture->linesize);
511 }
512 #endif
513
514 int avpicture_fill(AVPicture *picture, uint8_t *ptr,
515 enum PixelFormat pix_fmt, int width, int height)
516 {
517
518 if(avcodec_check_dimensions(NULL, width, height))
519 return -1;
520
521 if (av_fill_image_linesizes(picture->linesize, pix_fmt, width))
522 return -1;
523
524 return av_fill_image_pointers(picture->data, pix_fmt, height, ptr, picture->linesize);
525 }
526
527 int avpicture_layout(const AVPicture* src, enum PixelFormat pix_fmt, int width, int height,
528 unsigned char *dest, int dest_size)
529 {
530 const PixFmtInfo* pf = &pix_fmt_info[pix_fmt];
531 const AVPixFmtDescriptor *desc = &av_pix_fmt_descriptors[pix_fmt];
532 int i, j, w, ow, h, oh, data_planes;
533 const unsigned char* s;
534 int size = avpicture_get_size(pix_fmt, width, height);
535
536 if (size > dest_size || size < 0)
537 return -1;
538
539 if (pf->pixel_type == FF_PIXEL_PACKED || pf->pixel_type == FF_PIXEL_PALETTE) {
540 if (pix_fmt == PIX_FMT_YUYV422 ||
541 pix_fmt == PIX_FMT_UYVY422 ||
542 pix_fmt == PIX_FMT_BGR565BE ||
543 pix_fmt == PIX_FMT_BGR565LE ||
544 pix_fmt == PIX_FMT_BGR555BE ||
545 pix_fmt == PIX_FMT_BGR555LE ||
546 pix_fmt == PIX_FMT_BGR444BE ||
547 pix_fmt == PIX_FMT_BGR444LE ||
548 pix_fmt == PIX_FMT_RGB565BE ||
549 pix_fmt == PIX_FMT_RGB565LE ||
550 pix_fmt == PIX_FMT_RGB555BE ||
551 pix_fmt == PIX_FMT_RGB555LE ||
552 pix_fmt == PIX_FMT_RGB444BE ||
553 pix_fmt == PIX_FMT_RGB444LE)
554 w = width * 2;
555 else if (pix_fmt == PIX_FMT_UYYVYY411)
556 w = width + width/2;
557 else if (pix_fmt == PIX_FMT_PAL8)
558 w = width;
559 else
560 w = width * (pf->depth * pf->nb_channels / 8);
561
562 data_planes = 1;
563 h = height;
564 } else {
565 data_planes = pf->nb_channels;
566 w = (width*pf->depth + 7)/8;
567 h = height;
568 }
569
570 ow = w;
571 oh = h;
572
573 for (i=0; i<data_planes; i++) {
574 if (i == 1) {
575 w = (- ((-width) >> desc->log2_chroma_w) * pf->depth + 7) / 8;
576 h = -((-height) >> desc->log2_chroma_h);
577 if (pix_fmt == PIX_FMT_NV12 || pix_fmt == PIX_FMT_NV21)
578 w <<= 1;
579 } else if (i == 3) {
580 w = ow;
581 h = oh;
582 }
583 s = src->data[i];
584 for(j=0; j<h; j++) {
585 memcpy(dest, s, w);
586 dest += w;
587 s += src->linesize[i];
588 }
589 }
590
591 if (pf->pixel_type == FF_PIXEL_PALETTE)
592 memcpy((unsigned char *)(((size_t)dest + 3) & ~3), src->data[1], 256 * 4);
593
594 return size;
595 }
596
597 int avpicture_get_size(enum PixelFormat pix_fmt, int width, int height)
598 {
599 AVPicture dummy_pict;
600 if(avcodec_check_dimensions(NULL, width, height))
601 return -1;
602 switch (pix_fmt) {
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 // do not include palette for these pseudo-paletted formats
609 return width * height;
610 }
611 return avpicture_fill(&dummy_pict, NULL, pix_fmt, width, height);
612 }
613
614 int avcodec_get_pix_fmt_loss(enum PixelFormat dst_pix_fmt, enum PixelFormat src_pix_fmt,
615 int has_alpha)
616 {
617 const PixFmtInfo *pf, *ps;
618 const AVPixFmtDescriptor *src_desc = &av_pix_fmt_descriptors[src_pix_fmt];
619 const AVPixFmtDescriptor *dst_desc = &av_pix_fmt_descriptors[dst_pix_fmt];
620 int loss;
621
622 ps = &pix_fmt_info[src_pix_fmt];
623
624 /* compute loss */
625 loss = 0;
626 pf = &pix_fmt_info[dst_pix_fmt];
627 if (pf->depth < ps->depth ||
628 ((dst_pix_fmt == PIX_FMT_RGB555BE || dst_pix_fmt == PIX_FMT_RGB555LE ||
629 dst_pix_fmt == PIX_FMT_BGR555BE || dst_pix_fmt == PIX_FMT_BGR555LE) &&
630 (src_pix_fmt == PIX_FMT_RGB565BE || src_pix_fmt == PIX_FMT_RGB565LE ||
631 src_pix_fmt == PIX_FMT_BGR565BE || src_pix_fmt == PIX_FMT_BGR565LE)))
632 loss |= FF_LOSS_DEPTH;
633 if (dst_desc->log2_chroma_w > src_desc->log2_chroma_w ||
634 dst_desc->log2_chroma_h > src_desc->log2_chroma_h)
635 loss |= FF_LOSS_RESOLUTION;
636 switch(pf->color_type) {
637 case FF_COLOR_RGB:
638 if (ps->color_type != FF_COLOR_RGB &&
639 ps->color_type != FF_COLOR_GRAY)
640 loss |= FF_LOSS_COLORSPACE;
641 break;
642 case FF_COLOR_GRAY:
643 if (ps->color_type != FF_COLOR_GRAY)
644 loss |= FF_LOSS_COLORSPACE;
645 break;
646 case FF_COLOR_YUV:
647 if (ps->color_type != FF_COLOR_YUV)
648 loss |= FF_LOSS_COLORSPACE;
649 break;
650 case FF_COLOR_YUV_JPEG:
651 if (ps->color_type != FF_COLOR_YUV_JPEG &&
652 ps->color_type != FF_COLOR_YUV &&
653 ps->color_type != FF_COLOR_GRAY)
654 loss |= FF_LOSS_COLORSPACE;
655 break;
656 default:
657 /* fail safe test */
658 if (ps->color_type != pf->color_type)
659 loss |= FF_LOSS_COLORSPACE;
660 break;
661 }
662 if (pf->color_type == FF_COLOR_GRAY &&
663 ps->color_type != FF_COLOR_GRAY)
664 loss |= FF_LOSS_CHROMA;
665 if (!pf->is_alpha && (ps->is_alpha && has_alpha))
666 loss |= FF_LOSS_ALPHA;
667 if (pf->pixel_type == FF_PIXEL_PALETTE &&
668 (ps->pixel_type != FF_PIXEL_PALETTE && ps->color_type != FF_COLOR_GRAY))
669 loss |= FF_LOSS_COLORQUANT;
670 return loss;
671 }
672
673 static int avg_bits_per_pixel(enum PixelFormat pix_fmt)
674 {
675 int bits;
676 const PixFmtInfo *pf;
677 const AVPixFmtDescriptor *desc = &av_pix_fmt_descriptors[pix_fmt];
678
679 pf = &pix_fmt_info[pix_fmt];
680 switch(pf->pixel_type) {
681 case FF_PIXEL_PACKED:
682 switch(pix_fmt) {
683 case PIX_FMT_YUYV422:
684 case PIX_FMT_UYVY422:
685 case PIX_FMT_RGB565BE:
686 case PIX_FMT_RGB565LE:
687 case PIX_FMT_RGB555BE:
688 case PIX_FMT_RGB555LE:
689 case PIX_FMT_RGB444BE:
690 case PIX_FMT_RGB444LE:
691 case PIX_FMT_BGR565BE:
692 case PIX_FMT_BGR565LE:
693 case PIX_FMT_BGR555BE:
694 case PIX_FMT_BGR555LE:
695 case PIX_FMT_BGR444BE:
696 case PIX_FMT_BGR444LE:
697 bits = 16;
698 break;
699 case PIX_FMT_UYYVYY411:
700 bits = 12;
701 break;
702 default:
703 bits = pf->depth * pf->nb_channels;
704 break;
705 }
706 break;
707 case FF_PIXEL_PLANAR:
708 if (desc->log2_chroma_w == 0 && desc->log2_chroma_h == 0) {
709 bits = pf->depth * pf->nb_channels;
710 } else {
711 bits = pf->depth + ((2 * pf->depth) >>
712 (desc->log2_chroma_w + desc->log2_chroma_h));
713 }
714 break;
715 case FF_PIXEL_PALETTE:
716 bits = 8;
717 break;
718 default:
719 bits = -1;
720 break;
721 }
722 return bits;
723 }
724
725 static enum PixelFormat avcodec_find_best_pix_fmt1(int64_t pix_fmt_mask,
726 enum PixelFormat src_pix_fmt,
727 int has_alpha,
728 int loss_mask)
729 {
730 int dist, i, loss, min_dist;
731 enum PixelFormat dst_pix_fmt;
732
733 /* find exact color match with smallest size */
734 dst_pix_fmt = PIX_FMT_NONE;
735 min_dist = 0x7fffffff;
736 for(i = 0;i < PIX_FMT_NB; i++) {
737 if (pix_fmt_mask & (1ULL << i)) {
738 loss = avcodec_get_pix_fmt_loss(i, src_pix_fmt, has_alpha) & loss_mask;
739 if (loss == 0) {
740 dist = avg_bits_per_pixel(i);
741 if (dist < min_dist) {
742 min_dist = dist;
743 dst_pix_fmt = i;
744 }
745 }
746 }
747 }
748 return dst_pix_fmt;
749 }
750
751 enum PixelFormat avcodec_find_best_pix_fmt(int64_t pix_fmt_mask, enum PixelFormat src_pix_fmt,
752 int has_alpha, int *loss_ptr)
753 {
754 enum PixelFormat dst_pix_fmt;
755 int loss_mask, i;
756 static const int loss_mask_order[] = {
757 ~0, /* no loss first */
758 ~FF_LOSS_ALPHA,
759 ~FF_LOSS_RESOLUTION,
760 ~(FF_LOSS_COLORSPACE | FF_LOSS_RESOLUTION),
761 ~FF_LOSS_COLORQUANT,
762 ~FF_LOSS_DEPTH,
763 0,
764 };
765
766 /* try with successive loss */
767 i = 0;
768 for(;;) {
769 loss_mask = loss_mask_order[i++];
770 dst_pix_fmt = avcodec_find_best_pix_fmt1(pix_fmt_mask, src_pix_fmt,
771 has_alpha, loss_mask);
772 if (dst_pix_fmt >= 0)
773 goto found;
774 if (loss_mask == 0)
775 break;
776 }
777 return PIX_FMT_NONE;
778 found:
779 if (loss_ptr)
780 *loss_ptr = avcodec_get_pix_fmt_loss(dst_pix_fmt, src_pix_fmt, has_alpha);
781 return dst_pix_fmt;
782 }
783
784 void ff_img_copy_plane(uint8_t *dst, int dst_wrap,
785 const uint8_t *src, int src_wrap,
786 int width, int height)
787 {
788 if((!dst) || (!src))
789 return;
790 for(;height > 0; height--) {
791 memcpy(dst, src, width);
792 dst += dst_wrap;
793 src += src_wrap;
794 }
795 }
796
797 int ff_get_plane_bytewidth(enum PixelFormat pix_fmt, int width, int plane)
798 {
799 int bits;
800 const PixFmtInfo *pf = &pix_fmt_info[pix_fmt];
801 const AVPixFmtDescriptor *desc = &av_pix_fmt_descriptors[pix_fmt];
802
803 pf = &pix_fmt_info[pix_fmt];
804 switch(pf->pixel_type) {
805 case FF_PIXEL_PACKED:
806 switch(pix_fmt) {
807 case PIX_FMT_YUYV422:
808 case PIX_FMT_UYVY422:
809 case PIX_FMT_RGB565BE:
810 case PIX_FMT_RGB565LE:
811 case PIX_FMT_RGB555BE:
812 case PIX_FMT_RGB555LE:
813 case PIX_FMT_RGB444BE:
814 case PIX_FMT_RGB444LE:
815 case PIX_FMT_BGR565BE:
816 case PIX_FMT_BGR565LE:
817 case PIX_FMT_BGR555BE:
818 case PIX_FMT_BGR555LE:
819 case PIX_FMT_BGR444BE:
820 case PIX_FMT_BGR444LE:
821 bits = 16;
822 break;
823 case PIX_FMT_UYYVYY411:
824 bits = 12;
825 break;
826 default:
827 bits = pf->depth * pf->nb_channels;
828 break;
829 }
830 return (width * bits + 7) >> 3;
831 break;
832 case FF_PIXEL_PLANAR:
833 if ((pix_fmt != PIX_FMT_NV12 && pix_fmt != PIX_FMT_NV21) &&
834 (plane == 1 || plane == 2))
835 width= -((-width)>>desc->log2_chroma_w);
836
837 return (width * pf->depth + 7) >> 3;
838 break;
839 case FF_PIXEL_PALETTE:
840 if (plane == 0)
841 return width;
842 break;
843 }
844
845 return -1;
846 }
847
848 void av_picture_copy(AVPicture *dst, const AVPicture *src,
849 enum PixelFormat pix_fmt, int width, int height)
850 {
851 int i;
852 const PixFmtInfo *pf = &pix_fmt_info[pix_fmt];
853 const AVPixFmtDescriptor *desc = &av_pix_fmt_descriptors[pix_fmt];
854
855 switch(pf->pixel_type) {
856 case FF_PIXEL_PACKED:
857 case FF_PIXEL_PLANAR:
858 for(i = 0; i < pf->nb_channels; i++) {
859 int h;
860 int bwidth = ff_get_plane_bytewidth(pix_fmt, width, i);
861 h = height;
862 if (i == 1 || i == 2) {
863 h= -((-height)>>desc->log2_chroma_h);
864 }
865 ff_img_copy_plane(dst->data[i], dst->linesize[i],
866 src->data[i], src->linesize[i],
867 bwidth, h);
868 }
869 break;
870 case FF_PIXEL_PALETTE:
871 ff_img_copy_plane(dst->data[0], dst->linesize[0],
872 src->data[0], src->linesize[0],
873 width, height);
874 /* copy the palette */
875 memcpy(dst->data[1], src->data[1], 4*256);
876 break;
877 }
878 }
879
880 /* 2x2 -> 1x1 */
881 void ff_shrink22(uint8_t *dst, int dst_wrap,
882 const uint8_t *src, int src_wrap,
883 int width, int height)
884 {
885 int w;
886 const uint8_t *s1, *s2;
887 uint8_t *d;
888
889 for(;height > 0; height--) {
890 s1 = src;
891 s2 = s1 + src_wrap;
892 d = dst;
893 for(w = width;w >= 4; w-=4) {
894 d[0] = (s1[0] + s1[1] + s2[0] + s2[1] + 2) >> 2;
895 d[1] = (s1[2] + s1[3] + s2[2] + s2[3] + 2) >> 2;
896 d[2] = (s1[4] + s1[5] + s2[4] + s2[5] + 2) >> 2;
897 d[3] = (s1[6] + s1[7] + s2[6] + s2[7] + 2) >> 2;
898 s1 += 8;
899 s2 += 8;
900 d += 4;
901 }
902 for(;w > 0; w--) {
903 d[0] = (s1[0] + s1[1] + s2[0] + s2[1] + 2) >> 2;
904 s1 += 2;
905 s2 += 2;
906 d++;
907 }
908 src += 2 * src_wrap;
909 dst += dst_wrap;
910 }
911 }
912
913 /* 4x4 -> 1x1 */
914 void ff_shrink44(uint8_t *dst, int dst_wrap,
915 const uint8_t *src, int src_wrap,
916 int width, int height)
917 {
918 int w;
919 const uint8_t *s1, *s2, *s3, *s4;
920 uint8_t *d;
921
922 for(;height > 0; height--) {
923 s1 = src;
924 s2 = s1 + src_wrap;
925 s3 = s2 + src_wrap;
926 s4 = s3 + src_wrap;
927 d = dst;
928 for(w = width;w > 0; w--) {
929 d[0] = (s1[0] + s1[1] + s1[2] + s1[3] +
930 s2[0] + s2[1] + s2[2] + s2[3] +
931 s3[0] + s3[1] + s3[2] + s3[3] +
932 s4[0] + s4[1] + s4[2] + s4[3] + 8) >> 4;
933 s1 += 4;
934 s2 += 4;
935 s3 += 4;
936 s4 += 4;
937 d++;
938 }
939 src += 4 * src_wrap;
940 dst += dst_wrap;
941 }
942 }
943
944 /* 8x8 -> 1x1 */
945 void ff_shrink88(uint8_t *dst, int dst_wrap,
946 const uint8_t *src, int src_wrap,
947 int width, int height)
948 {
949 int w, i;
950
951 for(;height > 0; height--) {
952 for(w = width;w > 0; w--) {
953 int tmp=0;
954 for(i=0; i<8; i++){
955 tmp += src[0] + src[1] + src[2] + src[3] + src[4] + src[5] + src[6] + src[7];
956 src += src_wrap;
957 }
958 *(dst++) = (tmp + 32)>>6;
959 src += 8 - 8*src_wrap;
960 }
961 src += 8*src_wrap - 8*width;
962 dst += dst_wrap - width;
963 }
964 }
965
966
967 int avpicture_alloc(AVPicture *picture,
968 enum PixelFormat pix_fmt, int width, int height)
969 {
970 int size;
971 void *ptr;
972
973 size = avpicture_fill(picture, NULL, pix_fmt, width, height);
974 if(size<0)
975 goto fail;
976 ptr = av_malloc(size);
977 if (!ptr)
978 goto fail;
979 avpicture_fill(picture, ptr, pix_fmt, width, height);
980 if(picture->data[1] && !picture->data[2])
981 ff_set_systematic_pal((uint32_t*)picture->data[1], pix_fmt);
982
983 return 0;
984 fail:
985 memset(picture, 0, sizeof(AVPicture));
986 return -1;
987 }
988
989 void avpicture_free(AVPicture *picture)
990 {
991 av_free(picture->data[0]);
992 }
993
994 /* return true if yuv planar */
995 static inline int is_yuv_planar(const PixFmtInfo *ps)
996 {
997 return (ps->color_type == FF_COLOR_YUV ||
998 ps->color_type == FF_COLOR_YUV_JPEG) &&
999 ps->pixel_type == FF_PIXEL_PLANAR;
1000 }
1001
1002 int av_picture_crop(AVPicture *dst, const AVPicture *src,
1003 enum PixelFormat pix_fmt, int top_band, int left_band)
1004 {
1005 int y_shift;
1006 int x_shift;
1007
1008 if (pix_fmt < 0 || pix_fmt >= PIX_FMT_NB || !is_yuv_planar(&pix_fmt_info[pix_fmt]))
1009 return -1;
1010
1011 y_shift = av_pix_fmt_descriptors[pix_fmt].log2_chroma_h;
1012 x_shift = av_pix_fmt_descriptors[pix_fmt].log2_chroma_w;
1013
1014 dst->data[0] = src->data[0] + (top_band * src->linesize[0]) + left_band;
1015 dst->data[1] = src->data[1] + ((top_band >> y_shift) * src->linesize[1]) + (left_band >> x_shift);
1016 dst->data[2] = src->data[2] + ((top_band >> y_shift) * src->linesize[2]) + (left_band >> x_shift);
1017
1018 dst->linesize[0] = src->linesize[0];
1019 dst->linesize[1] = src->linesize[1];
1020 dst->linesize[2] = src->linesize[2];
1021 return 0;
1022 }
1023
1024 int av_picture_pad(AVPicture *dst, const AVPicture *src, int height, int width,
1025 enum PixelFormat pix_fmt, int padtop, int padbottom, int padleft, int padright,
1026 int *color)
1027 {
1028 uint8_t *optr;
1029 int y_shift;
1030 int x_shift;
1031 int yheight;
1032 int i, y;
1033
1034 if (pix_fmt < 0 || pix_fmt >= PIX_FMT_NB ||
1035 !is_yuv_planar(&pix_fmt_info[pix_fmt])) return -1;
1036
1037 for (i = 0; i < 3; i++) {
1038 x_shift = i ? av_pix_fmt_descriptors[pix_fmt].log2_chroma_w : 0;
1039 y_shift = i ? av_pix_fmt_descriptors[pix_fmt].log2_chroma_h : 0;
1040
1041 if (padtop || padleft) {
1042 memset(dst->data[i], color[i],
1043 dst->linesize[i] * (padtop >> y_shift) + (padleft >> x_shift));
1044 }
1045
1046 if (padleft || padright) {
1047 optr = dst->data[i] + dst->linesize[i] * (padtop >> y_shift) +
1048 (dst->linesize[i] - (padright >> x_shift));
1049 yheight = (height - 1 - (padtop + padbottom)) >> y_shift;
1050 for (y = 0; y < yheight; y++) {
1051 memset(optr, color[i], (padleft + padright) >> x_shift);
1052 optr += dst->linesize[i];
1053 }
1054 }
1055
1056 if (src) { /* first line */
1057 uint8_t *iptr = src->data[i];
1058 optr = dst->data[i] + dst->linesize[i] * (padtop >> y_shift) +
1059 (padleft >> x_shift);
1060 memcpy(optr, iptr, (width - padleft - padright) >> x_shift);
1061 iptr += src->linesize[i];
1062 optr = dst->data[i] + dst->linesize[i] * (padtop >> y_shift) +
1063 (dst->linesize[i] - (padright >> x_shift));
1064 yheight = (height - 1 - (padtop + padbottom)) >> y_shift;
1065 for (y = 0; y < yheight; y++) {
1066 memset(optr, color[i], (padleft + padright) >> x_shift);
1067 memcpy(optr + ((padleft + padright) >> x_shift), iptr,
1068 (width - padleft - padright) >> x_shift);
1069 iptr += src->linesize[i];
1070 optr += dst->linesize[i];
1071 }
1072 }
1073
1074 if (padbottom || padright) {
1075 optr = dst->data[i] + dst->linesize[i] *
1076 ((height - padbottom) >> y_shift) - (padright >> x_shift);
1077 memset(optr, color[i],dst->linesize[i] *
1078 (padbottom >> y_shift) + (padright >> x_shift));
1079 }
1080 }
1081 return 0;
1082 }
1083
1084 /* NOTE: we scan all the pixels to have an exact information */
1085 static int get_alpha_info_pal8(const AVPicture *src, int width, int height)
1086 {
1087 const unsigned char *p;
1088 int src_wrap, ret, x, y;
1089 unsigned int a;
1090 uint32_t *palette = (uint32_t *)src->data[1];
1091
1092 p = src->data[0];
1093 src_wrap = src->linesize[0] - width;
1094 ret = 0;
1095 for(y=0;y<height;y++) {
1096 for(x=0;x<width;x++) {
1097 a = palette[p[0]] >> 24;
1098 if (a == 0x00) {
1099 ret |= FF_ALPHA_TRANSP;
1100 } else if (a != 0xff) {
1101 ret |= FF_ALPHA_SEMI_TRANSP;
1102 }
1103 p++;
1104 }
1105 p += src_wrap;
1106 }
1107 return ret;
1108 }
1109
1110 int img_get_alpha_info(const AVPicture *src,
1111 enum PixelFormat pix_fmt, int width, int height)
1112 {
1113 const PixFmtInfo *pf = &pix_fmt_info[pix_fmt];
1114 int ret;
1115
1116 /* no alpha can be represented in format */
1117 if (!pf->is_alpha)
1118 return 0;
1119 switch(pix_fmt) {
1120 case PIX_FMT_PAL8:
1121 ret = get_alpha_info_pal8(src, width, height);
1122 break;
1123 default:
1124 /* we do not know, so everything is indicated */
1125 ret = FF_ALPHA_TRANSP | FF_ALPHA_SEMI_TRANSP;
1126 break;
1127 }
1128 return ret;
1129 }
1130
1131 #if !(HAVE_MMX && HAVE_YASM)
1132 /* filter parameters: [-1 4 2 4 -1] // 8 */
1133 static void deinterlace_line_c(uint8_t *dst,
1134 const uint8_t *lum_m4, const uint8_t *lum_m3,
1135 const uint8_t *lum_m2, const uint8_t *lum_m1,
1136 const uint8_t *lum,
1137 int size)
1138 {
1139 uint8_t *cm = ff_cropTbl + MAX_NEG_CROP;
1140 int sum;
1141
1142 for(;size > 0;size--) {
1143 sum = -lum_m4[0];
1144 sum += lum_m3[0] << 2;
1145 sum += lum_m2[0] << 1;
1146 sum += lum_m1[0] << 2;
1147 sum += -lum[0];
1148 dst[0] = cm[(sum + 4) >> 3];
1149 lum_m4++;
1150 lum_m3++;
1151 lum_m2++;
1152 lum_m1++;
1153 lum++;
1154 dst++;
1155 }
1156 }
1157
1158 static void deinterlace_line_inplace_c(uint8_t *lum_m4, uint8_t *lum_m3,
1159 uint8_t *lum_m2, uint8_t *lum_m1,
1160 uint8_t *lum, int size)
1161 {
1162 uint8_t *cm = ff_cropTbl + MAX_NEG_CROP;
1163 int sum;
1164
1165 for(;size > 0;size--) {
1166 sum = -lum_m4[0];
1167 sum += lum_m3[0] << 2;
1168 sum += lum_m2[0] << 1;
1169 lum_m4[0]=lum_m2[0];
1170 sum += lum_m1[0] << 2;
1171 sum += -lum[0];
1172 lum_m2[0] = cm[(sum + 4) >> 3];
1173 lum_m4++;
1174 lum_m3++;
1175 lum_m2++;
1176 lum_m1++;
1177 lum++;
1178 }
1179 }
1180 #endif
1181
1182 /* deinterlacing : 2 temporal taps, 3 spatial taps linear filter. The
1183 top field is copied as is, but the bottom field is deinterlaced
1184 against the top field. */
1185 static void deinterlace_bottom_field(uint8_t *dst, int dst_wrap,
1186 const uint8_t *src1, int src_wrap,
1187 int width, int height)
1188 {
1189 const uint8_t *src_m2, *src_m1, *src_0, *src_p1, *src_p2;
1190 int y;
1191
1192 src_m2 = src1;
1193 src_m1 = src1;
1194 src_0=&src_m1[src_wrap];
1195 src_p1=&src_0[src_wrap];
1196 src_p2=&src_p1[src_wrap];
1197 for(y=0;y<(height-2);y+=2) {
1198 memcpy(dst,src_m1,width);
1199 dst += dst_wrap;
1200 deinterlace_line(dst,src_m2,src_m1,src_0,src_p1,src_p2,width);
1201 src_m2 = src_0;
1202 src_m1 = src_p1;
1203 src_0 = src_p2;
1204 src_p1 += 2*src_wrap;
1205 src_p2 += 2*src_wrap;
1206 dst += dst_wrap;
1207 }
1208 memcpy(dst,src_m1,width);
1209 dst += dst_wrap;
1210 /* do last line */
1211 deinterlace_line(dst,src_m2,src_m1,src_0,src_0,src_0,width);
1212 }
1213
1214 static void deinterlace_bottom_field_inplace(uint8_t *src1, int src_wrap,
1215 int width, int height)
1216 {
1217 uint8_t *src_m1, *src_0, *src_p1, *src_p2;
1218 int y;
1219 uint8_t *buf;
1220 buf = (uint8_t*)av_malloc(width);
1221
1222 src_m1 = src1;
1223 memcpy(buf,src_m1,width);
1224 src_0=&src_m1[src_wrap];
1225 src_p1=&src_0[src_wrap];
1226 src_p2=&src_p1[src_wrap];
1227 for(y=0;y<(height-2);y+=2) {
1228 deinterlace_line_inplace(buf,src_m1,src_0,src_p1,src_p2,width);
1229 src_m1 = src_p1;
1230 src_0 = src_p2;
1231 src_p1 += 2*src_wrap;
1232 src_p2 += 2*src_wrap;
1233 }
1234 /* do last line */
1235 deinterlace_line_inplace(buf,src_m1,src_0,src_0,src_0,width);
1236 av_free(buf);
1237 }
1238
1239 int avpicture_deinterlace(AVPicture *dst, const AVPicture *src,
1240 enum PixelFormat pix_fmt, int width, int height)
1241 {
1242 int i;
1243
1244 if (pix_fmt != PIX_FMT_YUV420P &&
1245 pix_fmt != PIX_FMT_YUV422P &&
1246 pix_fmt != PIX_FMT_YUV444P &&
1247 pix_fmt != PIX_FMT_YUV411P &&
1248 pix_fmt != PIX_FMT_GRAY8)
1249 return -1;
1250 if ((width & 3) != 0 || (height & 3) != 0)
1251 return -1;
1252
1253 for(i=0;i<3;i++) {
1254 if (i == 1) {
1255 switch(pix_fmt) {
1256 case PIX_FMT_YUV420P:
1257 width >>= 1;
1258 height >>= 1;
1259 break;
1260 case PIX_FMT_YUV422P:
1261 width >>= 1;
1262 break;
1263 case PIX_FMT_YUV411P:
1264 width >>= 2;
1265 break;
1266 default:
1267 break;
1268 }
1269 if (pix_fmt == PIX_FMT_GRAY8) {
1270 break;
1271 }
1272 }
1273 if (src == dst) {
1274 deinterlace_bottom_field_inplace(dst->data[i], dst->linesize[i],
1275 width, height);
1276 } else {
1277 deinterlace_bottom_field(dst->data[i],dst->linesize[i],
1278 src->data[i], src->linesize[i],
1279 width, height);
1280 }
1281 }
1282 emms_c();
1283 return 0;
1284 }
1285