spelling
[libav.git] / libavcodec / imgconvert.c
CommitLineData
de6d9b64 1/*
f1ea5c2a 2 * Misc image conversion routines
524c6b63 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/**
1ab3d669 23 * @file imgconvert.c
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"
04d2e45f 35#include "colorspace.h"
de6d9b64 36
5981f4e6
F
37#ifdef HAVE_MMX
38#include "i386/mmx.h"
39#endif
524c6b63 40
7e7e5940
FB
41#define xglue(x, y) x ## y
42#define glue(x, y) xglue(x, y)
43
bb0f999b
GP
44#define FF_COLOR_RGB 0 /**< RGB color space */
45#define FF_COLOR_GRAY 1 /**< gray color space */
46#define FF_COLOR_YUV 2 /**< YUV color space. 16 <= Y <= 235, 16 <= U, V <= 240 */
47#define FF_COLOR_YUV_JPEG 3 /**< YUV color space. 0 <= Y <= 255, 0 <= U, V <= 255 */
b6147995 48
bb0f999b
GP
49#define FF_PIXEL_PLANAR 0 /**< each channel has one component in AVPicture */
50#define FF_PIXEL_PACKED 1 /**< only one components containing all the channels */
51#define FF_PIXEL_PALETTE 2 /**< one components containing indexes for a palette */
7e7e5940 52
524c6b63
FB
53typedef struct PixFmtInfo {
54 const char *name;
bb0f999b
GP
55 uint8_t nb_channels; /**< number of channels (including alpha) */
56 uint8_t color_type; /**< color type (see FF_COLOR_xxx constants) */
57 uint8_t pixel_type; /**< pixel storage type (see FF_PIXEL_xxx constants) */
58 uint8_t is_alpha : 1; /**< true if alpha can be specified */
59 uint8_t x_chroma_shift; /**< X chroma subsampling factor is 2 ^ shift */
60 uint8_t y_chroma_shift; /**< Y chroma subsampling factor is 2 ^ shift */
61 uint8_t depth; /**< bit depth of the color components */
524c6b63
FB
62} PixFmtInfo;
63
64/* this table gives more information about formats */
62a05b5b 65static const PixFmtInfo pix_fmt_info[PIX_FMT_NB] = {
524c6b63
FB
66 /* YUV formats */
67 [PIX_FMT_YUV420P] = {
ef9f7306 68 .name = "yuv420p",
7e7e5940 69 .nb_channels = 3,
b6147995 70 .color_type = FF_COLOR_YUV,
7e7e5940 71 .pixel_type = FF_PIXEL_PLANAR,
b6147995 72 .depth = 8,
115329f1 73 .x_chroma_shift = 1, .y_chroma_shift = 1,
524c6b63
FB
74 },
75 [PIX_FMT_YUV422P] = {
ef9f7306 76 .name = "yuv422p",
7e7e5940 77 .nb_channels = 3,
b6147995 78 .color_type = FF_COLOR_YUV,
7e7e5940 79 .pixel_type = FF_PIXEL_PLANAR,
b6147995 80 .depth = 8,
115329f1 81 .x_chroma_shift = 1, .y_chroma_shift = 0,
524c6b63
FB
82 },
83 [PIX_FMT_YUV444P] = {
ef9f7306 84 .name = "yuv444p",
7e7e5940 85 .nb_channels = 3,
b6147995 86 .color_type = FF_COLOR_YUV,
7e7e5940 87 .pixel_type = FF_PIXEL_PLANAR,
b6147995 88 .depth = 8,
115329f1 89 .x_chroma_shift = 0, .y_chroma_shift = 0,
524c6b63 90 },
71e445fc
DB
91 [PIX_FMT_YUYV422] = {
92 .name = "yuyv422",
7e7e5940 93 .nb_channels = 1,
b6147995 94 .color_type = FF_COLOR_YUV,
7e7e5940 95 .pixel_type = FF_PIXEL_PACKED,
b6147995 96 .depth = 8,
ef9f7306 97 .x_chroma_shift = 1, .y_chroma_shift = 0,
524c6b63 98 },
ebb177dd
TK
99 [PIX_FMT_UYVY422] = {
100 .name = "uyvy422",
101 .nb_channels = 1,
102 .color_type = FF_COLOR_YUV,
103 .pixel_type = FF_PIXEL_PACKED,
104 .depth = 8,
105 .x_chroma_shift = 1, .y_chroma_shift = 0,
106 },
524c6b63 107 [PIX_FMT_YUV410P] = {
ef9f7306 108 .name = "yuv410p",
7e7e5940 109 .nb_channels = 3,
b6147995 110 .color_type = FF_COLOR_YUV,
7e7e5940 111 .pixel_type = FF_PIXEL_PLANAR,
b6147995 112 .depth = 8,
ef9f7306 113 .x_chroma_shift = 2, .y_chroma_shift = 2,
524c6b63
FB
114 },
115 [PIX_FMT_YUV411P] = {
ef9f7306 116 .name = "yuv411p",
7e7e5940 117 .nb_channels = 3,
b6147995 118 .color_type = FF_COLOR_YUV,
7e7e5940 119 .pixel_type = FF_PIXEL_PLANAR,
b6147995 120 .depth = 8,
ef9f7306 121 .x_chroma_shift = 2, .y_chroma_shift = 0,
524c6b63 122 },
4196cfb7
123 [PIX_FMT_YUV440P] = {
124 .name = "yuv440p",
125 .nb_channels = 3,
126 .color_type = FF_COLOR_YUV,
127 .pixel_type = FF_PIXEL_PLANAR,
128 .depth = 8,
129 .x_chroma_shift = 0, .y_chroma_shift = 1,
130 },
524c6b63 131
b70335a2
AJ
132 /* YUV formats with alpha plane */
133 [PIX_FMT_YUVA420P] = {
134 .name = "yuva420p",
135 .nb_channels = 4,
136 .color_type = FF_COLOR_YUV,
137 .pixel_type = FF_PIXEL_PLANAR,
138 .depth = 8,
139 .x_chroma_shift = 1, .y_chroma_shift = 1,
140 },
141
b6147995
FB
142 /* JPEG YUV */
143 [PIX_FMT_YUVJ420P] = {
144 .name = "yuvj420p",
7e7e5940 145 .nb_channels = 3,
b6147995 146 .color_type = FF_COLOR_YUV_JPEG,
7e7e5940 147 .pixel_type = FF_PIXEL_PLANAR,
b6147995 148 .depth = 8,
115329f1 149 .x_chroma_shift = 1, .y_chroma_shift = 1,
b6147995
FB
150 },
151 [PIX_FMT_YUVJ422P] = {
152 .name = "yuvj422p",
7e7e5940 153 .nb_channels = 3,
b6147995 154 .color_type = FF_COLOR_YUV_JPEG,
7e7e5940 155 .pixel_type = FF_PIXEL_PLANAR,
b6147995 156 .depth = 8,
115329f1 157 .x_chroma_shift = 1, .y_chroma_shift = 0,
b6147995
FB
158 },
159 [PIX_FMT_YUVJ444P] = {
160 .name = "yuvj444p",
7e7e5940 161 .nb_channels = 3,
b6147995 162 .color_type = FF_COLOR_YUV_JPEG,
7e7e5940 163 .pixel_type = FF_PIXEL_PLANAR,
b6147995 164 .depth = 8,
115329f1 165 .x_chroma_shift = 0, .y_chroma_shift = 0,
b6147995 166 },
4196cfb7
167 [PIX_FMT_YUVJ440P] = {
168 .name = "yuvj440p",
169 .nb_channels = 3,
170 .color_type = FF_COLOR_YUV_JPEG,
171 .pixel_type = FF_PIXEL_PLANAR,
172 .depth = 8,
173 .x_chroma_shift = 0, .y_chroma_shift = 1,
174 },
b6147995 175
524c6b63
FB
176 /* RGB formats */
177 [PIX_FMT_RGB24] = {
ef9f7306 178 .name = "rgb24",
7e7e5940 179 .nb_channels = 3,
b6147995 180 .color_type = FF_COLOR_RGB,
7e7e5940 181 .pixel_type = FF_PIXEL_PACKED,
b6147995 182 .depth = 8,
2cbb7820 183 .x_chroma_shift = 0, .y_chroma_shift = 0,
524c6b63
FB
184 },
185 [PIX_FMT_BGR24] = {
ef9f7306 186 .name = "bgr24",
7e7e5940 187 .nb_channels = 3,
b6147995 188 .color_type = FF_COLOR_RGB,
7e7e5940 189 .pixel_type = FF_PIXEL_PACKED,
b6147995 190 .depth = 8,
2cbb7820 191 .x_chroma_shift = 0, .y_chroma_shift = 0,
524c6b63 192 },
71e445fc
DB
193 [PIX_FMT_RGB32] = {
194 .name = "rgb32",
7e7e5940 195 .nb_channels = 4, .is_alpha = 1,
b6147995 196 .color_type = FF_COLOR_RGB,
7e7e5940 197 .pixel_type = FF_PIXEL_PACKED,
b6147995 198 .depth = 8,
2cbb7820 199 .x_chroma_shift = 0, .y_chroma_shift = 0,
524c6b63
FB
200 },
201 [PIX_FMT_RGB565] = {
ef9f7306 202 .name = "rgb565",
7e7e5940 203 .nb_channels = 3,
b6147995 204 .color_type = FF_COLOR_RGB,
7e7e5940 205 .pixel_type = FF_PIXEL_PACKED,
b6147995 206 .depth = 5,
2cbb7820 207 .x_chroma_shift = 0, .y_chroma_shift = 0,
524c6b63
FB
208 },
209 [PIX_FMT_RGB555] = {
ef9f7306 210 .name = "rgb555",
20d46c03 211 .nb_channels = 3,
b6147995 212 .color_type = FF_COLOR_RGB,
7e7e5940 213 .pixel_type = FF_PIXEL_PACKED,
b6147995 214 .depth = 5,
2cbb7820 215 .x_chroma_shift = 0, .y_chroma_shift = 0,
524c6b63
FB
216 },
217
218 /* gray / mono formats */
34380af0
KS
219 [PIX_FMT_GRAY16BE] = {
220 .name = "gray16be",
221 .nb_channels = 1,
222 .color_type = FF_COLOR_GRAY,
223 .pixel_type = FF_PIXEL_PLANAR,
224 .depth = 16,
225 },
226 [PIX_FMT_GRAY16LE] = {
227 .name = "gray16le",
228 .nb_channels = 1,
229 .color_type = FF_COLOR_GRAY,
230 .pixel_type = FF_PIXEL_PLANAR,
231 .depth = 16,
232 },
524c6b63 233 [PIX_FMT_GRAY8] = {
ef9f7306 234 .name = "gray",
7e7e5940 235 .nb_channels = 1,
b6147995 236 .color_type = FF_COLOR_GRAY,
7e7e5940 237 .pixel_type = FF_PIXEL_PLANAR,
b6147995 238 .depth = 8,
524c6b63
FB
239 },
240 [PIX_FMT_MONOWHITE] = {
ef9f7306 241 .name = "monow",
7e7e5940 242 .nb_channels = 1,
b6147995 243 .color_type = FF_COLOR_GRAY,
7e7e5940 244 .pixel_type = FF_PIXEL_PLANAR,
b6147995 245 .depth = 1,
524c6b63
FB
246 },
247 [PIX_FMT_MONOBLACK] = {
ef9f7306 248 .name = "monob",
7e7e5940 249 .nb_channels = 1,
b6147995 250 .color_type = FF_COLOR_GRAY,
7e7e5940 251 .pixel_type = FF_PIXEL_PLANAR,
b6147995 252 .depth = 1,
524c6b63 253 },
7e6d70d0
FB
254
255 /* paletted formats */
256 [PIX_FMT_PAL8] = {
257 .name = "pal8",
7e7e5940 258 .nb_channels = 4, .is_alpha = 1,
b6147995 259 .color_type = FF_COLOR_RGB,
7e7e5940 260 .pixel_type = FF_PIXEL_PALETTE,
b6147995 261 .depth = 8,
7e6d70d0 262 },
eab895aa
TK
263 [PIX_FMT_XVMC_MPEG2_MC] = {
264 .name = "xvmcmc",
265 },
266 [PIX_FMT_XVMC_MPEG2_IDCT] = {
267 .name = "xvmcidct",
268 },
71e445fc
DB
269 [PIX_FMT_UYYVYY411] = {
270 .name = "uyyvyy411",
f02be79d
RS
271 .nb_channels = 1,
272 .color_type = FF_COLOR_YUV,
273 .pixel_type = FF_PIXEL_PACKED,
274 .depth = 8,
275 .x_chroma_shift = 2, .y_chroma_shift = 0,
276 },
00b2fa86
LA
277 [PIX_FMT_BGR32] = {
278 .name = "bgr32",
279 .nb_channels = 4, .is_alpha = 1,
280 .color_type = FF_COLOR_RGB,
281 .pixel_type = FF_PIXEL_PACKED,
282 .depth = 8,
283 .x_chroma_shift = 0, .y_chroma_shift = 0,
284 },
285 [PIX_FMT_BGR565] = {
286 .name = "bgr565",
287 .nb_channels = 3,
288 .color_type = FF_COLOR_RGB,
289 .pixel_type = FF_PIXEL_PACKED,
290 .depth = 5,
291 .x_chroma_shift = 0, .y_chroma_shift = 0,
292 },
293 [PIX_FMT_BGR555] = {
294 .name = "bgr555",
08d23410 295 .nb_channels = 3,
00b2fa86
LA
296 .color_type = FF_COLOR_RGB,
297 .pixel_type = FF_PIXEL_PACKED,
298 .depth = 5,
299 .x_chroma_shift = 0, .y_chroma_shift = 0,
300 },
301 [PIX_FMT_RGB8] = {
302 .name = "rgb8",
303 .nb_channels = 1,
304 .color_type = FF_COLOR_RGB,
305 .pixel_type = FF_PIXEL_PACKED,
306 .depth = 8,
307 .x_chroma_shift = 0, .y_chroma_shift = 0,
308 },
309 [PIX_FMT_RGB4] = {
310 .name = "rgb4",
311 .nb_channels = 1,
312 .color_type = FF_COLOR_RGB,
313 .pixel_type = FF_PIXEL_PACKED,
314 .depth = 4,
315 .x_chroma_shift = 0, .y_chroma_shift = 0,
316 },
317 [PIX_FMT_RGB4_BYTE] = {
318 .name = "rgb4_byte",
319 .nb_channels = 1,
320 .color_type = FF_COLOR_RGB,
321 .pixel_type = FF_PIXEL_PACKED,
322 .depth = 8,
323 .x_chroma_shift = 0, .y_chroma_shift = 0,
324 },
325 [PIX_FMT_BGR8] = {
326 .name = "bgr8",
327 .nb_channels = 1,
328 .color_type = FF_COLOR_RGB,
329 .pixel_type = FF_PIXEL_PACKED,
330 .depth = 8,
331 .x_chroma_shift = 0, .y_chroma_shift = 0,
332 },
333 [PIX_FMT_BGR4] = {
334 .name = "bgr4",
335 .nb_channels = 1,
336 .color_type = FF_COLOR_RGB,
337 .pixel_type = FF_PIXEL_PACKED,
338 .depth = 4,
339 .x_chroma_shift = 0, .y_chroma_shift = 0,
340 },
341 [PIX_FMT_BGR4_BYTE] = {
342 .name = "bgr4_byte",
343 .nb_channels = 1,
344 .color_type = FF_COLOR_RGB,
345 .pixel_type = FF_PIXEL_PACKED,
346 .depth = 8,
347 .x_chroma_shift = 0, .y_chroma_shift = 0,
348 },
349 [PIX_FMT_NV12] = {
350 .name = "nv12",
351 .nb_channels = 2,
352 .color_type = FF_COLOR_YUV,
353 .pixel_type = FF_PIXEL_PLANAR,
354 .depth = 8,
355 .x_chroma_shift = 1, .y_chroma_shift = 1,
356 },
357 [PIX_FMT_NV21] = {
358 .name = "nv12",
359 .nb_channels = 2,
360 .color_type = FF_COLOR_YUV,
361 .pixel_type = FF_PIXEL_PLANAR,
362 .depth = 8,
363 .x_chroma_shift = 1, .y_chroma_shift = 1,
364 },
365
366 [PIX_FMT_BGR32_1] = {
367 .name = "bgr32_1",
368 .nb_channels = 4, .is_alpha = 1,
369 .color_type = FF_COLOR_RGB,
370 .pixel_type = FF_PIXEL_PACKED,
371 .depth = 8,
372 .x_chroma_shift = 0, .y_chroma_shift = 0,
373 },
374 [PIX_FMT_RGB32_1] = {
375 .name = "rgb32_1",
376 .nb_channels = 4, .is_alpha = 1,
377 .color_type = FF_COLOR_RGB,
378 .pixel_type = FF_PIXEL_PACKED,
379 .depth = 8,
380 .x_chroma_shift = 0, .y_chroma_shift = 0,
381 },
524c6b63
FB
382};
383
384void avcodec_get_chroma_sub_sample(int pix_fmt, int *h_shift, int *v_shift)
385{
b6147995
FB
386 *h_shift = pix_fmt_info[pix_fmt].x_chroma_shift;
387 *v_shift = pix_fmt_info[pix_fmt].y_chroma_shift;
524c6b63
FB
388}
389
390const char *avcodec_get_pix_fmt_name(int pix_fmt)
391{
392 if (pix_fmt < 0 || pix_fmt >= PIX_FMT_NB)
393 return "???";
394 else
395 return pix_fmt_info[pix_fmt].name;
396}
397
63167088
RS
398enum PixelFormat avcodec_get_pix_fmt(const char* name)
399{
115329f1
DB
400 int i;
401
63167088
RS
402 for (i=0; i < PIX_FMT_NB; i++)
403 if (!strcmp(pix_fmt_info[i].name, name))
bb270c08 404 break;
63167088
RS
405 return i;
406}
407
c3b95b1d
SS
408void avcodec_pix_fmt_string (char *buf, int buf_size, int pix_fmt)
409{
410 PixFmtInfo info= pix_fmt_info[pix_fmt];
411
412 char is_alpha_char= info.is_alpha ? 'y' : 'n';
413
414 /* print header */
415 if (pix_fmt < 0)
416 snprintf (buf, buf_size,
417 "name " " nb_channels" " depth" " is_alpha"
418 );
419 else
420 snprintf (buf, buf_size,
421 "%-10s" " %1d " " %2d " " %c ",
422 info.name,
423 info.nb_channels,
424 info.depth,
425 is_alpha_char
426 );
427}
428
0c1a9eda 429int avpicture_fill(AVPicture *picture, uint8_t *ptr,
bb270c08 430 int pix_fmt, int width, int height)
2a877875 431{
4c7e8619 432 int size, w2, h2, size2;
62a05b5b 433 const PixFmtInfo *pinfo;
115329f1 434
0ecca7a4
MN
435 if(avcodec_check_dimensions(NULL, width, height))
436 goto fail;
437
4c7e8619 438 pinfo = &pix_fmt_info[pix_fmt];
2a877875
FB
439 size = width * height;
440 switch(pix_fmt) {
441 case PIX_FMT_YUV420P:
4c7e8619
FB
442 case PIX_FMT_YUV422P:
443 case PIX_FMT_YUV444P:
444 case PIX_FMT_YUV410P:
445 case PIX_FMT_YUV411P:
4196cfb7 446 case PIX_FMT_YUV440P:
c50c0bc8
FB
447 case PIX_FMT_YUVJ420P:
448 case PIX_FMT_YUVJ422P:
449 case PIX_FMT_YUVJ444P:
4196cfb7 450 case PIX_FMT_YUVJ440P:
4c7e8619
FB
451 w2 = (width + (1 << pinfo->x_chroma_shift) - 1) >> pinfo->x_chroma_shift;
452 h2 = (height + (1 << pinfo->y_chroma_shift) - 1) >> pinfo->y_chroma_shift;
453 size2 = w2 * h2;
2a877875
FB
454 picture->data[0] = ptr;
455 picture->data[1] = picture->data[0] + size;
4c7e8619 456 picture->data[2] = picture->data[1] + size2;
b70335a2 457 picture->data[3] = NULL;
2a877875 458 picture->linesize[0] = width;
4c7e8619
FB
459 picture->linesize[1] = w2;
460 picture->linesize[2] = w2;
b70335a2 461 picture->linesize[3] = 0;
4c7e8619 462 return size + 2 * size2;
b70335a2
AJ
463 case PIX_FMT_YUVA420P:
464 w2 = (width + (1 << pinfo->x_chroma_shift) - 1) >> pinfo->x_chroma_shift;
465 h2 = (height + (1 << pinfo->y_chroma_shift) - 1) >> pinfo->y_chroma_shift;
466 size2 = w2 * h2;
467 picture->data[0] = ptr;
468 picture->data[1] = picture->data[0] + size;
469 picture->data[2] = picture->data[1] + size2;
470 picture->data[3] = picture->data[1] + size2 + size2;
471 picture->linesize[0] = width;
472 picture->linesize[1] = w2;
473 picture->linesize[2] = w2;
474 picture->linesize[3] = width;
475 return 2 * size + 2 * size2;
00b2fa86
LA
476 case PIX_FMT_NV12:
477 case PIX_FMT_NV21:
478 w2 = (width + (1 << pinfo->x_chroma_shift) - 1) >> pinfo->x_chroma_shift;
479 h2 = (height + (1 << pinfo->y_chroma_shift) - 1) >> pinfo->y_chroma_shift;
480 size2 = w2 * h2 * 2;
481 picture->data[0] = ptr;
482 picture->data[1] = picture->data[0] + size;
483 picture->data[2] = NULL;
b70335a2 484 picture->data[3] = NULL;
00b2fa86
LA
485 picture->linesize[0] = width;
486 picture->linesize[1] = w2;
487 picture->linesize[2] = 0;
b70335a2 488 picture->linesize[3] = 0;
00b2fa86 489 return size + 2 * size2;
2a877875
FB
490 case PIX_FMT_RGB24:
491 case PIX_FMT_BGR24:
492 picture->data[0] = ptr;
493 picture->data[1] = NULL;
494 picture->data[2] = NULL;
b70335a2 495 picture->data[3] = NULL;
2a877875
FB
496 picture->linesize[0] = width * 3;
497 return size * 3;
71e445fc 498 case PIX_FMT_RGB32:
00b2fa86
LA
499 case PIX_FMT_BGR32:
500 case PIX_FMT_RGB32_1:
501 case PIX_FMT_BGR32_1:
2a877875
FB
502 picture->data[0] = ptr;
503 picture->data[1] = NULL;
504 picture->data[2] = NULL;
b70335a2 505 picture->data[3] = NULL;
2a877875
FB
506 picture->linesize[0] = width * 4;
507 return size * 4;
34380af0
KS
508 case PIX_FMT_GRAY16BE:
509 case PIX_FMT_GRAY16LE:
00b2fa86
LA
510 case PIX_FMT_BGR555:
511 case PIX_FMT_BGR565:
2a877875
FB
512 case PIX_FMT_RGB555:
513 case PIX_FMT_RGB565:
71e445fc 514 case PIX_FMT_YUYV422:
2a877875
FB
515 picture->data[0] = ptr;
516 picture->data[1] = NULL;
517 picture->data[2] = NULL;
b70335a2 518 picture->data[3] = NULL;
2a877875
FB
519 picture->linesize[0] = width * 2;
520 return size * 2;
ebb177dd
TK
521 case PIX_FMT_UYVY422:
522 picture->data[0] = ptr;
523 picture->data[1] = NULL;
524 picture->data[2] = NULL;
b70335a2 525 picture->data[3] = NULL;
ebb177dd
TK
526 picture->linesize[0] = width * 2;
527 return size * 2;
71e445fc 528 case PIX_FMT_UYYVYY411:
f02be79d
RS
529 picture->data[0] = ptr;
530 picture->data[1] = NULL;
531 picture->data[2] = NULL;
b70335a2 532 picture->data[3] = NULL;
f02be79d
RS
533 picture->linesize[0] = width + width/2;
534 return size + size/2;
00b2fa86
LA
535 case PIX_FMT_RGB8:
536 case PIX_FMT_BGR8:
537 case PIX_FMT_RGB4_BYTE:
538 case PIX_FMT_BGR4_BYTE:
2a877875
FB
539 case PIX_FMT_GRAY8:
540 picture->data[0] = ptr;
541 picture->data[1] = NULL;
542 picture->data[2] = NULL;
b70335a2 543 picture->data[3] = NULL;
2a877875
FB
544 picture->linesize[0] = width;
545 return size;
00b2fa86
LA
546 case PIX_FMT_RGB4:
547 case PIX_FMT_BGR4:
548 picture->data[0] = ptr;
549 picture->data[1] = NULL;
550 picture->data[2] = NULL;
b70335a2 551 picture->data[3] = NULL;
00b2fa86
LA
552 picture->linesize[0] = width / 2;
553 return size / 2;
2a877875
FB
554 case PIX_FMT_MONOWHITE:
555 case PIX_FMT_MONOBLACK:
556 picture->data[0] = ptr;
557 picture->data[1] = NULL;
558 picture->data[2] = NULL;
b70335a2 559 picture->data[3] = NULL;
2a877875
FB
560 picture->linesize[0] = (width + 7) >> 3;
561 return picture->linesize[0] * height;
7e6d70d0
FB
562 case PIX_FMT_PAL8:
563 size2 = (size + 3) & ~3;
564 picture->data[0] = ptr;
565 picture->data[1] = ptr + size2; /* palette is stored here as 256 32 bit words */
566 picture->data[2] = NULL;
b70335a2 567 picture->data[3] = NULL;
7e6d70d0
FB
568 picture->linesize[0] = width;
569 picture->linesize[1] = 4;
570 return size2 + 256 * 4;
2a877875 571 default:
0ecca7a4 572fail:
2a877875
FB
573 picture->data[0] = NULL;
574 picture->data[1] = NULL;
575 picture->data[2] = NULL;
7e6d70d0 576 picture->data[3] = NULL;
2a877875
FB
577 return -1;
578 }
579}
580
da64ecc3 581int avpicture_layout(const AVPicture* src, int pix_fmt, int width, int height,
63167088
RS
582 unsigned char *dest, int dest_size)
583{
62a05b5b 584 const PixFmtInfo* pf = &pix_fmt_info[pix_fmt];
63167088 585 int i, j, w, h, data_planes;
115329f1 586 const unsigned char* s;
63167088
RS
587 int size = avpicture_get_size(pix_fmt, width, height);
588
0ecca7a4 589 if (size > dest_size || size < 0)
63167088
RS
590 return -1;
591
affd55a1 592 if (pf->pixel_type == FF_PIXEL_PACKED || pf->pixel_type == FF_PIXEL_PALETTE) {
71e445fc 593 if (pix_fmt == PIX_FMT_YUYV422 ||
115329f1 594 pix_fmt == PIX_FMT_UYVY422 ||
00b2fa86 595 pix_fmt == PIX_FMT_BGR565 ||
418f17e0 596 pix_fmt == PIX_FMT_BGR555 ||
ebb177dd
TK
597 pix_fmt == PIX_FMT_RGB565 ||
598 pix_fmt == PIX_FMT_RGB555)
599 w = width * 2;
71e445fc 600 else if (pix_fmt == PIX_FMT_UYYVYY411)
bb270c08
DB
601 w = width + width/2;
602 else if (pix_fmt == PIX_FMT_PAL8)
603 w = width;
604 else
605 w = width * (pf->depth * pf->nb_channels / 8);
606
607 data_planes = 1;
608 h = height;
63167088
RS
609 } else {
610 data_planes = pf->nb_channels;
bb270c08
DB
611 w = (width*pf->depth + 7)/8;
612 h = height;
63167088 613 }
115329f1 614
63167088
RS
615 for (i=0; i<data_planes; i++) {
616 if (i == 1) {
bb270c08
DB
617 w = width >> pf->x_chroma_shift;
618 h = height >> pf->y_chroma_shift;
619 }
63167088 620 s = src->data[i];
bb270c08
DB
621 for(j=0; j<h; j++) {
622 memcpy(dest, s, w);
623 dest += w;
624 s += src->linesize[i];
625 }
63167088 626 }
115329f1 627
affd55a1 628 if (pf->pixel_type == FF_PIXEL_PALETTE)
bb270c08 629 memcpy((unsigned char *)(((size_t)dest + 3) & ~3), src->data[1], 256 * 4);
115329f1 630
63167088
RS
631 return size;
632}
633
2a877875
FB
634int avpicture_get_size(int pix_fmt, int width, int height)
635{
636 AVPicture dummy_pict;
637 return avpicture_fill(&dummy_pict, NULL, pix_fmt, width, height);
638}
639
b6147995
FB
640int avcodec_get_pix_fmt_loss(int dst_pix_fmt, int src_pix_fmt,
641 int has_alpha)
642{
643 const PixFmtInfo *pf, *ps;
644 int loss;
645
646 ps = &pix_fmt_info[src_pix_fmt];
647 pf = &pix_fmt_info[dst_pix_fmt];
648
649 /* compute loss */
650 loss = 0;
651 pf = &pix_fmt_info[dst_pix_fmt];
0a9ad8d1
FB
652 if (pf->depth < ps->depth ||
653 (dst_pix_fmt == PIX_FMT_RGB555 && src_pix_fmt == PIX_FMT_RGB565))
b6147995 654 loss |= FF_LOSS_DEPTH;
0a9ad8d1
FB
655 if (pf->x_chroma_shift > ps->x_chroma_shift ||
656 pf->y_chroma_shift > ps->y_chroma_shift)
b6147995
FB
657 loss |= FF_LOSS_RESOLUTION;
658 switch(pf->color_type) {
659 case FF_COLOR_RGB:
660 if (ps->color_type != FF_COLOR_RGB &&
661 ps->color_type != FF_COLOR_GRAY)
662 loss |= FF_LOSS_COLORSPACE;
663 break;
664 case FF_COLOR_GRAY:
665 if (ps->color_type != FF_COLOR_GRAY)
666 loss |= FF_LOSS_COLORSPACE;
667 break;
668 case FF_COLOR_YUV:
669 if (ps->color_type != FF_COLOR_YUV)
670 loss |= FF_LOSS_COLORSPACE;
671 break;
672 case FF_COLOR_YUV_JPEG:
673 if (ps->color_type != FF_COLOR_YUV_JPEG &&
115329f1 674 ps->color_type != FF_COLOR_YUV &&
0a9ad8d1 675 ps->color_type != FF_COLOR_GRAY)
b6147995
FB
676 loss |= FF_LOSS_COLORSPACE;
677 break;
678 default:
679 /* fail safe test */
680 if (ps->color_type != pf->color_type)
681 loss |= FF_LOSS_COLORSPACE;
682 break;
683 }
684 if (pf->color_type == FF_COLOR_GRAY &&
685 ps->color_type != FF_COLOR_GRAY)
686 loss |= FF_LOSS_CHROMA;
687 if (!pf->is_alpha && (ps->is_alpha && has_alpha))
688 loss |= FF_LOSS_ALPHA;
115329f1 689 if (pf->pixel_type == FF_PIXEL_PALETTE &&
7e7e5940 690 (ps->pixel_type != FF_PIXEL_PALETTE && ps->color_type != FF_COLOR_GRAY))
b6147995
FB
691 loss |= FF_LOSS_COLORQUANT;
692 return loss;
693}
694
695static int avg_bits_per_pixel(int pix_fmt)
696{
697 int bits;
698 const PixFmtInfo *pf;
699
700 pf = &pix_fmt_info[pix_fmt];
7e7e5940
FB
701 switch(pf->pixel_type) {
702 case FF_PIXEL_PACKED:
b6147995 703 switch(pix_fmt) {
71e445fc 704 case PIX_FMT_YUYV422:
ebb177dd 705 case PIX_FMT_UYVY422:
b6147995
FB
706 case PIX_FMT_RGB565:
707 case PIX_FMT_RGB555:
00b2fa86
LA
708 case PIX_FMT_BGR565:
709 case PIX_FMT_BGR555:
b6147995 710 bits = 16;
b6147995 711 break;
71e445fc 712 case PIX_FMT_UYYVYY411:
bb270c08
DB
713 bits = 12;
714 break;
b6147995 715 default:
7e7e5940 716 bits = pf->depth * pf->nb_channels;
b6147995
FB
717 break;
718 }
7e7e5940
FB
719 break;
720 case FF_PIXEL_PLANAR:
721 if (pf->x_chroma_shift == 0 && pf->y_chroma_shift == 0) {
722 bits = pf->depth * pf->nb_channels;
723 } else {
115329f1 724 bits = pf->depth + ((2 * pf->depth) >>
7e7e5940
FB
725 (pf->x_chroma_shift + pf->y_chroma_shift));
726 }
727 break;
728 case FF_PIXEL_PALETTE:
729 bits = 8;
730 break;
731 default:
732 bits = -1;
733 break;
b6147995
FB
734 }
735 return bits;
736}
737
115329f1 738static int avcodec_find_best_pix_fmt1(int pix_fmt_mask,
b6147995
FB
739 int src_pix_fmt,
740 int has_alpha,
741 int loss_mask)
742{
743 int dist, i, loss, min_dist, dst_pix_fmt;
744
745 /* find exact color match with smallest size */
746 dst_pix_fmt = -1;
747 min_dist = 0x7fffffff;
748 for(i = 0;i < PIX_FMT_NB; i++) {
749 if (pix_fmt_mask & (1 << i)) {
750 loss = avcodec_get_pix_fmt_loss(i, src_pix_fmt, has_alpha) & loss_mask;
751 if (loss == 0) {
752 dist = avg_bits_per_pixel(i);
753 if (dist < min_dist) {
754 min_dist = dist;
755 dst_pix_fmt = i;
756 }
757 }
758 }
759 }
760 return dst_pix_fmt;
761}
762
b6147995
FB
763int avcodec_find_best_pix_fmt(int pix_fmt_mask, int src_pix_fmt,
764 int has_alpha, int *loss_ptr)
765{
766 int dst_pix_fmt, loss_mask, i;
767 static const int loss_mask_order[] = {
768 ~0, /* no loss first */
769 ~FF_LOSS_ALPHA,
770 ~FF_LOSS_RESOLUTION,
771 ~(FF_LOSS_COLORSPACE | FF_LOSS_RESOLUTION),
772 ~FF_LOSS_COLORQUANT,
773 ~FF_LOSS_DEPTH,
774 0,
775 };
776
777 /* try with successive loss */
778 i = 0;
779 for(;;) {
780 loss_mask = loss_mask_order[i++];
115329f1 781 dst_pix_fmt = avcodec_find_best_pix_fmt1(pix_fmt_mask, src_pix_fmt,
b6147995
FB
782 has_alpha, loss_mask);
783 if (dst_pix_fmt >= 0)
784 goto found;
785 if (loss_mask == 0)
786 break;
787 }
788 return -1;
789 found:
790 if (loss_ptr)
791 *loss_ptr = avcodec_get_pix_fmt_loss(dst_pix_fmt, src_pix_fmt, has_alpha);
792 return dst_pix_fmt;
793}
794
54009d42 795void ff_img_copy_plane(uint8_t *dst, int dst_wrap,
e352ff08
FB
796 const uint8_t *src, int src_wrap,
797 int width, int height)
7e7e5940 798{
115329f1 799 if((!dst) || (!src))
5b2ad9f5 800 return;
7e7e5940
FB
801 for(;height > 0; height--) {
802 memcpy(dst, src, width);
803 dst += dst_wrap;
804 src += src_wrap;
805 }
806}
807
636d6a4a 808void av_picture_copy(AVPicture *dst, const AVPicture *src,
7e7e5940
FB
809 int pix_fmt, int width, int height)
810{
811 int bwidth, bits, i;
62a05b5b 812 const PixFmtInfo *pf = &pix_fmt_info[pix_fmt];
115329f1 813
7e7e5940
FB
814 pf = &pix_fmt_info[pix_fmt];
815 switch(pf->pixel_type) {
816 case FF_PIXEL_PACKED:
817 switch(pix_fmt) {
71e445fc 818 case PIX_FMT_YUYV422:
ebb177dd 819 case PIX_FMT_UYVY422:
7e7e5940
FB
820 case PIX_FMT_RGB565:
821 case PIX_FMT_RGB555:
00b2fa86
LA
822 case PIX_FMT_BGR565:
823 case PIX_FMT_BGR555:
7e7e5940
FB
824 bits = 16;
825 break;
71e445fc 826 case PIX_FMT_UYYVYY411:
bb270c08
DB
827 bits = 12;
828 break;
7e7e5940
FB
829 default:
830 bits = pf->depth * pf->nb_channels;
831 break;
832 }
833 bwidth = (width * bits + 7) >> 3;
54009d42 834 ff_img_copy_plane(dst->data[0], dst->linesize[0],
7e7e5940
FB
835 src->data[0], src->linesize[0],
836 bwidth, height);
837 break;
838 case FF_PIXEL_PLANAR:
839 for(i = 0; i < pf->nb_channels; i++) {
840 int w, h;
841 w = width;
842 h = height;
843 if (i == 1 || i == 2) {
844 w >>= pf->x_chroma_shift;
845 h >>= pf->y_chroma_shift;
846 }
847 bwidth = (w * pf->depth + 7) >> 3;
54009d42 848 ff_img_copy_plane(dst->data[i], dst->linesize[i],
7e7e5940
FB
849 src->data[i], src->linesize[i],
850 bwidth, h);
851 }
852 break;
853 case FF_PIXEL_PALETTE:
54009d42 854 ff_img_copy_plane(dst->data[0], dst->linesize[0],
7e7e5940
FB
855 src->data[0], src->linesize[0],
856 width, height);
857 /* copy the palette */
54009d42 858 ff_img_copy_plane(dst->data[1], dst->linesize[1],
7e7e5940
FB
859 src->data[1], src->linesize[1],
860 4, 256);
861 break;
862 }
863}
2a877875 864
de6d9b64
FB
865/* XXX: totally non optimized */
866
dc02fc6a 867static void yuyv422_to_yuv420p(AVPicture *dst, const AVPicture *src,
524c6b63 868 int width, int height)
de6d9b64 869{
c50c0bc8
FB
870 const uint8_t *p, *p1;
871 uint8_t *lum, *cr, *cb, *lum1, *cr1, *cb1;
d4f5d74a 872 int w;
115329f1 873
c50c0bc8
FB
874 p1 = src->data[0];
875 lum1 = dst->data[0];
0a05e494
FB
876 cb1 = dst->data[1];
877 cr1 = dst->data[2];
c50c0bc8 878
d4f5d74a 879 for(;height >= 1; height -= 2) {
c50c0bc8
FB
880 p = p1;
881 lum = lum1;
882 cb = cb1;
883 cr = cr1;
d4f5d74a 884 for(w = width; w >= 2; w -= 2) {
e78df699
MN
885 lum[0] = p[0];
886 cb[0] = p[1];
887 lum[1] = p[2];
888 cr[0] = p[3];
de6d9b64
FB
889 p += 4;
890 lum += 2;
891 cb++;
892 cr++;
893 }
d4f5d74a 894 if (w) {
e78df699 895 lum[0] = p[0];
d4f5d74a
GM
896 cb[0] = p[1];
897 cr[0] = p[3];
898 cb++;
899 cr++;
de6d9b64 900 }
c50c0bc8
FB
901 p1 += src->linesize[0];
902 lum1 += dst->linesize[0];
d4f5d74a
GM
903 if (height>1) {
904 p = p1;
905 lum = lum1;
906 for(w = width; w >= 2; w -= 2) {
907 lum[0] = p[0];
908 lum[1] = p[2];
909 p += 4;
910 lum += 2;
911 }
912 if (w) {
913 lum[0] = p[0];
914 }
915 p1 += src->linesize[0];
916 lum1 += dst->linesize[0];
917 }
c50c0bc8
FB
918 cb1 += dst->linesize[1];
919 cr1 += dst->linesize[2];
920 }
921}
922
ebb177dd
TK
923static void uyvy422_to_yuv420p(AVPicture *dst, const AVPicture *src,
924 int width, int height)
925{
926 const uint8_t *p, *p1;
927 uint8_t *lum, *cr, *cb, *lum1, *cr1, *cb1;
928 int w;
115329f1 929
ebb177dd 930 p1 = src->data[0];
115329f1 931
ebb177dd
TK
932 lum1 = dst->data[0];
933 cb1 = dst->data[1];
934 cr1 = dst->data[2];
935
936 for(;height >= 1; height -= 2) {
937 p = p1;
938 lum = lum1;
939 cb = cb1;
940 cr = cr1;
941 for(w = width; w >= 2; w -= 2) {
942 lum[0] = p[1];
943 cb[0] = p[0];
944 lum[1] = p[3];
945 cr[0] = p[2];
946 p += 4;
947 lum += 2;
948 cb++;
949 cr++;
950 }
951 if (w) {
952 lum[0] = p[1];
953 cb[0] = p[0];
954 cr[0] = p[2];
955 cb++;
956 cr++;
957 }
958 p1 += src->linesize[0];
959 lum1 += dst->linesize[0];
960 if (height>1) {
961 p = p1;
962 lum = lum1;
963 for(w = width; w >= 2; w -= 2) {
964 lum[0] = p[1];
965 lum[1] = p[3];
966 p += 4;
967 lum += 2;
968 }
969 if (w) {
970 lum[0] = p[1];
971 }
972 p1 += src->linesize[0];
973 lum1 += dst->linesize[0];
974 }
975 cb1 += dst->linesize[1];
976 cr1 += dst->linesize[2];
977 }
978}
979
980
981static void uyvy422_to_yuv422p(AVPicture *dst, const AVPicture *src,
982 int width, int height)
983{
984 const uint8_t *p, *p1;
985 uint8_t *lum, *cr, *cb, *lum1, *cr1, *cb1;
986 int w;
987
988 p1 = src->data[0];
989 lum1 = dst->data[0];
990 cb1 = dst->data[1];
991 cr1 = dst->data[2];
992 for(;height > 0; height--) {
993 p = p1;
994 lum = lum1;
995 cb = cb1;
996 cr = cr1;
997 for(w = width; w >= 2; w -= 2) {
998 lum[0] = p[1];
999 cb[0] = p[0];
1000 lum[1] = p[3];
1001 cr[0] = p[2];
1002 p += 4;
1003 lum += 2;
1004 cb++;
1005 cr++;
1006 }
1007 p1 += src->linesize[0];
1008 lum1 += dst->linesize[0];
1009 cb1 += dst->linesize[1];
1010 cr1 += dst->linesize[2];
1011 }
1012}
1013
1014
dc02fc6a 1015static void yuyv422_to_yuv422p(AVPicture *dst, const AVPicture *src,
c50c0bc8
FB
1016 int width, int height)
1017{
1018 const uint8_t *p, *p1;
1019 uint8_t *lum, *cr, *cb, *lum1, *cr1, *cb1;
1020 int w;
1021
1022 p1 = src->data[0];
1023 lum1 = dst->data[0];
0a05e494
FB
1024 cb1 = dst->data[1];
1025 cr1 = dst->data[2];
1026 for(;height > 0; height--) {
c50c0bc8
FB
1027 p = p1;
1028 lum = lum1;
1029 cb = cb1;
1030 cr = cr1;
1031 for(w = width; w >= 2; w -= 2) {
1032 lum[0] = p[0];
1033 cb[0] = p[1];
1034 lum[1] = p[2];
1035 cr[0] = p[3];
1036 p += 4;
1037 lum += 2;
1038 cb++;
1039 cr++;
1040 }
1041 p1 += src->linesize[0];
1042 lum1 += dst->linesize[0];
1043 cb1 += dst->linesize[1];
1044 cr1 += dst->linesize[2];
de6d9b64
FB
1045 }
1046}
1047
dc02fc6a 1048static void yuv422p_to_yuyv422(AVPicture *dst, const AVPicture *src,
c50c0bc8
FB
1049 int width, int height)
1050{
1051 uint8_t *p, *p1;
1052 const uint8_t *lum, *cr, *cb, *lum1, *cr1, *cb1;
1053 int w;
1054
1055 p1 = dst->data[0];
1056 lum1 = src->data[0];
0a05e494
FB
1057 cb1 = src->data[1];
1058 cr1 = src->data[2];
1059 for(;height > 0; height--) {
c50c0bc8
FB
1060 p = p1;
1061 lum = lum1;
1062 cb = cb1;
1063 cr = cr1;
1064 for(w = width; w >= 2; w -= 2) {
1065 p[0] = lum[0];
1066 p[1] = cb[0];
1067 p[2] = lum[1];
1068 p[3] = cr[0];
1069 p += 4;
1070 lum += 2;
1071 cb++;
1072 cr++;
1073 }
0a05e494
FB
1074 p1 += dst->linesize[0];
1075 lum1 += src->linesize[0];
1076 cb1 += src->linesize[1];
1077 cr1 += src->linesize[2];
c50c0bc8
FB
1078 }
1079}
1080
ebb177dd
TK
1081static void yuv422p_to_uyvy422(AVPicture *dst, const AVPicture *src,
1082 int width, int height)
1083{
1084 uint8_t *p, *p1;
1085 const uint8_t *lum, *cr, *cb, *lum1, *cr1, *cb1;
1086 int w;
1087
1088 p1 = dst->data[0];
1089 lum1 = src->data[0];
1090 cb1 = src->data[1];
1091 cr1 = src->data[2];
1092 for(;height > 0; height--) {
1093 p = p1;
1094 lum = lum1;
1095 cb = cb1;
1096 cr = cr1;
1097 for(w = width; w >= 2; w -= 2) {
1098 p[1] = lum[0];
1099 p[0] = cb[0];
1100 p[3] = lum[1];
1101 p[2] = cr[0];
1102 p += 4;
1103 lum += 2;
1104 cb++;
1105 cr++;
1106 }
1107 p1 += dst->linesize[0];
1108 lum1 += src->linesize[0];
1109 cb1 += src->linesize[1];
1110 cr1 += src->linesize[2];
1111 }
1112}
1113
9ac529a5 1114static void uyyvyy411_to_yuv411p(AVPicture *dst, const AVPicture *src,
f02be79d
RS
1115 int width, int height)
1116{
1117 const uint8_t *p, *p1;
1118 uint8_t *lum, *cr, *cb, *lum1, *cr1, *cb1;
1119 int w;
1120
1121 p1 = src->data[0];
1122 lum1 = dst->data[0];
1123 cb1 = dst->data[1];
1124 cr1 = dst->data[2];
1125 for(;height > 0; height--) {
1126 p = p1;
1127 lum = lum1;
1128 cb = cb1;
1129 cr = cr1;
1130 for(w = width; w >= 4; w -= 4) {
1131 cb[0] = p[0];
bb270c08 1132 lum[0] = p[1];
f02be79d
RS
1133 lum[1] = p[2];
1134 cr[0] = p[3];
bb270c08
DB
1135 lum[2] = p[4];
1136 lum[3] = p[5];
f02be79d
RS
1137 p += 6;
1138 lum += 4;
1139 cb++;
1140 cr++;
1141 }
1142 p1 += src->linesize[0];
1143 lum1 += dst->linesize[0];
1144 cb1 += dst->linesize[1];
1145 cr1 += dst->linesize[2];
1146 }
1147}
ebb177dd
TK
1148
1149
dc02fc6a 1150static void yuv420p_to_yuyv422(AVPicture *dst, const AVPicture *src,
d7e2f57f
MN
1151 int width, int height)
1152{
1153 int w, h;
1154 uint8_t *line1, *line2, *linesrc = dst->data[0];
1155 uint8_t *lum1, *lum2, *lumsrc = src->data[0];
1156 uint8_t *cb1, *cb2 = src->data[1];
1157 uint8_t *cr1, *cr2 = src->data[2];
115329f1 1158
d7e2f57f
MN
1159 for(h = height / 2; h--;) {
1160 line1 = linesrc;
1161 line2 = linesrc + dst->linesize[0];
115329f1 1162
d7e2f57f
MN
1163 lum1 = lumsrc;
1164 lum2 = lumsrc + src->linesize[0];
115329f1 1165
d7e2f57f
MN
1166 cb1 = cb2;
1167 cr1 = cr2;
115329f1 1168
d7e2f57f 1169 for(w = width / 2; w--;) {
115329f1
DB
1170 *line1++ = *lum1++; *line2++ = *lum2++;
1171 *line1++ = *line2++ = *cb1++;
1172 *line1++ = *lum1++; *line2++ = *lum2++;
d7e2f57f
MN
1173 *line1++ = *line2++ = *cr1++;
1174 }
115329f1 1175
d7e2f57f
MN
1176 linesrc += dst->linesize[0] * 2;
1177 lumsrc += src->linesize[0] * 2;
1178 cb2 += src->linesize[1];
1179 cr2 += src->linesize[2];
1180 }
1181}
1182
bac65165
LA
1183static void yuv420p_to_uyvy422(AVPicture *dst, const AVPicture *src,
1184 int width, int height)
1185{
1186 int w, h;
1187 uint8_t *line1, *line2, *linesrc = dst->data[0];
1188 uint8_t *lum1, *lum2, *lumsrc = src->data[0];
1189 uint8_t *cb1, *cb2 = src->data[1];
1190 uint8_t *cr1, *cr2 = src->data[2];
115329f1 1191
bac65165
LA
1192 for(h = height / 2; h--;) {
1193 line1 = linesrc;
1194 line2 = linesrc + dst->linesize[0];
115329f1 1195
bac65165
LA
1196 lum1 = lumsrc;
1197 lum2 = lumsrc + src->linesize[0];
115329f1 1198
bac65165
LA
1199 cb1 = cb2;
1200 cr1 = cr2;
115329f1 1201
bac65165 1202 for(w = width / 2; w--;) {
115329f1
DB
1203 *line1++ = *line2++ = *cb1++;
1204 *line1++ = *lum1++; *line2++ = *lum2++;
bac65165 1205 *line1++ = *line2++ = *cr1++;
115329f1 1206 *line1++ = *lum1++; *line2++ = *lum2++;
bac65165 1207 }
115329f1 1208
bac65165
LA
1209 linesrc += dst->linesize[0] * 2;
1210 lumsrc += src->linesize[0] * 2;
1211 cb2 += src->linesize[1];
1212 cr2 += src->linesize[2];
1213 }
1214}
1215
c50c0bc8
FB
1216static uint8_t y_ccir_to_jpeg[256];
1217static uint8_t y_jpeg_to_ccir[256];
1218static uint8_t c_ccir_to_jpeg[256];
1219static uint8_t c_jpeg_to_ccir[256];
1220
1221/* init various conversion tables */
1222static void img_convert_init(void)
b6147995 1223{
c50c0bc8 1224 int i;
55fde95e 1225 uint8_t *cm = ff_cropTbl + MAX_NEG_CROP;
b6147995 1226
c50c0bc8
FB
1227 for(i = 0;i < 256; i++) {
1228 y_ccir_to_jpeg[i] = Y_CCIR_TO_JPEG(i);
1229 y_jpeg_to_ccir[i] = Y_JPEG_TO_CCIR(i);
1230 c_ccir_to_jpeg[i] = C_CCIR_TO_JPEG(i);
1231 c_jpeg_to_ccir[i] = C_JPEG_TO_CCIR(i);
b6147995
FB
1232 }
1233}
1234
c50c0bc8 1235/* apply to each pixel the given table */
115329f1 1236static void img_apply_table(uint8_t *dst, int dst_wrap,
c50c0bc8
FB
1237 const uint8_t *src, int src_wrap,
1238 int width, int height, const uint8_t *table1)
b6147995
FB
1239{
1240 int n;
1241 const uint8_t *s;
1242 uint8_t *d;
c50c0bc8 1243 const uint8_t *table;
b6147995 1244
c50c0bc8 1245 table = table1;
b6147995
FB
1246 for(;height > 0; height--) {
1247 s = src;
1248 d = dst;
1249 n = width;
1250 while (n >= 4) {
c50c0bc8
FB
1251 d[0] = table[s[0]];
1252 d[1] = table[s[1]];
1253 d[2] = table[s[2]];
1254 d[3] = table[s[3]];
b6147995
FB
1255 d += 4;
1256 s += 4;
1257 n -= 4;
1258 }
1259 while (n > 0) {
c50c0bc8 1260 d[0] = table[s[0]];
b6147995
FB
1261 d++;
1262 s++;
1263 n--;
1264 }
1265 dst += dst_wrap;
1266 src += src_wrap;
1267 }
1268}
1269
85c242d8 1270/* XXX: use generic filter ? */
e352ff08
FB
1271/* XXX: in most cases, the sampling position is incorrect */
1272
1273/* 4x1 -> 1x1 */
115329f1 1274static void shrink41(uint8_t *dst, int dst_wrap,
e352ff08
FB
1275 const uint8_t *src, int src_wrap,
1276 int width, int height)
1277{
1278 int w;
1279 const uint8_t *s;
1280 uint8_t *d;
1281
1282 for(;height > 0; height--) {
1283 s = src;
1284 d = dst;
1285 for(w = width;w > 0; w--) {
1286 d[0] = (s[0] + s[1] + s[2] + s[3] + 2) >> 2;
1287 s += 4;
1288 d++;
1289 }
1290 src += src_wrap;
1291 dst += dst_wrap;
1292 }
1293}
1294
1295/* 2x1 -> 1x1 */
115329f1 1296static void shrink21(uint8_t *dst, int dst_wrap,
e352ff08
FB
1297 const uint8_t *src, int src_wrap,
1298 int width, int height)
1299{
1300 int w;
1301 const uint8_t *s;
1302 uint8_t *d;
1303
1304 for(;height > 0; height--) {
1305 s = src;
1306 d = dst;
1307 for(w = width;w > 0; w--) {
1308 d[0] = (s[0] + s[1]) >> 1;
1309 s += 2;
1310 d++;
1311 }
1312 src += src_wrap;
1313 dst += dst_wrap;
1314 }
1315}
1316
85c242d8 1317/* 1x2 -> 1x1 */
115329f1 1318static void shrink12(uint8_t *dst, int dst_wrap,
e352ff08
FB
1319 const uint8_t *src, int src_wrap,
1320 int width, int height)
85c242d8
FB
1321{
1322 int w;
e352ff08
FB
1323 uint8_t *d;
1324 const uint8_t *s1, *s2;
85c242d8
FB
1325
1326 for(;height > 0; height--) {
1327 s1 = src;
1328 s2 = s1 + src_wrap;
1329 d = dst;
1330 for(w = width;w >= 4; w-=4) {
1331 d[0] = (s1[0] + s2[0]) >> 1;
1332 d[1] = (s1[1] + s2[1]) >> 1;
1333 d[2] = (s1[2] + s2[2]) >> 1;
1334 d[3] = (s1[3] + s2[3]) >> 1;
1335 s1 += 4;
1336 s2 += 4;
1337 d += 4;
1338 }
1339 for(;w > 0; w--) {
1340 d[0] = (s1[0] + s2[0]) >> 1;
1341 s1++;
1342 s2++;
1343 d++;
1344 }
1345 src += 2 * src_wrap;
1346 dst += dst_wrap;
1347 }
1348}
1349
1350/* 2x2 -> 1x1 */
54009d42 1351void ff_shrink22(uint8_t *dst, int dst_wrap,
e352ff08 1352 const uint8_t *src, int src_wrap,
85c242d8
FB
1353 int width, int height)
1354{
1355 int w;
e352ff08
FB
1356 const uint8_t *s1, *s2;
1357 uint8_t *d;
85c242d8
FB
1358
1359 for(;height > 0; height--) {
1360 s1 = src;
1361 s2 = s1 + src_wrap;
1362 d = dst;
1363 for(w = width;w >= 4; w-=4) {
0a9ad8d1
FB
1364 d[0] = (s1[0] + s1[1] + s2[0] + s2[1] + 2) >> 2;
1365 d[1] = (s1[2] + s1[3] + s2[2] + s2[3] + 2) >> 2;
1366 d[2] = (s1[4] + s1[5] + s2[4] + s2[5] + 2) >> 2;
1367 d[3] = (s1[6] + s1[7] + s2[6] + s2[7] + 2) >> 2;
85c242d8
FB
1368 s1 += 8;
1369 s2 += 8;
1370 d += 4;
1371 }
1372 for(;w > 0; w--) {
0a9ad8d1 1373 d[0] = (s1[0] + s1[1] + s2[0] + s2[1] + 2) >> 2;
85c242d8
FB
1374 s1 += 2;
1375 s2 += 2;
1376 d++;
1377 }
1378 src += 2 * src_wrap;
1379 dst += dst_wrap;
1380 }
1381}
1382
e352ff08 1383/* 4x4 -> 1x1 */
54009d42 1384void ff_shrink44(uint8_t *dst, int dst_wrap,
e352ff08 1385 const uint8_t *src, int src_wrap,
6742d95d
FR
1386 int width, int height)
1387{
1388 int w;
e352ff08
FB
1389 const uint8_t *s1, *s2, *s3, *s4;
1390 uint8_t *d;
6742d95d
FR
1391
1392 for(;height > 0; height--) {
1393 s1 = src;
e352ff08
FB
1394 s2 = s1 + src_wrap;
1395 s3 = s2 + src_wrap;
1396 s4 = s3 + src_wrap;
6742d95d 1397 d = dst;
e352ff08
FB
1398 for(w = width;w > 0; w--) {
1399 d[0] = (s1[0] + s1[1] + s1[2] + s1[3] +
1400 s2[0] + s2[1] + s2[2] + s2[3] +
1401 s3[0] + s3[1] + s3[2] + s3[3] +
1402 s4[0] + s4[1] + s4[2] + s4[3] + 8) >> 4;
1403 s1 += 4;
1404 s2 += 4;
1405 s3 += 4;
1406 s4 += 4;
6742d95d
FR
1407 d++;
1408 }
e352ff08
FB
1409 src += 4 * src_wrap;
1410 dst += dst_wrap;
1411 }
1412}
1413
54009d42
MN
1414/* 8x8 -> 1x1 */
1415void ff_shrink88(uint8_t *dst, int dst_wrap,
1416 const uint8_t *src, int src_wrap,
1417 int width, int height)
1418{
1419 int w, i;
1420
1421 for(;height > 0; height--) {
1422 for(w = width;w > 0; w--) {
1423 int tmp=0;
1424 for(i=0; i<8; i++){
1425 tmp += src[0] + src[1] + src[2] + src[3] + src[4] + src[5] + src[6] + src[7];
1426 src += src_wrap;
1427 }
1428 *(dst++) = (tmp + 32)>>6;
1429 src += 8 - 8*src_wrap;
1430 }
1431 src += 8*src_wrap - 8*width;
1432 dst += dst_wrap - width;
1433 }
1434}
1435
e352ff08
FB
1436static void grow21_line(uint8_t *dst, const uint8_t *src,
1437 int width)
1438{
1439 int w;
1440 const uint8_t *s1;
1441 uint8_t *d;
1442
1443 s1 = src;
1444 d = dst;
1445 for(w = width;w >= 4; w-=4) {
1446 d[1] = d[0] = s1[0];
1447 d[3] = d[2] = s1[1];
1448 s1 += 2;
1449 d += 4;
1450 }
1451 for(;w >= 2; w -= 2) {
1452 d[1] = d[0] = s1[0];
1453 s1 ++;
1454 d += 2;
1455 }
1456 /* only needed if width is not a multiple of two */
1457 /* XXX: veryfy that */
1458 if (w) {
1459 d[0] = s1[0];
1460 }
1461}
1462
1463static void grow41_line(uint8_t *dst, const uint8_t *src,
1464 int width)
1465{
1466 int w, v;
1467 const uint8_t *s1;
1468 uint8_t *d;
1469
1470 s1 = src;
1471 d = dst;
1472 for(w = width;w >= 4; w-=4) {
1473 v = s1[0];
1474 d[0] = v;
1475 d[1] = v;
1476 d[2] = v;
1477 d[3] = v;
1478 s1 ++;
1479 d += 4;
1480 }
1481}
1482
1483/* 1x1 -> 2x1 */
1484static void grow21(uint8_t *dst, int dst_wrap,
1485 const uint8_t *src, int src_wrap,
1486 int width, int height)
1487{
1488 for(;height > 0; height--) {
1489 grow21_line(dst, src, width);
1490 src += src_wrap;
1491 dst += dst_wrap;
1492 }
1493}
1494
4196cfb7
1495/* 1x1 -> 1x2 */
1496static void grow12(uint8_t *dst, int dst_wrap,
1497 const uint8_t *src, int src_wrap,
1498 int width, int height)
1499{
1500 for(;height > 0; height-=2) {
1501 memcpy(dst, src, width);
1502 dst += dst_wrap;
1503 memcpy(dst, src, width);
1504 dst += dst_wrap;
1505 src += src_wrap;
1506 }
1507}
1508
e352ff08
FB
1509/* 1x1 -> 2x2 */
1510static void grow22(uint8_t *dst, int dst_wrap,
1511 const uint8_t *src, int src_wrap,
1512 int width, int height)
1513{
1514 for(;height > 0; height--) {
1515 grow21_line(dst, src, width);
6742d95d
FR
1516 if (height%2)
1517 src += src_wrap;
1518 dst += dst_wrap;
1519 }
1520}
1521
e352ff08
FB
1522/* 1x1 -> 4x1 */
1523static void grow41(uint8_t *dst, int dst_wrap,
1524 const uint8_t *src, int src_wrap,
1525 int width, int height)
1526{
1527 for(;height > 0; height--) {
1528 grow41_line(dst, src, width);
1529 src += src_wrap;
1530 dst += dst_wrap;
1531 }
1532}
1533
1534/* 1x1 -> 4x4 */
1535static void grow44(uint8_t *dst, int dst_wrap,
1536 const uint8_t *src, int src_wrap,
1537 int width, int height)
1538{
1539 for(;height > 0; height--) {
1540 grow41_line(dst, src, width);
1541 if ((height & 3) == 1)
1542 src += src_wrap;
1543 dst += dst_wrap;
1544 }
1545}
1546
524c6b63 1547/* 1x2 -> 2x1 */
115329f1 1548static void conv411(uint8_t *dst, int dst_wrap,
e352ff08 1549 const uint8_t *src, int src_wrap,
789587d5
FB
1550 int width, int height)
1551{
1552 int w, c;
e352ff08
FB
1553 const uint8_t *s1, *s2;
1554 uint8_t *d;
789587d5 1555
50643575
MN
1556 width>>=1;
1557
524c6b63 1558 for(;height > 0; height--) {
789587d5
FB
1559 s1 = src;
1560 s2 = src + src_wrap;
1561 d = dst;
1562 for(w = width;w > 0; w--) {
1563 c = (s1[0] + s2[0]) >> 1;
1564 d[0] = c;
1565 d[1] = c;
1566 s1++;
1567 s2++;
1568 d += 2;
1569 }
1570 src += src_wrap * 2;
1571 dst += dst_wrap;
1572 }
1573}
1574
7e7e5940
FB
1575/* XXX: add jpeg quantize code */
1576
1577#define TRANSP_INDEX (6*6*6)
1578
1579/* this is maybe slow, but allows for extensions */
1580static inline unsigned char gif_clut_index(uint8_t r, uint8_t g, uint8_t b)
85c242d8 1581{
7e7e5940 1582 return ((((r)/47)%6)*6*6+(((g)/47)%6)*6+(((b)/47)%6));
85c242d8
FB
1583}
1584
7e7e5940
FB
1585static void build_rgb_palette(uint8_t *palette, int has_alpha)
1586{
1587 uint32_t *pal;
1588 static const uint8_t pal_value[6] = { 0x00, 0x33, 0x66, 0x99, 0xcc, 0xff };
1589 int i, r, g, b;
1590
1591 pal = (uint32_t *)palette;
1592 i = 0;
1593 for(r = 0; r < 6; r++) {
1594 for(g = 0; g < 6; g++) {
1595 for(b = 0; b < 6; b++) {
115329f1 1596 pal[i++] = (0xff << 24) | (pal_value[r] << 16) |
7e7e5940
FB
1597 (pal_value[g] << 8) | pal_value[b];
1598 }
1599 }
1600 }
1601 if (has_alpha)
1602 pal[i++] = 0;
1603 while (i < 256)
1604 pal[i++] = 0xff000000;
524c6b63
FB
1605}
1606
1607/* copy bit n to bits 0 ... n - 1 */
1608static inline unsigned int bitcopy_n(unsigned int a, int n)
b71472eb 1609{
524c6b63
FB
1610 int mask;
1611 mask = (1 << n) - 1;
1612 return (a & (0xff & ~mask)) | ((-((a >> n) & 1)) & mask);
1613}
1614
1615/* rgb555 handling */
1616
7e7e5940
FB
1617#define RGB_NAME rgb555
1618
524c6b63
FB
1619#define RGB_IN(r, g, b, s)\
1620{\
0c1a9eda 1621 unsigned int v = ((const uint16_t *)(s))[0];\
524c6b63
FB
1622 r = bitcopy_n(v >> (10 - 3), 3);\
1623 g = bitcopy_n(v >> (5 - 3), 3);\
1624 b = bitcopy_n(v << 3, 3);\
1625}
1626
7e7e5940 1627
20d46c03 1628#define RGB_OUT(d, r, g, b)\
7e7e5940 1629{\
20d46c03 1630 ((uint16_t *)(d))[0] = ((r >> 3) << 10) | ((g >> 3) << 5) | (b >> 3);\
524c6b63
FB
1631}
1632
1633#define BPP 2
1634
7e7e5940 1635#include "imgconvert_template.h"
524c6b63
FB
1636
1637/* rgb565 handling */
1638
7e7e5940
FB
1639#define RGB_NAME rgb565
1640
524c6b63
FB
1641#define RGB_IN(r, g, b, s)\
1642{\
0c1a9eda 1643 unsigned int v = ((const uint16_t *)(s))[0];\
524c6b63
FB
1644 r = bitcopy_n(v >> (11 - 3), 3);\
1645 g = bitcopy_n(v >> (5 - 2), 2);\
1646 b = bitcopy_n(v << 3, 3);\
1647}
1648
1649#define RGB_OUT(d, r, g, b)\
1650{\
0c1a9eda 1651 ((uint16_t *)(d))[0] = ((r >> 3) << 11) | ((g >> 2) << 5) | (b >> 3);\
524c6b63
FB
1652}
1653
1654#define BPP 2
1655
7e7e5940 1656#include "imgconvert_template.h"
524c6b63
FB
1657
1658/* bgr24 handling */
1659
7e7e5940
FB
1660#define RGB_NAME bgr24
1661
524c6b63
FB
1662#define RGB_IN(r, g, b, s)\
1663{\
1664 b = (s)[0];\
1665 g = (s)[1];\
1666 r = (s)[2];\
1667}
1668
1669#define RGB_OUT(d, r, g, b)\
1670{\
1671 (d)[0] = b;\
1672 (d)[1] = g;\
1673 (d)[2] = r;\
1674}
1675
1676#define BPP 3
1677
7e7e5940 1678#include "imgconvert_template.h"
524c6b63
FB
1679
1680#undef RGB_IN
1681#undef RGB_OUT
1682#undef BPP
1683
1684/* rgb24 handling */
1685
7e7e5940
FB
1686#define RGB_NAME rgb24
1687#define FMT_RGB24
1688
524c6b63
FB
1689#define RGB_IN(r, g, b, s)\
1690{\
1691 r = (s)[0];\
1692 g = (s)[1];\
1693 b = (s)[2];\
1694}
1695
1696#define RGB_OUT(d, r, g, b)\
1697{\
1698 (d)[0] = r;\
1699 (d)[1] = g;\
1700 (d)[2] = b;\
1701}
1702
1703#define BPP 3
1704
7e7e5940 1705#include "imgconvert_template.h"
524c6b63 1706
3cf5b6be 1707/* rgb32 handling */
524c6b63 1708
3cf5b6be
DB
1709#define RGB_NAME rgb32
1710#define FMT_RGB32
7e7e5940 1711
524c6b63
FB
1712#define RGB_IN(r, g, b, s)\
1713{\
0c1a9eda 1714 unsigned int v = ((const uint32_t *)(s))[0];\
524c6b63
FB
1715 r = (v >> 16) & 0xff;\
1716 g = (v >> 8) & 0xff;\
1717 b = v & 0xff;\
1718}
1719
7e7e5940 1720#define RGBA_IN(r, g, b, a, s)\
524c6b63 1721{\
7e7e5940
FB
1722 unsigned int v = ((const uint32_t *)(s))[0];\
1723 a = (v >> 24) & 0xff;\
1724 r = (v >> 16) & 0xff;\
1725 g = (v >> 8) & 0xff;\
1726 b = v & 0xff;\
524c6b63
FB
1727}
1728
7e7e5940
FB
1729#define RGBA_OUT(d, r, g, b, a)\
1730{\
1731 ((uint32_t *)(d))[0] = (a << 24) | (r << 16) | (g << 8) | b;\
b71472eb
PG
1732}
1733
7e7e5940 1734#define BPP 4
524c6b63 1735
7e7e5940 1736#include "imgconvert_template.h"
b71472eb 1737
da64ecc3 1738static void mono_to_gray(AVPicture *dst, const AVPicture *src,
2a877875 1739 int width, int height, int xor_mask)
524c6b63
FB
1740{
1741 const unsigned char *p;
1742 unsigned char *q;
1743 int v, dst_wrap, src_wrap;
1744 int y, w;
1745
1746 p = src->data[0];
1747 src_wrap = src->linesize[0] - ((width + 7) >> 3);
1748
1749 q = dst->data[0];
2a877875 1750 dst_wrap = dst->linesize[0] - width;
524c6b63 1751 for(y=0;y<height;y++) {
115329f1 1752 w = width;
524c6b63 1753 while (w >= 8) {
2a877875
FB
1754 v = *p++ ^ xor_mask;
1755 q[0] = -(v >> 7);
1756 q[1] = -((v >> 6) & 1);
1757 q[2] = -((v >> 5) & 1);
1758 q[3] = -((v >> 4) & 1);
1759 q[4] = -((v >> 3) & 1);
1760 q[5] = -((v >> 2) & 1);
1761 q[6] = -((v >> 1) & 1);
1762 q[7] = -((v >> 0) & 1);
524c6b63 1763 w -= 8;
2a877875 1764 q += 8;
524c6b63
FB
1765 }
1766 if (w > 0) {
2a877875 1767 v = *p++ ^ xor_mask;
524c6b63 1768 do {
2a877875
FB
1769 q[0] = -((v >> 7) & 1);
1770 q++;
524c6b63
FB
1771 v <<= 1;
1772 } while (--w);
85c242d8 1773 }
524c6b63
FB
1774 p += src_wrap;
1775 q += dst_wrap;
85c242d8
FB
1776 }
1777}
1778
da64ecc3 1779static void monowhite_to_gray(AVPicture *dst, const AVPicture *src,
524c6b63
FB
1780 int width, int height)
1781{
2a877875
FB
1782 mono_to_gray(dst, src, width, height, 0xff);
1783}
524c6b63 1784
da64ecc3 1785static void monoblack_to_gray(AVPicture *dst, const AVPicture *src,
2a877875
FB
1786 int width, int height)
1787{
1788 mono_to_gray(dst, src, width, height, 0x00);
1789}
524c6b63 1790
da64ecc3 1791static void gray_to_mono(AVPicture *dst, const AVPicture *src,
2a877875
FB
1792 int width, int height, int xor_mask)
1793{
1794 int n;
0c1a9eda
ZK
1795 const uint8_t *s;
1796 uint8_t *d;
2a877875
FB
1797 int j, b, v, n1, src_wrap, dst_wrap, y;
1798
1799 s = src->data[0];
1800 src_wrap = src->linesize[0] - width;
1801
1802 d = dst->data[0];
1803 dst_wrap = dst->linesize[0] - ((width + 7) >> 3);
524c6b63
FB
1804
1805 for(y=0;y<height;y++) {
2a877875
FB
1806 n = width;
1807 while (n >= 8) {
1808 v = 0;
1809 for(j=0;j<8;j++) {
1810 b = s[0];
1811 s++;
1812 v = (v << 1) | (b >> 7);
1813 }
1814 d[0] = v ^ xor_mask;
1815 d++;
1816 n -= 8;
524c6b63 1817 }
2a877875
FB
1818 if (n > 0) {
1819 n1 = n;
1820 v = 0;
1821 while (n > 0) {
1822 b = s[0];
1823 s++;
1824 v = (v << 1) | (b >> 7);
1825 n--;
1826 }
1827 d[0] = (v << (8 - (n1 & 7))) ^ xor_mask;
1828 d++;
524c6b63 1829 }
2a877875
FB
1830 s += src_wrap;
1831 d += dst_wrap;
524c6b63
FB
1832 }
1833}
1834
da64ecc3 1835static void gray_to_monowhite(AVPicture *dst, const AVPicture *src,
2a877875
FB
1836 int width, int height)
1837{
1838 gray_to_mono(dst, src, width, height, 0xff);
1839}
1840
da64ecc3 1841static void gray_to_monoblack(AVPicture *dst, const AVPicture *src,
2a877875
FB
1842 int width, int height)
1843{
1844 gray_to_mono(dst, src, width, height, 0x00);
1845}
1846
34380af0
KS
1847static void gray_to_gray16(AVPicture *dst, const AVPicture *src,
1848 int width, int height)
1849{
1850 int x, y, src_wrap, dst_wrap;
1851 uint8_t *s, *d;
1852 s = src->data[0];
1853 src_wrap = src->linesize[0] - width;
1854 d = dst->data[0];
1855 dst_wrap = dst->linesize[0] - width * 2;
1856 for(y=0; y<height; y++){
1857 for(x=0; x<width; x++){
1858 *d++ = *s;
1859 *d++ = *s++;
1860 }
1861 s += src_wrap;
1862 d += dst_wrap;
1863 }
1864}
1865
1866static void gray16_to_gray(AVPicture *dst, const AVPicture *src,
1867 int width, int height)
1868{
1869 int x, y, src_wrap, dst_wrap;
1870 uint8_t *s, *d;
1871 s = src->data[0];
1872 src_wrap = src->linesize[0] - width * 2;
1873 d = dst->data[0];
1874 dst_wrap = dst->linesize[0] - width;
1875 for(y=0; y<height; y++){
1876 for(x=0; x<width; x++){
1877 *d++ = *s;
1878 s += 2;
1879 }
1880 s += src_wrap;
1881 d += dst_wrap;
1882 }
1883}
1884
1885static void gray16be_to_gray(AVPicture *dst, const AVPicture *src,
1886 int width, int height)
1887{
1888 gray16_to_gray(dst, src, width, height);
1889}
1890
1891static void gray16le_to_gray(AVPicture *dst, const AVPicture *src,
1892 int width, int height)
1893{
e5b51496
IP
1894 AVPicture tmpsrc = *src;
1895 tmpsrc.data[0]++;
1896 gray16_to_gray(dst, &tmpsrc, width, height);
34380af0
KS
1897}
1898
1899static void gray16_to_gray16(AVPicture *dst, const AVPicture *src,
1900 int width, int height)
1901{
1902 int x, y, src_wrap, dst_wrap;
1903 uint16_t *s, *d;
1904 s = src->data[0];
1905 src_wrap = (src->linesize[0] - width * 2)/2;
1906 d = dst->data[0];
1907 dst_wrap = (dst->linesize[0] - width * 2)/2;
1908 for(y=0; y<height; y++){
1909 for(x=0; x<width; x++){
1910 *d++ = bswap_16(*s++);
1911 }
1912 s += src_wrap;
1913 d += dst_wrap;
1914 }
1915}
1916
1917
524c6b63 1918typedef struct ConvertEntry {
da64ecc3 1919 void (*convert)(AVPicture *dst,
bb270c08 1920 const AVPicture *src, int width, int height);
524c6b63
FB
1921} ConvertEntry;
1922
f1ea5c2a 1923/* Add each new conversion function in this table. In order to be able
c50c0bc8
FB
1924 to convert from any format to any format, the following constraints
1925 must be satisfied:
1926
115329f1 1927 - all FF_COLOR_RGB formats must convert to and from PIX_FMT_RGB24
c50c0bc8
FB
1928
1929 - all FF_COLOR_GRAY formats must convert to and from PIX_FMT_GRAY8
1930
71e445fc 1931 - all FF_COLOR_RGB formats with alpha must convert to and from PIX_FMT_RGB32
c50c0bc8 1932
e352ff08 1933 - PIX_FMT_YUV444P and PIX_FMT_YUVJ444P must convert to and from
c50c0bc8
FB
1934 PIX_FMT_RGB24.
1935
1936 - PIX_FMT_422 must convert to and from PIX_FMT_422P.
e352ff08 1937
52b541ad 1938 The other conversion functions are just optimizations for common cases.
524c6b63 1939*/
62a05b5b 1940static const ConvertEntry convert_table[PIX_FMT_NB][PIX_FMT_NB] = {
524c6b63 1941 [PIX_FMT_YUV420P] = {
71e445fc 1942 [PIX_FMT_YUYV422] = {
dc02fc6a 1943 .convert = yuv420p_to_yuyv422,
d7e2f57f 1944 },
115329f1 1945 [PIX_FMT_RGB555] = {
ef9f7306 1946 .convert = yuv420p_to_rgb555
524c6b63 1947 },
115329f1 1948 [PIX_FMT_RGB565] = {
ef9f7306 1949 .convert = yuv420p_to_rgb565
524c6b63 1950 },
115329f1 1951 [PIX_FMT_BGR24] = {
ef9f7306 1952 .convert = yuv420p_to_bgr24
524c6b63 1953 },
115329f1 1954 [PIX_FMT_RGB24] = {
ef9f7306 1955 .convert = yuv420p_to_rgb24
524c6b63 1956 },
71e445fc 1957 [PIX_FMT_RGB32] = {
3cf5b6be 1958 .convert = yuv420p_to_rgb32
524c6b63 1959 },
bb270c08 1960 [PIX_FMT_UYVY422] = {
bac65165
LA
1961 .convert = yuv420p_to_uyvy422,
1962 },
524c6b63 1963 },
115329f1 1964 [PIX_FMT_YUV422P] = {
71e445fc 1965 [PIX_FMT_YUYV422] = {
dc02fc6a 1966 .convert = yuv422p_to_yuyv422,
c50c0bc8 1967 },
115329f1 1968 [PIX_FMT_UYVY422] = {
ebb177dd
TK
1969 .convert = yuv422p_to_uyvy422,
1970 },
c50c0bc8 1971 },
115329f1
DB
1972 [PIX_FMT_YUV444P] = {
1973 [PIX_FMT_RGB24] = {
c50c0bc8
FB
1974 .convert = yuv444p_to_rgb24
1975 },
1976 },
1977 [PIX_FMT_YUVJ420P] = {
115329f1 1978 [PIX_FMT_RGB555] = {
c50c0bc8 1979 .convert = yuvj420p_to_rgb555
524c6b63 1980 },
115329f1 1981 [PIX_FMT_RGB565] = {
c50c0bc8 1982 .convert = yuvj420p_to_rgb565
524c6b63 1983 },
115329f1 1984 [PIX_FMT_BGR24] = {
c50c0bc8 1985 .convert = yuvj420p_to_bgr24
524c6b63 1986 },
115329f1 1987 [PIX_FMT_RGB24] = {
c50c0bc8 1988 .convert = yuvj420p_to_rgb24
524c6b63 1989 },
71e445fc 1990 [PIX_FMT_RGB32] = {
3cf5b6be 1991 .convert = yuvj420p_to_rgb32
c50c0bc8
FB
1992 },
1993 },
115329f1
DB
1994 [PIX_FMT_YUVJ444P] = {
1995 [PIX_FMT_RGB24] = {
c50c0bc8 1996 .convert = yuvj444p_to_rgb24
524c6b63
FB
1997 },
1998 },
71e445fc 1999 [PIX_FMT_YUYV422] = {
115329f1 2000 [PIX_FMT_YUV420P] = {
dc02fc6a 2001 .convert = yuyv422_to_yuv420p,
524c6b63 2002 },
115329f1 2003 [PIX_FMT_YUV422P] = {
dc02fc6a 2004 .convert = yuyv422_to_yuv422p,
c50c0bc8 2005 },
524c6b63 2006 },
115329f1
DB
2007 [PIX_FMT_UYVY422] = {
2008 [PIX_FMT_YUV420P] = {
ebb177dd
TK
2009 .convert = uyvy422_to_yuv420p,
2010 },
115329f1 2011 [PIX_FMT_YUV422P] = {
ebb177dd
TK
2012 .convert = uyvy422_to_yuv422p,
2013 },
2014 },
524c6b63 2015 [PIX_FMT_RGB24] = {
115329f1 2016 [PIX_FMT_YUV420P] = {
ef9f7306 2017 .convert = rgb24_to_yuv420p
524c6b63 2018 },
115329f1 2019 [PIX_FMT_RGB565] = {
ef9f7306 2020 .convert = rgb24_to_rgb565
524c6b63 2021 },
115329f1 2022 [PIX_FMT_RGB555] = {
ef9f7306 2023 .convert = rgb24_to_rgb555
524c6b63 2024 },
71e445fc 2025 [PIX_FMT_RGB32] = {
3cf5b6be 2026 .convert = rgb24_to_rgb32
7e7e5940 2027 },
115329f1 2028 [PIX_FMT_BGR24] = {
7e7e5940
FB
2029 .convert = rgb24_to_bgr24
2030 },
115329f1 2031 [PIX_FMT_GRAY8] = {
ef9f7306 2032 .convert = rgb24_to_gray
524c6b63 2033 },
7e7e5940 2034 [PIX_FMT_PAL8] = {
7e6d70d0
FB
2035 .convert = rgb24_to_pal8
2036 },
115329f1 2037 [PIX_FMT_YUV444P] = {
c50c0bc8
FB
2038 .convert = rgb24_to_yuv444p
2039 },
115329f1 2040 [PIX_FMT_YUVJ420P] = {
c50c0bc8
FB
2041 .convert = rgb24_to_yuvj420p
2042 },
115329f1 2043 [PIX_FMT_YUVJ444P] = {
c50c0bc8
FB
2044 .convert = rgb24_to_yuvj444p
2045 },
524c6b63 2046 },
71e445fc 2047 [PIX_FMT_RGB32] = {
115329f1 2048 [PIX_FMT_RGB24] = {
3cf5b6be 2049 .convert = rgb32_to_rgb24
7e7e5940 2050 },
b3625676 2051 [PIX_FMT_BGR24] = {
3cf5b6be 2052 .convert = rgb32_to_bgr24
b3625676
AB
2053 },
2054 [PIX_FMT_RGB565] = {
3cf5b6be 2055 .convert = rgb32_to_rgb565
b3625676 2056 },
115329f1 2057 [PIX_FMT_RGB555] = {
3cf5b6be 2058 .convert = rgb32_to_rgb555
7e7e5940 2059 },
115329f1 2060 [PIX_FMT_PAL8] = {
3cf5b6be 2061 .convert = rgb32_to_pal8
7e7e5940 2062 },
115329f1 2063 [PIX_FMT_YUV420P] = {
3cf5b6be 2064 .convert = rgb32_to_yuv420p
524c6b63 2065 },
115329f1 2066 [PIX_FMT_GRAY8] = {
3cf5b6be 2067 .convert = rgb32_to_gray
69572401 2068 },
524c6b63
FB
2069 },
2070 [PIX_FMT_BGR24] = {
71e445fc 2071 [PIX_FMT_RGB32] = {
3cf5b6be 2072 .convert = bgr24_to_rgb32
b3625676 2073 },
115329f1 2074 [PIX_FMT_RGB24] = {
7e7e5940
FB
2075 .convert = bgr24_to_rgb24
2076 },
115329f1 2077 [PIX_FMT_YUV420P] = {
ef9f7306 2078 .convert = bgr24_to_yuv420p
524c6b63 2079 },
115329f1 2080 [PIX_FMT_GRAY8] = {
69572401
FB
2081 .convert = bgr24_to_gray
2082 },
524c6b63
FB
2083 },
2084 [PIX_FMT_RGB555] = {
115329f1 2085 [PIX_FMT_RGB24] = {
7e7e5940
FB
2086 .convert = rgb555_to_rgb24
2087 },
71e445fc 2088 [PIX_FMT_RGB32] = {
3cf5b6be 2089 .convert = rgb555_to_rgb32
7e7e5940 2090 },
115329f1 2091 [PIX_FMT_YUV420P] = {
ef9f7306 2092 .convert = rgb555_to_yuv420p
524c6b63 2093 },
115329f1 2094 [PIX_FMT_GRAY8] = {
69572401
FB
2095 .convert = rgb555_to_gray
2096 },
524c6b63
FB
2097 },
2098 [PIX_FMT_RGB565] = {
71e445fc 2099 [PIX_FMT_RGB32] = {
3cf5b6be 2100 .convert = rgb565_to_rgb32
b3625676 2101 },
115329f1 2102 [PIX_FMT_RGB24] = {
7e7e5940
FB
2103 .convert = rgb565_to_rgb24
2104 },
115329f1 2105 [PIX_FMT_YUV420P] = {
ef9f7306 2106 .convert = rgb565_to_yuv420p
524c6b63 2107 },
115329f1 2108 [PIX_FMT_GRAY8] = {
69572401
FB
2109 .convert = rgb565_to_gray
2110 },
524c6b63 2111 },
34380af0
KS
2112 [PIX_FMT_GRAY16BE] = {
2113 [PIX_FMT_GRAY8] = {
2114 .convert = gray16be_to_gray
2115 },
2116 [PIX_FMT_GRAY16LE] = {
2117 .convert = gray16_to_gray16
2118 },
2119 },
2120 [PIX_FMT_GRAY16LE] = {
2121 [PIX_FMT_GRAY8] = {
2122 .convert = gray16le_to_gray
2123 },
2124 [PIX_FMT_GRAY16BE] = {
2125 .convert = gray16_to_gray16
2126 },
2127 },
524c6b63 2128 [PIX_FMT_GRAY8] = {
115329f1 2129 [PIX_FMT_RGB555] = {
69572401
FB
2130 .convert = gray_to_rgb555
2131 },
115329f1 2132 [PIX_FMT_RGB565] = {
69572401
FB
2133 .convert = gray_to_rgb565
2134 },
115329f1 2135 [PIX_FMT_RGB24] = {
ef9f7306 2136 .convert = gray_to_rgb24
524c6b63 2137 },
115329f1 2138 [PIX_FMT_BGR24] = {
69572401
FB
2139 .convert = gray_to_bgr24
2140 },
71e445fc 2141 [PIX_FMT_RGB32] = {
3cf5b6be 2142 .convert = gray_to_rgb32
69572401 2143 },
115329f1 2144 [PIX_FMT_MONOWHITE] = {
ef9f7306 2145 .convert = gray_to_monowhite
2a877875 2146 },
115329f1 2147 [PIX_FMT_MONOBLACK] = {
ef9f7306 2148 .convert = gray_to_monoblack
2a877875 2149 },
34380af0
KS
2150 [PIX_FMT_GRAY16LE] = {
2151 .convert = gray_to_gray16
2152 },
2153 [PIX_FMT_GRAY16BE] = {
2154 .convert = gray_to_gray16
2155 },
524c6b63
FB
2156 },
2157 [PIX_FMT_MONOWHITE] = {
115329f1 2158 [PIX_FMT_GRAY8] = {
ef9f7306 2159 .convert = monowhite_to_gray
524c6b63
FB
2160 },
2161 },
2162 [PIX_FMT_MONOBLACK] = {
115329f1 2163 [PIX_FMT_GRAY8] = {
ef9f7306 2164 .convert = monoblack_to_gray
524c6b63
FB
2165 },
2166 },
7e6d70d0 2167 [PIX_FMT_PAL8] = {
115329f1 2168 [PIX_FMT_RGB555] = {
7e6d70d0
FB
2169 .convert = pal8_to_rgb555
2170 },
115329f1 2171 [PIX_FMT_RGB565] = {
7e6d70d0
FB
2172 .convert = pal8_to_rgb565
2173 },
115329f1 2174 [PIX_FMT_BGR24] = {
7e6d70d0
FB
2175 .convert = pal8_to_bgr24
2176 },
115329f1 2177 [PIX_FMT_RGB24] = {
7e6d70d0
FB
2178 .convert = pal8_to_rgb24
2179 },
71e445fc 2180 [PIX_FMT_RGB32] = {
3cf5b6be 2181 .convert = pal8_to_rgb32
7e6d70d0
FB
2182 },
2183 },
71e445fc 2184 [PIX_FMT_UYYVYY411] = {
115329f1 2185 [PIX_FMT_YUV411P] = {
9ac529a5 2186 .convert = uyyvyy411_to_yuv411p,
f02be79d
RS
2187 },
2188 },
2189
524c6b63
FB
2190};
2191
75917b88 2192int avpicture_alloc(AVPicture *picture,
524c6b63
FB
2193 int pix_fmt, int width, int height)
2194{
2d5545c3 2195 int size;
524c6b63
FB
2196 void *ptr;
2197
2198 size = avpicture_get_size(pix_fmt, width, height);
0ecca7a4
MN
2199 if(size<0)
2200 goto fail;
524c6b63
FB
2201 ptr = av_malloc(size);
2202 if (!ptr)
2203 goto fail;
2204 avpicture_fill(picture, ptr, pix_fmt, width, height);
2205 return 0;
2206 fail:
2207 memset(picture, 0, sizeof(AVPicture));
2208 return -1;
2209}
2210
75917b88 2211void avpicture_free(AVPicture *picture)
524c6b63 2212{
8e1e6f31 2213 av_free(picture->data[0]);
524c6b63
FB
2214}
2215
c50c0bc8 2216/* return true if yuv planar */
62a05b5b 2217static inline int is_yuv_planar(const PixFmtInfo *ps)
c50c0bc8
FB
2218{
2219 return (ps->color_type == FF_COLOR_YUV ||
115329f1 2220 ps->color_type == FF_COLOR_YUV_JPEG) &&
7e7e5940 2221 ps->pixel_type == FF_PIXEL_PLANAR;
c50c0bc8
FB
2222}
2223
636d6a4a 2224int av_picture_crop(AVPicture *dst, const AVPicture *src,
f2651e7a
BC
2225 int pix_fmt, int top_band, int left_band)
2226{
2227 int y_shift;
2228 int x_shift;
2229
2230 if (pix_fmt < 0 || pix_fmt >= PIX_FMT_NB || !is_yuv_planar(&pix_fmt_info[pix_fmt]))
2231 return -1;
2232
2233 y_shift = pix_fmt_info[pix_fmt].y_chroma_shift;
2234 x_shift = pix_fmt_info[pix_fmt].x_chroma_shift;
2235
2236 dst->data[0] = src->data[0] + (top_band * src->linesize[0]) + left_band;
2237 dst->data[1] = src->data[1] + ((top_band >> y_shift) * src->linesize[1]) + (left_band >> x_shift);
2238 dst->data[2] = src->data[2] + ((top_band >> y_shift) * src->linesize[2]) + (left_band >> x_shift);
2239
2240 dst->linesize[0] = src->linesize[0];
2241 dst->linesize[1] = src->linesize[1];
2242 dst->linesize[2] = src->linesize[2];
2243 return 0;
2244}
2245
636d6a4a 2246int av_picture_pad(AVPicture *dst, const AVPicture *src, int height, int width,
6845801f
LB
2247 int pix_fmt, int padtop, int padbottom, int padleft, int padright,
2248 int *color)
5341c209 2249{
79acfb0e 2250 uint8_t *optr;
5341c209
LA
2251 int y_shift;
2252 int x_shift;
2253 int yheight;
2254 int i, y;
2255
6845801f
LB
2256 if (pix_fmt < 0 || pix_fmt >= PIX_FMT_NB ||
2257 !is_yuv_planar(&pix_fmt_info[pix_fmt])) return -1;
5341c209
LA
2258
2259 for (i = 0; i < 3; i++) {
2260 x_shift = i ? pix_fmt_info[pix_fmt].x_chroma_shift : 0;
2261 y_shift = i ? pix_fmt_info[pix_fmt].y_chroma_shift : 0;
2262
2263 if (padtop || padleft) {
6845801f
LB
2264 memset(dst->data[i], color[i],
2265 dst->linesize[i] * (padtop >> y_shift) + (padleft >> x_shift));
5341c209
LA
2266 }
2267
79acfb0e
LB
2268 if (padleft || padright) {
2269 optr = dst->data[i] + dst->linesize[i] * (padtop >> y_shift) +
2270 (dst->linesize[i] - (padright >> x_shift));
2271 yheight = (height - 1 - (padtop + padbottom)) >> y_shift;
2272 for (y = 0; y < yheight; y++) {
2273 memset(optr, color[i], (padleft + padright) >> x_shift);
2274 optr += dst->linesize[i];
5341c209 2275 }
79acfb0e
LB
2276 }
2277
2278 if (src) { /* first line */
2279 uint8_t *iptr = src->data[i];
2280 optr = dst->data[i] + dst->linesize[i] * (padtop >> y_shift) +
2281 (padleft >> x_shift);
2282 memcpy(optr, iptr, src->linesize[i]);
2283 iptr += src->linesize[i];
6845801f
LB
2284 optr = dst->data[i] + dst->linesize[i] * (padtop >> y_shift) +
2285 (dst->linesize[i] - (padright >> x_shift));
5341c209
LA
2286 yheight = (height - 1 - (padtop + padbottom)) >> y_shift;
2287 for (y = 0; y < yheight; y++) {
2288 memset(optr, color[i], (padleft + padright) >> x_shift);
79acfb0e
LB
2289 memcpy(optr + ((padleft + padright) >> x_shift), iptr,
2290 src->linesize[i]);
2291 iptr += src->linesize[i];
5341c209
LA
2292 optr += dst->linesize[i];
2293 }
2294 }
2295
2296 if (padbottom || padright) {
6845801f
LB
2297 optr = dst->data[i] + dst->linesize[i] *
2298 ((height - padbottom) >> y_shift) - (padright >> x_shift);
2299 memset(optr, color[i],dst->linesize[i] *
2300 (padbottom >> y_shift) + (padright >> x_shift));
5341c209
LA
2301 }
2302 }
2303 return 0;
2304}
2305
636d6a4a
PI
2306#if LIBAVCODEC_VERSION_INT < ((52<<16)+(0<<8)+0)
2307void img_copy(AVPicture *dst, const AVPicture *src,
2308 int pix_fmt, int width, int height)
2309{
2310 av_picture_copy(dst, src, pix_fmt, width, height);
2311}
2312
2313int img_crop(AVPicture *dst, const AVPicture *src,
2314 int pix_fmt, int top_band, int left_band)
2315{
2316 return av_picture_crop(dst, src, pix_fmt, top_band, left_band);
2317}
2318
2319int img_pad(AVPicture *dst, const AVPicture *src, int height, int width,
2320 int pix_fmt, int padtop, int padbottom, int padleft, int padright,
2321 int *color)
2322{
2323 return av_picture_pad(dst, src, height, width, pix_fmt, padtop, padbottom, padleft, padright, color);
2324}
2325#endif
2326
790c9ca7 2327#ifndef CONFIG_SWSCALER
85c242d8
FB
2328/* XXX: always use linesize. Return -1 if not supported */
2329int img_convert(AVPicture *dst, int dst_pix_fmt,
115329f1 2330 const AVPicture *src, int src_pix_fmt,
524c6b63 2331 int src_width, int src_height)
85c242d8 2332{
c50c0bc8 2333 static int inited;
2a877875 2334 int i, ret, dst_width, dst_height, int_pix_fmt;
62a05b5b
SH
2335 const PixFmtInfo *src_pix, *dst_pix;
2336 const ConvertEntry *ce;
524c6b63
FB
2337 AVPicture tmp1, *tmp = &tmp1;
2338
2339 if (src_pix_fmt < 0 || src_pix_fmt >= PIX_FMT_NB ||
2340 dst_pix_fmt < 0 || dst_pix_fmt >= PIX_FMT_NB)
2341 return -1;
2342 if (src_width <= 0 || src_height <= 0)
2343 return 0;
69572401 2344
c50c0bc8
FB
2345 if (!inited) {
2346 inited = 1;
2347 img_convert_init();
2348 }
2349
524c6b63
FB
2350 dst_width = src_width;
2351 dst_height = src_height;
69572401 2352
524c6b63
FB
2353 dst_pix = &pix_fmt_info[dst_pix_fmt];
2354 src_pix = &pix_fmt_info[src_pix_fmt];
2355 if (src_pix_fmt == dst_pix_fmt) {
7e7e5940 2356 /* no conversion needed: just copy */
636d6a4a 2357 av_picture_copy(dst, src, dst_pix_fmt, dst_width, dst_height);
524c6b63
FB
2358 return 0;
2359 }
2360
2361 ce = &convert_table[src_pix_fmt][dst_pix_fmt];
2362 if (ce->convert) {
ebb177dd 2363 /* specific conversion routine */
524c6b63
FB
2364 ce->convert(dst, src, dst_width, dst_height);
2365 return 0;
2366 }
2367
524c6b63 2368 /* gray to YUV */
c50c0bc8 2369 if (is_yuv_planar(dst_pix) &&
b6147995 2370 src_pix_fmt == PIX_FMT_GRAY8) {
524c6b63
FB
2371 int w, h, y;
2372 uint8_t *d;
2373
b6147995 2374 if (dst_pix->color_type == FF_COLOR_YUV_JPEG) {
54009d42 2375 ff_img_copy_plane(dst->data[0], dst->linesize[0],
b6147995
FB
2376 src->data[0], src->linesize[0],
2377 dst_width, dst_height);
2378 } else {
c50c0bc8
FB
2379 img_apply_table(dst->data[0], dst->linesize[0],
2380 src->data[0], src->linesize[0],
2381 dst_width, dst_height,
2382 y_jpeg_to_ccir);
b6147995 2383 }
524c6b63
FB
2384 /* fill U and V with 128 */
2385 w = dst_width;
2386 h = dst_height;
2387 w >>= dst_pix->x_chroma_shift;
2388 h >>= dst_pix->y_chroma_shift;
2389 for(i = 1; i <= 2; i++) {
2390 d = dst->data[i];
2a877875
FB
2391 for(y = 0; y< h; y++) {
2392 memset(d, 128, w);
524c6b63
FB
2393 d += dst->linesize[i];
2394 }
b71472eb 2395 }
524c6b63
FB
2396 return 0;
2397 }
2398
2399 /* YUV to gray */
115329f1 2400 if (is_yuv_planar(src_pix) &&
b6147995
FB
2401 dst_pix_fmt == PIX_FMT_GRAY8) {
2402 if (src_pix->color_type == FF_COLOR_YUV_JPEG) {
54009d42 2403 ff_img_copy_plane(dst->data[0], dst->linesize[0],
b6147995
FB
2404 src->data[0], src->linesize[0],
2405 dst_width, dst_height);
2406 } else {
c50c0bc8
FB
2407 img_apply_table(dst->data[0], dst->linesize[0],
2408 src->data[0], src->linesize[0],
2409 dst_width, dst_height,
2410 y_ccir_to_jpeg);
b6147995 2411 }
524c6b63
FB
2412 return 0;
2413 }
2414
c50c0bc8
FB
2415 /* YUV to YUV planar */
2416 if (is_yuv_planar(dst_pix) && is_yuv_planar(src_pix)) {
e352ff08 2417 int x_shift, y_shift, w, h, xy_shift;
115329f1 2418 void (*resize_func)(uint8_t *dst, int dst_wrap,
e352ff08 2419 const uint8_t *src, int src_wrap,
524c6b63
FB
2420 int width, int height);
2421
2422 /* compute chroma size of the smallest dimensions */
2423 w = dst_width;
2424 h = dst_height;
2425 if (dst_pix->x_chroma_shift >= src_pix->x_chroma_shift)
2426 w >>= dst_pix->x_chroma_shift;
2427 else
2428 w >>= src_pix->x_chroma_shift;
2429 if (dst_pix->y_chroma_shift >= src_pix->y_chroma_shift)
2430 h >>= dst_pix->y_chroma_shift;
2431 else
2432 h >>= src_pix->y_chroma_shift;
2433
2434 x_shift = (dst_pix->x_chroma_shift - src_pix->x_chroma_shift);
2435 y_shift = (dst_pix->y_chroma_shift - src_pix->y_chroma_shift);
e352ff08
FB
2436 xy_shift = ((x_shift & 0xf) << 4) | (y_shift & 0xf);
2437 /* there must be filters for conversion at least from and to
2438 YUV444 format */
2439 switch(xy_shift) {
2440 case 0x00:
54009d42 2441 resize_func = ff_img_copy_plane;
e352ff08
FB
2442 break;
2443 case 0x10:
2444 resize_func = shrink21;
2445 break;
2446 case 0x20:
2447 resize_func = shrink41;
2448 break;
2449 case 0x01:
2450 resize_func = shrink12;
2451 break;
2452 case 0x11:
54009d42 2453 resize_func = ff_shrink22;
e352ff08
FB
2454 break;
2455 case 0x22:
54009d42 2456 resize_func = ff_shrink44;
e352ff08
FB
2457 break;
2458 case 0xf0:
2459 resize_func = grow21;
2460 break;
4196cfb7
2461 case 0x0f:
2462 resize_func = grow12;
2463 break;
e352ff08
FB
2464 case 0xe0:
2465 resize_func = grow41;
2466 break;
2467 case 0xff:
524c6b63 2468 resize_func = grow22;
e352ff08
FB
2469 break;
2470 case 0xee:
2471 resize_func = grow44;
2472 break;
2473 case 0xf1:
524c6b63 2474 resize_func = conv411;
e352ff08
FB
2475 break;
2476 default:
524c6b63 2477 /* currently not handled */
e352ff08 2478 goto no_chroma_filter;
85c242d8 2479 }
524c6b63 2480
54009d42 2481 ff_img_copy_plane(dst->data[0], dst->linesize[0],
7e7e5940
FB
2482 src->data[0], src->linesize[0],
2483 dst_width, dst_height);
566986ee 2484
524c6b63 2485 for(i = 1;i <= 2; i++)
566986ee
MK
2486 resize_func(dst->data[i], dst->linesize[i],
2487 src->data[i], src->linesize[i],
185fdc54 2488 dst_width>>dst_pix->x_chroma_shift, dst_height>>dst_pix->y_chroma_shift);
c50c0bc8
FB
2489 /* if yuv color space conversion is needed, we do it here on
2490 the destination image */
2491 if (dst_pix->color_type != src_pix->color_type) {
2492 const uint8_t *y_table, *c_table;
2493 if (dst_pix->color_type == FF_COLOR_YUV) {
2494 y_table = y_jpeg_to_ccir;
2495 c_table = c_jpeg_to_ccir;
2496 } else {
2497 y_table = y_ccir_to_jpeg;
2498 c_table = c_ccir_to_jpeg;
2499 }
2500 img_apply_table(dst->data[0], dst->linesize[0],
2501 dst->data[0], dst->linesize[0],
2502 dst_width, dst_height,
2503 y_table);
2504
2505 for(i = 1;i <= 2; i++)
2506 img_apply_table(dst->data[i], dst->linesize[i],
2507 dst->data[i], dst->linesize[i],
115329f1 2508 dst_width>>dst_pix->x_chroma_shift,
c50c0bc8
FB
2509 dst_height>>dst_pix->y_chroma_shift,
2510 c_table);
2511 }
2512 return 0;
85c242d8 2513 }
e352ff08 2514 no_chroma_filter:
524c6b63 2515
2a877875 2516 /* try to use an intermediate format */
71e445fc
DB
2517 if (src_pix_fmt == PIX_FMT_YUYV422 ||
2518 dst_pix_fmt == PIX_FMT_YUYV422) {
c50c0bc8
FB
2519 /* specific case: convert to YUV422P first */
2520 int_pix_fmt = PIX_FMT_YUV422P;
ebb177dd
TK
2521 } else if (src_pix_fmt == PIX_FMT_UYVY422 ||
2522 dst_pix_fmt == PIX_FMT_UYVY422) {
2523 /* specific case: convert to YUV422P first */
2524 int_pix_fmt = PIX_FMT_YUV422P;
71e445fc
DB
2525 } else if (src_pix_fmt == PIX_FMT_UYYVYY411 ||
2526 dst_pix_fmt == PIX_FMT_UYYVYY411) {
f02be79d
RS
2527 /* specific case: convert to YUV411P first */
2528 int_pix_fmt = PIX_FMT_YUV411P;
c50c0bc8 2529 } else if ((src_pix->color_type == FF_COLOR_GRAY &&
115329f1 2530 src_pix_fmt != PIX_FMT_GRAY8) ||
c50c0bc8
FB
2531 (dst_pix->color_type == FF_COLOR_GRAY &&
2532 dst_pix_fmt != PIX_FMT_GRAY8)) {
2533 /* gray8 is the normalized format */
2a877875 2534 int_pix_fmt = PIX_FMT_GRAY8;
115329f1 2535 } else if ((is_yuv_planar(src_pix) &&
c50c0bc8
FB
2536 src_pix_fmt != PIX_FMT_YUV444P &&
2537 src_pix_fmt != PIX_FMT_YUVJ444P)) {
2538 /* yuv444 is the normalized format */
2539 if (src_pix->color_type == FF_COLOR_YUV_JPEG)
2540 int_pix_fmt = PIX_FMT_YUVJ444P;
2541 else
2542 int_pix_fmt = PIX_FMT_YUV444P;
115329f1 2543 } else if ((is_yuv_planar(dst_pix) &&
c50c0bc8
FB
2544 dst_pix_fmt != PIX_FMT_YUV444P &&
2545 dst_pix_fmt != PIX_FMT_YUVJ444P)) {
2546 /* yuv444 is the normalized format */
2547 if (dst_pix->color_type == FF_COLOR_YUV_JPEG)
2548 int_pix_fmt = PIX_FMT_YUVJ444P;
2549 else
2550 int_pix_fmt = PIX_FMT_YUV444P;
2a877875 2551 } else {
c50c0bc8
FB
2552 /* the two formats are rgb or gray8 or yuv[j]444p */
2553 if (src_pix->is_alpha && dst_pix->is_alpha)
71e445fc 2554 int_pix_fmt = PIX_FMT_RGB32;
c50c0bc8
FB
2555 else
2556 int_pix_fmt = PIX_FMT_RGB24;
2a877875
FB
2557 }
2558 if (avpicture_alloc(tmp, int_pix_fmt, dst_width, dst_height) < 0)
2559 return -1;
2560 ret = -1;
2561 if (img_convert(tmp, int_pix_fmt,
2562 src, src_pix_fmt, src_width, src_height) < 0)
2563 goto fail1;
2564 if (img_convert(dst, dst_pix_fmt,
2565 tmp, int_pix_fmt, dst_width, dst_height) < 0)
2566 goto fail1;
2567 ret = 0;
2568 fail1:
2569 avpicture_free(tmp);
2570 return ret;
85c242d8 2571}
790c9ca7 2572#endif
85c242d8 2573
0469baf1 2574/* NOTE: we scan all the pixels to have an exact information */
da64ecc3 2575static int get_alpha_info_pal8(const AVPicture *src, int width, int height)
0469baf1
FB
2576{
2577 const unsigned char *p;
2578 int src_wrap, ret, x, y;
2579 unsigned int a;
2580 uint32_t *palette = (uint32_t *)src->data[1];
115329f1 2581
0469baf1
FB
2582 p = src->data[0];
2583 src_wrap = src->linesize[0] - width;
2584 ret = 0;
2585 for(y=0;y<height;y++) {
2586 for(x=0;x<width;x++) {
2587 a = palette[p[0]] >> 24;
2588 if (a == 0x00) {
2589 ret |= FF_ALPHA_TRANSP;
2590 } else if (a != 0xff) {
2591 ret |= FF_ALPHA_SEMI_TRANSP;
2592 }
2593 p++;
2594 }
2595 p += src_wrap;
2596 }
2597 return ret;
2598}
2599
da64ecc3 2600int img_get_alpha_info(const AVPicture *src,
bb270c08 2601 int pix_fmt, int width, int height)
0469baf1 2602{
62a05b5b 2603 const PixFmtInfo *pf = &pix_fmt_info[pix_fmt];
0469baf1
FB
2604 int ret;
2605
2606 pf = &pix_fmt_info[pix_fmt];
2607 /* no alpha can be represented in format */
2608 if (!pf->is_alpha)
2609 return 0;
2610 switch(pix_fmt) {
71e445fc 2611 case PIX_FMT_RGB32:
3cf5b6be 2612 ret = get_alpha_info_rgb32(src, width, height);
0469baf1 2613 break;
0469baf1
FB
2614 case PIX_FMT_PAL8:
2615 ret = get_alpha_info_pal8(src, width, height);
2616 break;
2617 default:
2618 /* we do not know, so everything is indicated */
2619 ret = FF_ALPHA_TRANSP | FF_ALPHA_SEMI_TRANSP;
2620 break;
2621 }
2622 return ret;
2623}
5981f4e6
F
2624
2625#ifdef HAVE_MMX
2626#define DEINT_INPLACE_LINE_LUM \
2627 movd_m2r(lum_m4[0],mm0);\
2628 movd_m2r(lum_m3[0],mm1);\
2629 movd_m2r(lum_m2[0],mm2);\
2630 movd_m2r(lum_m1[0],mm3);\
2631 movd_m2r(lum[0],mm4);\
2632 punpcklbw_r2r(mm7,mm0);\
2633 movd_r2m(mm2,lum_m4[0]);\
2634 punpcklbw_r2r(mm7,mm1);\
2635 punpcklbw_r2r(mm7,mm2);\
2636 punpcklbw_r2r(mm7,mm3);\
2637 punpcklbw_r2r(mm7,mm4);\
2638 paddw_r2r(mm3,mm1);\
2639 psllw_i2r(1,mm2);\
2640 paddw_r2r(mm4,mm0);\
2641 psllw_i2r(2,mm1);\
2642 paddw_r2r(mm6,mm2);\
2643 paddw_r2r(mm2,mm1);\
2644 psubusw_r2r(mm0,mm1);\
2645 psrlw_i2r(3,mm1);\
2646 packuswb_r2r(mm7,mm1);\
2647 movd_r2m(mm1,lum_m2[0]);
2648
2649#define DEINT_LINE_LUM \
2650 movd_m2r(lum_m4[0],mm0);\
2651 movd_m2r(lum_m3[0],mm1);\
2652 movd_m2r(lum_m2[0],mm2);\
2653 movd_m2r(lum_m1[0],mm3);\
2654 movd_m2r(lum[0],mm4);\
2655 punpcklbw_r2r(mm7,mm0);\
2656 punpcklbw_r2r(mm7,mm1);\
2657 punpcklbw_r2r(mm7,mm2);\
2658 punpcklbw_r2r(mm7,mm3);\
2659 punpcklbw_r2r(mm7,mm4);\
2660 paddw_r2r(mm3,mm1);\
2661 psllw_i2r(1,mm2);\
2662 paddw_r2r(mm4,mm0);\
2663 psllw_i2r(2,mm1);\
2664 paddw_r2r(mm6,mm2);\
2665 paddw_r2r(mm2,mm1);\
2666 psubusw_r2r(mm0,mm1);\
2667 psrlw_i2r(3,mm1);\
2668 packuswb_r2r(mm7,mm1);\
2669 movd_r2m(mm1,dst[0]);
2670#endif
2671
85c242d8 2672/* filter parameters: [-1 4 2 4 -1] // 8 */
115329f1 2673static void deinterlace_line(uint8_t *dst,
bb270c08
DB
2674 const uint8_t *lum_m4, const uint8_t *lum_m3,
2675 const uint8_t *lum_m2, const uint8_t *lum_m1,
2676 const uint8_t *lum,
2677 int size)
85c242d8 2678{
5981f4e6 2679#ifndef HAVE_MMX
55fde95e 2680 uint8_t *cm = ff_cropTbl + MAX_NEG_CROP;
85c242d8 2681 int sum;
85c242d8
FB
2682
2683 for(;size > 0;size--) {
5981f4e6
F
2684 sum = -lum_m4[0];
2685 sum += lum_m3[0] << 2;
2686 sum += lum_m2[0] << 1;
2687 sum += lum_m1[0] << 2;
2688 sum += -lum[0];
85c242d8 2689 dst[0] = cm[(sum + 4) >> 3];
5981f4e6
F
2690 lum_m4++;
2691 lum_m3++;
2692 lum_m2++;
2693 lum_m1++;
2694 lum++;
85c242d8 2695 dst++;
85c242d8 2696 }
5981f4e6
F
2697#else
2698
782c5984
MN
2699 {
2700 mmx_t rounder;
2701 rounder.uw[0]=4;
2702 rounder.uw[1]=4;
2703 rounder.uw[2]=4;
2704 rounder.uw[3]=4;
2705 pxor_r2r(mm7,mm7);
2706 movq_m2r(rounder,mm6);
2707 }
5981f4e6
F
2708 for (;size > 3; size-=4) {
2709 DEINT_LINE_LUM
2710 lum_m4+=4;
2711 lum_m3+=4;
2712 lum_m2+=4;
2713 lum_m1+=4;
2714 lum+=4;
2715 dst+=4;
2716 }
2717#endif
2718}
0c1a9eda 2719static 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
2720 int size)
2721{
2722#ifndef HAVE_MMX
55fde95e 2723 uint8_t *cm = ff_cropTbl + MAX_NEG_CROP;
5981f4e6
F
2724 int sum;
2725
2726 for(;size > 0;size--) {
2727 sum = -lum_m4[0];
2728 sum += lum_m3[0] << 2;
2729 sum += lum_m2[0] << 1;
2730 lum_m4[0]=lum_m2[0];
2731 sum += lum_m1[0] << 2;
2732 sum += -lum[0];
2733 lum_m2[0] = cm[(sum + 4) >> 3];
2734 lum_m4++;
2735 lum_m3++;
2736 lum_m2++;
2737 lum_m1++;
2738 lum++;
2739 }
2740#else
2741
782c5984
MN
2742 {
2743 mmx_t rounder;
2744 rounder.uw[0]=4;
2745 rounder.uw[1]=4;
2746 rounder.uw[2]=4;
2747 rounder.uw[3]=4;
2748 pxor_r2r(mm7,mm7);
2749 movq_m2r(rounder,mm6);
2750 }
5981f4e6
F
2751 for (;size > 3; size-=4) {
2752 DEINT_INPLACE_LINE_LUM
2753 lum_m4+=4;
2754 lum_m3+=4;
2755 lum_m2+=4;
2756 lum_m1+=4;
2757 lum+=4;
2758 }
2759#endif
85c242d8
FB
2760}
2761
2762/* deinterlacing : 2 temporal taps, 3 spatial taps linear filter. The
2763 top field is copied as is, but the bottom field is deinterlaced
2764 against the top field. */
0c1a9eda 2765static void deinterlace_bottom_field(uint8_t *dst, int dst_wrap,
da64ecc3 2766 const uint8_t *src1, int src_wrap,
5981f4e6 2767 int width, int height)
85c242d8 2768{
da64ecc3 2769 const uint8_t *src_m2, *src_m1, *src_0, *src_p1, *src_p2;
5981f4e6
F
2770 int y;
2771
2772 src_m2 = src1;
2773 src_m1 = src1;
2774 src_0=&src_m1[src_wrap];
2775 src_p1=&src_0[src_wrap];
2776 src_p2=&src_p1[src_wrap];
2777 for(y=0;y<(height-2);y+=2) {
2778 memcpy(dst,src_m1,width);
85c242d8 2779 dst += dst_wrap;
5981f4e6
F
2780 deinterlace_line(dst,src_m2,src_m1,src_0,src_p1,src_p2,width);
2781 src_m2 = src_0;
2782 src_m1 = src_p1;
2783 src_0 = src_p2;
2784 src_p1 += 2*src_wrap;
2785 src_p2 += 2*src_wrap;
85c242d8 2786 dst += dst_wrap;
85c242d8 2787 }
5981f4e6
F
2788 memcpy(dst,src_m1,width);
2789 dst += dst_wrap;
2790 /* do last line */
2791 deinterlace_line(dst,src_m2,src_m1,src_0,src_0,src_0,width);
2792}
2793
0c1a9eda 2794static void deinterlace_bottom_field_inplace(uint8_t *src1, int src_wrap,
bb270c08 2795 int width, int height)
5981f4e6 2796{
0c1a9eda 2797 uint8_t *src_m1, *src_0, *src_p1, *src_p2;
5981f4e6 2798 int y;
0c1a9eda
ZK
2799 uint8_t *buf;
2800 buf = (uint8_t*)av_malloc(width);
5981f4e6
F
2801
2802 src_m1 = src1;
2803 memcpy(buf,src_m1,width);
2804 src_0=&src_m1[src_wrap];
2805 src_p1=&src_0[src_wrap];
2806 src_p2=&src_p1[src_wrap];
2807 for(y=0;y<(height-2);y+=2) {
2808 deinterlace_line_inplace(buf,src_m1,src_0,src_p1,src_p2,width);
2809 src_m1 = src_p1;
2810 src_0 = src_p2;
2811 src_p1 += 2*src_wrap;
2812 src_p2 += 2*src_wrap;
2813 }
2814 /* do last line */
2815 deinterlace_line_inplace(buf,src_m1,src_0,src_0,src_0,width);
6000abfa 2816 av_free(buf);
85c242d8
FB
2817}
2818
da64ecc3 2819int avpicture_deinterlace(AVPicture *dst, const AVPicture *src,
de6d9b64
FB
2820 int pix_fmt, int width, int height)
2821{
85c242d8
FB
2822 int i;
2823
2824 if (pix_fmt != PIX_FMT_YUV420P &&
2825 pix_fmt != PIX_FMT_YUV422P &&
47017dd8 2826 pix_fmt != PIX_FMT_YUV444P &&
2a7feb18
AG
2827 pix_fmt != PIX_FMT_YUV411P &&
2828 pix_fmt != PIX_FMT_GRAY8)
85c242d8 2829 return -1;
5981f4e6 2830 if ((width & 3) != 0 || (height & 3) != 0)
85c242d8 2831 return -1;
5981f4e6 2832
85c242d8
FB
2833 for(i=0;i<3;i++) {
2834 if (i == 1) {
2835 switch(pix_fmt) {
2836 case PIX_FMT_YUV420P:
2837 width >>= 1;
2838 height >>= 1;
2839 break;
2840 case PIX_FMT_YUV422P:
2841 width >>= 1;
2842 break;
47017dd8
RS
2843 case PIX_FMT_YUV411P:
2844 width >>= 2;
2845 break;
85c242d8
FB
2846 default:
2847 break;
2848 }
2a7feb18
AG
2849 if (pix_fmt == PIX_FMT_GRAY8) {
2850 break;
2851 }
85c242d8 2852 }
5981f4e6 2853 if (src == dst) {
da64ecc3 2854 deinterlace_bottom_field_inplace(dst->data[i], dst->linesize[i],
85c242d8 2855 width, height);
5981f4e6
F
2856 } else {
2857 deinterlace_bottom_field(dst->data[i],dst->linesize[i],
2858 src->data[i], src->linesize[i],
2859 width, height);
2860 }
de6d9b64 2861 }
55ffe9df 2862 emms_c();
85c242d8 2863 return 0;
de6d9b64 2864}
cd4af68a 2865