set keyframe flag at a more central place instead of in every demuxer for containers...
[libav.git] / libavcodec / imgconvert.c
CommitLineData
de6d9b64
FB
1/*
2 * Misc image convertion routines
524c6b63 3 * Copyright (c) 2001, 2002, 2003 Fabrice Bellard.
de6d9b64 4 *
ff4ec49e
FB
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2 of the License, or (at your option) any later version.
de6d9b64 9 *
ff4ec49e 10 * This library is distributed in the hope that it will be useful,
de6d9b64 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
ff4ec49e
FB
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
de6d9b64 14 *
ff4ec49e
FB
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this library; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
de6d9b64 18 */
983e3246
MN
19
20/**
1ab3d669 21 * @file imgconvert.c
983e3246
MN
22 * Misc image convertion routines.
23 */
24
c50c0bc8
FB
25/* TODO:
26 * - write 'ffimg' program to test all the image related stuff
27 * - move all api to slice based system
28 * - integrate deinterlacing, postprocessing and scaling in the conversion process
29 */
983e3246 30
de6d9b64 31#include "avcodec.h"
85c242d8 32#include "dsputil.h"
de6d9b64 33
54329dd5
NK
34#ifdef USE_FASTMEMCPY
35#include "fastmemcpy.h"
36#endif
5981f4e6
F
37
38#ifdef HAVE_MMX
39#include "i386/mmx.h"
40#endif
524c6b63 41
7e7e5940
FB
42#define xglue(x, y) x ## y
43#define glue(x, y) xglue(x, y)
44
b6147995
FB
45#define FF_COLOR_RGB 0 /* RGB color space */
46#define FF_COLOR_GRAY 1 /* gray color space */
47#define FF_COLOR_YUV 2 /* YUV color space. 16 <= Y <= 235, 16 <= U, V <= 240 */
48#define FF_COLOR_YUV_JPEG 3 /* YUV color space. 0 <= Y <= 255, 0 <= U, V <= 255 */
49
7e7e5940
FB
50#define FF_PIXEL_PLANAR 0 /* each channel has one component in AVPicture */
51#define FF_PIXEL_PACKED 1 /* only one components containing all the channels */
52#define FF_PIXEL_PALETTE 2 /* one components containing indexes for a palette */
53
524c6b63
FB
54typedef struct PixFmtInfo {
55 const char *name;
7e7e5940
FB
56 uint8_t nb_channels; /* number of channels (including alpha) */
57 uint8_t color_type; /* color type (see FF_COLOR_xxx constants) */
58 uint8_t pixel_type; /* pixel storage type (see FF_PIXEL_xxx constants) */
0c1a9eda 59 uint8_t is_alpha : 1; /* true if alpha can be specified */
7e7e5940
FB
60 uint8_t x_chroma_shift; /* X chroma subsampling factor is 2 ^ shift */
61 uint8_t y_chroma_shift; /* Y chroma subsampling factor is 2 ^ shift */
62 uint8_t depth; /* bit depth of the color components */
524c6b63
FB
63} PixFmtInfo;
64
65/* this table gives more information about formats */
66static PixFmtInfo pix_fmt_info[PIX_FMT_NB] = {
67 /* YUV formats */
68 [PIX_FMT_YUV420P] = {
ef9f7306 69 .name = "yuv420p",
7e7e5940 70 .nb_channels = 3,
b6147995 71 .color_type = FF_COLOR_YUV,
7e7e5940 72 .pixel_type = FF_PIXEL_PLANAR,
b6147995 73 .depth = 8,
ef9f7306 74 .x_chroma_shift = 1, .y_chroma_shift = 1,
524c6b63
FB
75 },
76 [PIX_FMT_YUV422P] = {
ef9f7306 77 .name = "yuv422p",
7e7e5940 78 .nb_channels = 3,
b6147995 79 .color_type = FF_COLOR_YUV,
7e7e5940 80 .pixel_type = FF_PIXEL_PLANAR,
b6147995 81 .depth = 8,
ef9f7306 82 .x_chroma_shift = 1, .y_chroma_shift = 0,
524c6b63
FB
83 },
84 [PIX_FMT_YUV444P] = {
ef9f7306 85 .name = "yuv444p",
7e7e5940 86 .nb_channels = 3,
b6147995 87 .color_type = FF_COLOR_YUV,
7e7e5940 88 .pixel_type = FF_PIXEL_PLANAR,
b6147995 89 .depth = 8,
ef9f7306 90 .x_chroma_shift = 0, .y_chroma_shift = 0,
524c6b63
FB
91 },
92 [PIX_FMT_YUV422] = {
ef9f7306 93 .name = "yuv422",
7e7e5940 94 .nb_channels = 1,
b6147995 95 .color_type = FF_COLOR_YUV,
7e7e5940 96 .pixel_type = FF_PIXEL_PACKED,
b6147995 97 .depth = 8,
ef9f7306 98 .x_chroma_shift = 1, .y_chroma_shift = 0,
524c6b63 99 },
ebb177dd
TK
100 [PIX_FMT_UYVY422] = {
101 .name = "uyvy422",
102 .nb_channels = 1,
103 .color_type = FF_COLOR_YUV,
104 .pixel_type = FF_PIXEL_PACKED,
105 .depth = 8,
106 .x_chroma_shift = 1, .y_chroma_shift = 0,
107 },
524c6b63 108 [PIX_FMT_YUV410P] = {
ef9f7306 109 .name = "yuv410p",
7e7e5940 110 .nb_channels = 3,
b6147995 111 .color_type = FF_COLOR_YUV,
7e7e5940 112 .pixel_type = FF_PIXEL_PLANAR,
b6147995 113 .depth = 8,
ef9f7306 114 .x_chroma_shift = 2, .y_chroma_shift = 2,
524c6b63
FB
115 },
116 [PIX_FMT_YUV411P] = {
ef9f7306 117 .name = "yuv411p",
7e7e5940 118 .nb_channels = 3,
b6147995 119 .color_type = FF_COLOR_YUV,
7e7e5940 120 .pixel_type = FF_PIXEL_PLANAR,
b6147995 121 .depth = 8,
ef9f7306 122 .x_chroma_shift = 2, .y_chroma_shift = 0,
524c6b63
FB
123 },
124
b6147995
FB
125 /* JPEG YUV */
126 [PIX_FMT_YUVJ420P] = {
127 .name = "yuvj420p",
7e7e5940 128 .nb_channels = 3,
b6147995 129 .color_type = FF_COLOR_YUV_JPEG,
7e7e5940 130 .pixel_type = FF_PIXEL_PLANAR,
b6147995
FB
131 .depth = 8,
132 .x_chroma_shift = 1, .y_chroma_shift = 1,
133 },
134 [PIX_FMT_YUVJ422P] = {
135 .name = "yuvj422p",
7e7e5940 136 .nb_channels = 3,
b6147995 137 .color_type = FF_COLOR_YUV_JPEG,
7e7e5940 138 .pixel_type = FF_PIXEL_PLANAR,
b6147995
FB
139 .depth = 8,
140 .x_chroma_shift = 1, .y_chroma_shift = 0,
141 },
142 [PIX_FMT_YUVJ444P] = {
143 .name = "yuvj444p",
7e7e5940 144 .nb_channels = 3,
b6147995 145 .color_type = FF_COLOR_YUV_JPEG,
7e7e5940 146 .pixel_type = FF_PIXEL_PLANAR,
b6147995
FB
147 .depth = 8,
148 .x_chroma_shift = 0, .y_chroma_shift = 0,
149 },
150
524c6b63
FB
151 /* RGB formats */
152 [PIX_FMT_RGB24] = {
ef9f7306 153 .name = "rgb24",
7e7e5940 154 .nb_channels = 3,
b6147995 155 .color_type = FF_COLOR_RGB,
7e7e5940 156 .pixel_type = FF_PIXEL_PACKED,
b6147995 157 .depth = 8,
2cbb7820 158 .x_chroma_shift = 0, .y_chroma_shift = 0,
524c6b63
FB
159 },
160 [PIX_FMT_BGR24] = {
ef9f7306 161 .name = "bgr24",
7e7e5940 162 .nb_channels = 3,
b6147995 163 .color_type = FF_COLOR_RGB,
7e7e5940 164 .pixel_type = FF_PIXEL_PACKED,
b6147995 165 .depth = 8,
2cbb7820 166 .x_chroma_shift = 0, .y_chroma_shift = 0,
524c6b63
FB
167 },
168 [PIX_FMT_RGBA32] = {
ef9f7306 169 .name = "rgba32",
7e7e5940 170 .nb_channels = 4, .is_alpha = 1,
b6147995 171 .color_type = FF_COLOR_RGB,
7e7e5940 172 .pixel_type = FF_PIXEL_PACKED,
b6147995 173 .depth = 8,
2cbb7820 174 .x_chroma_shift = 0, .y_chroma_shift = 0,
524c6b63
FB
175 },
176 [PIX_FMT_RGB565] = {
ef9f7306 177 .name = "rgb565",
7e7e5940 178 .nb_channels = 3,
b6147995 179 .color_type = FF_COLOR_RGB,
7e7e5940 180 .pixel_type = FF_PIXEL_PACKED,
b6147995 181 .depth = 5,
2cbb7820 182 .x_chroma_shift = 0, .y_chroma_shift = 0,
524c6b63
FB
183 },
184 [PIX_FMT_RGB555] = {
ef9f7306 185 .name = "rgb555",
7e7e5940 186 .nb_channels = 4, .is_alpha = 1,
b6147995 187 .color_type = FF_COLOR_RGB,
7e7e5940 188 .pixel_type = FF_PIXEL_PACKED,
b6147995 189 .depth = 5,
2cbb7820 190 .x_chroma_shift = 0, .y_chroma_shift = 0,
524c6b63
FB
191 },
192
193 /* gray / mono formats */
194 [PIX_FMT_GRAY8] = {
ef9f7306 195 .name = "gray",
7e7e5940 196 .nb_channels = 1,
b6147995 197 .color_type = FF_COLOR_GRAY,
7e7e5940 198 .pixel_type = FF_PIXEL_PLANAR,
b6147995 199 .depth = 8,
524c6b63
FB
200 },
201 [PIX_FMT_MONOWHITE] = {
ef9f7306 202 .name = "monow",
7e7e5940 203 .nb_channels = 1,
b6147995 204 .color_type = FF_COLOR_GRAY,
7e7e5940 205 .pixel_type = FF_PIXEL_PLANAR,
b6147995 206 .depth = 1,
524c6b63
FB
207 },
208 [PIX_FMT_MONOBLACK] = {
ef9f7306 209 .name = "monob",
7e7e5940 210 .nb_channels = 1,
b6147995 211 .color_type = FF_COLOR_GRAY,
7e7e5940 212 .pixel_type = FF_PIXEL_PLANAR,
b6147995 213 .depth = 1,
524c6b63 214 },
7e6d70d0
FB
215
216 /* paletted formats */
217 [PIX_FMT_PAL8] = {
218 .name = "pal8",
7e7e5940 219 .nb_channels = 4, .is_alpha = 1,
b6147995 220 .color_type = FF_COLOR_RGB,
7e7e5940 221 .pixel_type = FF_PIXEL_PALETTE,
b6147995 222 .depth = 8,
7e6d70d0 223 },
eab895aa
TK
224 [PIX_FMT_XVMC_MPEG2_MC] = {
225 .name = "xvmcmc",
226 },
227 [PIX_FMT_XVMC_MPEG2_IDCT] = {
228 .name = "xvmcidct",
229 },
524c6b63
FB
230};
231
232void avcodec_get_chroma_sub_sample(int pix_fmt, int *h_shift, int *v_shift)
233{
b6147995
FB
234 *h_shift = pix_fmt_info[pix_fmt].x_chroma_shift;
235 *v_shift = pix_fmt_info[pix_fmt].y_chroma_shift;
524c6b63
FB
236}
237
238const char *avcodec_get_pix_fmt_name(int pix_fmt)
239{
240 if (pix_fmt < 0 || pix_fmt >= PIX_FMT_NB)
241 return "???";
242 else
243 return pix_fmt_info[pix_fmt].name;
244}
245
63167088
RS
246enum PixelFormat avcodec_get_pix_fmt(const char* name)
247{
248 int i;
249
250 for (i=0; i < PIX_FMT_NB; i++)
251 if (!strcmp(pix_fmt_info[i].name, name))
252 break;
253 return i;
254}
255
2a877875 256/* Picture field are filled with 'ptr' addresses. Also return size */
0c1a9eda 257int avpicture_fill(AVPicture *picture, uint8_t *ptr,
da64ecc3 258 int pix_fmt, int width, int height)
2a877875 259{
4c7e8619
FB
260 int size, w2, h2, size2;
261 PixFmtInfo *pinfo;
262
263 pinfo = &pix_fmt_info[pix_fmt];
2a877875
FB
264 size = width * height;
265 switch(pix_fmt) {
266 case PIX_FMT_YUV420P:
4c7e8619
FB
267 case PIX_FMT_YUV422P:
268 case PIX_FMT_YUV444P:
269 case PIX_FMT_YUV410P:
270 case PIX_FMT_YUV411P:
c50c0bc8
FB
271 case PIX_FMT_YUVJ420P:
272 case PIX_FMT_YUVJ422P:
273 case PIX_FMT_YUVJ444P:
4c7e8619
FB
274 w2 = (width + (1 << pinfo->x_chroma_shift) - 1) >> pinfo->x_chroma_shift;
275 h2 = (height + (1 << pinfo->y_chroma_shift) - 1) >> pinfo->y_chroma_shift;
276 size2 = w2 * h2;
2a877875
FB
277 picture->data[0] = ptr;
278 picture->data[1] = picture->data[0] + size;
4c7e8619 279 picture->data[2] = picture->data[1] + size2;
2a877875 280 picture->linesize[0] = width;
4c7e8619
FB
281 picture->linesize[1] = w2;
282 picture->linesize[2] = w2;
283 return size + 2 * size2;
2a877875
FB
284 case PIX_FMT_RGB24:
285 case PIX_FMT_BGR24:
286 picture->data[0] = ptr;
287 picture->data[1] = NULL;
288 picture->data[2] = NULL;
289 picture->linesize[0] = width * 3;
290 return size * 3;
2a877875
FB
291 case PIX_FMT_RGBA32:
292 picture->data[0] = ptr;
293 picture->data[1] = NULL;
294 picture->data[2] = NULL;
295 picture->linesize[0] = width * 4;
296 return size * 4;
2a877875
FB
297 case PIX_FMT_RGB555:
298 case PIX_FMT_RGB565:
299 case PIX_FMT_YUV422:
300 picture->data[0] = ptr;
301 picture->data[1] = NULL;
302 picture->data[2] = NULL;
303 picture->linesize[0] = width * 2;
304 return size * 2;
ebb177dd
TK
305 case PIX_FMT_UYVY422:
306 picture->data[0] = ptr;
307 picture->data[1] = NULL;
308 picture->data[2] = NULL;
309 picture->linesize[0] = width * 2;
310 return size * 2;
2a877875
FB
311 case PIX_FMT_GRAY8:
312 picture->data[0] = ptr;
313 picture->data[1] = NULL;
314 picture->data[2] = NULL;
315 picture->linesize[0] = width;
316 return size;
317 case PIX_FMT_MONOWHITE:
318 case PIX_FMT_MONOBLACK:
319 picture->data[0] = ptr;
320 picture->data[1] = NULL;
321 picture->data[2] = NULL;
322 picture->linesize[0] = (width + 7) >> 3;
323 return picture->linesize[0] * height;
7e6d70d0
FB
324 case PIX_FMT_PAL8:
325 size2 = (size + 3) & ~3;
326 picture->data[0] = ptr;
327 picture->data[1] = ptr + size2; /* palette is stored here as 256 32 bit words */
328 picture->data[2] = NULL;
329 picture->linesize[0] = width;
330 picture->linesize[1] = 4;
331 return size2 + 256 * 4;
2a877875
FB
332 default:
333 picture->data[0] = NULL;
334 picture->data[1] = NULL;
335 picture->data[2] = NULL;
7e6d70d0 336 picture->data[3] = NULL;
2a877875
FB
337 return -1;
338 }
339}
340
da64ecc3 341int avpicture_layout(const AVPicture* src, int pix_fmt, int width, int height,
63167088
RS
342 unsigned char *dest, int dest_size)
343{
344 PixFmtInfo* pf = &pix_fmt_info[pix_fmt];
345 int i, j, w, h, data_planes;
da64ecc3 346 const unsigned char* s;
63167088
RS
347 int size = avpicture_get_size(pix_fmt, width, height);
348
349 if (size > dest_size)
350 return -1;
351
affd55a1 352 if (pf->pixel_type == FF_PIXEL_PACKED || pf->pixel_type == FF_PIXEL_PALETTE) {
ebb177dd
TK
353 if (pix_fmt == PIX_FMT_YUV422 ||
354 pix_fmt == PIX_FMT_UYVY422 ||
355 pix_fmt == PIX_FMT_RGB565 ||
356 pix_fmt == PIX_FMT_RGB555)
357 w = width * 2;
affd55a1
RS
358 else if (pix_fmt == PIX_FMT_PAL8)
359 w = width;
63167088
RS
360 else
361 w = width * (pf->depth * pf->nb_channels / 8);
affd55a1 362
63167088
RS
363 data_planes = 1;
364 h = height;
365 } else {
366 data_planes = pf->nb_channels;
367 w = width;
368 h = height;
369 }
370
371 for (i=0; i<data_planes; i++) {
372 if (i == 1) {
373 w = width >> pf->x_chroma_shift;
374 h = height >> pf->y_chroma_shift;
375 }
376 s = src->data[i];
377 for(j=0; j<h; j++) {
378 memcpy(dest, s, w);
379 dest += w;
380 s += src->linesize[i];
381 }
382 }
affd55a1
RS
383
384 if (pf->pixel_type == FF_PIXEL_PALETTE)
385 memcpy((unsigned char *)(((size_t)dest + 3) & ~3), src->data[1], 256 * 4);
386
63167088
RS
387 return size;
388}
389
2a877875
FB
390int avpicture_get_size(int pix_fmt, int width, int height)
391{
392 AVPicture dummy_pict;
393 return avpicture_fill(&dummy_pict, NULL, pix_fmt, width, height);
394}
395
b6147995
FB
396/**
397 * compute the loss when converting from a pixel format to another
398 */
399int avcodec_get_pix_fmt_loss(int dst_pix_fmt, int src_pix_fmt,
400 int has_alpha)
401{
402 const PixFmtInfo *pf, *ps;
403 int loss;
404
405 ps = &pix_fmt_info[src_pix_fmt];
406 pf = &pix_fmt_info[dst_pix_fmt];
407
408 /* compute loss */
409 loss = 0;
410 pf = &pix_fmt_info[dst_pix_fmt];
0a9ad8d1
FB
411 if (pf->depth < ps->depth ||
412 (dst_pix_fmt == PIX_FMT_RGB555 && src_pix_fmt == PIX_FMT_RGB565))
b6147995 413 loss |= FF_LOSS_DEPTH;
0a9ad8d1
FB
414 if (pf->x_chroma_shift > ps->x_chroma_shift ||
415 pf->y_chroma_shift > ps->y_chroma_shift)
b6147995
FB
416 loss |= FF_LOSS_RESOLUTION;
417 switch(pf->color_type) {
418 case FF_COLOR_RGB:
419 if (ps->color_type != FF_COLOR_RGB &&
420 ps->color_type != FF_COLOR_GRAY)
421 loss |= FF_LOSS_COLORSPACE;
422 break;
423 case FF_COLOR_GRAY:
424 if (ps->color_type != FF_COLOR_GRAY)
425 loss |= FF_LOSS_COLORSPACE;
426 break;
427 case FF_COLOR_YUV:
428 if (ps->color_type != FF_COLOR_YUV)
429 loss |= FF_LOSS_COLORSPACE;
430 break;
431 case FF_COLOR_YUV_JPEG:
432 if (ps->color_type != FF_COLOR_YUV_JPEG &&
0a9ad8d1
FB
433 ps->color_type != FF_COLOR_YUV &&
434 ps->color_type != FF_COLOR_GRAY)
b6147995
FB
435 loss |= FF_LOSS_COLORSPACE;
436 break;
437 default:
438 /* fail safe test */
439 if (ps->color_type != pf->color_type)
440 loss |= FF_LOSS_COLORSPACE;
441 break;
442 }
443 if (pf->color_type == FF_COLOR_GRAY &&
444 ps->color_type != FF_COLOR_GRAY)
445 loss |= FF_LOSS_CHROMA;
446 if (!pf->is_alpha && (ps->is_alpha && has_alpha))
447 loss |= FF_LOSS_ALPHA;
7e7e5940
FB
448 if (pf->pixel_type == FF_PIXEL_PALETTE &&
449 (ps->pixel_type != FF_PIXEL_PALETTE && ps->color_type != FF_COLOR_GRAY))
b6147995
FB
450 loss |= FF_LOSS_COLORQUANT;
451 return loss;
452}
453
454static int avg_bits_per_pixel(int pix_fmt)
455{
456 int bits;
457 const PixFmtInfo *pf;
458
459 pf = &pix_fmt_info[pix_fmt];
7e7e5940
FB
460 switch(pf->pixel_type) {
461 case FF_PIXEL_PACKED:
b6147995 462 switch(pix_fmt) {
7e7e5940 463 case PIX_FMT_YUV422:
ebb177dd 464 case PIX_FMT_UYVY422:
b6147995
FB
465 case PIX_FMT_RGB565:
466 case PIX_FMT_RGB555:
467 bits = 16;
b6147995
FB
468 break;
469 default:
7e7e5940 470 bits = pf->depth * pf->nb_channels;
b6147995
FB
471 break;
472 }
7e7e5940
FB
473 break;
474 case FF_PIXEL_PLANAR:
475 if (pf->x_chroma_shift == 0 && pf->y_chroma_shift == 0) {
476 bits = pf->depth * pf->nb_channels;
477 } else {
478 bits = pf->depth + ((2 * pf->depth) >>
479 (pf->x_chroma_shift + pf->y_chroma_shift));
480 }
481 break;
482 case FF_PIXEL_PALETTE:
483 bits = 8;
484 break;
485 default:
486 bits = -1;
487 break;
b6147995
FB
488 }
489 return bits;
490}
491
492static int avcodec_find_best_pix_fmt1(int pix_fmt_mask,
493 int src_pix_fmt,
494 int has_alpha,
495 int loss_mask)
496{
497 int dist, i, loss, min_dist, dst_pix_fmt;
498
499 /* find exact color match with smallest size */
500 dst_pix_fmt = -1;
501 min_dist = 0x7fffffff;
502 for(i = 0;i < PIX_FMT_NB; i++) {
503 if (pix_fmt_mask & (1 << i)) {
504 loss = avcodec_get_pix_fmt_loss(i, src_pix_fmt, has_alpha) & loss_mask;
505 if (loss == 0) {
506 dist = avg_bits_per_pixel(i);
507 if (dist < min_dist) {
508 min_dist = dist;
509 dst_pix_fmt = i;
510 }
511 }
512 }
513 }
514 return dst_pix_fmt;
515}
516
517/**
518 * find best pixel format to convert to. Return -1 if none found
519 */
520int avcodec_find_best_pix_fmt(int pix_fmt_mask, int src_pix_fmt,
521 int has_alpha, int *loss_ptr)
522{
523 int dst_pix_fmt, loss_mask, i;
524 static const int loss_mask_order[] = {
525 ~0, /* no loss first */
526 ~FF_LOSS_ALPHA,
527 ~FF_LOSS_RESOLUTION,
528 ~(FF_LOSS_COLORSPACE | FF_LOSS_RESOLUTION),
529 ~FF_LOSS_COLORQUANT,
530 ~FF_LOSS_DEPTH,
531 0,
532 };
533
534 /* try with successive loss */
535 i = 0;
536 for(;;) {
537 loss_mask = loss_mask_order[i++];
538 dst_pix_fmt = avcodec_find_best_pix_fmt1(pix_fmt_mask, src_pix_fmt,
539 has_alpha, loss_mask);
540 if (dst_pix_fmt >= 0)
541 goto found;
542 if (loss_mask == 0)
543 break;
544 }
545 return -1;
546 found:
547 if (loss_ptr)
548 *loss_ptr = avcodec_get_pix_fmt_loss(dst_pix_fmt, src_pix_fmt, has_alpha);
549 return dst_pix_fmt;
550}
551
7e7e5940 552static void img_copy_plane(uint8_t *dst, int dst_wrap,
e352ff08
FB
553 const uint8_t *src, int src_wrap,
554 int width, int height)
7e7e5940
FB
555{
556 for(;height > 0; height--) {
557 memcpy(dst, src, width);
558 dst += dst_wrap;
559 src += src_wrap;
560 }
561}
562
0469baf1
FB
563/**
564 * Copy image 'src' to 'dst'.
565 */
da64ecc3 566void img_copy(AVPicture *dst, const AVPicture *src,
7e7e5940
FB
567 int pix_fmt, int width, int height)
568{
569 int bwidth, bits, i;
570 PixFmtInfo *pf = &pix_fmt_info[pix_fmt];
571
572 pf = &pix_fmt_info[pix_fmt];
573 switch(pf->pixel_type) {
574 case FF_PIXEL_PACKED:
575 switch(pix_fmt) {
576 case PIX_FMT_YUV422:
ebb177dd 577 case PIX_FMT_UYVY422:
7e7e5940
FB
578 case PIX_FMT_RGB565:
579 case PIX_FMT_RGB555:
580 bits = 16;
581 break;
582 default:
583 bits = pf->depth * pf->nb_channels;
584 break;
585 }
586 bwidth = (width * bits + 7) >> 3;
587 img_copy_plane(dst->data[0], dst->linesize[0],
588 src->data[0], src->linesize[0],
589 bwidth, height);
590 break;
591 case FF_PIXEL_PLANAR:
592 for(i = 0; i < pf->nb_channels; i++) {
593 int w, h;
594 w = width;
595 h = height;
596 if (i == 1 || i == 2) {
597 w >>= pf->x_chroma_shift;
598 h >>= pf->y_chroma_shift;
599 }
600 bwidth = (w * pf->depth + 7) >> 3;
601 img_copy_plane(dst->data[i], dst->linesize[i],
602 src->data[i], src->linesize[i],
603 bwidth, h);
604 }
605 break;
606 case FF_PIXEL_PALETTE:
607 img_copy_plane(dst->data[0], dst->linesize[0],
608 src->data[0], src->linesize[0],
609 width, height);
610 /* copy the palette */
611 img_copy_plane(dst->data[1], dst->linesize[1],
612 src->data[1], src->linesize[1],
613 4, 256);
614 break;
615 }
616}
2a877875 617
de6d9b64
FB
618/* XXX: totally non optimized */
619
da64ecc3 620static void yuv422_to_yuv420p(AVPicture *dst, const AVPicture *src,
524c6b63 621 int width, int height)
de6d9b64 622{
c50c0bc8
FB
623 const uint8_t *p, *p1;
624 uint8_t *lum, *cr, *cb, *lum1, *cr1, *cb1;
d4f5d74a 625 int w;
524c6b63 626
c50c0bc8
FB
627 p1 = src->data[0];
628 lum1 = dst->data[0];
0a05e494
FB
629 cb1 = dst->data[1];
630 cr1 = dst->data[2];
c50c0bc8 631
d4f5d74a 632 for(;height >= 1; height -= 2) {
c50c0bc8
FB
633 p = p1;
634 lum = lum1;
635 cb = cb1;
636 cr = cr1;
d4f5d74a 637 for(w = width; w >= 2; w -= 2) {
e78df699
MN
638 lum[0] = p[0];
639 cb[0] = p[1];
640 lum[1] = p[2];
641 cr[0] = p[3];
de6d9b64
FB
642 p += 4;
643 lum += 2;
644 cb++;
645 cr++;
646 }
d4f5d74a 647 if (w) {
e78df699 648 lum[0] = p[0];
d4f5d74a
GM
649 cb[0] = p[1];
650 cr[0] = p[3];
651 cb++;
652 cr++;
de6d9b64 653 }
c50c0bc8
FB
654 p1 += src->linesize[0];
655 lum1 += dst->linesize[0];
d4f5d74a
GM
656 if (height>1) {
657 p = p1;
658 lum = lum1;
659 for(w = width; w >= 2; w -= 2) {
660 lum[0] = p[0];
661 lum[1] = p[2];
662 p += 4;
663 lum += 2;
664 }
665 if (w) {
666 lum[0] = p[0];
667 }
668 p1 += src->linesize[0];
669 lum1 += dst->linesize[0];
670 }
c50c0bc8
FB
671 cb1 += dst->linesize[1];
672 cr1 += dst->linesize[2];
673 }
674}
675
ebb177dd
TK
676static void uyvy422_to_yuv420p(AVPicture *dst, const AVPicture *src,
677 int width, int height)
678{
679 const uint8_t *p, *p1;
680 uint8_t *lum, *cr, *cb, *lum1, *cr1, *cb1;
681 int w;
682
683 p1 = src->data[0];
684
685 lum1 = dst->data[0];
686 cb1 = dst->data[1];
687 cr1 = dst->data[2];
688
689 for(;height >= 1; height -= 2) {
690 p = p1;
691 lum = lum1;
692 cb = cb1;
693 cr = cr1;
694 for(w = width; w >= 2; w -= 2) {
695 lum[0] = p[1];
696 cb[0] = p[0];
697 lum[1] = p[3];
698 cr[0] = p[2];
699 p += 4;
700 lum += 2;
701 cb++;
702 cr++;
703 }
704 if (w) {
705 lum[0] = p[1];
706 cb[0] = p[0];
707 cr[0] = p[2];
708 cb++;
709 cr++;
710 }
711 p1 += src->linesize[0];
712 lum1 += dst->linesize[0];
713 if (height>1) {
714 p = p1;
715 lum = lum1;
716 for(w = width; w >= 2; w -= 2) {
717 lum[0] = p[1];
718 lum[1] = p[3];
719 p += 4;
720 lum += 2;
721 }
722 if (w) {
723 lum[0] = p[1];
724 }
725 p1 += src->linesize[0];
726 lum1 += dst->linesize[0];
727 }
728 cb1 += dst->linesize[1];
729 cr1 += dst->linesize[2];
730 }
731}
732
733
734static void uyvy422_to_yuv422p(AVPicture *dst, const AVPicture *src,
735 int width, int height)
736{
737 const uint8_t *p, *p1;
738 uint8_t *lum, *cr, *cb, *lum1, *cr1, *cb1;
739 int w;
740
741 p1 = src->data[0];
742 lum1 = dst->data[0];
743 cb1 = dst->data[1];
744 cr1 = dst->data[2];
745 for(;height > 0; height--) {
746 p = p1;
747 lum = lum1;
748 cb = cb1;
749 cr = cr1;
750 for(w = width; w >= 2; w -= 2) {
751 lum[0] = p[1];
752 cb[0] = p[0];
753 lum[1] = p[3];
754 cr[0] = p[2];
755 p += 4;
756 lum += 2;
757 cb++;
758 cr++;
759 }
760 p1 += src->linesize[0];
761 lum1 += dst->linesize[0];
762 cb1 += dst->linesize[1];
763 cr1 += dst->linesize[2];
764 }
765}
766
767
da64ecc3 768static void yuv422_to_yuv422p(AVPicture *dst, const AVPicture *src,
c50c0bc8
FB
769 int width, int height)
770{
771 const uint8_t *p, *p1;
772 uint8_t *lum, *cr, *cb, *lum1, *cr1, *cb1;
773 int w;
774
775 p1 = src->data[0];
776 lum1 = dst->data[0];
0a05e494
FB
777 cb1 = dst->data[1];
778 cr1 = dst->data[2];
779 for(;height > 0; height--) {
c50c0bc8
FB
780 p = p1;
781 lum = lum1;
782 cb = cb1;
783 cr = cr1;
784 for(w = width; w >= 2; w -= 2) {
785 lum[0] = p[0];
786 cb[0] = p[1];
787 lum[1] = p[2];
788 cr[0] = p[3];
789 p += 4;
790 lum += 2;
791 cb++;
792 cr++;
793 }
794 p1 += src->linesize[0];
795 lum1 += dst->linesize[0];
796 cb1 += dst->linesize[1];
797 cr1 += dst->linesize[2];
de6d9b64
FB
798 }
799}
800
da64ecc3 801static void yuv422p_to_yuv422(AVPicture *dst, const AVPicture *src,
c50c0bc8
FB
802 int width, int height)
803{
804 uint8_t *p, *p1;
805 const uint8_t *lum, *cr, *cb, *lum1, *cr1, *cb1;
806 int w;
807
808 p1 = dst->data[0];
809 lum1 = src->data[0];
0a05e494
FB
810 cb1 = src->data[1];
811 cr1 = src->data[2];
812 for(;height > 0; height--) {
c50c0bc8
FB
813 p = p1;
814 lum = lum1;
815 cb = cb1;
816 cr = cr1;
817 for(w = width; w >= 2; w -= 2) {
818 p[0] = lum[0];
819 p[1] = cb[0];
820 p[2] = lum[1];
821 p[3] = cr[0];
822 p += 4;
823 lum += 2;
824 cb++;
825 cr++;
826 }
0a05e494
FB
827 p1 += dst->linesize[0];
828 lum1 += src->linesize[0];
829 cb1 += src->linesize[1];
830 cr1 += src->linesize[2];
c50c0bc8
FB
831 }
832}
833
ebb177dd
TK
834static void yuv422p_to_uyvy422(AVPicture *dst, const AVPicture *src,
835 int width, int height)
836{
837 uint8_t *p, *p1;
838 const uint8_t *lum, *cr, *cb, *lum1, *cr1, *cb1;
839 int w;
840
841 p1 = dst->data[0];
842 lum1 = src->data[0];
843 cb1 = src->data[1];
844 cr1 = src->data[2];
845 for(;height > 0; height--) {
846 p = p1;
847 lum = lum1;
848 cb = cb1;
849 cr = cr1;
850 for(w = width; w >= 2; w -= 2) {
851 p[1] = lum[0];
852 p[0] = cb[0];
853 p[3] = lum[1];
854 p[2] = cr[0];
855 p += 4;
856 lum += 2;
857 cb++;
858 cr++;
859 }
860 p1 += dst->linesize[0];
861 lum1 += src->linesize[0];
862 cb1 += src->linesize[1];
863 cr1 += src->linesize[2];
864 }
865}
866
867
868
c50c0bc8 869#define SCALEBITS 10
de6d9b64 870#define ONE_HALF (1 << (SCALEBITS - 1))
c50c0bc8 871#define FIX(x) ((int) ((x) * (1<<SCALEBITS) + 0.5))
de6d9b64 872
c50c0bc8
FB
873#define YUV_TO_RGB1_CCIR(cb1, cr1)\
874{\
875 cb = (cb1) - 128;\
876 cr = (cr1) - 128;\
877 r_add = FIX(1.40200*255.0/224.0) * cr + ONE_HALF;\
878 g_add = - FIX(0.34414*255.0/224.0) * cb - FIX(0.71414*255.0/224.0) * cr + \
879 ONE_HALF;\
880 b_add = FIX(1.77200*255.0/224.0) * cb + ONE_HALF;\
881}
b6147995 882
c50c0bc8
FB
883#define YUV_TO_RGB2_CCIR(r, g, b, y1)\
884{\
885 y = ((y1) - 16) * FIX(255.0/219.0);\
886 r = cm[(y + r_add) >> SCALEBITS];\
887 g = cm[(y + g_add) >> SCALEBITS];\
888 b = cm[(y + b_add) >> SCALEBITS];\
889}
890
891#define YUV_TO_RGB1(cb1, cr1)\
892{\
893 cb = (cb1) - 128;\
894 cr = (cr1) - 128;\
895 r_add = FIX(1.40200) * cr + ONE_HALF;\
896 g_add = - FIX(0.34414) * cb - FIX(0.71414) * cr + ONE_HALF;\
897 b_add = FIX(1.77200) * cb + ONE_HALF;\
898}
b6147995
FB
899
900#define YUV_TO_RGB2(r, g, b, y1)\
901{\
c50c0bc8
FB
902 y = (y1) << SCALEBITS;\
903 r = cm[(y + r_add) >> SCALEBITS];\
904 g = cm[(y + g_add) >> SCALEBITS];\
905 b = cm[(y + b_add) >> SCALEBITS];\
b6147995
FB
906}
907
c50c0bc8 908#define Y_CCIR_TO_JPEG(y)\
b6147995
FB
909 cm[((y) * FIX(255.0/219.0) + (ONE_HALF - 16 * FIX(255.0/219.0))) >> SCALEBITS]
910
c50c0bc8 911#define Y_JPEG_TO_CCIR(y)\
b6147995
FB
912 (((y) * FIX(219.0/255.0) + (ONE_HALF + (16 << SCALEBITS))) >> SCALEBITS)
913
c50c0bc8
FB
914#define C_CCIR_TO_JPEG(y)\
915 cm[(((y) - 128) * FIX(127.0/112.0) + (ONE_HALF + (128 << SCALEBITS))) >> SCALEBITS]
916
917/* NOTE: the clamp is really necessary! */
4cfbf61b
FH
918static inline int C_JPEG_TO_CCIR(int y) {
919 y = (((y - 128) * FIX(112.0/127.0) + (ONE_HALF + (128 << SCALEBITS))) >> SCALEBITS);
920 if (y < 16)
921 y = 16;
922 return y;
923}
924
c50c0bc8 925
b6147995
FB
926#define RGB_TO_Y(r, g, b) \
927((FIX(0.29900) * (r) + FIX(0.58700) * (g) + \
928 FIX(0.11400) * (b) + ONE_HALF) >> SCALEBITS)
929
c50c0bc8 930#define RGB_TO_U(r1, g1, b1, shift)\
b6147995 931(((- FIX(0.16874) * r1 - FIX(0.33126) * g1 + \
c50c0bc8 932 FIX(0.50000) * b1 + (ONE_HALF << shift) - 1) >> (SCALEBITS + shift)) + 128)
b6147995 933
c50c0bc8 934#define RGB_TO_V(r1, g1, b1, shift)\
b6147995 935(((FIX(0.50000) * r1 - FIX(0.41869) * g1 - \
c50c0bc8 936 FIX(0.08131) * b1 + (ONE_HALF << shift) - 1) >> (SCALEBITS + shift)) + 128)
b6147995
FB
937
938#define RGB_TO_Y_CCIR(r, g, b) \
939((FIX(0.29900*219.0/255.0) * (r) + FIX(0.58700*219.0/255.0) * (g) + \
940 FIX(0.11400*219.0/255.0) * (b) + (ONE_HALF + (16 << SCALEBITS))) >> SCALEBITS)
941
c50c0bc8 942#define RGB_TO_U_CCIR(r1, g1, b1, shift)\
b6147995 943(((- FIX(0.16874*224.0/255.0) * r1 - FIX(0.33126*224.0/255.0) * g1 + \
c50c0bc8 944 FIX(0.50000*224.0/255.0) * b1 + (ONE_HALF << shift) - 1) >> (SCALEBITS + shift)) + 128)
b6147995 945
c50c0bc8 946#define RGB_TO_V_CCIR(r1, g1, b1, shift)\
b6147995 947(((FIX(0.50000*224.0/255.0) * r1 - FIX(0.41869*224.0/255.0) * g1 - \
c50c0bc8 948 FIX(0.08131*224.0/255.0) * b1 + (ONE_HALF << shift) - 1) >> (SCALEBITS + shift)) + 128)
b6147995 949
c50c0bc8
FB
950static uint8_t y_ccir_to_jpeg[256];
951static uint8_t y_jpeg_to_ccir[256];
952static uint8_t c_ccir_to_jpeg[256];
953static uint8_t c_jpeg_to_ccir[256];
954
955/* init various conversion tables */
956static void img_convert_init(void)
b6147995 957{
c50c0bc8 958 int i;
b6147995
FB
959 uint8_t *cm = cropTbl + MAX_NEG_CROP;
960
c50c0bc8
FB
961 for(i = 0;i < 256; i++) {
962 y_ccir_to_jpeg[i] = Y_CCIR_TO_JPEG(i);
963 y_jpeg_to_ccir[i] = Y_JPEG_TO_CCIR(i);
964 c_ccir_to_jpeg[i] = C_CCIR_TO_JPEG(i);
965 c_jpeg_to_ccir[i] = C_JPEG_TO_CCIR(i);
b6147995
FB
966 }
967}
968
c50c0bc8
FB
969/* apply to each pixel the given table */
970static void img_apply_table(uint8_t *dst, int dst_wrap,
971 const uint8_t *src, int src_wrap,
972 int width, int height, const uint8_t *table1)
b6147995
FB
973{
974 int n;
975 const uint8_t *s;
976 uint8_t *d;
c50c0bc8 977 const uint8_t *table;
b6147995 978
c50c0bc8 979 table = table1;
b6147995
FB
980 for(;height > 0; height--) {
981 s = src;
982 d = dst;
983 n = width;
984 while (n >= 4) {
c50c0bc8
FB
985 d[0] = table[s[0]];
986 d[1] = table[s[1]];
987 d[2] = table[s[2]];
988 d[3] = table[s[3]];
b6147995
FB
989 d += 4;
990 s += 4;
991 n -= 4;
992 }
993 while (n > 0) {
c50c0bc8 994 d[0] = table[s[0]];
b6147995
FB
995 d++;
996 s++;
997 n--;
998 }
999 dst += dst_wrap;
1000 src += src_wrap;
1001 }
1002}
1003
85c242d8 1004/* XXX: use generic filter ? */
e352ff08
FB
1005/* XXX: in most cases, the sampling position is incorrect */
1006
1007/* 4x1 -> 1x1 */
1008static void shrink41(uint8_t *dst, int dst_wrap,
1009 const uint8_t *src, int src_wrap,
1010 int width, int height)
1011{
1012 int w;
1013 const uint8_t *s;
1014 uint8_t *d;
1015
1016 for(;height > 0; height--) {
1017 s = src;
1018 d = dst;
1019 for(w = width;w > 0; w--) {
1020 d[0] = (s[0] + s[1] + s[2] + s[3] + 2) >> 2;
1021 s += 4;
1022 d++;
1023 }
1024 src += src_wrap;
1025 dst += dst_wrap;
1026 }
1027}
1028
1029/* 2x1 -> 1x1 */
1030static void shrink21(uint8_t *dst, int dst_wrap,
1031 const uint8_t *src, int src_wrap,
1032 int width, int height)
1033{
1034 int w;
1035 const uint8_t *s;
1036 uint8_t *d;
1037
1038 for(;height > 0; height--) {
1039 s = src;
1040 d = dst;
1041 for(w = width;w > 0; w--) {
1042 d[0] = (s[0] + s[1]) >> 1;
1043 s += 2;
1044 d++;
1045 }
1046 src += src_wrap;
1047 dst += dst_wrap;
1048 }
1049}
1050
85c242d8 1051/* 1x2 -> 1x1 */
e352ff08
FB
1052static void shrink12(uint8_t *dst, int dst_wrap,
1053 const uint8_t *src, int src_wrap,
1054 int width, int height)
85c242d8
FB
1055{
1056 int w;
e352ff08
FB
1057 uint8_t *d;
1058 const uint8_t *s1, *s2;
85c242d8
FB
1059
1060 for(;height > 0; height--) {
1061 s1 = src;
1062 s2 = s1 + src_wrap;
1063 d = dst;
1064 for(w = width;w >= 4; w-=4) {
1065 d[0] = (s1[0] + s2[0]) >> 1;
1066 d[1] = (s1[1] + s2[1]) >> 1;
1067 d[2] = (s1[2] + s2[2]) >> 1;
1068 d[3] = (s1[3] + s2[3]) >> 1;
1069 s1 += 4;
1070 s2 += 4;
1071 d += 4;
1072 }
1073 for(;w > 0; w--) {
1074 d[0] = (s1[0] + s2[0]) >> 1;
1075 s1++;
1076 s2++;
1077 d++;
1078 }
1079 src += 2 * src_wrap;
1080 dst += dst_wrap;
1081 }
1082}
1083
1084/* 2x2 -> 1x1 */
0c1a9eda 1085static void shrink22(uint8_t *dst, int dst_wrap,
e352ff08 1086 const uint8_t *src, int src_wrap,
85c242d8
FB
1087 int width, int height)
1088{
1089 int w;
e352ff08
FB
1090 const uint8_t *s1, *s2;
1091 uint8_t *d;
85c242d8
FB
1092
1093 for(;height > 0; height--) {
1094 s1 = src;
1095 s2 = s1 + src_wrap;
1096 d = dst;
1097 for(w = width;w >= 4; w-=4) {
0a9ad8d1
FB
1098 d[0] = (s1[0] + s1[1] + s2[0] + s2[1] + 2) >> 2;
1099 d[1] = (s1[2] + s1[3] + s2[2] + s2[3] + 2) >> 2;
1100 d[2] = (s1[4] + s1[5] + s2[4] + s2[5] + 2) >> 2;
1101 d[3] = (s1[6] + s1[7] + s2[6] + s2[7] + 2) >> 2;
85c242d8
FB
1102 s1 += 8;
1103 s2 += 8;
1104 d += 4;
1105 }
1106 for(;w > 0; w--) {
0a9ad8d1 1107 d[0] = (s1[0] + s1[1] + s2[0] + s2[1] + 2) >> 2;
85c242d8
FB
1108 s1 += 2;
1109 s2 += 2;
1110 d++;
1111 }
1112 src += 2 * src_wrap;
1113 dst += dst_wrap;
1114 }
1115}
1116
e352ff08
FB
1117/* 4x4 -> 1x1 */
1118static void shrink44(uint8_t *dst, int dst_wrap,
1119 const uint8_t *src, int src_wrap,
6742d95d
FR
1120 int width, int height)
1121{
1122 int w;
e352ff08
FB
1123 const uint8_t *s1, *s2, *s3, *s4;
1124 uint8_t *d;
6742d95d
FR
1125
1126 for(;height > 0; height--) {
1127 s1 = src;
e352ff08
FB
1128 s2 = s1 + src_wrap;
1129 s3 = s2 + src_wrap;
1130 s4 = s3 + src_wrap;
6742d95d 1131 d = dst;
e352ff08
FB
1132 for(w = width;w > 0; w--) {
1133 d[0] = (s1[0] + s1[1] + s1[2] + s1[3] +
1134 s2[0] + s2[1] + s2[2] + s2[3] +
1135 s3[0] + s3[1] + s3[2] + s3[3] +
1136 s4[0] + s4[1] + s4[2] + s4[3] + 8) >> 4;
1137 s1 += 4;
1138 s2 += 4;
1139 s3 += 4;
1140 s4 += 4;
6742d95d
FR
1141 d++;
1142 }
e352ff08
FB
1143 src += 4 * src_wrap;
1144 dst += dst_wrap;
1145 }
1146}
1147
1148static void grow21_line(uint8_t *dst, const uint8_t *src,
1149 int width)
1150{
1151 int w;
1152 const uint8_t *s1;
1153 uint8_t *d;
1154
1155 s1 = src;
1156 d = dst;
1157 for(w = width;w >= 4; w-=4) {
1158 d[1] = d[0] = s1[0];
1159 d[3] = d[2] = s1[1];
1160 s1 += 2;
1161 d += 4;
1162 }
1163 for(;w >= 2; w -= 2) {
1164 d[1] = d[0] = s1[0];
1165 s1 ++;
1166 d += 2;
1167 }
1168 /* only needed if width is not a multiple of two */
1169 /* XXX: veryfy that */
1170 if (w) {
1171 d[0] = s1[0];
1172 }
1173}
1174
1175static void grow41_line(uint8_t *dst, const uint8_t *src,
1176 int width)
1177{
1178 int w, v;
1179 const uint8_t *s1;
1180 uint8_t *d;
1181
1182 s1 = src;
1183 d = dst;
1184 for(w = width;w >= 4; w-=4) {
1185 v = s1[0];
1186 d[0] = v;
1187 d[1] = v;
1188 d[2] = v;
1189 d[3] = v;
1190 s1 ++;
1191 d += 4;
1192 }
1193}
1194
1195/* 1x1 -> 2x1 */
1196static void grow21(uint8_t *dst, int dst_wrap,
1197 const uint8_t *src, int src_wrap,
1198 int width, int height)
1199{
1200 for(;height > 0; height--) {
1201 grow21_line(dst, src, width);
1202 src += src_wrap;
1203 dst += dst_wrap;
1204 }
1205}
1206
1207/* 1x1 -> 2x2 */
1208static void grow22(uint8_t *dst, int dst_wrap,
1209 const uint8_t *src, int src_wrap,
1210 int width, int height)
1211{
1212 for(;height > 0; height--) {
1213 grow21_line(dst, src, width);
6742d95d
FR
1214 if (height%2)
1215 src += src_wrap;
1216 dst += dst_wrap;
1217 }
1218}
1219
e352ff08
FB
1220/* 1x1 -> 4x1 */
1221static void grow41(uint8_t *dst, int dst_wrap,
1222 const uint8_t *src, int src_wrap,
1223 int width, int height)
1224{
1225 for(;height > 0; height--) {
1226 grow41_line(dst, src, width);
1227 src += src_wrap;
1228 dst += dst_wrap;
1229 }
1230}
1231
1232/* 1x1 -> 4x4 */
1233static void grow44(uint8_t *dst, int dst_wrap,
1234 const uint8_t *src, int src_wrap,
1235 int width, int height)
1236{
1237 for(;height > 0; height--) {
1238 grow41_line(dst, src, width);
1239 if ((height & 3) == 1)
1240 src += src_wrap;
1241 dst += dst_wrap;
1242 }
1243}
1244
524c6b63 1245/* 1x2 -> 2x1 */
0c1a9eda 1246static void conv411(uint8_t *dst, int dst_wrap,
e352ff08 1247 const uint8_t *src, int src_wrap,
789587d5
FB
1248 int width, int height)
1249{
1250 int w, c;
e352ff08
FB
1251 const uint8_t *s1, *s2;
1252 uint8_t *d;
789587d5 1253
50643575
MN
1254 width>>=1;
1255
524c6b63 1256 for(;height > 0; height--) {
789587d5
FB
1257 s1 = src;
1258 s2 = src + src_wrap;
1259 d = dst;
1260 for(w = width;w > 0; w--) {
1261 c = (s1[0] + s2[0]) >> 1;
1262 d[0] = c;
1263 d[1] = c;
1264 s1++;
1265 s2++;
1266 d += 2;
1267 }
1268 src += src_wrap * 2;
1269 dst += dst_wrap;
1270 }
1271}
1272
7e7e5940
FB
1273/* XXX: add jpeg quantize code */
1274
1275#define TRANSP_INDEX (6*6*6)
1276
1277/* this is maybe slow, but allows for extensions */
1278static inline unsigned char gif_clut_index(uint8_t r, uint8_t g, uint8_t b)
85c242d8 1279{
7e7e5940 1280 return ((((r)/47)%6)*6*6+(((g)/47)%6)*6+(((b)/47)%6));
85c242d8
FB
1281}
1282
7e7e5940
FB
1283static void build_rgb_palette(uint8_t *palette, int has_alpha)
1284{
1285 uint32_t *pal;
1286 static const uint8_t pal_value[6] = { 0x00, 0x33, 0x66, 0x99, 0xcc, 0xff };
1287 int i, r, g, b;
1288
1289 pal = (uint32_t *)palette;
1290 i = 0;
1291 for(r = 0; r < 6; r++) {
1292 for(g = 0; g < 6; g++) {
1293 for(b = 0; b < 6; b++) {
1294 pal[i++] = (0xff << 24) | (pal_value[r] << 16) |
1295 (pal_value[g] << 8) | pal_value[b];
1296 }
1297 }
1298 }
1299 if (has_alpha)
1300 pal[i++] = 0;
1301 while (i < 256)
1302 pal[i++] = 0xff000000;
524c6b63
FB
1303}
1304
1305/* copy bit n to bits 0 ... n - 1 */
1306static inline unsigned int bitcopy_n(unsigned int a, int n)
b71472eb 1307{
524c6b63
FB
1308 int mask;
1309 mask = (1 << n) - 1;
1310 return (a & (0xff & ~mask)) | ((-((a >> n) & 1)) & mask);
1311}
1312
1313/* rgb555 handling */
1314
7e7e5940
FB
1315#define RGB_NAME rgb555
1316
524c6b63
FB
1317#define RGB_IN(r, g, b, s)\
1318{\
0c1a9eda 1319 unsigned int v = ((const uint16_t *)(s))[0];\
524c6b63
FB
1320 r = bitcopy_n(v >> (10 - 3), 3);\
1321 g = bitcopy_n(v >> (5 - 3), 3);\
1322 b = bitcopy_n(v << 3, 3);\
1323}
1324
7e7e5940 1325#define RGBA_IN(r, g, b, a, s)\
524c6b63 1326{\
7e7e5940
FB
1327 unsigned int v = ((const uint16_t *)(s))[0];\
1328 r = bitcopy_n(v >> (10 - 3), 3);\
1329 g = bitcopy_n(v >> (5 - 3), 3);\
1330 b = bitcopy_n(v << 3, 3);\
b5ff5e22 1331 a = (-(v >> 15)) & 0xff;\
7e7e5940
FB
1332}
1333
1334#define RGBA_OUT(d, r, g, b, a)\
1335{\
1336 ((uint16_t *)(d))[0] = ((r >> 3) << 10) | ((g >> 3) << 5) | (b >> 3) | \
1337 ((a << 8) & 0x8000);\
524c6b63
FB
1338}
1339
1340#define BPP 2
1341
7e7e5940 1342#include "imgconvert_template.h"
524c6b63
FB
1343
1344/* rgb565 handling */
1345
7e7e5940
FB
1346#define RGB_NAME rgb565
1347
524c6b63
FB
1348#define RGB_IN(r, g, b, s)\
1349{\
0c1a9eda 1350 unsigned int v = ((const uint16_t *)(s))[0];\
524c6b63
FB
1351 r = bitcopy_n(v >> (11 - 3), 3);\
1352 g = bitcopy_n(v >> (5 - 2), 2);\
1353 b = bitcopy_n(v << 3, 3);\
1354}
1355
1356#define RGB_OUT(d, r, g, b)\
1357{\
0c1a9eda 1358 ((uint16_t *)(d))[0] = ((r >> 3) << 11) | ((g >> 2) << 5) | (b >> 3);\
524c6b63
FB
1359}
1360
1361#define BPP 2
1362
7e7e5940 1363#include "imgconvert_template.h"
524c6b63
FB
1364
1365/* bgr24 handling */
1366
7e7e5940
FB
1367#define RGB_NAME bgr24
1368
524c6b63
FB
1369#define RGB_IN(r, g, b, s)\
1370{\
1371 b = (s)[0];\
1372 g = (s)[1];\
1373 r = (s)[2];\
1374}
1375
1376#define RGB_OUT(d, r, g, b)\
1377{\
1378 (d)[0] = b;\
1379 (d)[1] = g;\
1380 (d)[2] = r;\
1381}
1382
1383#define BPP 3
1384
7e7e5940 1385#include "imgconvert_template.h"
524c6b63
FB
1386
1387#undef RGB_IN
1388#undef RGB_OUT
1389#undef BPP
1390
1391/* rgb24 handling */
1392
7e7e5940
FB
1393#define RGB_NAME rgb24
1394#define FMT_RGB24
1395
524c6b63
FB
1396#define RGB_IN(r, g, b, s)\
1397{\
1398 r = (s)[0];\
1399 g = (s)[1];\
1400 b = (s)[2];\
1401}
1402
1403#define RGB_OUT(d, r, g, b)\
1404{\
1405 (d)[0] = r;\
1406 (d)[1] = g;\
1407 (d)[2] = b;\
1408}
1409
1410#define BPP 3
1411
7e7e5940 1412#include "imgconvert_template.h"
524c6b63
FB
1413
1414/* rgba32 handling */
1415
7e7e5940
FB
1416#define RGB_NAME rgba32
1417#define FMT_RGBA32
1418
524c6b63
FB
1419#define RGB_IN(r, g, b, s)\
1420{\
0c1a9eda 1421 unsigned int v = ((const uint32_t *)(s))[0];\
524c6b63
FB
1422 r = (v >> 16) & 0xff;\
1423 g = (v >> 8) & 0xff;\
1424 b = v & 0xff;\
1425}
1426
7e7e5940 1427#define RGBA_IN(r, g, b, a, s)\
524c6b63 1428{\
7e7e5940
FB
1429 unsigned int v = ((const uint32_t *)(s))[0];\
1430 a = (v >> 24) & 0xff;\
1431 r = (v >> 16) & 0xff;\
1432 g = (v >> 8) & 0xff;\
1433 b = v & 0xff;\
524c6b63
FB
1434}
1435
7e7e5940
FB
1436#define RGBA_OUT(d, r, g, b, a)\
1437{\
1438 ((uint32_t *)(d))[0] = (a << 24) | (r << 16) | (g << 8) | b;\
b71472eb
PG
1439}
1440
7e7e5940 1441#define BPP 4
524c6b63 1442
7e7e5940 1443#include "imgconvert_template.h"
b71472eb 1444
da64ecc3 1445static void mono_to_gray(AVPicture *dst, const AVPicture *src,
2a877875 1446 int width, int height, int xor_mask)
524c6b63
FB
1447{
1448 const unsigned char *p;
1449 unsigned char *q;
1450 int v, dst_wrap, src_wrap;
1451 int y, w;
1452
1453 p = src->data[0];
1454 src_wrap = src->linesize[0] - ((width + 7) >> 3);
1455
1456 q = dst->data[0];
2a877875 1457 dst_wrap = dst->linesize[0] - width;
524c6b63
FB
1458 for(y=0;y<height;y++) {
1459 w = width;
1460 while (w >= 8) {
2a877875
FB
1461 v = *p++ ^ xor_mask;
1462 q[0] = -(v >> 7);
1463 q[1] = -((v >> 6) & 1);
1464 q[2] = -((v >> 5) & 1);
1465 q[3] = -((v >> 4) & 1);
1466 q[4] = -((v >> 3) & 1);
1467 q[5] = -((v >> 2) & 1);
1468 q[6] = -((v >> 1) & 1);
1469 q[7] = -((v >> 0) & 1);
524c6b63 1470 w -= 8;
2a877875 1471 q += 8;
524c6b63
FB
1472 }
1473 if (w > 0) {
2a877875 1474 v = *p++ ^ xor_mask;
524c6b63 1475 do {
2a877875
FB
1476 q[0] = -((v >> 7) & 1);
1477 q++;
524c6b63
FB
1478 v <<= 1;
1479 } while (--w);
85c242d8 1480 }
524c6b63
FB
1481 p += src_wrap;
1482 q += dst_wrap;
85c242d8
FB
1483 }
1484}
1485
da64ecc3 1486static void monowhite_to_gray(AVPicture *dst, const AVPicture *src,
524c6b63
FB
1487 int width, int height)
1488{
2a877875
FB
1489 mono_to_gray(dst, src, width, height, 0xff);
1490}
524c6b63 1491
da64ecc3 1492static void monoblack_to_gray(AVPicture *dst, const AVPicture *src,
2a877875
FB
1493 int width, int height)
1494{
1495 mono_to_gray(dst, src, width, height, 0x00);
1496}
524c6b63 1497
da64ecc3 1498static void gray_to_mono(AVPicture *dst, const AVPicture *src,
2a877875
FB
1499 int width, int height, int xor_mask)
1500{
1501 int n;
0c1a9eda
ZK
1502 const uint8_t *s;
1503 uint8_t *d;
2a877875
FB
1504 int j, b, v, n1, src_wrap, dst_wrap, y;
1505
1506 s = src->data[0];
1507 src_wrap = src->linesize[0] - width;
1508
1509 d = dst->data[0];
1510 dst_wrap = dst->linesize[0] - ((width + 7) >> 3);
524c6b63
FB
1511
1512 for(y=0;y<height;y++) {
2a877875
FB
1513 n = width;
1514 while (n >= 8) {
1515 v = 0;
1516 for(j=0;j<8;j++) {
1517 b = s[0];
1518 s++;
1519 v = (v << 1) | (b >> 7);
1520 }
1521 d[0] = v ^ xor_mask;
1522 d++;
1523 n -= 8;
524c6b63 1524 }
2a877875
FB
1525 if (n > 0) {
1526 n1 = n;
1527 v = 0;
1528 while (n > 0) {
1529 b = s[0];
1530 s++;
1531 v = (v << 1) | (b >> 7);
1532 n--;
1533 }
1534 d[0] = (v << (8 - (n1 & 7))) ^ xor_mask;
1535 d++;
524c6b63 1536 }
2a877875
FB
1537 s += src_wrap;
1538 d += dst_wrap;
524c6b63
FB
1539 }
1540}
1541
da64ecc3 1542static void gray_to_monowhite(AVPicture *dst, const AVPicture *src,
2a877875
FB
1543 int width, int height)
1544{
1545 gray_to_mono(dst, src, width, height, 0xff);
1546}
1547
da64ecc3 1548static void gray_to_monoblack(AVPicture *dst, const AVPicture *src,
2a877875
FB
1549 int width, int height)
1550{
1551 gray_to_mono(dst, src, width, height, 0x00);
1552}
1553
524c6b63 1554typedef struct ConvertEntry {
da64ecc3
DH
1555 void (*convert)(AVPicture *dst,
1556 const AVPicture *src, int width, int height);
524c6b63
FB
1557} ConvertEntry;
1558
c50c0bc8
FB
1559/* Add each new convertion function in this table. In order to be able
1560 to convert from any format to any format, the following constraints
1561 must be satisfied:
1562
1563 - all FF_COLOR_RGB formats must convert to and from PIX_FMT_RGB24
1564
1565 - all FF_COLOR_GRAY formats must convert to and from PIX_FMT_GRAY8
1566
1567 - all FF_COLOR_RGB formats with alpha must convert to and from PIX_FMT_RGBA32
1568
e352ff08 1569 - PIX_FMT_YUV444P and PIX_FMT_YUVJ444P must convert to and from
c50c0bc8
FB
1570 PIX_FMT_RGB24.
1571
1572 - PIX_FMT_422 must convert to and from PIX_FMT_422P.
e352ff08
FB
1573
1574 The other conversion functions are just optimisations for common cases.
524c6b63
FB
1575*/
1576static ConvertEntry convert_table[PIX_FMT_NB][PIX_FMT_NB] = {
1577 [PIX_FMT_YUV420P] = {
1578 [PIX_FMT_RGB555] = {
ef9f7306 1579 .convert = yuv420p_to_rgb555
524c6b63
FB
1580 },
1581 [PIX_FMT_RGB565] = {
ef9f7306 1582 .convert = yuv420p_to_rgb565
524c6b63
FB
1583 },
1584 [PIX_FMT_BGR24] = {
ef9f7306 1585 .convert = yuv420p_to_bgr24
524c6b63
FB
1586 },
1587 [PIX_FMT_RGB24] = {
ef9f7306 1588 .convert = yuv420p_to_rgb24
524c6b63
FB
1589 },
1590 [PIX_FMT_RGBA32] = {
ef9f7306 1591 .convert = yuv420p_to_rgba32
524c6b63
FB
1592 },
1593 },
c50c0bc8
FB
1594 [PIX_FMT_YUV422P] = {
1595 [PIX_FMT_YUV422] = {
1596 .convert = yuv422p_to_yuv422,
1597 },
ebb177dd
TK
1598 [PIX_FMT_UYVY422] = {
1599 .convert = yuv422p_to_uyvy422,
1600 },
c50c0bc8
FB
1601 },
1602 [PIX_FMT_YUV444P] = {
1603 [PIX_FMT_RGB24] = {
1604 .convert = yuv444p_to_rgb24
1605 },
1606 },
1607 [PIX_FMT_YUVJ420P] = {
524c6b63 1608 [PIX_FMT_RGB555] = {
c50c0bc8 1609 .convert = yuvj420p_to_rgb555
524c6b63
FB
1610 },
1611 [PIX_FMT_RGB565] = {
c50c0bc8 1612 .convert = yuvj420p_to_rgb565
524c6b63
FB
1613 },
1614 [PIX_FMT_BGR24] = {
c50c0bc8 1615 .convert = yuvj420p_to_bgr24
524c6b63
FB
1616 },
1617 [PIX_FMT_RGB24] = {
c50c0bc8 1618 .convert = yuvj420p_to_rgb24
524c6b63
FB
1619 },
1620 [PIX_FMT_RGBA32] = {
c50c0bc8
FB
1621 .convert = yuvj420p_to_rgba32
1622 },
1623 },
1624 [PIX_FMT_YUVJ444P] = {
1625 [PIX_FMT_RGB24] = {
1626 .convert = yuvj444p_to_rgb24
524c6b63
FB
1627 },
1628 },
1629 [PIX_FMT_YUV422] = {
1630 [PIX_FMT_YUV420P] = {
ef9f7306 1631 .convert = yuv422_to_yuv420p,
524c6b63 1632 },
c50c0bc8
FB
1633 [PIX_FMT_YUV422P] = {
1634 .convert = yuv422_to_yuv422p,
1635 },
524c6b63 1636 },
ebb177dd
TK
1637 [PIX_FMT_UYVY422] = {
1638 [PIX_FMT_YUV420P] = {
1639 .convert = uyvy422_to_yuv420p,
1640 },
1641 [PIX_FMT_YUV422P] = {
1642 .convert = uyvy422_to_yuv422p,
1643 },
1644 },
524c6b63
FB
1645 [PIX_FMT_RGB24] = {
1646 [PIX_FMT_YUV420P] = {
ef9f7306 1647 .convert = rgb24_to_yuv420p
524c6b63
FB
1648 },
1649 [PIX_FMT_RGB565] = {
ef9f7306 1650 .convert = rgb24_to_rgb565
524c6b63
FB
1651 },
1652 [PIX_FMT_RGB555] = {
ef9f7306 1653 .convert = rgb24_to_rgb555
524c6b63 1654 },
7e7e5940
FB
1655 [PIX_FMT_RGBA32] = {
1656 .convert = rgb24_to_rgba32
1657 },
1658 [PIX_FMT_BGR24] = {
1659 .convert = rgb24_to_bgr24
1660 },
524c6b63 1661 [PIX_FMT_GRAY8] = {
ef9f7306 1662 .convert = rgb24_to_gray
524c6b63 1663 },
7e7e5940 1664 [PIX_FMT_PAL8] = {
7e6d70d0
FB
1665 .convert = rgb24_to_pal8
1666 },
c50c0bc8
FB
1667 [PIX_FMT_YUV444P] = {
1668 .convert = rgb24_to_yuv444p
1669 },
1670 [PIX_FMT_YUVJ420P] = {
1671 .convert = rgb24_to_yuvj420p
1672 },
1673 [PIX_FMT_YUVJ444P] = {
1674 .convert = rgb24_to_yuvj444p
1675 },
524c6b63
FB
1676 },
1677 [PIX_FMT_RGBA32] = {
7e7e5940
FB
1678 [PIX_FMT_RGB24] = {
1679 .convert = rgba32_to_rgb24
1680 },
1681 [PIX_FMT_RGB555] = {
1682 .convert = rgba32_to_rgb555
1683 },
1684 [PIX_FMT_PAL8] = {
1685 .convert = rgba32_to_pal8
1686 },
524c6b63 1687 [PIX_FMT_YUV420P] = {
ef9f7306 1688 .convert = rgba32_to_yuv420p
524c6b63 1689 },
69572401
FB
1690 [PIX_FMT_GRAY8] = {
1691 .convert = rgba32_to_gray
1692 },
524c6b63
FB
1693 },
1694 [PIX_FMT_BGR24] = {
7e7e5940
FB
1695 [PIX_FMT_RGB24] = {
1696 .convert = bgr24_to_rgb24
1697 },
524c6b63 1698 [PIX_FMT_YUV420P] = {
ef9f7306 1699 .convert = bgr24_to_yuv420p
524c6b63 1700 },
69572401
FB
1701 [PIX_FMT_GRAY8] = {
1702 .convert = bgr24_to_gray
1703 },
524c6b63
FB
1704 },
1705 [PIX_FMT_RGB555] = {
7e7e5940
FB
1706 [PIX_FMT_RGB24] = {
1707 .convert = rgb555_to_rgb24
1708 },
1709 [PIX_FMT_RGBA32] = {
1710 .convert = rgb555_to_rgba32
1711 },
524c6b63 1712 [PIX_FMT_YUV420P] = {
ef9f7306 1713 .convert = rgb555_to_yuv420p
524c6b63 1714 },
69572401
FB
1715 [PIX_FMT_GRAY8] = {
1716 .convert = rgb555_to_gray
1717 },
524c6b63
FB
1718 },
1719 [PIX_FMT_RGB565] = {
7e7e5940
FB
1720 [PIX_FMT_RGB24] = {
1721 .convert = rgb565_to_rgb24
1722 },
524c6b63 1723 [PIX_FMT_YUV420P] = {
ef9f7306 1724 .convert = rgb565_to_yuv420p
524c6b63 1725 },
69572401
FB
1726 [PIX_FMT_GRAY8] = {
1727 .convert = rgb565_to_gray
1728 },
524c6b63
FB
1729 },
1730 [PIX_FMT_GRAY8] = {
69572401
FB
1731 [PIX_FMT_RGB555] = {
1732 .convert = gray_to_rgb555
1733 },
1734 [PIX_FMT_RGB565] = {
1735 .convert = gray_to_rgb565
1736 },
524c6b63 1737 [PIX_FMT_RGB24] = {
ef9f7306 1738 .convert = gray_to_rgb24
524c6b63 1739 },
69572401
FB
1740 [PIX_FMT_BGR24] = {
1741 .convert = gray_to_bgr24
1742 },
1743 [PIX_FMT_RGBA32] = {
1744 .convert = gray_to_rgba32
1745 },
2a877875 1746 [PIX_FMT_MONOWHITE] = {
ef9f7306 1747 .convert = gray_to_monowhite
2a877875
FB
1748 },
1749 [PIX_FMT_MONOBLACK] = {
ef9f7306 1750 .convert = gray_to_monoblack
2a877875 1751 },
524c6b63
FB
1752 },
1753 [PIX_FMT_MONOWHITE] = {
2a877875 1754 [PIX_FMT_GRAY8] = {
ef9f7306 1755 .convert = monowhite_to_gray
524c6b63
FB
1756 },
1757 },
1758 [PIX_FMT_MONOBLACK] = {
2a877875 1759 [PIX_FMT_GRAY8] = {
ef9f7306 1760 .convert = monoblack_to_gray
524c6b63
FB
1761 },
1762 },
7e6d70d0
FB
1763 [PIX_FMT_PAL8] = {
1764 [PIX_FMT_RGB555] = {
1765 .convert = pal8_to_rgb555
1766 },
1767 [PIX_FMT_RGB565] = {
1768 .convert = pal8_to_rgb565
1769 },
1770 [PIX_FMT_BGR24] = {
1771 .convert = pal8_to_bgr24
1772 },
1773 [PIX_FMT_RGB24] = {
1774 .convert = pal8_to_rgb24
1775 },
1776 [PIX_FMT_RGBA32] = {
1777 .convert = pal8_to_rgba32
1778 },
1779 },
524c6b63
FB
1780};
1781
75917b88 1782int avpicture_alloc(AVPicture *picture,
524c6b63
FB
1783 int pix_fmt, int width, int height)
1784{
5c91a675 1785 unsigned int size;
524c6b63
FB
1786 void *ptr;
1787
1788 size = avpicture_get_size(pix_fmt, width, height);
524c6b63
FB
1789 ptr = av_malloc(size);
1790 if (!ptr)
1791 goto fail;
1792 avpicture_fill(picture, ptr, pix_fmt, width, height);
1793 return 0;
1794 fail:
1795 memset(picture, 0, sizeof(AVPicture));
1796 return -1;
1797}
1798
75917b88 1799void avpicture_free(AVPicture *picture)
524c6b63 1800{
8e1e6f31 1801 av_free(picture->data[0]);
524c6b63
FB
1802}
1803
c50c0bc8
FB
1804/* return true if yuv planar */
1805static inline int is_yuv_planar(PixFmtInfo *ps)
1806{
1807 return (ps->color_type == FF_COLOR_YUV ||
7e7e5940
FB
1808 ps->color_type == FF_COLOR_YUV_JPEG) &&
1809 ps->pixel_type == FF_PIXEL_PLANAR;
c50c0bc8
FB
1810}
1811
85c242d8
FB
1812/* XXX: always use linesize. Return -1 if not supported */
1813int img_convert(AVPicture *dst, int dst_pix_fmt,
da64ecc3 1814 const AVPicture *src, int src_pix_fmt,
524c6b63 1815 int src_width, int src_height)
85c242d8 1816{
c50c0bc8 1817 static int inited;
2a877875 1818 int i, ret, dst_width, dst_height, int_pix_fmt;
524c6b63
FB
1819 PixFmtInfo *src_pix, *dst_pix;
1820 ConvertEntry *ce;
1821 AVPicture tmp1, *tmp = &tmp1;
1822
1823 if (src_pix_fmt < 0 || src_pix_fmt >= PIX_FMT_NB ||
1824 dst_pix_fmt < 0 || dst_pix_fmt >= PIX_FMT_NB)
1825 return -1;
1826 if (src_width <= 0 || src_height <= 0)
1827 return 0;
69572401 1828
c50c0bc8
FB
1829 if (!inited) {
1830 inited = 1;
1831 img_convert_init();
1832 }
1833
524c6b63
FB
1834 dst_width = src_width;
1835 dst_height = src_height;
69572401 1836
524c6b63
FB
1837 dst_pix = &pix_fmt_info[dst_pix_fmt];
1838 src_pix = &pix_fmt_info[src_pix_fmt];
1839 if (src_pix_fmt == dst_pix_fmt) {
7e7e5940
FB
1840 /* no conversion needed: just copy */
1841 img_copy(dst, src, dst_pix_fmt, dst_width, dst_height);
524c6b63
FB
1842 return 0;
1843 }
1844
1845 ce = &convert_table[src_pix_fmt][dst_pix_fmt];
1846 if (ce->convert) {
ebb177dd 1847 /* specific conversion routine */
524c6b63
FB
1848 ce->convert(dst, src, dst_width, dst_height);
1849 return 0;
1850 }
1851
524c6b63 1852 /* gray to YUV */
c50c0bc8 1853 if (is_yuv_planar(dst_pix) &&
b6147995 1854 src_pix_fmt == PIX_FMT_GRAY8) {
524c6b63
FB
1855 int w, h, y;
1856 uint8_t *d;
1857
b6147995 1858 if (dst_pix->color_type == FF_COLOR_YUV_JPEG) {
7e7e5940 1859 img_copy_plane(dst->data[0], dst->linesize[0],
b6147995
FB
1860 src->data[0], src->linesize[0],
1861 dst_width, dst_height);
1862 } else {
c50c0bc8
FB
1863 img_apply_table(dst->data[0], dst->linesize[0],
1864 src->data[0], src->linesize[0],
1865 dst_width, dst_height,
1866 y_jpeg_to_ccir);
b6147995 1867 }
524c6b63
FB
1868 /* fill U and V with 128 */
1869 w = dst_width;
1870 h = dst_height;
1871 w >>= dst_pix->x_chroma_shift;
1872 h >>= dst_pix->y_chroma_shift;
1873 for(i = 1; i <= 2; i++) {
1874 d = dst->data[i];
2a877875
FB
1875 for(y = 0; y< h; y++) {
1876 memset(d, 128, w);
524c6b63
FB
1877 d += dst->linesize[i];
1878 }
b71472eb 1879 }
524c6b63
FB
1880 return 0;
1881 }
1882
1883 /* YUV to gray */
c50c0bc8 1884 if (is_yuv_planar(src_pix) &&
b6147995
FB
1885 dst_pix_fmt == PIX_FMT_GRAY8) {
1886 if (src_pix->color_type == FF_COLOR_YUV_JPEG) {
7e7e5940 1887 img_copy_plane(dst->data[0], dst->linesize[0],
b6147995
FB
1888 src->data[0], src->linesize[0],
1889 dst_width, dst_height);
1890 } else {
c50c0bc8
FB
1891 img_apply_table(dst->data[0], dst->linesize[0],
1892 src->data[0], src->linesize[0],
1893 dst_width, dst_height,
1894 y_ccir_to_jpeg);
b6147995 1895 }
524c6b63
FB
1896 return 0;
1897 }
1898
c50c0bc8
FB
1899 /* YUV to YUV planar */
1900 if (is_yuv_planar(dst_pix) && is_yuv_planar(src_pix)) {
e352ff08 1901 int x_shift, y_shift, w, h, xy_shift;
0c1a9eda 1902 void (*resize_func)(uint8_t *dst, int dst_wrap,
e352ff08 1903 const uint8_t *src, int src_wrap,
524c6b63
FB
1904 int width, int height);
1905
1906 /* compute chroma size of the smallest dimensions */
1907 w = dst_width;
1908 h = dst_height;
1909 if (dst_pix->x_chroma_shift >= src_pix->x_chroma_shift)
1910 w >>= dst_pix->x_chroma_shift;
1911 else
1912 w >>= src_pix->x_chroma_shift;
1913 if (dst_pix->y_chroma_shift >= src_pix->y_chroma_shift)
1914 h >>= dst_pix->y_chroma_shift;
1915 else
1916 h >>= src_pix->y_chroma_shift;
1917
1918 x_shift = (dst_pix->x_chroma_shift - src_pix->x_chroma_shift);
1919 y_shift = (dst_pix->y_chroma_shift - src_pix->y_chroma_shift);
e352ff08
FB
1920 xy_shift = ((x_shift & 0xf) << 4) | (y_shift & 0xf);
1921 /* there must be filters for conversion at least from and to
1922 YUV444 format */
1923 switch(xy_shift) {
1924 case 0x00:
7e7e5940 1925 resize_func = img_copy_plane;
e352ff08
FB
1926 break;
1927 case 0x10:
1928 resize_func = shrink21;
1929 break;
1930 case 0x20:
1931 resize_func = shrink41;
1932 break;
1933 case 0x01:
1934 resize_func = shrink12;
1935 break;
1936 case 0x11:
524c6b63 1937 resize_func = shrink22;
e352ff08
FB
1938 break;
1939 case 0x22:
1940 resize_func = shrink44;
1941 break;
1942 case 0xf0:
1943 resize_func = grow21;
1944 break;
1945 case 0xe0:
1946 resize_func = grow41;
1947 break;
1948 case 0xff:
524c6b63 1949 resize_func = grow22;
e352ff08
FB
1950 break;
1951 case 0xee:
1952 resize_func = grow44;
1953 break;
1954 case 0xf1:
524c6b63 1955 resize_func = conv411;
e352ff08
FB
1956 break;
1957 default:
524c6b63 1958 /* currently not handled */
e352ff08 1959 goto no_chroma_filter;
85c242d8 1960 }
524c6b63 1961
7e7e5940
FB
1962 img_copy_plane(dst->data[0], dst->linesize[0],
1963 src->data[0], src->linesize[0],
1964 dst_width, dst_height);
566986ee 1965
524c6b63 1966 for(i = 1;i <= 2; i++)
566986ee
MK
1967 resize_func(dst->data[i], dst->linesize[i],
1968 src->data[i], src->linesize[i],
185fdc54 1969 dst_width>>dst_pix->x_chroma_shift, dst_height>>dst_pix->y_chroma_shift);
c50c0bc8
FB
1970 /* if yuv color space conversion is needed, we do it here on
1971 the destination image */
1972 if (dst_pix->color_type != src_pix->color_type) {
1973 const uint8_t *y_table, *c_table;
1974 if (dst_pix->color_type == FF_COLOR_YUV) {
1975 y_table = y_jpeg_to_ccir;
1976 c_table = c_jpeg_to_ccir;
1977 } else {
1978 y_table = y_ccir_to_jpeg;
1979 c_table = c_ccir_to_jpeg;
1980 }
1981 img_apply_table(dst->data[0], dst->linesize[0],
1982 dst->data[0], dst->linesize[0],
1983 dst_width, dst_height,
1984 y_table);
1985
1986 for(i = 1;i <= 2; i++)
1987 img_apply_table(dst->data[i], dst->linesize[i],
1988 dst->data[i], dst->linesize[i],
1989 dst_width>>dst_pix->x_chroma_shift,
1990 dst_height>>dst_pix->y_chroma_shift,
1991 c_table);
1992 }
1993 return 0;
85c242d8 1994 }
e352ff08 1995 no_chroma_filter:
524c6b63 1996
2a877875 1997 /* try to use an intermediate format */
c50c0bc8
FB
1998 if (src_pix_fmt == PIX_FMT_YUV422 ||
1999 dst_pix_fmt == PIX_FMT_YUV422) {
2000 /* specific case: convert to YUV422P first */
2001 int_pix_fmt = PIX_FMT_YUV422P;
ebb177dd
TK
2002 } else if (src_pix_fmt == PIX_FMT_UYVY422 ||
2003 dst_pix_fmt == PIX_FMT_UYVY422) {
2004 /* specific case: convert to YUV422P first */
2005 int_pix_fmt = PIX_FMT_YUV422P;
c50c0bc8
FB
2006 } else if ((src_pix->color_type == FF_COLOR_GRAY &&
2007 src_pix_fmt != PIX_FMT_GRAY8) ||
2008 (dst_pix->color_type == FF_COLOR_GRAY &&
2009 dst_pix_fmt != PIX_FMT_GRAY8)) {
2010 /* gray8 is the normalized format */
2a877875 2011 int_pix_fmt = PIX_FMT_GRAY8;
c50c0bc8
FB
2012 } else if ((is_yuv_planar(src_pix) &&
2013 src_pix_fmt != PIX_FMT_YUV444P &&
2014 src_pix_fmt != PIX_FMT_YUVJ444P)) {
2015 /* yuv444 is the normalized format */
2016 if (src_pix->color_type == FF_COLOR_YUV_JPEG)
2017 int_pix_fmt = PIX_FMT_YUVJ444P;
2018 else
2019 int_pix_fmt = PIX_FMT_YUV444P;
2020 } else if ((is_yuv_planar(dst_pix) &&
2021 dst_pix_fmt != PIX_FMT_YUV444P &&
2022 dst_pix_fmt != PIX_FMT_YUVJ444P)) {
2023 /* yuv444 is the normalized format */
2024 if (dst_pix->color_type == FF_COLOR_YUV_JPEG)
2025 int_pix_fmt = PIX_FMT_YUVJ444P;
2026 else
2027 int_pix_fmt = PIX_FMT_YUV444P;
2a877875 2028 } else {
c50c0bc8
FB
2029 /* the two formats are rgb or gray8 or yuv[j]444p */
2030 if (src_pix->is_alpha && dst_pix->is_alpha)
2031 int_pix_fmt = PIX_FMT_RGBA32;
2032 else
2033 int_pix_fmt = PIX_FMT_RGB24;
2a877875
FB
2034 }
2035 if (avpicture_alloc(tmp, int_pix_fmt, dst_width, dst_height) < 0)
2036 return -1;
2037 ret = -1;
2038 if (img_convert(tmp, int_pix_fmt,
2039 src, src_pix_fmt, src_width, src_height) < 0)
2040 goto fail1;
2041 if (img_convert(dst, dst_pix_fmt,
2042 tmp, int_pix_fmt, dst_width, dst_height) < 0)
2043 goto fail1;
2044 ret = 0;
2045 fail1:
2046 avpicture_free(tmp);
2047 return ret;
85c242d8
FB
2048}
2049
0469baf1 2050/* NOTE: we scan all the pixels to have an exact information */
da64ecc3 2051static int get_alpha_info_pal8(const AVPicture *src, int width, int height)
0469baf1
FB
2052{
2053 const unsigned char *p;
2054 int src_wrap, ret, x, y;
2055 unsigned int a;
2056 uint32_t *palette = (uint32_t *)src->data[1];
2057
2058 p = src->data[0];
2059 src_wrap = src->linesize[0] - width;
2060 ret = 0;
2061 for(y=0;y<height;y++) {
2062 for(x=0;x<width;x++) {
2063 a = palette[p[0]] >> 24;
2064 if (a == 0x00) {
2065 ret |= FF_ALPHA_TRANSP;
2066 } else if (a != 0xff) {
2067 ret |= FF_ALPHA_SEMI_TRANSP;
2068 }
2069 p++;
2070 }
2071 p += src_wrap;
2072 }
2073 return ret;
2074}
2075
2076/**
2077 * Tell if an image really has transparent alpha values.
2078 * @return ored mask of FF_ALPHA_xxx constants
2079 */
da64ecc3
DH
2080int img_get_alpha_info(const AVPicture *src,
2081 int pix_fmt, int width, int height)
0469baf1
FB
2082{
2083 PixFmtInfo *pf = &pix_fmt_info[pix_fmt];
2084 int ret;
2085
2086 pf = &pix_fmt_info[pix_fmt];
2087 /* no alpha can be represented in format */
2088 if (!pf->is_alpha)
2089 return 0;
2090 switch(pix_fmt) {
2091 case PIX_FMT_RGBA32:
2092 ret = get_alpha_info_rgba32(src, width, height);
2093 break;
2094 case PIX_FMT_RGB555:
2095 ret = get_alpha_info_rgb555(src, width, height);
2096 break;
2097 case PIX_FMT_PAL8:
2098 ret = get_alpha_info_pal8(src, width, height);
2099 break;
2100 default:
2101 /* we do not know, so everything is indicated */
2102 ret = FF_ALPHA_TRANSP | FF_ALPHA_SEMI_TRANSP;
2103 break;
2104 }
2105 return ret;
2106}
5981f4e6
F
2107
2108#ifdef HAVE_MMX
2109#define DEINT_INPLACE_LINE_LUM \
2110 movd_m2r(lum_m4[0],mm0);\
2111 movd_m2r(lum_m3[0],mm1);\
2112 movd_m2r(lum_m2[0],mm2);\
2113 movd_m2r(lum_m1[0],mm3);\
2114 movd_m2r(lum[0],mm4);\
2115 punpcklbw_r2r(mm7,mm0);\
2116 movd_r2m(mm2,lum_m4[0]);\
2117 punpcklbw_r2r(mm7,mm1);\
2118 punpcklbw_r2r(mm7,mm2);\
2119 punpcklbw_r2r(mm7,mm3);\
2120 punpcklbw_r2r(mm7,mm4);\
2121 paddw_r2r(mm3,mm1);\
2122 psllw_i2r(1,mm2);\
2123 paddw_r2r(mm4,mm0);\
2124 psllw_i2r(2,mm1);\
2125 paddw_r2r(mm6,mm2);\
2126 paddw_r2r(mm2,mm1);\
2127 psubusw_r2r(mm0,mm1);\
2128 psrlw_i2r(3,mm1);\
2129 packuswb_r2r(mm7,mm1);\
2130 movd_r2m(mm1,lum_m2[0]);
2131
2132#define DEINT_LINE_LUM \
2133 movd_m2r(lum_m4[0],mm0);\
2134 movd_m2r(lum_m3[0],mm1);\
2135 movd_m2r(lum_m2[0],mm2);\
2136 movd_m2r(lum_m1[0],mm3);\
2137 movd_m2r(lum[0],mm4);\
2138 punpcklbw_r2r(mm7,mm0);\
2139 punpcklbw_r2r(mm7,mm1);\
2140 punpcklbw_r2r(mm7,mm2);\
2141 punpcklbw_r2r(mm7,mm3);\
2142 punpcklbw_r2r(mm7,mm4);\
2143 paddw_r2r(mm3,mm1);\
2144 psllw_i2r(1,mm2);\
2145 paddw_r2r(mm4,mm0);\
2146 psllw_i2r(2,mm1);\
2147 paddw_r2r(mm6,mm2);\
2148 paddw_r2r(mm2,mm1);\
2149 psubusw_r2r(mm0,mm1);\
2150 psrlw_i2r(3,mm1);\
2151 packuswb_r2r(mm7,mm1);\
2152 movd_r2m(mm1,dst[0]);
2153#endif
2154
85c242d8 2155/* filter parameters: [-1 4 2 4 -1] // 8 */
da64ecc3
DH
2156static void deinterlace_line(uint8_t *dst,
2157 const uint8_t *lum_m4, const uint8_t *lum_m3,
2158 const uint8_t *lum_m2, const uint8_t *lum_m1,
2159 const uint8_t *lum,
2160 int size)
85c242d8 2161{
5981f4e6 2162#ifndef HAVE_MMX
0c1a9eda 2163 uint8_t *cm = cropTbl + MAX_NEG_CROP;
85c242d8 2164 int sum;
85c242d8
FB
2165
2166 for(;size > 0;size--) {
5981f4e6
F
2167 sum = -lum_m4[0];
2168 sum += lum_m3[0] << 2;
2169 sum += lum_m2[0] << 1;
2170 sum += lum_m1[0] << 2;
2171 sum += -lum[0];
85c242d8 2172 dst[0] = cm[(sum + 4) >> 3];
5981f4e6
F
2173 lum_m4++;
2174 lum_m3++;
2175 lum_m2++;
2176 lum_m1++;
2177 lum++;
85c242d8 2178 dst++;
85c242d8 2179 }
5981f4e6
F
2180#else
2181
782c5984
MN
2182 {
2183 mmx_t rounder;
2184 rounder.uw[0]=4;
2185 rounder.uw[1]=4;
2186 rounder.uw[2]=4;
2187 rounder.uw[3]=4;
2188 pxor_r2r(mm7,mm7);
2189 movq_m2r(rounder,mm6);
2190 }
5981f4e6
F
2191 for (;size > 3; size-=4) {
2192 DEINT_LINE_LUM
2193 lum_m4+=4;
2194 lum_m3+=4;
2195 lum_m2+=4;
2196 lum_m1+=4;
2197 lum+=4;
2198 dst+=4;
2199 }
2200#endif
2201}
0c1a9eda 2202static void deinterlace_line_inplace(uint8_t *lum_m4, uint8_t *lum_m3, uint8_t *lum_m2, uint8_t *lum_m1, uint8_t *lum,
5981f4e6
F
2203 int size)
2204{
2205#ifndef HAVE_MMX
0c1a9eda 2206 uint8_t *cm = cropTbl + MAX_NEG_CROP;
5981f4e6
F
2207 int sum;
2208
2209 for(;size > 0;size--) {
2210 sum = -lum_m4[0];
2211 sum += lum_m3[0] << 2;
2212 sum += lum_m2[0] << 1;
2213 lum_m4[0]=lum_m2[0];
2214 sum += lum_m1[0] << 2;
2215 sum += -lum[0];
2216 lum_m2[0] = cm[(sum + 4) >> 3];
2217 lum_m4++;
2218 lum_m3++;
2219 lum_m2++;
2220 lum_m1++;
2221 lum++;
2222 }
2223#else
2224
782c5984
MN
2225 {
2226 mmx_t rounder;
2227 rounder.uw[0]=4;
2228 rounder.uw[1]=4;
2229 rounder.uw[2]=4;
2230 rounder.uw[3]=4;
2231 pxor_r2r(mm7,mm7);
2232 movq_m2r(rounder,mm6);
2233 }
5981f4e6
F
2234 for (;size > 3; size-=4) {
2235 DEINT_INPLACE_LINE_LUM
2236 lum_m4+=4;
2237 lum_m3+=4;
2238 lum_m2+=4;
2239 lum_m1+=4;
2240 lum+=4;
2241 }
2242#endif
85c242d8
FB
2243}
2244
2245/* deinterlacing : 2 temporal taps, 3 spatial taps linear filter. The
2246 top field is copied as is, but the bottom field is deinterlaced
2247 against the top field. */
0c1a9eda 2248static void deinterlace_bottom_field(uint8_t *dst, int dst_wrap,
da64ecc3 2249 const uint8_t *src1, int src_wrap,
5981f4e6 2250 int width, int height)
85c242d8 2251{
da64ecc3 2252 const uint8_t *src_m2, *src_m1, *src_0, *src_p1, *src_p2;
5981f4e6
F
2253 int y;
2254
2255 src_m2 = src1;
2256 src_m1 = src1;
2257 src_0=&src_m1[src_wrap];
2258 src_p1=&src_0[src_wrap];
2259 src_p2=&src_p1[src_wrap];
2260 for(y=0;y<(height-2);y+=2) {
2261 memcpy(dst,src_m1,width);
85c242d8 2262 dst += dst_wrap;
5981f4e6
F
2263 deinterlace_line(dst,src_m2,src_m1,src_0,src_p1,src_p2,width);
2264 src_m2 = src_0;
2265 src_m1 = src_p1;
2266 src_0 = src_p2;
2267 src_p1 += 2*src_wrap;
2268 src_p2 += 2*src_wrap;
85c242d8 2269 dst += dst_wrap;
85c242d8 2270 }
5981f4e6
F
2271 memcpy(dst,src_m1,width);
2272 dst += dst_wrap;
2273 /* do last line */
2274 deinterlace_line(dst,src_m2,src_m1,src_0,src_0,src_0,width);
2275}
2276
0c1a9eda 2277static void deinterlace_bottom_field_inplace(uint8_t *src1, int src_wrap,
da64ecc3 2278 int width, int height)
5981f4e6 2279{
0c1a9eda 2280 uint8_t *src_m1, *src_0, *src_p1, *src_p2;
5981f4e6 2281 int y;
0c1a9eda
ZK
2282 uint8_t *buf;
2283 buf = (uint8_t*)av_malloc(width);
5981f4e6
F
2284
2285 src_m1 = src1;
2286 memcpy(buf,src_m1,width);
2287 src_0=&src_m1[src_wrap];
2288 src_p1=&src_0[src_wrap];
2289 src_p2=&src_p1[src_wrap];
2290 for(y=0;y<(height-2);y+=2) {
2291 deinterlace_line_inplace(buf,src_m1,src_0,src_p1,src_p2,width);
2292 src_m1 = src_p1;
2293 src_0 = src_p2;
2294 src_p1 += 2*src_wrap;
2295 src_p2 += 2*src_wrap;
2296 }
2297 /* do last line */
2298 deinterlace_line_inplace(buf,src_m1,src_0,src_0,src_0,width);
6000abfa 2299 av_free(buf);
85c242d8
FB
2300}
2301
2302
5981f4e6 2303/* deinterlace - if not supported return -1 */
da64ecc3 2304int avpicture_deinterlace(AVPicture *dst, const AVPicture *src,
de6d9b64
FB
2305 int pix_fmt, int width, int height)
2306{
85c242d8
FB
2307 int i;
2308
2309 if (pix_fmt != PIX_FMT_YUV420P &&
2310 pix_fmt != PIX_FMT_YUV422P &&
47017dd8
RS
2311 pix_fmt != PIX_FMT_YUV444P &&
2312 pix_fmt != PIX_FMT_YUV411P)
85c242d8 2313 return -1;
5981f4e6 2314 if ((width & 3) != 0 || (height & 3) != 0)
85c242d8 2315 return -1;
5981f4e6 2316
85c242d8
FB
2317 for(i=0;i<3;i++) {
2318 if (i == 1) {
2319 switch(pix_fmt) {
2320 case PIX_FMT_YUV420P:
2321 width >>= 1;
2322 height >>= 1;
2323 break;
2324 case PIX_FMT_YUV422P:
2325 width >>= 1;
2326 break;
47017dd8
RS
2327 case PIX_FMT_YUV411P:
2328 width >>= 2;
2329 break;
85c242d8
FB
2330 default:
2331 break;
2332 }
2333 }
5981f4e6 2334 if (src == dst) {
da64ecc3 2335 deinterlace_bottom_field_inplace(dst->data[i], dst->linesize[i],
85c242d8 2336 width, height);
5981f4e6
F
2337 } else {
2338 deinterlace_bottom_field(dst->data[i],dst->linesize[i],
2339 src->data[i], src->linesize[i],
2340 width, height);
2341 }
de6d9b64 2342 }
5981f4e6
F
2343#ifdef HAVE_MMX
2344 emms();
2345#endif
85c242d8 2346 return 0;
de6d9b64 2347}
cd4af68a
ZK
2348
2349#undef FIX