Use av_fill_image_pointers/linesizes in place of ff_fill_pointer/linesize,
[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 *
b78e7197
DB
5 * This file is part of FFmpeg.
6 *
7 * FFmpeg 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 *
b78e7197 12 * FFmpeg 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
b78e7197 18 * License along with FFmpeg; 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
CEH
35#include "internal.h"
36#include "imgconvert.h"
2b4abbd6 37#include "libavutil/colorspace.h"
8e861e1b 38#include "libavutil/pixdesc.h"
e7bd48a6 39#include "libavcore/imgutils.h"
de6d9b64 40
0913a92a 41#if HAVE_MMX && HAVE_YASM
a6493a8f 42#include "x86/dsputil_mmx.h"
5981f4e6 43#endif
524c6b63 44
7e7e5940
FB
45#define xglue(x, y) x ## y
46#define glue(x, y) xglue(x, y)
47
bb0f999b
GP
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 */
b6147995 52
bb0f999b
GP
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 */
7e7e5940 56
0913a92a 57#if HAVE_MMX && HAVE_YASM
de4bc44a
VS
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
524c6b63 65typedef struct PixFmtInfo {
bb0f999b
GP
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 */
bb0f999b 70 uint8_t depth; /**< bit depth of the color components */
524c6b63
FB
71} PixFmtInfo;
72
73/* this table gives more information about formats */
62a05b5b 74static const PixFmtInfo pix_fmt_info[PIX_FMT_NB] = {
524c6b63
FB
75 /* YUV formats */
76 [PIX_FMT_YUV420P] = {
7e7e5940 77 .nb_channels = 3,
b6147995 78 .color_type = FF_COLOR_YUV,
7e7e5940 79 .pixel_type = FF_PIXEL_PLANAR,
b6147995 80 .depth = 8,
524c6b63
FB
81 },
82 [PIX_FMT_YUV422P] = {
7e7e5940 83 .nb_channels = 3,
b6147995 84 .color_type = FF_COLOR_YUV,
7e7e5940 85 .pixel_type = FF_PIXEL_PLANAR,
b6147995 86 .depth = 8,
524c6b63
FB
87 },
88 [PIX_FMT_YUV444P] = {
7e7e5940 89 .nb_channels = 3,
b6147995 90 .color_type = FF_COLOR_YUV,
7e7e5940 91 .pixel_type = FF_PIXEL_PLANAR,
b6147995 92 .depth = 8,
524c6b63 93 },
71e445fc 94 [PIX_FMT_YUYV422] = {
7e7e5940 95 .nb_channels = 1,
b6147995 96 .color_type = FF_COLOR_YUV,
7e7e5940 97 .pixel_type = FF_PIXEL_PACKED,
b6147995 98 .depth = 8,
524c6b63 99 },
ebb177dd 100 [PIX_FMT_UYVY422] = {
ebb177dd
TK
101 .nb_channels = 1,
102 .color_type = FF_COLOR_YUV,
103 .pixel_type = FF_PIXEL_PACKED,
104 .depth = 8,
ebb177dd 105 },
524c6b63 106 [PIX_FMT_YUV410P] = {
7e7e5940 107 .nb_channels = 3,
b6147995 108 .color_type = FF_COLOR_YUV,
7e7e5940 109 .pixel_type = FF_PIXEL_PLANAR,
b6147995 110 .depth = 8,
524c6b63
FB
111 },
112 [PIX_FMT_YUV411P] = {
7e7e5940 113 .nb_channels = 3,
b6147995 114 .color_type = FF_COLOR_YUV,
7e7e5940 115 .pixel_type = FF_PIXEL_PLANAR,
b6147995 116 .depth = 8,
524c6b63 117 },
4196cfb7 118 [PIX_FMT_YUV440P] = {
4196cfb7
119 .nb_channels = 3,
120 .color_type = FF_COLOR_YUV,
121 .pixel_type = FF_PIXEL_PLANAR,
122 .depth = 8,
4196cfb7 123 },
35f6c154 124 [PIX_FMT_YUV420P16LE] = {
6c2a8608
MN
125 .nb_channels = 3,
126 .color_type = FF_COLOR_YUV,
127 .pixel_type = FF_PIXEL_PLANAR,
128 .depth = 16,
6c2a8608 129 },
35f6c154 130 [PIX_FMT_YUV422P16LE] = {
6c2a8608
MN
131 .nb_channels = 3,
132 .color_type = FF_COLOR_YUV,
133 .pixel_type = FF_PIXEL_PLANAR,
134 .depth = 16,
6c2a8608 135 },
35f6c154 136 [PIX_FMT_YUV444P16LE] = {
6c2a8608
MN
137 .nb_channels = 3,
138 .color_type = FF_COLOR_YUV,
139 .pixel_type = FF_PIXEL_PLANAR,
140 .depth = 16,
6c2a8608 141 },
35f6c154 142 [PIX_FMT_YUV420P16BE] = {
6c2a8608
MN
143 .nb_channels = 3,
144 .color_type = FF_COLOR_YUV,
145 .pixel_type = FF_PIXEL_PLANAR,
146 .depth = 16,
6c2a8608 147 },
35f6c154 148 [PIX_FMT_YUV422P16BE] = {
6c2a8608
MN
149 .nb_channels = 3,
150 .color_type = FF_COLOR_YUV,
151 .pixel_type = FF_PIXEL_PLANAR,
152 .depth = 16,
6c2a8608 153 },
35f6c154 154 [PIX_FMT_YUV444P16BE] = {
6c2a8608
MN
155 .nb_channels = 3,
156 .color_type = FF_COLOR_YUV,
157 .pixel_type = FF_PIXEL_PLANAR,
158 .depth = 16,
6c2a8608
MN
159 },
160
524c6b63 161
b70335a2
AJ
162 /* YUV formats with alpha plane */
163 [PIX_FMT_YUVA420P] = {
b70335a2
AJ
164 .nb_channels = 4,
165 .color_type = FF_COLOR_YUV,
166 .pixel_type = FF_PIXEL_PLANAR,
167 .depth = 8,
b70335a2
AJ
168 },
169
b6147995
FB
170 /* JPEG YUV */
171 [PIX_FMT_YUVJ420P] = {
7e7e5940 172 .nb_channels = 3,
b6147995 173 .color_type = FF_COLOR_YUV_JPEG,
7e7e5940 174 .pixel_type = FF_PIXEL_PLANAR,
b6147995 175 .depth = 8,
b6147995
FB
176 },
177 [PIX_FMT_YUVJ422P] = {
7e7e5940 178 .nb_channels = 3,
b6147995 179 .color_type = FF_COLOR_YUV_JPEG,
7e7e5940 180 .pixel_type = FF_PIXEL_PLANAR,
b6147995 181 .depth = 8,
b6147995
FB
182 },
183 [PIX_FMT_YUVJ444P] = {
7e7e5940 184 .nb_channels = 3,
b6147995 185 .color_type = FF_COLOR_YUV_JPEG,
7e7e5940 186 .pixel_type = FF_PIXEL_PLANAR,
b6147995 187 .depth = 8,
b6147995 188 },
4196cfb7 189 [PIX_FMT_YUVJ440P] = {
4196cfb7
190 .nb_channels = 3,
191 .color_type = FF_COLOR_YUV_JPEG,
192 .pixel_type = FF_PIXEL_PLANAR,
193 .depth = 8,
4196cfb7 194 },
b6147995 195
524c6b63
FB
196 /* RGB formats */
197 [PIX_FMT_RGB24] = {
7e7e5940 198 .nb_channels = 3,
b6147995 199 .color_type = FF_COLOR_RGB,
7e7e5940 200 .pixel_type = FF_PIXEL_PACKED,
b6147995 201 .depth = 8,
524c6b63
FB
202 },
203 [PIX_FMT_BGR24] = {
7e7e5940 204 .nb_channels = 3,
b6147995 205 .color_type = FF_COLOR_RGB,
7e7e5940 206 .pixel_type = FF_PIXEL_PACKED,
b6147995 207 .depth = 8,
524c6b63 208 },
6e08ca9c 209 [PIX_FMT_ARGB] = {
7e7e5940 210 .nb_channels = 4, .is_alpha = 1,
b6147995 211 .color_type = FF_COLOR_RGB,
7e7e5940 212 .pixel_type = FF_PIXEL_PACKED,
b6147995 213 .depth = 8,
524c6b63 214 },
88c21a6f 215 [PIX_FMT_RGB48BE] = {
88c21a6f
PR
216 .nb_channels = 3,
217 .color_type = FF_COLOR_RGB,
218 .pixel_type = FF_PIXEL_PACKED,
219 .depth = 16,
88c21a6f
PR
220 },
221 [PIX_FMT_RGB48LE] = {
88c21a6f
PR
222 .nb_channels = 3,
223 .color_type = FF_COLOR_RGB,
224 .pixel_type = FF_PIXEL_PACKED,
225 .depth = 16,
88c21a6f 226 },
f82674e5 227 [PIX_FMT_RGB565BE] = {
7e7e5940 228 .nb_channels = 3,
b6147995 229 .color_type = FF_COLOR_RGB,
7e7e5940 230 .pixel_type = FF_PIXEL_PACKED,
b6147995 231 .depth = 5,
524c6b63 232 },
f82674e5 233 [PIX_FMT_RGB565LE] = {
f82674e5
SS
234 .nb_channels = 3,
235 .color_type = FF_COLOR_RGB,
236 .pixel_type = FF_PIXEL_PACKED,
237 .depth = 5,
f82674e5
SS
238 },
239 [PIX_FMT_RGB555BE] = {
f82674e5
SS
240 .nb_channels = 3,
241 .color_type = FF_COLOR_RGB,
242 .pixel_type = FF_PIXEL_PACKED,
243 .depth = 5,
f82674e5
SS
244 },
245 [PIX_FMT_RGB555LE] = {
20d46c03 246 .nb_channels = 3,
b6147995 247 .color_type = FF_COLOR_RGB,
7e7e5940 248 .pixel_type = FF_PIXEL_PACKED,
b6147995 249 .depth = 5,
524c6b63 250 },
2b7cf167
JK
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 },
524c6b63
FB
263
264 /* gray / mono formats */
34380af0 265 [PIX_FMT_GRAY16BE] = {
34380af0
KS
266 .nb_channels = 1,
267 .color_type = FF_COLOR_GRAY,
268 .pixel_type = FF_PIXEL_PLANAR,
269 .depth = 16,
270 },
271 [PIX_FMT_GRAY16LE] = {
34380af0
KS
272 .nb_channels = 1,
273 .color_type = FF_COLOR_GRAY,
274 .pixel_type = FF_PIXEL_PLANAR,
275 .depth = 16,
276 },
524c6b63 277 [PIX_FMT_GRAY8] = {
7e7e5940 278 .nb_channels = 1,
b6147995 279 .color_type = FF_COLOR_GRAY,
7e7e5940 280 .pixel_type = FF_PIXEL_PLANAR,
b6147995 281 .depth = 8,
524c6b63
FB
282 },
283 [PIX_FMT_MONOWHITE] = {
7e7e5940 284 .nb_channels = 1,
b6147995 285 .color_type = FF_COLOR_GRAY,
7e7e5940 286 .pixel_type = FF_PIXEL_PLANAR,
b6147995 287 .depth = 1,
524c6b63
FB
288 },
289 [PIX_FMT_MONOBLACK] = {
7e7e5940 290 .nb_channels = 1,
b6147995 291 .color_type = FF_COLOR_GRAY,
7e7e5940 292 .pixel_type = FF_PIXEL_PLANAR,
b6147995 293 .depth = 1,
524c6b63 294 },
7e6d70d0
FB
295
296 /* paletted formats */
297 [PIX_FMT_PAL8] = {
7e7e5940 298 .nb_channels = 4, .is_alpha = 1,
b6147995 299 .color_type = FF_COLOR_RGB,
7e7e5940 300 .pixel_type = FF_PIXEL_PALETTE,
b6147995 301 .depth = 8,
7e6d70d0 302 },
71e445fc 303 [PIX_FMT_UYYVYY411] = {
f02be79d
RS
304 .nb_channels = 1,
305 .color_type = FF_COLOR_YUV,
306 .pixel_type = FF_PIXEL_PACKED,
307 .depth = 8,
f02be79d 308 },
6e08ca9c 309 [PIX_FMT_ABGR] = {
00b2fa86
LA
310 .nb_channels = 4, .is_alpha = 1,
311 .color_type = FF_COLOR_RGB,
312 .pixel_type = FF_PIXEL_PACKED,
313 .depth = 8,
00b2fa86 314 },
f82674e5 315 [PIX_FMT_BGR565BE] = {
f82674e5
SS
316 .nb_channels = 3,
317 .color_type = FF_COLOR_RGB,
318 .pixel_type = FF_PIXEL_PACKED,
319 .depth = 5,
f82674e5
SS
320 },
321 [PIX_FMT_BGR565LE] = {
f82674e5
SS
322 .nb_channels = 3,
323 .color_type = FF_COLOR_RGB,
324 .pixel_type = FF_PIXEL_PACKED,
325 .depth = 5,
f82674e5
SS
326 },
327 [PIX_FMT_BGR555BE] = {
00b2fa86
LA
328 .nb_channels = 3,
329 .color_type = FF_COLOR_RGB,
330 .pixel_type = FF_PIXEL_PACKED,
331 .depth = 5,
00b2fa86 332 },
f82674e5 333 [PIX_FMT_BGR555LE] = {
08d23410 334 .nb_channels = 3,
00b2fa86
LA
335 .color_type = FF_COLOR_RGB,
336 .pixel_type = FF_PIXEL_PACKED,
337 .depth = 5,
00b2fa86 338 },
2b7cf167
JK
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 },
00b2fa86 351 [PIX_FMT_RGB8] = {
00b2fa86
LA
352 .nb_channels = 1,
353 .color_type = FF_COLOR_RGB,
354 .pixel_type = FF_PIXEL_PACKED,
355 .depth = 8,
00b2fa86
LA
356 },
357 [PIX_FMT_RGB4] = {
00b2fa86
LA
358 .nb_channels = 1,
359 .color_type = FF_COLOR_RGB,
360 .pixel_type = FF_PIXEL_PACKED,
361 .depth = 4,
00b2fa86
LA
362 },
363 [PIX_FMT_RGB4_BYTE] = {
00b2fa86
LA
364 .nb_channels = 1,
365 .color_type = FF_COLOR_RGB,
366 .pixel_type = FF_PIXEL_PACKED,
367 .depth = 8,
00b2fa86
LA
368 },
369 [PIX_FMT_BGR8] = {
00b2fa86
LA
370 .nb_channels = 1,
371 .color_type = FF_COLOR_RGB,
372 .pixel_type = FF_PIXEL_PACKED,
373 .depth = 8,
00b2fa86
LA
374 },
375 [PIX_FMT_BGR4] = {
00b2fa86
LA
376 .nb_channels = 1,
377 .color_type = FF_COLOR_RGB,
378 .pixel_type = FF_PIXEL_PACKED,
379 .depth = 4,
00b2fa86
LA
380 },
381 [PIX_FMT_BGR4_BYTE] = {
00b2fa86
LA
382 .nb_channels = 1,
383 .color_type = FF_COLOR_RGB,
384 .pixel_type = FF_PIXEL_PACKED,
385 .depth = 8,
00b2fa86
LA
386 },
387 [PIX_FMT_NV12] = {
00b2fa86
LA
388 .nb_channels = 2,
389 .color_type = FF_COLOR_YUV,
390 .pixel_type = FF_PIXEL_PLANAR,
391 .depth = 8,
00b2fa86
LA
392 },
393 [PIX_FMT_NV21] = {
00b2fa86
LA
394 .nb_channels = 2,
395 .color_type = FF_COLOR_YUV,
396 .pixel_type = FF_PIXEL_PLANAR,
397 .depth = 8,
00b2fa86
LA
398 },
399
6e08ca9c 400 [PIX_FMT_BGRA] = {
00b2fa86
LA
401 .nb_channels = 4, .is_alpha = 1,
402 .color_type = FF_COLOR_RGB,
403 .pixel_type = FF_PIXEL_PACKED,
404 .depth = 8,
00b2fa86 405 },
6e08ca9c 406 [PIX_FMT_RGBA] = {
00b2fa86
LA
407 .nb_channels = 4, .is_alpha = 1,
408 .color_type = FF_COLOR_RGB,
409 .pixel_type = FF_PIXEL_PACKED,
410 .depth = 8,
00b2fa86 411 },
524c6b63
FB
412};
413
a61ec8e7 414void avcodec_get_chroma_sub_sample(enum PixelFormat pix_fmt, int *h_shift, int *v_shift)
524c6b63 415{
38264abb
SS
416 *h_shift = av_pix_fmt_descriptors[pix_fmt].log2_chroma_w;
417 *v_shift = av_pix_fmt_descriptors[pix_fmt].log2_chroma_h;
524c6b63
FB
418}
419
a61ec8e7 420const char *avcodec_get_pix_fmt_name(enum PixelFormat pix_fmt)
524c6b63
FB
421{
422 if (pix_fmt < 0 || pix_fmt >= PIX_FMT_NB)
42a45a03 423 return NULL;
524c6b63 424 else
797229a6 425 return av_pix_fmt_descriptors[pix_fmt].name;
524c6b63
FB
426}
427
80a07f6e 428#if LIBAVCODEC_VERSION_MAJOR < 53
d89f692f
SS
429enum PixelFormat avcodec_get_pix_fmt(const char *name)
430{
80a07f6e 431 return av_get_pix_fmt(name);
d89f692f 432}
80a07f6e 433#endif
d89f692f 434
a61ec8e7 435void avcodec_pix_fmt_string (char *buf, int buf_size, enum PixelFormat pix_fmt)
c3b95b1d 436{
c3b95b1d
SS
437 /* print header */
438 if (pix_fmt < 0)
439 snprintf (buf, buf_size,
440 "name " " nb_channels" " depth" " is_alpha"
441 );
8e6f8869
MN
442 else{
443 PixFmtInfo info= pix_fmt_info[pix_fmt];
444
445 char is_alpha_char= info.is_alpha ? 'y' : 'n';
446
c3b95b1d 447 snprintf (buf, buf_size,
65935bc7 448 "%-11s %5d %9d %6c",
106c72fa 449 av_pix_fmt_descriptors[pix_fmt].name,
c3b95b1d
SS
450 info.nb_channels,
451 info.depth,
452 is_alpha_char
453 );
8e6f8869 454 }
c3b95b1d
SS
455}
456
c269cf68
MN
457int ff_is_hwaccel_pix_fmt(enum PixelFormat pix_fmt)
458{
8e861e1b 459 return av_pix_fmt_descriptors[pix_fmt].flags & PIX_FMT_HWACCEL;
c269cf68
MN
460}
461
6337178b
MN
462int 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;
c7efffcb
PK
492 default:
493 return -1;
6337178b
MN
494 }
495 pal[i] = b + (g<<8) + (r<<16);
496 }
497
498 return 0;
499}
500
05236ed7 501#if LIBAVCODEC_VERSION_MAJOR < 53
9dd9d67b
HM
502int ff_fill_linesize(AVPicture *picture, enum PixelFormat pix_fmt, int width)
503{
e7bd48a6 504 return av_fill_image_linesizes(picture->linesize, pix_fmt, width);
2a877875
FB
505}
506
9dd9d67b
HM
507int ff_fill_pointer(AVPicture *picture, uint8_t *ptr, enum PixelFormat pix_fmt,
508 int height)
509{
e7bd48a6 510 return av_fill_image_pointers(picture->data, pix_fmt, height, ptr, picture->linesize);
9dd9d67b 511}
05236ed7 512#endif
9dd9d67b 513
cc9853d3 514int avpicture_fill(AVPicture *picture, uint8_t *ptr,
a61ec8e7 515 enum PixelFormat pix_fmt, int width, int height)
cc9853d3
VS
516{
517
518 if(avcodec_check_dimensions(NULL, width, height))
519 return -1;
520
fc2db52e 521 if (av_fill_image_linesizes(picture->linesize, pix_fmt, width))
cc9853d3
VS
522 return -1;
523
fc2db52e 524 return av_fill_image_pointers(picture->data, pix_fmt, height, ptr, picture->linesize);
cc9853d3
VS
525}
526
a61ec8e7 527int avpicture_layout(const AVPicture* src, enum PixelFormat pix_fmt, int width, int height,
63167088
RS
528 unsigned char *dest, int dest_size)
529{
62a05b5b 530 const PixFmtInfo* pf = &pix_fmt_info[pix_fmt];
14b903f3 531 const AVPixFmtDescriptor *desc = &av_pix_fmt_descriptors[pix_fmt];
5f59207d 532 int i, j, w, ow, h, oh, data_planes;
115329f1 533 const unsigned char* s;
63167088
RS
534 int size = avpicture_get_size(pix_fmt, width, height);
535
0ecca7a4 536 if (size > dest_size || size < 0)
63167088
RS
537 return -1;
538
affd55a1 539 if (pf->pixel_type == FF_PIXEL_PACKED || pf->pixel_type == FF_PIXEL_PALETTE) {
71e445fc 540 if (pix_fmt == PIX_FMT_YUYV422 ||
115329f1 541 pix_fmt == PIX_FMT_UYVY422 ||
ffd38d8b
AB
542 pix_fmt == PIX_FMT_BGR565BE ||
543 pix_fmt == PIX_FMT_BGR565LE ||
544 pix_fmt == PIX_FMT_BGR555BE ||
545 pix_fmt == PIX_FMT_BGR555LE ||
2b7cf167
JK
546 pix_fmt == PIX_FMT_BGR444BE ||
547 pix_fmt == PIX_FMT_BGR444LE ||
ffd38d8b
AB
548 pix_fmt == PIX_FMT_RGB565BE ||
549 pix_fmt == PIX_FMT_RGB565LE ||
550 pix_fmt == PIX_FMT_RGB555BE ||
2b7cf167
JK
551 pix_fmt == PIX_FMT_RGB555LE ||
552 pix_fmt == PIX_FMT_RGB444BE ||
553 pix_fmt == PIX_FMT_RGB444LE)
ebb177dd 554 w = width * 2;
71e445fc 555 else if (pix_fmt == PIX_FMT_UYYVYY411)
b16569d2 556 w = width + width/2;
bb270c08 557 else if (pix_fmt == PIX_FMT_PAL8)
b16569d2 558 w = width;
bb270c08 559 else
b16569d2 560 w = width * (pf->depth * pf->nb_channels / 8);
bb270c08
DB
561
562 data_planes = 1;
563 h = height;
63167088
RS
564 } else {
565 data_planes = pf->nb_channels;
bb270c08
DB
566 w = (width*pf->depth + 7)/8;
567 h = height;
63167088 568 }
115329f1 569
5f59207d
CS
570 ow = w;
571 oh = h;
572
63167088 573 for (i=0; i<data_planes; i++) {
b16569d2 574 if (i == 1) {
09ab8859
VS
575 w = (- ((-width) >> desc->log2_chroma_w) * pf->depth + 7) / 8;
576 h = -((-height) >> desc->log2_chroma_h);
f2526204
RP
577 if (pix_fmt == PIX_FMT_NV12 || pix_fmt == PIX_FMT_NV21)
578 w <<= 1;
b16569d2
RP
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 }
63167088 589 }
115329f1 590
affd55a1 591 if (pf->pixel_type == FF_PIXEL_PALETTE)
bb270c08 592 memcpy((unsigned char *)(((size_t)dest + 3) & ~3), src->data[1], 256 * 4);
115329f1 593
63167088
RS
594 return size;
595}
596
a61ec8e7 597int avpicture_get_size(enum PixelFormat pix_fmt, int width, int height)
2a877875
FB
598{
599 AVPicture dummy_pict;
899a8fa1
RD
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 }
2a877875
FB
611 return avpicture_fill(&dummy_pict, NULL, pix_fmt, width, height);
612}
613
a61ec8e7 614int avcodec_get_pix_fmt_loss(enum PixelFormat dst_pix_fmt, enum PixelFormat src_pix_fmt,
b6147995
FB
615 int has_alpha)
616{
617 const PixFmtInfo *pf, *ps;
14b903f3
SS
618 const AVPixFmtDescriptor *src_desc = &av_pix_fmt_descriptors[src_pix_fmt];
619 const AVPixFmtDescriptor *dst_desc = &av_pix_fmt_descriptors[dst_pix_fmt];
b6147995
FB
620 int loss;
621
622 ps = &pix_fmt_info[src_pix_fmt];
b6147995
FB
623
624 /* compute loss */
625 loss = 0;
626 pf = &pix_fmt_info[dst_pix_fmt];
0a9ad8d1 627 if (pf->depth < ps->depth ||
4ef82b17
JK
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)))
b6147995 632 loss |= FF_LOSS_DEPTH;
14b903f3
SS
633 if (dst_desc->log2_chroma_w > src_desc->log2_chroma_w ||
634 dst_desc->log2_chroma_h > src_desc->log2_chroma_h)
b6147995
FB
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 &&
115329f1 652 ps->color_type != FF_COLOR_YUV &&
0a9ad8d1 653 ps->color_type != FF_COLOR_GRAY)
b6147995
FB
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;
115329f1 667 if (pf->pixel_type == FF_PIXEL_PALETTE &&
7e7e5940 668 (ps->pixel_type != FF_PIXEL_PALETTE && ps->color_type != FF_COLOR_GRAY))
b6147995
FB
669 loss |= FF_LOSS_COLORQUANT;
670 return loss;
671}
672
a61ec8e7 673static int avg_bits_per_pixel(enum PixelFormat pix_fmt)
b6147995
FB
674{
675 int bits;
676 const PixFmtInfo *pf;
14b903f3 677 const AVPixFmtDescriptor *desc = &av_pix_fmt_descriptors[pix_fmt];
b6147995
FB
678
679 pf = &pix_fmt_info[pix_fmt];
7e7e5940
FB
680 switch(pf->pixel_type) {
681 case FF_PIXEL_PACKED:
b6147995 682 switch(pix_fmt) {
71e445fc 683 case PIX_FMT_YUYV422:
ebb177dd 684 case PIX_FMT_UYVY422:
ffd38d8b
AB
685 case PIX_FMT_RGB565BE:
686 case PIX_FMT_RGB565LE:
687 case PIX_FMT_RGB555BE:
688 case PIX_FMT_RGB555LE:
2b7cf167
JK
689 case PIX_FMT_RGB444BE:
690 case PIX_FMT_RGB444LE:
ffd38d8b
AB
691 case PIX_FMT_BGR565BE:
692 case PIX_FMT_BGR565LE:
693 case PIX_FMT_BGR555BE:
694 case PIX_FMT_BGR555LE:
2b7cf167
JK
695 case PIX_FMT_BGR444BE:
696 case PIX_FMT_BGR444LE:
b6147995 697 bits = 16;
b6147995 698 break;
71e445fc 699 case PIX_FMT_UYYVYY411:
bb270c08
DB
700 bits = 12;
701 break;
b6147995 702 default:
7e7e5940 703 bits = pf->depth * pf->nb_channels;
b6147995
FB
704 break;
705 }
7e7e5940
FB
706 break;
707 case FF_PIXEL_PLANAR:
14b903f3 708 if (desc->log2_chroma_w == 0 && desc->log2_chroma_h == 0) {
7e7e5940
FB
709 bits = pf->depth * pf->nb_channels;
710 } else {
115329f1 711 bits = pf->depth + ((2 * pf->depth) >>
14b903f3 712 (desc->log2_chroma_w + desc->log2_chroma_h));
7e7e5940
FB
713 }
714 break;
715 case FF_PIXEL_PALETTE:
716 bits = 8;
717 break;
718 default:
719 bits = -1;
720 break;
b6147995
FB
721 }
722 return bits;
723}
724
a61ec8e7
SS
725static enum PixelFormat avcodec_find_best_pix_fmt1(int64_t pix_fmt_mask,
726 enum PixelFormat src_pix_fmt,
b6147995
FB
727 int has_alpha,
728 int loss_mask)
729{
a61ec8e7
SS
730 int dist, i, loss, min_dist;
731 enum PixelFormat dst_pix_fmt;
b6147995
FB
732
733 /* find exact color match with smallest size */
f0bc8449 734 dst_pix_fmt = PIX_FMT_NONE;
b6147995
FB
735 min_dist = 0x7fffffff;
736 for(i = 0;i < PIX_FMT_NB; i++) {
31c3a4dc 737 if (pix_fmt_mask & (1ULL << i)) {
b6147995
FB
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
a61ec8e7 751enum PixelFormat avcodec_find_best_pix_fmt(int64_t pix_fmt_mask, enum PixelFormat src_pix_fmt,
b6147995
FB
752 int has_alpha, int *loss_ptr)
753{
a61ec8e7
SS
754 enum PixelFormat dst_pix_fmt;
755 int loss_mask, i;
b6147995
FB
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++];
115329f1 770 dst_pix_fmt = avcodec_find_best_pix_fmt1(pix_fmt_mask, src_pix_fmt,
b6147995
FB
771 has_alpha, loss_mask);
772 if (dst_pix_fmt >= 0)
773 goto found;
774 if (loss_mask == 0)
775 break;
776 }
f0bc8449 777 return PIX_FMT_NONE;
b6147995
FB
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
54009d42 784void ff_img_copy_plane(uint8_t *dst, int dst_wrap,
e352ff08
FB
785 const uint8_t *src, int src_wrap,
786 int width, int height)
7e7e5940 787{
115329f1 788 if((!dst) || (!src))
5b2ad9f5 789 return;
7e7e5940
FB
790 for(;height > 0; height--) {
791 memcpy(dst, src, width);
792 dst += dst_wrap;
793 src += src_wrap;
794 }
795}
796
6dd36490 797int ff_get_plane_bytewidth(enum PixelFormat pix_fmt, int width, int plane)
7e7e5940 798{
22ed53e5 799 int bits;
62a05b5b 800 const PixFmtInfo *pf = &pix_fmt_info[pix_fmt];
14b903f3 801 const AVPixFmtDescriptor *desc = &av_pix_fmt_descriptors[pix_fmt];
115329f1 802
7e7e5940
FB
803 pf = &pix_fmt_info[pix_fmt];
804 switch(pf->pixel_type) {
805 case FF_PIXEL_PACKED:
806 switch(pix_fmt) {
71e445fc 807 case PIX_FMT_YUYV422:
ebb177dd 808 case PIX_FMT_UYVY422:
ffd38d8b
AB
809 case PIX_FMT_RGB565BE:
810 case PIX_FMT_RGB565LE:
811 case PIX_FMT_RGB555BE:
812 case PIX_FMT_RGB555LE:
2b7cf167
JK
813 case PIX_FMT_RGB444BE:
814 case PIX_FMT_RGB444LE:
ffd38d8b
AB
815 case PIX_FMT_BGR565BE:
816 case PIX_FMT_BGR565LE:
817 case PIX_FMT_BGR555BE:
818 case PIX_FMT_BGR555LE:
2b7cf167
JK
819 case PIX_FMT_BGR444BE:
820 case PIX_FMT_BGR444LE:
7e7e5940
FB
821 bits = 16;
822 break;
71e445fc 823 case PIX_FMT_UYYVYY411:
bb270c08
DB
824 bits = 12;
825 break;
7e7e5940
FB
826 default:
827 bits = pf->depth * pf->nb_channels;
828 break;
829 }
22ed53e5
VS
830 return (width * bits + 7) >> 3;
831 break;
832 case FF_PIXEL_PLANAR:
2839c56e
SS
833 if ((pix_fmt != PIX_FMT_NV12 && pix_fmt != PIX_FMT_NV21) &&
834 (plane == 1 || plane == 2))
14b903f3 835 width= -((-width)>>desc->log2_chroma_w);
22ed53e5
VS
836
837 return (width * pf->depth + 7) >> 3;
838 break;
839 case FF_PIXEL_PALETTE:
840 if (plane == 0)
841 return width;
7e7e5940 842 break;
22ed53e5
VS
843 }
844
845 return -1;
846}
847
848void av_picture_copy(AVPicture *dst, const AVPicture *src,
a61ec8e7 849 enum PixelFormat pix_fmt, int width, int height)
22ed53e5
VS
850{
851 int i;
852 const PixFmtInfo *pf = &pix_fmt_info[pix_fmt];
14b903f3 853 const AVPixFmtDescriptor *desc = &av_pix_fmt_descriptors[pix_fmt];
22ed53e5 854
22ed53e5
VS
855 switch(pf->pixel_type) {
856 case FF_PIXEL_PACKED:
7e7e5940
FB
857 case FF_PIXEL_PLANAR:
858 for(i = 0; i < pf->nb_channels; i++) {
bc48bb08 859 int h;
6dd36490 860 int bwidth = ff_get_plane_bytewidth(pix_fmt, width, i);
7e7e5940
FB
861 h = height;
862 if (i == 1 || i == 2) {
14b903f3 863 h= -((-height)>>desc->log2_chroma_h);
7e7e5940 864 }
54009d42 865 ff_img_copy_plane(dst->data[i], dst->linesize[i],
7e7e5940
FB
866 src->data[i], src->linesize[i],
867 bwidth, h);
868 }
869 break;
870 case FF_PIXEL_PALETTE:
54009d42 871 ff_img_copy_plane(dst->data[0], dst->linesize[0],
7e7e5940
FB
872 src->data[0], src->linesize[0],
873 width, height);
874 /* copy the palette */
51ae2142 875 memcpy(dst->data[1], src->data[1], 4*256);
7e7e5940
FB
876 break;
877 }
878}
2a877875 879
85c242d8 880/* 2x2 -> 1x1 */
54009d42 881void ff_shrink22(uint8_t *dst, int dst_wrap,
e352ff08 882 const uint8_t *src, int src_wrap,
85c242d8
FB
883 int width, int height)
884{
885 int w;
e352ff08
FB
886 const uint8_t *s1, *s2;
887 uint8_t *d;
85c242d8
FB
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) {
0a9ad8d1
FB
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;
85c242d8
FB
898 s1 += 8;
899 s2 += 8;
900 d += 4;
901 }
902 for(;w > 0; w--) {
0a9ad8d1 903 d[0] = (s1[0] + s1[1] + s2[0] + s2[1] + 2) >> 2;
85c242d8
FB
904 s1 += 2;
905 s2 += 2;
906 d++;
907 }
908 src += 2 * src_wrap;
909 dst += dst_wrap;
910 }
911}
912
e352ff08 913/* 4x4 -> 1x1 */
54009d42 914void ff_shrink44(uint8_t *dst, int dst_wrap,
e352ff08 915 const uint8_t *src, int src_wrap,
6742d95d
FR
916 int width, int height)
917{
918 int w;
e352ff08
FB
919 const uint8_t *s1, *s2, *s3, *s4;
920 uint8_t *d;
6742d95d
FR
921
922 for(;height > 0; height--) {
923 s1 = src;
e352ff08
FB
924 s2 = s1 + src_wrap;
925 s3 = s2 + src_wrap;
926 s4 = s3 + src_wrap;
6742d95d 927 d = dst;
e352ff08
FB
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;
6742d95d
FR
937 d++;
938 }
e352ff08
FB
939 src += 4 * src_wrap;
940 dst += dst_wrap;
941 }
942}
943
54009d42
MN
944/* 8x8 -> 1x1 */
945void 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
524c6b63 966
75917b88 967int avpicture_alloc(AVPicture *picture,
a61ec8e7 968 enum PixelFormat pix_fmt, int width, int height)
524c6b63 969{
2d5545c3 970 int size;
524c6b63
FB
971 void *ptr;
972
899a8fa1 973 size = avpicture_fill(picture, NULL, pix_fmt, width, height);
0ecca7a4
MN
974 if(size<0)
975 goto fail;
524c6b63
FB
976 ptr = av_malloc(size);
977 if (!ptr)
978 goto fail;
979 avpicture_fill(picture, ptr, pix_fmt, width, height);
6337178b
MN
980 if(picture->data[1] && !picture->data[2])
981 ff_set_systematic_pal((uint32_t*)picture->data[1], pix_fmt);
982
524c6b63
FB
983 return 0;
984 fail:
985 memset(picture, 0, sizeof(AVPicture));
986 return -1;
987}
988
75917b88 989void avpicture_free(AVPicture *picture)
524c6b63 990{
8e1e6f31 991 av_free(picture->data[0]);
524c6b63
FB
992}
993
c50c0bc8 994/* return true if yuv planar */
62a05b5b 995static inline int is_yuv_planar(const PixFmtInfo *ps)
c50c0bc8
FB
996{
997 return (ps->color_type == FF_COLOR_YUV ||
115329f1 998 ps->color_type == FF_COLOR_YUV_JPEG) &&
7e7e5940 999 ps->pixel_type == FF_PIXEL_PLANAR;
c50c0bc8
FB
1000}
1001
636d6a4a 1002int av_picture_crop(AVPicture *dst, const AVPicture *src,
4a30fff6 1003 enum PixelFormat pix_fmt, int top_band, int left_band)
f2651e7a
BC
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
14b903f3
SS
1011 y_shift = av_pix_fmt_descriptors[pix_fmt].log2_chroma_h;
1012 x_shift = av_pix_fmt_descriptors[pix_fmt].log2_chroma_w;
f2651e7a
BC
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
636d6a4a 1024int av_picture_pad(AVPicture *dst, const AVPicture *src, int height, int width,
a61ec8e7 1025 enum PixelFormat pix_fmt, int padtop, int padbottom, int padleft, int padright,
6845801f 1026 int *color)
5341c209 1027{
79acfb0e 1028 uint8_t *optr;
5341c209
LA
1029 int y_shift;
1030 int x_shift;
1031 int yheight;
1032 int i, y;
1033
6845801f
LB
1034 if (pix_fmt < 0 || pix_fmt >= PIX_FMT_NB ||
1035 !is_yuv_planar(&pix_fmt_info[pix_fmt])) return -1;
5341c209
LA
1036
1037 for (i = 0; i < 3; i++) {
14b903f3
SS
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;
5341c209
LA
1040
1041 if (padtop || padleft) {
6845801f
LB
1042 memset(dst->data[i], color[i],
1043 dst->linesize[i] * (padtop >> y_shift) + (padleft >> x_shift));
5341c209
LA
1044 }
1045
79acfb0e
LB
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];
5341c209 1053 }
79acfb0e
LB
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);
1be97a21 1060 memcpy(optr, iptr, (width - padleft - padright) >> x_shift);
79acfb0e 1061 iptr += src->linesize[i];
6845801f
LB
1062 optr = dst->data[i] + dst->linesize[i] * (padtop >> y_shift) +
1063 (dst->linesize[i] - (padright >> x_shift));
5341c209
LA
1064 yheight = (height - 1 - (padtop + padbottom)) >> y_shift;
1065 for (y = 0; y < yheight; y++) {
1066 memset(optr, color[i], (padleft + padright) >> x_shift);
79acfb0e 1067 memcpy(optr + ((padleft + padright) >> x_shift), iptr,
1be97a21 1068 (width - padleft - padright) >> x_shift);
79acfb0e 1069 iptr += src->linesize[i];
5341c209
LA
1070 optr += dst->linesize[i];
1071 }
1072 }
1073
1074 if (padbottom || padright) {
6845801f
LB
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));
5341c209
LA
1079 }
1080 }
1081 return 0;
1082}
1083
0469baf1 1084/* NOTE: we scan all the pixels to have an exact information */
da64ecc3 1085static int get_alpha_info_pal8(const AVPicture *src, int width, int height)
0469baf1
FB
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];
115329f1 1091
0469baf1
FB
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
da64ecc3 1110int img_get_alpha_info(const AVPicture *src,
a61ec8e7 1111 enum PixelFormat pix_fmt, int width, int height)
0469baf1 1112{
62a05b5b 1113 const PixFmtInfo *pf = &pix_fmt_info[pix_fmt];
0469baf1
FB
1114 int ret;
1115
0469baf1
FB
1116 /* no alpha can be represented in format */
1117 if (!pf->is_alpha)
1118 return 0;
1119 switch(pix_fmt) {
0469baf1
FB
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}
5981f4e6 1130
0913a92a 1131#if !(HAVE_MMX && HAVE_YASM)
85c242d8 1132/* filter parameters: [-1 4 2 4 -1] // 8 */
de4bc44a 1133static void deinterlace_line_c(uint8_t *dst,
bb270c08
DB
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)
85c242d8 1138{
55fde95e 1139 uint8_t *cm = ff_cropTbl + MAX_NEG_CROP;
85c242d8 1140 int sum;
85c242d8
FB
1141
1142 for(;size > 0;size--) {
5981f4e6
F
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];
85c242d8 1148 dst[0] = cm[(sum + 4) >> 3];
5981f4e6
F
1149 lum_m4++;
1150 lum_m3++;
1151 lum_m2++;
1152 lum_m1++;
1153 lum++;
85c242d8 1154 dst++;
85c242d8 1155 }
5981f4e6 1156}
de4bc44a
VS
1157
1158static 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)
5981f4e6 1161{
55fde95e 1162 uint8_t *cm = ff_cropTbl + MAX_NEG_CROP;
5981f4e6
F
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 }
85c242d8 1179}
de4bc44a 1180#endif
85c242d8
FB
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. */
0c1a9eda 1185static void deinterlace_bottom_field(uint8_t *dst, int dst_wrap,
da64ecc3 1186 const uint8_t *src1, int src_wrap,
5981f4e6 1187 int width, int height)
85c242d8 1188{
da64ecc3 1189 const uint8_t *src_m2, *src_m1, *src_0, *src_p1, *src_p2;
5981f4e6
F
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);
85c242d8 1199 dst += dst_wrap;
5981f4e6
F
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;
85c242d8 1206 dst += dst_wrap;
85c242d8 1207 }
5981f4e6
F
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
0c1a9eda 1214static void deinterlace_bottom_field_inplace(uint8_t *src1, int src_wrap,
bb270c08 1215 int width, int height)
5981f4e6 1216{
0c1a9eda 1217 uint8_t *src_m1, *src_0, *src_p1, *src_p2;
5981f4e6 1218 int y;
0c1a9eda
ZK
1219 uint8_t *buf;
1220 buf = (uint8_t*)av_malloc(width);
5981f4e6
F
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);
6000abfa 1236 av_free(buf);
85c242d8
FB
1237}
1238
da64ecc3 1239int avpicture_deinterlace(AVPicture *dst, const AVPicture *src,
a61ec8e7 1240 enum PixelFormat pix_fmt, int width, int height)
de6d9b64 1241{
85c242d8
FB
1242 int i;
1243
1244 if (pix_fmt != PIX_FMT_YUV420P &&
1245 pix_fmt != PIX_FMT_YUV422P &&
47017dd8 1246 pix_fmt != PIX_FMT_YUV444P &&
2a7feb18
AG
1247 pix_fmt != PIX_FMT_YUV411P &&
1248 pix_fmt != PIX_FMT_GRAY8)
85c242d8 1249 return -1;
5981f4e6 1250 if ((width & 3) != 0 || (height & 3) != 0)
85c242d8 1251 return -1;
5981f4e6 1252
85c242d8
FB
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;
47017dd8
RS
1263 case PIX_FMT_YUV411P:
1264 width >>= 2;
1265 break;
85c242d8
FB
1266 default:
1267 break;
1268 }
2a7feb18
AG
1269 if (pix_fmt == PIX_FMT_GRAY8) {
1270 break;
1271 }
85c242d8 1272 }
5981f4e6 1273 if (src == dst) {
da64ecc3 1274 deinterlace_bottom_field_inplace(dst->data[i], dst->linesize[i],
85c242d8 1275 width, height);
5981f4e6
F
1276 } else {
1277 deinterlace_bottom_field(dst->data[i],dst->linesize[i],
1278 src->data[i], src->linesize[i],
1279 width, height);
1280 }
de6d9b64 1281 }
55ffe9df 1282 emms_c();
85c242d8 1283 return 0;
de6d9b64 1284}
cd4af68a 1285