pixfmt: add AV_ prefixes to PIX_FMT_*
[libav.git] / libavcodec / imgconvert.c
CommitLineData
de6d9b64 1/*
f1ea5c2a 2 * Misc image conversion routines
406792e7 3 * Copyright (c) 2001, 2002, 2003 Fabrice Bellard
de6d9b64 4 *
2912e87a 5 * This file is part of Libav.
b78e7197 6 *
2912e87a 7 * Libav is free software; you can redistribute it and/or
ff4ec49e
FB
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
b78e7197 10 * version 2.1 of the License, or (at your option) any later version.
de6d9b64 11 *
2912e87a 12 * Libav is distributed in the hope that it will be useful,
de6d9b64 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
ff4ec49e
FB
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
de6d9b64 16 *
ff4ec49e 17 * You should have received a copy of the GNU Lesser General Public
2912e87a 18 * License along with Libav; if not, write to the Free Software
5509bffa 19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
de6d9b64 20 */
983e3246
MN
21
22/**
ba87f080 23 * @file
f1ea5c2a 24 * misc image conversion routines
983e3246
MN
25 */
26
c50c0bc8
FB
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 */
983e3246 32
de6d9b64 33#include "avcodec.h"
85c242d8 34#include "dsputil.h"
4443c0e9 35#include "internal.h"
2b4abbd6 36#include "libavutil/colorspace.h"
1d9c2dc8 37#include "libavutil/common.h"
8e861e1b 38#include "libavutil/pixdesc.h"
737eb597 39#include "libavutil/imgutils.h"
de6d9b64 40
17337f54 41#if HAVE_MMX_EXTERNAL
a6493a8f 42#include "x86/dsputil_mmx.h"
5981f4e6 43#endif
524c6b63 44
bb0f999b
GP
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 */
b6147995 49
bb0f999b
GP
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 */
7e7e5940 53
17337f54 54#if HAVE_MMX_EXTERNAL
de4bc44a
VS
55#define deinterlace_line_inplace ff_deinterlace_line_inplace_mmx
56#define deinterlace_line ff_deinterlace_line_mmx
57#else
58#define deinterlace_line_inplace deinterlace_line_inplace_c
59#define deinterlace_line deinterlace_line_c
60#endif
61
524c6b63 62typedef struct PixFmtInfo {
bb0f999b
GP
63 uint8_t nb_channels; /**< number of channels (including alpha) */
64 uint8_t color_type; /**< color type (see FF_COLOR_xxx constants) */
65 uint8_t pixel_type; /**< pixel storage type (see FF_PIXEL_xxx constants) */
66 uint8_t is_alpha : 1; /**< true if alpha can be specified */
bb0f999b 67 uint8_t depth; /**< bit depth of the color components */
524c6b63
FB
68} PixFmtInfo;
69
70/* this table gives more information about formats */
62a05b5b 71static const PixFmtInfo pix_fmt_info[PIX_FMT_NB] = {
524c6b63
FB
72 /* YUV formats */
73 [PIX_FMT_YUV420P] = {
7e7e5940 74 .nb_channels = 3,
b6147995 75 .color_type = FF_COLOR_YUV,
7e7e5940 76 .pixel_type = FF_PIXEL_PLANAR,
b6147995 77 .depth = 8,
524c6b63
FB
78 },
79 [PIX_FMT_YUV422P] = {
7e7e5940 80 .nb_channels = 3,
b6147995 81 .color_type = FF_COLOR_YUV,
7e7e5940 82 .pixel_type = FF_PIXEL_PLANAR,
b6147995 83 .depth = 8,
524c6b63
FB
84 },
85 [PIX_FMT_YUV444P] = {
7e7e5940 86 .nb_channels = 3,
b6147995 87 .color_type = FF_COLOR_YUV,
7e7e5940 88 .pixel_type = FF_PIXEL_PLANAR,
b6147995 89 .depth = 8,
524c6b63 90 },
71e445fc 91 [PIX_FMT_YUYV422] = {
7e7e5940 92 .nb_channels = 1,
b6147995 93 .color_type = FF_COLOR_YUV,
7e7e5940 94 .pixel_type = FF_PIXEL_PACKED,
b6147995 95 .depth = 8,
524c6b63 96 },
ebb177dd 97 [PIX_FMT_UYVY422] = {
ebb177dd
TK
98 .nb_channels = 1,
99 .color_type = FF_COLOR_YUV,
100 .pixel_type = FF_PIXEL_PACKED,
101 .depth = 8,
ebb177dd 102 },
524c6b63 103 [PIX_FMT_YUV410P] = {
7e7e5940 104 .nb_channels = 3,
b6147995 105 .color_type = FF_COLOR_YUV,
7e7e5940 106 .pixel_type = FF_PIXEL_PLANAR,
b6147995 107 .depth = 8,
524c6b63
FB
108 },
109 [PIX_FMT_YUV411P] = {
7e7e5940 110 .nb_channels = 3,
b6147995 111 .color_type = FF_COLOR_YUV,
7e7e5940 112 .pixel_type = FF_PIXEL_PLANAR,
b6147995 113 .depth = 8,
524c6b63 114 },
4196cfb7 115 [PIX_FMT_YUV440P] = {
4196cfb7
116 .nb_channels = 3,
117 .color_type = FF_COLOR_YUV,
118 .pixel_type = FF_PIXEL_PLANAR,
119 .depth = 8,
4196cfb7 120 },
35f6c154 121 [PIX_FMT_YUV420P16LE] = {
6c2a8608
MN
122 .nb_channels = 3,
123 .color_type = FF_COLOR_YUV,
124 .pixel_type = FF_PIXEL_PLANAR,
125 .depth = 16,
6c2a8608 126 },
35f6c154 127 [PIX_FMT_YUV422P16LE] = {
6c2a8608
MN
128 .nb_channels = 3,
129 .color_type = FF_COLOR_YUV,
130 .pixel_type = FF_PIXEL_PLANAR,
131 .depth = 16,
6c2a8608 132 },
35f6c154 133 [PIX_FMT_YUV444P16LE] = {
6c2a8608
MN
134 .nb_channels = 3,
135 .color_type = FF_COLOR_YUV,
136 .pixel_type = FF_PIXEL_PLANAR,
137 .depth = 16,
6c2a8608 138 },
35f6c154 139 [PIX_FMT_YUV420P16BE] = {
6c2a8608
MN
140 .nb_channels = 3,
141 .color_type = FF_COLOR_YUV,
142 .pixel_type = FF_PIXEL_PLANAR,
143 .depth = 16,
6c2a8608 144 },
35f6c154 145 [PIX_FMT_YUV422P16BE] = {
6c2a8608
MN
146 .nb_channels = 3,
147 .color_type = FF_COLOR_YUV,
148 .pixel_type = FF_PIXEL_PLANAR,
149 .depth = 16,
6c2a8608 150 },
35f6c154 151 [PIX_FMT_YUV444P16BE] = {
6c2a8608
MN
152 .nb_channels = 3,
153 .color_type = FF_COLOR_YUV,
154 .pixel_type = FF_PIXEL_PLANAR,
155 .depth = 16,
6c2a8608
MN
156 },
157
524c6b63 158
b70335a2
AJ
159 /* YUV formats with alpha plane */
160 [PIX_FMT_YUVA420P] = {
b70335a2
AJ
161 .nb_channels = 4,
162 .color_type = FF_COLOR_YUV,
163 .pixel_type = FF_PIXEL_PLANAR,
164 .depth = 8,
b70335a2
AJ
165 },
166
b6147995
FB
167 /* JPEG YUV */
168 [PIX_FMT_YUVJ420P] = {
7e7e5940 169 .nb_channels = 3,
b6147995 170 .color_type = FF_COLOR_YUV_JPEG,
7e7e5940 171 .pixel_type = FF_PIXEL_PLANAR,
b6147995 172 .depth = 8,
b6147995
FB
173 },
174 [PIX_FMT_YUVJ422P] = {
7e7e5940 175 .nb_channels = 3,
b6147995 176 .color_type = FF_COLOR_YUV_JPEG,
7e7e5940 177 .pixel_type = FF_PIXEL_PLANAR,
b6147995 178 .depth = 8,
b6147995
FB
179 },
180 [PIX_FMT_YUVJ444P] = {
7e7e5940 181 .nb_channels = 3,
b6147995 182 .color_type = FF_COLOR_YUV_JPEG,
7e7e5940 183 .pixel_type = FF_PIXEL_PLANAR,
b6147995 184 .depth = 8,
b6147995 185 },
4196cfb7 186 [PIX_FMT_YUVJ440P] = {
4196cfb7
187 .nb_channels = 3,
188 .color_type = FF_COLOR_YUV_JPEG,
189 .pixel_type = FF_PIXEL_PLANAR,
190 .depth = 8,
4196cfb7 191 },
b6147995 192
524c6b63
FB
193 /* RGB formats */
194 [PIX_FMT_RGB24] = {
7e7e5940 195 .nb_channels = 3,
b6147995 196 .color_type = FF_COLOR_RGB,
7e7e5940 197 .pixel_type = FF_PIXEL_PACKED,
b6147995 198 .depth = 8,
524c6b63
FB
199 },
200 [PIX_FMT_BGR24] = {
7e7e5940 201 .nb_channels = 3,
b6147995 202 .color_type = FF_COLOR_RGB,
7e7e5940 203 .pixel_type = FF_PIXEL_PACKED,
b6147995 204 .depth = 8,
524c6b63 205 },
6e08ca9c 206 [PIX_FMT_ARGB] = {
7e7e5940 207 .nb_channels = 4, .is_alpha = 1,
b6147995 208 .color_type = FF_COLOR_RGB,
7e7e5940 209 .pixel_type = FF_PIXEL_PACKED,
b6147995 210 .depth = 8,
524c6b63 211 },
88c21a6f 212 [PIX_FMT_RGB48BE] = {
88c21a6f
PR
213 .nb_channels = 3,
214 .color_type = FF_COLOR_RGB,
215 .pixel_type = FF_PIXEL_PACKED,
216 .depth = 16,
88c21a6f
PR
217 },
218 [PIX_FMT_RGB48LE] = {
88c21a6f
PR
219 .nb_channels = 3,
220 .color_type = FF_COLOR_RGB,
221 .pixel_type = FF_PIXEL_PACKED,
222 .depth = 16,
88c21a6f 223 },
f82674e5 224 [PIX_FMT_RGB565BE] = {
7e7e5940 225 .nb_channels = 3,
b6147995 226 .color_type = FF_COLOR_RGB,
7e7e5940 227 .pixel_type = FF_PIXEL_PACKED,
b6147995 228 .depth = 5,
524c6b63 229 },
f82674e5 230 [PIX_FMT_RGB565LE] = {
f82674e5
SS
231 .nb_channels = 3,
232 .color_type = FF_COLOR_RGB,
233 .pixel_type = FF_PIXEL_PACKED,
234 .depth = 5,
f82674e5
SS
235 },
236 [PIX_FMT_RGB555BE] = {
f82674e5
SS
237 .nb_channels = 3,
238 .color_type = FF_COLOR_RGB,
239 .pixel_type = FF_PIXEL_PACKED,
240 .depth = 5,
f82674e5
SS
241 },
242 [PIX_FMT_RGB555LE] = {
20d46c03 243 .nb_channels = 3,
b6147995 244 .color_type = FF_COLOR_RGB,
7e7e5940 245 .pixel_type = FF_PIXEL_PACKED,
b6147995 246 .depth = 5,
524c6b63 247 },
2b7cf167
JK
248 [PIX_FMT_RGB444BE] = {
249 .nb_channels = 3,
250 .color_type = FF_COLOR_RGB,
251 .pixel_type = FF_PIXEL_PACKED,
252 .depth = 4,
253 },
254 [PIX_FMT_RGB444LE] = {
255 .nb_channels = 3,
256 .color_type = FF_COLOR_RGB,
257 .pixel_type = FF_PIXEL_PACKED,
258 .depth = 4,
259 },
524c6b63
FB
260
261 /* gray / mono formats */
34380af0 262 [PIX_FMT_GRAY16BE] = {
34380af0
KS
263 .nb_channels = 1,
264 .color_type = FF_COLOR_GRAY,
265 .pixel_type = FF_PIXEL_PLANAR,
266 .depth = 16,
267 },
268 [PIX_FMT_GRAY16LE] = {
34380af0
KS
269 .nb_channels = 1,
270 .color_type = FF_COLOR_GRAY,
271 .pixel_type = FF_PIXEL_PLANAR,
272 .depth = 16,
273 },
524c6b63 274 [PIX_FMT_GRAY8] = {
7e7e5940 275 .nb_channels = 1,
b6147995 276 .color_type = FF_COLOR_GRAY,
7e7e5940 277 .pixel_type = FF_PIXEL_PLANAR,
b6147995 278 .depth = 8,
524c6b63
FB
279 },
280 [PIX_FMT_MONOWHITE] = {
7e7e5940 281 .nb_channels = 1,
b6147995 282 .color_type = FF_COLOR_GRAY,
7e7e5940 283 .pixel_type = FF_PIXEL_PLANAR,
b6147995 284 .depth = 1,
524c6b63
FB
285 },
286 [PIX_FMT_MONOBLACK] = {
7e7e5940 287 .nb_channels = 1,
b6147995 288 .color_type = FF_COLOR_GRAY,
7e7e5940 289 .pixel_type = FF_PIXEL_PLANAR,
b6147995 290 .depth = 1,
524c6b63 291 },
7e6d70d0
FB
292
293 /* paletted formats */
294 [PIX_FMT_PAL8] = {
7e7e5940 295 .nb_channels = 4, .is_alpha = 1,
b6147995 296 .color_type = FF_COLOR_RGB,
7e7e5940 297 .pixel_type = FF_PIXEL_PALETTE,
b6147995 298 .depth = 8,
7e6d70d0 299 },
71e445fc 300 [PIX_FMT_UYYVYY411] = {
f02be79d
RS
301 .nb_channels = 1,
302 .color_type = FF_COLOR_YUV,
303 .pixel_type = FF_PIXEL_PACKED,
304 .depth = 8,
f02be79d 305 },
6e08ca9c 306 [PIX_FMT_ABGR] = {
00b2fa86
LA
307 .nb_channels = 4, .is_alpha = 1,
308 .color_type = FF_COLOR_RGB,
309 .pixel_type = FF_PIXEL_PACKED,
310 .depth = 8,
00b2fa86 311 },
f82674e5 312 [PIX_FMT_BGR565BE] = {
f82674e5
SS
313 .nb_channels = 3,
314 .color_type = FF_COLOR_RGB,
315 .pixel_type = FF_PIXEL_PACKED,
316 .depth = 5,
f82674e5
SS
317 },
318 [PIX_FMT_BGR565LE] = {
f82674e5
SS
319 .nb_channels = 3,
320 .color_type = FF_COLOR_RGB,
321 .pixel_type = FF_PIXEL_PACKED,
322 .depth = 5,
f82674e5
SS
323 },
324 [PIX_FMT_BGR555BE] = {
00b2fa86
LA
325 .nb_channels = 3,
326 .color_type = FF_COLOR_RGB,
327 .pixel_type = FF_PIXEL_PACKED,
328 .depth = 5,
00b2fa86 329 },
f82674e5 330 [PIX_FMT_BGR555LE] = {
08d23410 331 .nb_channels = 3,
00b2fa86
LA
332 .color_type = FF_COLOR_RGB,
333 .pixel_type = FF_PIXEL_PACKED,
334 .depth = 5,
00b2fa86 335 },
2b7cf167
JK
336 [PIX_FMT_BGR444BE] = {
337 .nb_channels = 3,
338 .color_type = FF_COLOR_RGB,
339 .pixel_type = FF_PIXEL_PACKED,
340 .depth = 4,
341 },
342 [PIX_FMT_BGR444LE] = {
343 .nb_channels = 3,
344 .color_type = FF_COLOR_RGB,
345 .pixel_type = FF_PIXEL_PACKED,
346 .depth = 4,
347 },
00b2fa86 348 [PIX_FMT_RGB8] = {
00b2fa86
LA
349 .nb_channels = 1,
350 .color_type = FF_COLOR_RGB,
351 .pixel_type = FF_PIXEL_PACKED,
352 .depth = 8,
00b2fa86
LA
353 },
354 [PIX_FMT_RGB4] = {
00b2fa86
LA
355 .nb_channels = 1,
356 .color_type = FF_COLOR_RGB,
357 .pixel_type = FF_PIXEL_PACKED,
358 .depth = 4,
00b2fa86
LA
359 },
360 [PIX_FMT_RGB4_BYTE] = {
00b2fa86
LA
361 .nb_channels = 1,
362 .color_type = FF_COLOR_RGB,
363 .pixel_type = FF_PIXEL_PACKED,
364 .depth = 8,
00b2fa86
LA
365 },
366 [PIX_FMT_BGR8] = {
00b2fa86
LA
367 .nb_channels = 1,
368 .color_type = FF_COLOR_RGB,
369 .pixel_type = FF_PIXEL_PACKED,
370 .depth = 8,
00b2fa86
LA
371 },
372 [PIX_FMT_BGR4] = {
00b2fa86
LA
373 .nb_channels = 1,
374 .color_type = FF_COLOR_RGB,
375 .pixel_type = FF_PIXEL_PACKED,
376 .depth = 4,
00b2fa86
LA
377 },
378 [PIX_FMT_BGR4_BYTE] = {
00b2fa86
LA
379 .nb_channels = 1,
380 .color_type = FF_COLOR_RGB,
381 .pixel_type = FF_PIXEL_PACKED,
382 .depth = 8,
00b2fa86
LA
383 },
384 [PIX_FMT_NV12] = {
00b2fa86
LA
385 .nb_channels = 2,
386 .color_type = FF_COLOR_YUV,
387 .pixel_type = FF_PIXEL_PLANAR,
388 .depth = 8,
00b2fa86
LA
389 },
390 [PIX_FMT_NV21] = {
00b2fa86
LA
391 .nb_channels = 2,
392 .color_type = FF_COLOR_YUV,
393 .pixel_type = FF_PIXEL_PLANAR,
394 .depth = 8,
00b2fa86
LA
395 },
396
6e08ca9c 397 [PIX_FMT_BGRA] = {
00b2fa86
LA
398 .nb_channels = 4, .is_alpha = 1,
399 .color_type = FF_COLOR_RGB,
400 .pixel_type = FF_PIXEL_PACKED,
401 .depth = 8,
00b2fa86 402 },
6e08ca9c 403 [PIX_FMT_RGBA] = {
00b2fa86
LA
404 .nb_channels = 4, .is_alpha = 1,
405 .color_type = FF_COLOR_RGB,
406 .pixel_type = FF_PIXEL_PACKED,
407 .depth = 8,
00b2fa86 408 },
524c6b63
FB
409};
410
a61ec8e7 411void avcodec_get_chroma_sub_sample(enum PixelFormat pix_fmt, int *h_shift, int *v_shift)
524c6b63 412{
38264abb
SS
413 *h_shift = av_pix_fmt_descriptors[pix_fmt].log2_chroma_w;
414 *v_shift = av_pix_fmt_descriptors[pix_fmt].log2_chroma_h;
524c6b63
FB
415}
416
c269cf68
MN
417int ff_is_hwaccel_pix_fmt(enum PixelFormat pix_fmt)
418{
8e861e1b 419 return av_pix_fmt_descriptors[pix_fmt].flags & PIX_FMT_HWACCEL;
c269cf68
MN
420}
421
cc9853d3 422int avpicture_fill(AVPicture *picture, uint8_t *ptr,
a61ec8e7 423 enum PixelFormat pix_fmt, int width, int height)
cc9853d3 424{
f35a41ff 425 int ret;
cc9853d3 426
f35a41ff
SS
427 if ((ret = av_image_check_size(width, height, 0, NULL)) < 0)
428 return ret;
cc9853d3 429
f35a41ff
SS
430 if ((ret = av_image_fill_linesizes(picture->linesize, pix_fmt, width)) < 0)
431 return ret;
cc9853d3 432
e16f217c 433 return av_image_fill_pointers(picture->data, pix_fmt, height, ptr, picture->linesize);
cc9853d3
VS
434}
435
a61ec8e7 436int avpicture_layout(const AVPicture* src, enum PixelFormat pix_fmt, int width, int height,
63167088
RS
437 unsigned char *dest, int dest_size)
438{
d2cbdb17 439 int i, j, nb_planes = 0, linesizes[4];
14b903f3 440 const AVPixFmtDescriptor *desc = &av_pix_fmt_descriptors[pix_fmt];
63167088
RS
441 int size = avpicture_get_size(pix_fmt, width, height);
442
0ecca7a4 443 if (size > dest_size || size < 0)
d2cbdb17 444 return AVERROR(EINVAL);
63167088 445
d2cbdb17
SS
446 for (i = 0; i < desc->nb_components; i++)
447 nb_planes = FFMAX(desc->comp[i].plane, nb_planes);
448 nb_planes++;
449
450 av_image_fill_linesizes(linesizes, pix_fmt, width);
451 for (i = 0; i < nb_planes; i++) {
8f190d8b
RP
452 int h, shift = (i == 1 || i == 2) ? desc->log2_chroma_h : 0;
453 const unsigned char *s = src->data[i];
454 h = (height + (1 << shift) - 1) >> shift;
115329f1 455
d2cbdb17
SS
456 for (j = 0; j < h; j++) {
457 memcpy(dest, s, linesizes[i]);
458 dest += linesizes[i];
b16569d2
RP
459 s += src->linesize[i];
460 }
63167088 461 }
115329f1 462
d2cbdb17 463 if (desc->flags & PIX_FMT_PAL)
bb270c08 464 memcpy((unsigned char *)(((size_t)dest + 3) & ~3), src->data[1], 256 * 4);
115329f1 465
63167088
RS
466 return size;
467}
468
a61ec8e7 469int avpicture_get_size(enum PixelFormat pix_fmt, int width, int height)
2a877875
FB
470{
471 AVPicture dummy_pict;
e16f217c 472 if(av_image_check_size(width, height, 0, NULL))
899a8fa1 473 return -1;
38d55332 474 if (av_pix_fmt_descriptors[pix_fmt].flags & PIX_FMT_PSEUDOPAL)
899a8fa1
RD
475 // do not include palette for these pseudo-paletted formats
476 return width * height;
2a877875
FB
477 return avpicture_fill(&dummy_pict, NULL, pix_fmt, width, height);
478}
479
a61ec8e7 480int avcodec_get_pix_fmt_loss(enum PixelFormat dst_pix_fmt, enum PixelFormat src_pix_fmt,
b6147995
FB
481 int has_alpha)
482{
483 const PixFmtInfo *pf, *ps;
14b903f3
SS
484 const AVPixFmtDescriptor *src_desc = &av_pix_fmt_descriptors[src_pix_fmt];
485 const AVPixFmtDescriptor *dst_desc = &av_pix_fmt_descriptors[dst_pix_fmt];
b6147995
FB
486 int loss;
487
488 ps = &pix_fmt_info[src_pix_fmt];
b6147995
FB
489
490 /* compute loss */
491 loss = 0;
492 pf = &pix_fmt_info[dst_pix_fmt];
0a9ad8d1 493 if (pf->depth < ps->depth ||
4ef82b17
JK
494 ((dst_pix_fmt == PIX_FMT_RGB555BE || dst_pix_fmt == PIX_FMT_RGB555LE ||
495 dst_pix_fmt == PIX_FMT_BGR555BE || dst_pix_fmt == PIX_FMT_BGR555LE) &&
496 (src_pix_fmt == PIX_FMT_RGB565BE || src_pix_fmt == PIX_FMT_RGB565LE ||
497 src_pix_fmt == PIX_FMT_BGR565BE || src_pix_fmt == PIX_FMT_BGR565LE)))
b6147995 498 loss |= FF_LOSS_DEPTH;
14b903f3
SS
499 if (dst_desc->log2_chroma_w > src_desc->log2_chroma_w ||
500 dst_desc->log2_chroma_h > src_desc->log2_chroma_h)
b6147995
FB
501 loss |= FF_LOSS_RESOLUTION;
502 switch(pf->color_type) {
503 case FF_COLOR_RGB:
504 if (ps->color_type != FF_COLOR_RGB &&
505 ps->color_type != FF_COLOR_GRAY)
506 loss |= FF_LOSS_COLORSPACE;
507 break;
508 case FF_COLOR_GRAY:
509 if (ps->color_type != FF_COLOR_GRAY)
510 loss |= FF_LOSS_COLORSPACE;
511 break;
512 case FF_COLOR_YUV:
513 if (ps->color_type != FF_COLOR_YUV)
514 loss |= FF_LOSS_COLORSPACE;
515 break;
516 case FF_COLOR_YUV_JPEG:
517 if (ps->color_type != FF_COLOR_YUV_JPEG &&
115329f1 518 ps->color_type != FF_COLOR_YUV &&
0a9ad8d1 519 ps->color_type != FF_COLOR_GRAY)
b6147995
FB
520 loss |= FF_LOSS_COLORSPACE;
521 break;
522 default:
523 /* fail safe test */
524 if (ps->color_type != pf->color_type)
525 loss |= FF_LOSS_COLORSPACE;
526 break;
527 }
528 if (pf->color_type == FF_COLOR_GRAY &&
529 ps->color_type != FF_COLOR_GRAY)
530 loss |= FF_LOSS_CHROMA;
531 if (!pf->is_alpha && (ps->is_alpha && has_alpha))
532 loss |= FF_LOSS_ALPHA;
115329f1 533 if (pf->pixel_type == FF_PIXEL_PALETTE &&
7e7e5940 534 (ps->pixel_type != FF_PIXEL_PALETTE && ps->color_type != FF_COLOR_GRAY))
b6147995
FB
535 loss |= FF_LOSS_COLORQUANT;
536 return loss;
537}
538
a61ec8e7 539static int avg_bits_per_pixel(enum PixelFormat pix_fmt)
b6147995
FB
540{
541 int bits;
542 const PixFmtInfo *pf;
14b903f3 543 const AVPixFmtDescriptor *desc = &av_pix_fmt_descriptors[pix_fmt];
b6147995
FB
544
545 pf = &pix_fmt_info[pix_fmt];
7e7e5940
FB
546 switch(pf->pixel_type) {
547 case FF_PIXEL_PACKED:
b6147995 548 switch(pix_fmt) {
71e445fc 549 case PIX_FMT_YUYV422:
ebb177dd 550 case PIX_FMT_UYVY422:
ffd38d8b
AB
551 case PIX_FMT_RGB565BE:
552 case PIX_FMT_RGB565LE:
553 case PIX_FMT_RGB555BE:
554 case PIX_FMT_RGB555LE:
2b7cf167
JK
555 case PIX_FMT_RGB444BE:
556 case PIX_FMT_RGB444LE:
ffd38d8b
AB
557 case PIX_FMT_BGR565BE:
558 case PIX_FMT_BGR565LE:
559 case PIX_FMT_BGR555BE:
560 case PIX_FMT_BGR555LE:
2b7cf167
JK
561 case PIX_FMT_BGR444BE:
562 case PIX_FMT_BGR444LE:
b6147995 563 bits = 16;
b6147995 564 break;
71e445fc 565 case PIX_FMT_UYYVYY411:
bb270c08
DB
566 bits = 12;
567 break;
b6147995 568 default:
7e7e5940 569 bits = pf->depth * pf->nb_channels;
b6147995
FB
570 break;
571 }
7e7e5940
FB
572 break;
573 case FF_PIXEL_PLANAR:
14b903f3 574 if (desc->log2_chroma_w == 0 && desc->log2_chroma_h == 0) {
7e7e5940
FB
575 bits = pf->depth * pf->nb_channels;
576 } else {
115329f1 577 bits = pf->depth + ((2 * pf->depth) >>
14b903f3 578 (desc->log2_chroma_w + desc->log2_chroma_h));
7e7e5940
FB
579 }
580 break;
581 case FF_PIXEL_PALETTE:
582 bits = 8;
583 break;
584 default:
585 bits = -1;
586 break;
b6147995
FB
587 }
588 return bits;
589}
590
ac29054f 591static enum PixelFormat avcodec_find_best_pix_fmt1(enum PixelFormat *pix_fmt_list,
a61ec8e7 592 enum PixelFormat src_pix_fmt,
b6147995
FB
593 int has_alpha,
594 int loss_mask)
595{
a61ec8e7
SS
596 int dist, i, loss, min_dist;
597 enum PixelFormat dst_pix_fmt;
b6147995
FB
598
599 /* find exact color match with smallest size */
f0bc8449 600 dst_pix_fmt = PIX_FMT_NONE;
b6147995 601 min_dist = 0x7fffffff;
ac29054f
JG
602 i = 0;
603 while (pix_fmt_list[i] != PIX_FMT_NONE) {
604 enum PixelFormat pix_fmt = pix_fmt_list[i];
605
606 if (i > PIX_FMT_NB) {
607 av_log(NULL, AV_LOG_ERROR, "Pixel format list longer than expected, "
608 "it is either not properly terminated or contains duplicates\n");
609 return PIX_FMT_NONE;
610 }
611
612 loss = avcodec_get_pix_fmt_loss(pix_fmt, src_pix_fmt, has_alpha) & loss_mask;
613 if (loss == 0) {
614 dist = avg_bits_per_pixel(pix_fmt);
615 if (dist < min_dist) {
616 min_dist = dist;
617 dst_pix_fmt = pix_fmt;
b6147995
FB
618 }
619 }
ac29054f 620 i++;
b6147995
FB
621 }
622 return dst_pix_fmt;
623}
624
f30260d3 625#if FF_API_FIND_BEST_PIX_FMT
a61ec8e7 626enum PixelFormat avcodec_find_best_pix_fmt(int64_t pix_fmt_mask, enum PixelFormat src_pix_fmt,
b6147995
FB
627 int has_alpha, int *loss_ptr)
628{
ac29054f
JG
629 enum PixelFormat list[64];
630 int i, j = 0;
631
632 // test only the first 64 pixel formats to avoid undefined behaviour
633 for (i = 0; i < 64; i++) {
634 if (pix_fmt_mask & (1ULL << i))
635 list[j++] = i;
636 }
637 list[j] = PIX_FMT_NONE;
638
639 return avcodec_find_best_pix_fmt2(list, src_pix_fmt, has_alpha, loss_ptr);
640}
f30260d3 641#endif /* FF_API_FIND_BEST_PIX_FMT */
ac29054f
JG
642
643enum PixelFormat avcodec_find_best_pix_fmt2(enum PixelFormat *pix_fmt_list,
644 enum PixelFormat src_pix_fmt,
645 int has_alpha, int *loss_ptr)
646{
a61ec8e7
SS
647 enum PixelFormat dst_pix_fmt;
648 int loss_mask, i;
b6147995
FB
649 static const int loss_mask_order[] = {
650 ~0, /* no loss first */
651 ~FF_LOSS_ALPHA,
652 ~FF_LOSS_RESOLUTION,
653 ~(FF_LOSS_COLORSPACE | FF_LOSS_RESOLUTION),
654 ~FF_LOSS_COLORQUANT,
655 ~FF_LOSS_DEPTH,
656 0,
657 };
658
659 /* try with successive loss */
660 i = 0;
661 for(;;) {
662 loss_mask = loss_mask_order[i++];
ac29054f 663 dst_pix_fmt = avcodec_find_best_pix_fmt1(pix_fmt_list, src_pix_fmt,
b6147995
FB
664 has_alpha, loss_mask);
665 if (dst_pix_fmt >= 0)
666 goto found;
667 if (loss_mask == 0)
668 break;
669 }
f0bc8449 670 return PIX_FMT_NONE;
b6147995
FB
671 found:
672 if (loss_ptr)
673 *loss_ptr = avcodec_get_pix_fmt_loss(dst_pix_fmt, src_pix_fmt, has_alpha);
674 return dst_pix_fmt;
675}
676
9f08d803
HM
677void av_picture_copy(AVPicture *dst, const AVPicture *src,
678 enum PixelFormat pix_fmt, int width, int height)
679{
34017fd9 680 av_image_copy(dst->data, dst->linesize, src->data,
4afbcf46 681 src->linesize, pix_fmt, width, height);
9f08d803
HM
682}
683
85c242d8 684/* 2x2 -> 1x1 */
54009d42 685void ff_shrink22(uint8_t *dst, int dst_wrap,
e352ff08 686 const uint8_t *src, int src_wrap,
85c242d8
FB
687 int width, int height)
688{
689 int w;
e352ff08
FB
690 const uint8_t *s1, *s2;
691 uint8_t *d;
85c242d8
FB
692
693 for(;height > 0; height--) {
694 s1 = src;
695 s2 = s1 + src_wrap;
696 d = dst;
697 for(w = width;w >= 4; w-=4) {
0a9ad8d1
FB
698 d[0] = (s1[0] + s1[1] + s2[0] + s2[1] + 2) >> 2;
699 d[1] = (s1[2] + s1[3] + s2[2] + s2[3] + 2) >> 2;
700 d[2] = (s1[4] + s1[5] + s2[4] + s2[5] + 2) >> 2;
701 d[3] = (s1[6] + s1[7] + s2[6] + s2[7] + 2) >> 2;
85c242d8
FB
702 s1 += 8;
703 s2 += 8;
704 d += 4;
705 }
706 for(;w > 0; w--) {
0a9ad8d1 707 d[0] = (s1[0] + s1[1] + s2[0] + s2[1] + 2) >> 2;
85c242d8
FB
708 s1 += 2;
709 s2 += 2;
710 d++;
711 }
712 src += 2 * src_wrap;
713 dst += dst_wrap;
714 }
715}
716
e352ff08 717/* 4x4 -> 1x1 */
54009d42 718void ff_shrink44(uint8_t *dst, int dst_wrap,
e352ff08 719 const uint8_t *src, int src_wrap,
6742d95d
FR
720 int width, int height)
721{
722 int w;
e352ff08
FB
723 const uint8_t *s1, *s2, *s3, *s4;
724 uint8_t *d;
6742d95d
FR
725
726 for(;height > 0; height--) {
727 s1 = src;
e352ff08
FB
728 s2 = s1 + src_wrap;
729 s3 = s2 + src_wrap;
730 s4 = s3 + src_wrap;
6742d95d 731 d = dst;
e352ff08
FB
732 for(w = width;w > 0; w--) {
733 d[0] = (s1[0] + s1[1] + s1[2] + s1[3] +
734 s2[0] + s2[1] + s2[2] + s2[3] +
735 s3[0] + s3[1] + s3[2] + s3[3] +
736 s4[0] + s4[1] + s4[2] + s4[3] + 8) >> 4;
737 s1 += 4;
738 s2 += 4;
739 s3 += 4;
740 s4 += 4;
6742d95d
FR
741 d++;
742 }
e352ff08
FB
743 src += 4 * src_wrap;
744 dst += dst_wrap;
745 }
746}
747
54009d42
MN
748/* 8x8 -> 1x1 */
749void ff_shrink88(uint8_t *dst, int dst_wrap,
750 const uint8_t *src, int src_wrap,
751 int width, int height)
752{
753 int w, i;
754
755 for(;height > 0; height--) {
756 for(w = width;w > 0; w--) {
757 int tmp=0;
758 for(i=0; i<8; i++){
759 tmp += src[0] + src[1] + src[2] + src[3] + src[4] + src[5] + src[6] + src[7];
760 src += src_wrap;
761 }
762 *(dst++) = (tmp + 32)>>6;
763 src += 8 - 8*src_wrap;
764 }
765 src += 8*src_wrap - 8*width;
766 dst += dst_wrap - width;
767 }
768}
769
524c6b63 770
75917b88 771int avpicture_alloc(AVPicture *picture,
a61ec8e7 772 enum PixelFormat pix_fmt, int width, int height)
524c6b63 773{
6d34323e
SS
774 int ret;
775
4ba22e04 776 if ((ret = av_image_alloc(picture->data, picture->linesize, width, height, pix_fmt, 1)) < 0) {
0141163d 777 memset(picture, 0, sizeof(AVPicture));
6d34323e 778 return ret;
e74929e8
SS
779 }
780
781 return 0;
524c6b63
FB
782}
783
75917b88 784void avpicture_free(AVPicture *picture)
524c6b63 785{
8e1e6f31 786 av_free(picture->data[0]);
524c6b63
FB
787}
788
c50c0bc8 789/* return true if yuv planar */
62a05b5b 790static inline int is_yuv_planar(const PixFmtInfo *ps)
c50c0bc8
FB
791{
792 return (ps->color_type == FF_COLOR_YUV ||
115329f1 793 ps->color_type == FF_COLOR_YUV_JPEG) &&
7e7e5940 794 ps->pixel_type == FF_PIXEL_PLANAR;
c50c0bc8
FB
795}
796
636d6a4a 797int av_picture_crop(AVPicture *dst, const AVPicture *src,
4a30fff6 798 enum PixelFormat pix_fmt, int top_band, int left_band)
f2651e7a
BC
799{
800 int y_shift;
801 int x_shift;
802
803 if (pix_fmt < 0 || pix_fmt >= PIX_FMT_NB || !is_yuv_planar(&pix_fmt_info[pix_fmt]))
804 return -1;
805
14b903f3
SS
806 y_shift = av_pix_fmt_descriptors[pix_fmt].log2_chroma_h;
807 x_shift = av_pix_fmt_descriptors[pix_fmt].log2_chroma_w;
f2651e7a
BC
808
809 dst->data[0] = src->data[0] + (top_band * src->linesize[0]) + left_band;
810 dst->data[1] = src->data[1] + ((top_band >> y_shift) * src->linesize[1]) + (left_band >> x_shift);
811 dst->data[2] = src->data[2] + ((top_band >> y_shift) * src->linesize[2]) + (left_band >> x_shift);
812
813 dst->linesize[0] = src->linesize[0];
814 dst->linesize[1] = src->linesize[1];
815 dst->linesize[2] = src->linesize[2];
816 return 0;
817}
818
636d6a4a 819int av_picture_pad(AVPicture *dst, const AVPicture *src, int height, int width,
a61ec8e7 820 enum PixelFormat pix_fmt, int padtop, int padbottom, int padleft, int padright,
6845801f 821 int *color)
5341c209 822{
79acfb0e 823 uint8_t *optr;
5341c209
LA
824 int y_shift;
825 int x_shift;
826 int yheight;
827 int i, y;
828
6845801f
LB
829 if (pix_fmt < 0 || pix_fmt >= PIX_FMT_NB ||
830 !is_yuv_planar(&pix_fmt_info[pix_fmt])) return -1;
5341c209
LA
831
832 for (i = 0; i < 3; i++) {
14b903f3
SS
833 x_shift = i ? av_pix_fmt_descriptors[pix_fmt].log2_chroma_w : 0;
834 y_shift = i ? av_pix_fmt_descriptors[pix_fmt].log2_chroma_h : 0;
5341c209
LA
835
836 if (padtop || padleft) {
6845801f
LB
837 memset(dst->data[i], color[i],
838 dst->linesize[i] * (padtop >> y_shift) + (padleft >> x_shift));
5341c209
LA
839 }
840
79acfb0e
LB
841 if (padleft || padright) {
842 optr = dst->data[i] + dst->linesize[i] * (padtop >> y_shift) +
843 (dst->linesize[i] - (padright >> x_shift));
844 yheight = (height - 1 - (padtop + padbottom)) >> y_shift;
845 for (y = 0; y < yheight; y++) {
846 memset(optr, color[i], (padleft + padright) >> x_shift);
847 optr += dst->linesize[i];
5341c209 848 }
79acfb0e
LB
849 }
850
851 if (src) { /* first line */
852 uint8_t *iptr = src->data[i];
853 optr = dst->data[i] + dst->linesize[i] * (padtop >> y_shift) +
854 (padleft >> x_shift);
1be97a21 855 memcpy(optr, iptr, (width - padleft - padright) >> x_shift);
79acfb0e 856 iptr += src->linesize[i];
6845801f
LB
857 optr = dst->data[i] + dst->linesize[i] * (padtop >> y_shift) +
858 (dst->linesize[i] - (padright >> x_shift));
5341c209
LA
859 yheight = (height - 1 - (padtop + padbottom)) >> y_shift;
860 for (y = 0; y < yheight; y++) {
861 memset(optr, color[i], (padleft + padright) >> x_shift);
79acfb0e 862 memcpy(optr + ((padleft + padright) >> x_shift), iptr,
1be97a21 863 (width - padleft - padright) >> x_shift);
79acfb0e 864 iptr += src->linesize[i];
5341c209
LA
865 optr += dst->linesize[i];
866 }
867 }
868
869 if (padbottom || padright) {
6845801f
LB
870 optr = dst->data[i] + dst->linesize[i] *
871 ((height - padbottom) >> y_shift) - (padright >> x_shift);
872 memset(optr, color[i],dst->linesize[i] *
873 (padbottom >> y_shift) + (padright >> x_shift));
5341c209
LA
874 }
875 }
876 return 0;
877}
878
17337f54 879#if !HAVE_MMX_EXTERNAL
85c242d8 880/* filter parameters: [-1 4 2 4 -1] // 8 */
de4bc44a 881static void deinterlace_line_c(uint8_t *dst,
bb270c08
DB
882 const uint8_t *lum_m4, const uint8_t *lum_m3,
883 const uint8_t *lum_m2, const uint8_t *lum_m1,
884 const uint8_t *lum,
885 int size)
85c242d8 886{
55fde95e 887 uint8_t *cm = ff_cropTbl + MAX_NEG_CROP;
85c242d8 888 int sum;
85c242d8
FB
889
890 for(;size > 0;size--) {
5981f4e6
F
891 sum = -lum_m4[0];
892 sum += lum_m3[0] << 2;
893 sum += lum_m2[0] << 1;
894 sum += lum_m1[0] << 2;
895 sum += -lum[0];
85c242d8 896 dst[0] = cm[(sum + 4) >> 3];
5981f4e6
F
897 lum_m4++;
898 lum_m3++;
899 lum_m2++;
900 lum_m1++;
901 lum++;
85c242d8 902 dst++;
85c242d8 903 }
5981f4e6 904}
de4bc44a
VS
905
906static void deinterlace_line_inplace_c(uint8_t *lum_m4, uint8_t *lum_m3,
907 uint8_t *lum_m2, uint8_t *lum_m1,
908 uint8_t *lum, int size)
5981f4e6 909{
55fde95e 910 uint8_t *cm = ff_cropTbl + MAX_NEG_CROP;
5981f4e6
F
911 int sum;
912
913 for(;size > 0;size--) {
914 sum = -lum_m4[0];
915 sum += lum_m3[0] << 2;
916 sum += lum_m2[0] << 1;
917 lum_m4[0]=lum_m2[0];
918 sum += lum_m1[0] << 2;
919 sum += -lum[0];
920 lum_m2[0] = cm[(sum + 4) >> 3];
921 lum_m4++;
922 lum_m3++;
923 lum_m2++;
924 lum_m1++;
925 lum++;
926 }
85c242d8 927}
17337f54 928#endif /* !HAVE_MMX_EXTERNAL */
85c242d8
FB
929
930/* deinterlacing : 2 temporal taps, 3 spatial taps linear filter. The
931 top field is copied as is, but the bottom field is deinterlaced
932 against the top field. */
0c1a9eda 933static void deinterlace_bottom_field(uint8_t *dst, int dst_wrap,
da64ecc3 934 const uint8_t *src1, int src_wrap,
5981f4e6 935 int width, int height)
85c242d8 936{
da64ecc3 937 const uint8_t *src_m2, *src_m1, *src_0, *src_p1, *src_p2;
5981f4e6
F
938 int y;
939
940 src_m2 = src1;
941 src_m1 = src1;
942 src_0=&src_m1[src_wrap];
943 src_p1=&src_0[src_wrap];
944 src_p2=&src_p1[src_wrap];
945 for(y=0;y<(height-2);y+=2) {
946 memcpy(dst,src_m1,width);
85c242d8 947 dst += dst_wrap;
5981f4e6
F
948 deinterlace_line(dst,src_m2,src_m1,src_0,src_p1,src_p2,width);
949 src_m2 = src_0;
950 src_m1 = src_p1;
951 src_0 = src_p2;
952 src_p1 += 2*src_wrap;
953 src_p2 += 2*src_wrap;
85c242d8 954 dst += dst_wrap;
85c242d8 955 }
5981f4e6
F
956 memcpy(dst,src_m1,width);
957 dst += dst_wrap;
958 /* do last line */
959 deinterlace_line(dst,src_m2,src_m1,src_0,src_0,src_0,width);
960}
961
0c1a9eda 962static void deinterlace_bottom_field_inplace(uint8_t *src1, int src_wrap,
bb270c08 963 int width, int height)
5981f4e6 964{
0c1a9eda 965 uint8_t *src_m1, *src_0, *src_p1, *src_p2;
5981f4e6 966 int y;
0c1a9eda 967 uint8_t *buf;
44b0edda 968 buf = av_malloc(width);
5981f4e6
F
969
970 src_m1 = src1;
971 memcpy(buf,src_m1,width);
972 src_0=&src_m1[src_wrap];
973 src_p1=&src_0[src_wrap];
974 src_p2=&src_p1[src_wrap];
975 for(y=0;y<(height-2);y+=2) {
976 deinterlace_line_inplace(buf,src_m1,src_0,src_p1,src_p2,width);
977 src_m1 = src_p1;
978 src_0 = src_p2;
979 src_p1 += 2*src_wrap;
980 src_p2 += 2*src_wrap;
981 }
982 /* do last line */
983 deinterlace_line_inplace(buf,src_m1,src_0,src_0,src_0,width);
6000abfa 984 av_free(buf);
85c242d8
FB
985}
986
da64ecc3 987int avpicture_deinterlace(AVPicture *dst, const AVPicture *src,
a61ec8e7 988 enum PixelFormat pix_fmt, int width, int height)
de6d9b64 989{
85c242d8
FB
990 int i;
991
992 if (pix_fmt != PIX_FMT_YUV420P &&
4792d1e7 993 pix_fmt != PIX_FMT_YUVJ420P &&
85c242d8 994 pix_fmt != PIX_FMT_YUV422P &&
b299c4e4 995 pix_fmt != PIX_FMT_YUVJ422P &&
47017dd8 996 pix_fmt != PIX_FMT_YUV444P &&
2a7feb18
AG
997 pix_fmt != PIX_FMT_YUV411P &&
998 pix_fmt != PIX_FMT_GRAY8)
85c242d8 999 return -1;
5981f4e6 1000 if ((width & 3) != 0 || (height & 3) != 0)
85c242d8 1001 return -1;
5981f4e6 1002
85c242d8
FB
1003 for(i=0;i<3;i++) {
1004 if (i == 1) {
1005 switch(pix_fmt) {
4792d1e7 1006 case PIX_FMT_YUVJ420P:
85c242d8
FB
1007 case PIX_FMT_YUV420P:
1008 width >>= 1;
1009 height >>= 1;
1010 break;
1011 case PIX_FMT_YUV422P:
b299c4e4 1012 case PIX_FMT_YUVJ422P:
85c242d8
FB
1013 width >>= 1;
1014 break;
47017dd8
RS
1015 case PIX_FMT_YUV411P:
1016 width >>= 2;
1017 break;
85c242d8
FB
1018 default:
1019 break;
1020 }
2a7feb18
AG
1021 if (pix_fmt == PIX_FMT_GRAY8) {
1022 break;
1023 }
85c242d8 1024 }
5981f4e6 1025 if (src == dst) {
da64ecc3 1026 deinterlace_bottom_field_inplace(dst->data[i], dst->linesize[i],
85c242d8 1027 width, height);
5981f4e6
F
1028 } else {
1029 deinterlace_bottom_field(dst->data[i],dst->linesize[i],
1030 src->data[i], src->linesize[i],
1031 width, height);
1032 }
de6d9b64 1033 }
55ffe9df 1034 emms_c();
85c242d8 1035 return 0;
de6d9b64 1036}