Factor bytewidth determination in its own function
[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
22ed53e5 808int av_get_plane_bytewidth(enum PixelFormat pix_fmt, int width, int plane)
7e7e5940 809{
22ed53e5 810 int bits;
62a05b5b 811 const PixFmtInfo *pf = &pix_fmt_info[pix_fmt];
115329f1 812
7e7e5940
FB
813 pf = &pix_fmt_info[pix_fmt];
814 switch(pf->pixel_type) {
815 case FF_PIXEL_PACKED:
816 switch(pix_fmt) {
71e445fc 817 case PIX_FMT_YUYV422:
ebb177dd 818 case PIX_FMT_UYVY422:
7e7e5940
FB
819 case PIX_FMT_RGB565:
820 case PIX_FMT_RGB555:
00b2fa86
LA
821 case PIX_FMT_BGR565:
822 case PIX_FMT_BGR555:
7e7e5940
FB
823 bits = 16;
824 break;
71e445fc 825 case PIX_FMT_UYYVYY411:
bb270c08
DB
826 bits = 12;
827 break;
7e7e5940
FB
828 default:
829 bits = pf->depth * pf->nb_channels;
830 break;
831 }
22ed53e5
VS
832 return (width * bits + 7) >> 3;
833 break;
834 case FF_PIXEL_PLANAR:
835 if (plane == 1 || plane == 2)
836 width >>= pf->x_chroma_shift;
837
838 return (width * pf->depth + 7) >> 3;
839 break;
840 case FF_PIXEL_PALETTE:
841 if (plane == 0)
842 return width;
7e7e5940 843 break;
22ed53e5
VS
844 }
845
846 return -1;
847}
848
849void av_picture_copy(AVPicture *dst, const AVPicture *src,
850 int pix_fmt, int width, int height)
851{
852 int i;
853 const PixFmtInfo *pf = &pix_fmt_info[pix_fmt];
854
855 pf = &pix_fmt_info[pix_fmt];
856 switch(pf->pixel_type) {
857 case FF_PIXEL_PACKED:
7e7e5940
FB
858 case FF_PIXEL_PLANAR:
859 for(i = 0; i < pf->nb_channels; i++) {
860 int w, h;
22ed53e5 861 int bwidth = av_get_plane_bytewidth(pix_fmt, width, i);
7e7e5940
FB
862 w = width;
863 h = height;
864 if (i == 1 || i == 2) {
865 w >>= pf->x_chroma_shift;
866 h >>= pf->y_chroma_shift;
867 }
54009d42 868 ff_img_copy_plane(dst->data[i], dst->linesize[i],
7e7e5940
FB
869 src->data[i], src->linesize[i],
870 bwidth, h);
871 }
872 break;
873 case FF_PIXEL_PALETTE:
54009d42 874 ff_img_copy_plane(dst->data[0], dst->linesize[0],
7e7e5940
FB
875 src->data[0], src->linesize[0],
876 width, height);
877 /* copy the palette */
54009d42 878 ff_img_copy_plane(dst->data[1], dst->linesize[1],
7e7e5940
FB
879 src->data[1], src->linesize[1],
880 4, 256);
881 break;
882 }
883}
2a877875 884
de6d9b64
FB
885/* XXX: totally non optimized */
886
dc02fc6a 887static void yuyv422_to_yuv420p(AVPicture *dst, const AVPicture *src,
524c6b63 888 int width, int height)
de6d9b64 889{
c50c0bc8
FB
890 const uint8_t *p, *p1;
891 uint8_t *lum, *cr, *cb, *lum1, *cr1, *cb1;
d4f5d74a 892 int w;
115329f1 893
c50c0bc8
FB
894 p1 = src->data[0];
895 lum1 = dst->data[0];
0a05e494
FB
896 cb1 = dst->data[1];
897 cr1 = dst->data[2];
c50c0bc8 898
d4f5d74a 899 for(;height >= 1; height -= 2) {
c50c0bc8
FB
900 p = p1;
901 lum = lum1;
902 cb = cb1;
903 cr = cr1;
d4f5d74a 904 for(w = width; w >= 2; w -= 2) {
e78df699
MN
905 lum[0] = p[0];
906 cb[0] = p[1];
907 lum[1] = p[2];
908 cr[0] = p[3];
de6d9b64
FB
909 p += 4;
910 lum += 2;
911 cb++;
912 cr++;
913 }
d4f5d74a 914 if (w) {
e78df699 915 lum[0] = p[0];
d4f5d74a
GM
916 cb[0] = p[1];
917 cr[0] = p[3];
918 cb++;
919 cr++;
de6d9b64 920 }
c50c0bc8
FB
921 p1 += src->linesize[0];
922 lum1 += dst->linesize[0];
d4f5d74a
GM
923 if (height>1) {
924 p = p1;
925 lum = lum1;
926 for(w = width; w >= 2; w -= 2) {
927 lum[0] = p[0];
928 lum[1] = p[2];
929 p += 4;
930 lum += 2;
931 }
932 if (w) {
933 lum[0] = p[0];
934 }
935 p1 += src->linesize[0];
936 lum1 += dst->linesize[0];
937 }
c50c0bc8
FB
938 cb1 += dst->linesize[1];
939 cr1 += dst->linesize[2];
940 }
941}
942
ebb177dd
TK
943static void uyvy422_to_yuv420p(AVPicture *dst, const AVPicture *src,
944 int width, int height)
945{
946 const uint8_t *p, *p1;
947 uint8_t *lum, *cr, *cb, *lum1, *cr1, *cb1;
948 int w;
115329f1 949
ebb177dd 950 p1 = src->data[0];
115329f1 951
ebb177dd
TK
952 lum1 = dst->data[0];
953 cb1 = dst->data[1];
954 cr1 = dst->data[2];
955
956 for(;height >= 1; height -= 2) {
957 p = p1;
958 lum = lum1;
959 cb = cb1;
960 cr = cr1;
961 for(w = width; w >= 2; w -= 2) {
962 lum[0] = p[1];
963 cb[0] = p[0];
964 lum[1] = p[3];
965 cr[0] = p[2];
966 p += 4;
967 lum += 2;
968 cb++;
969 cr++;
970 }
971 if (w) {
972 lum[0] = p[1];
973 cb[0] = p[0];
974 cr[0] = p[2];
975 cb++;
976 cr++;
977 }
978 p1 += src->linesize[0];
979 lum1 += dst->linesize[0];
980 if (height>1) {
981 p = p1;
982 lum = lum1;
983 for(w = width; w >= 2; w -= 2) {
984 lum[0] = p[1];
985 lum[1] = p[3];
986 p += 4;
987 lum += 2;
988 }
989 if (w) {
990 lum[0] = p[1];
991 }
992 p1 += src->linesize[0];
993 lum1 += dst->linesize[0];
994 }
995 cb1 += dst->linesize[1];
996 cr1 += dst->linesize[2];
997 }
998}
999
1000
1001static void uyvy422_to_yuv422p(AVPicture *dst, const AVPicture *src,
1002 int width, int height)
1003{
1004 const uint8_t *p, *p1;
1005 uint8_t *lum, *cr, *cb, *lum1, *cr1, *cb1;
1006 int w;
1007
1008 p1 = src->data[0];
1009 lum1 = dst->data[0];
1010 cb1 = dst->data[1];
1011 cr1 = dst->data[2];
1012 for(;height > 0; height--) {
1013 p = p1;
1014 lum = lum1;
1015 cb = cb1;
1016 cr = cr1;
1017 for(w = width; w >= 2; w -= 2) {
1018 lum[0] = p[1];
1019 cb[0] = p[0];
1020 lum[1] = p[3];
1021 cr[0] = p[2];
1022 p += 4;
1023 lum += 2;
1024 cb++;
1025 cr++;
1026 }
1027 p1 += src->linesize[0];
1028 lum1 += dst->linesize[0];
1029 cb1 += dst->linesize[1];
1030 cr1 += dst->linesize[2];
1031 }
1032}
1033
1034
dc02fc6a 1035static void yuyv422_to_yuv422p(AVPicture *dst, const AVPicture *src,
c50c0bc8
FB
1036 int width, int height)
1037{
1038 const uint8_t *p, *p1;
1039 uint8_t *lum, *cr, *cb, *lum1, *cr1, *cb1;
1040 int w;
1041
1042 p1 = src->data[0];
1043 lum1 = dst->data[0];
0a05e494
FB
1044 cb1 = dst->data[1];
1045 cr1 = dst->data[2];
1046 for(;height > 0; height--) {
c50c0bc8
FB
1047 p = p1;
1048 lum = lum1;
1049 cb = cb1;
1050 cr = cr1;
1051 for(w = width; w >= 2; w -= 2) {
1052 lum[0] = p[0];
1053 cb[0] = p[1];
1054 lum[1] = p[2];
1055 cr[0] = p[3];
1056 p += 4;
1057 lum += 2;
1058 cb++;
1059 cr++;
1060 }
1061 p1 += src->linesize[0];
1062 lum1 += dst->linesize[0];
1063 cb1 += dst->linesize[1];
1064 cr1 += dst->linesize[2];
de6d9b64
FB
1065 }
1066}
1067
dc02fc6a 1068static void yuv422p_to_yuyv422(AVPicture *dst, const AVPicture *src,
c50c0bc8
FB
1069 int width, int height)
1070{
1071 uint8_t *p, *p1;
1072 const uint8_t *lum, *cr, *cb, *lum1, *cr1, *cb1;
1073 int w;
1074
1075 p1 = dst->data[0];
1076 lum1 = src->data[0];
0a05e494
FB
1077 cb1 = src->data[1];
1078 cr1 = src->data[2];
1079 for(;height > 0; height--) {
c50c0bc8
FB
1080 p = p1;
1081 lum = lum1;
1082 cb = cb1;
1083 cr = cr1;
1084 for(w = width; w >= 2; w -= 2) {
1085 p[0] = lum[0];
1086 p[1] = cb[0];
1087 p[2] = lum[1];
1088 p[3] = cr[0];
1089 p += 4;
1090 lum += 2;
1091 cb++;
1092 cr++;
1093 }
0a05e494
FB
1094 p1 += dst->linesize[0];
1095 lum1 += src->linesize[0];
1096 cb1 += src->linesize[1];
1097 cr1 += src->linesize[2];
c50c0bc8
FB
1098 }
1099}
1100
ebb177dd
TK
1101static void yuv422p_to_uyvy422(AVPicture *dst, const AVPicture *src,
1102 int width, int height)
1103{
1104 uint8_t *p, *p1;
1105 const uint8_t *lum, *cr, *cb, *lum1, *cr1, *cb1;
1106 int w;
1107
1108 p1 = dst->data[0];
1109 lum1 = src->data[0];
1110 cb1 = src->data[1];
1111 cr1 = src->data[2];
1112 for(;height > 0; height--) {
1113 p = p1;
1114 lum = lum1;
1115 cb = cb1;
1116 cr = cr1;
1117 for(w = width; w >= 2; w -= 2) {
1118 p[1] = lum[0];
1119 p[0] = cb[0];
1120 p[3] = lum[1];
1121 p[2] = cr[0];
1122 p += 4;
1123 lum += 2;
1124 cb++;
1125 cr++;
1126 }
1127 p1 += dst->linesize[0];
1128 lum1 += src->linesize[0];
1129 cb1 += src->linesize[1];
1130 cr1 += src->linesize[2];
1131 }
1132}
1133
9ac529a5 1134static void uyyvyy411_to_yuv411p(AVPicture *dst, const AVPicture *src,
f02be79d
RS
1135 int width, int height)
1136{
1137 const uint8_t *p, *p1;
1138 uint8_t *lum, *cr, *cb, *lum1, *cr1, *cb1;
1139 int w;
1140
1141 p1 = src->data[0];
1142 lum1 = dst->data[0];
1143 cb1 = dst->data[1];
1144 cr1 = dst->data[2];
1145 for(;height > 0; height--) {
1146 p = p1;
1147 lum = lum1;
1148 cb = cb1;
1149 cr = cr1;
1150 for(w = width; w >= 4; w -= 4) {
1151 cb[0] = p[0];
bb270c08 1152 lum[0] = p[1];
f02be79d
RS
1153 lum[1] = p[2];
1154 cr[0] = p[3];
bb270c08
DB
1155 lum[2] = p[4];
1156 lum[3] = p[5];
f02be79d
RS
1157 p += 6;
1158 lum += 4;
1159 cb++;
1160 cr++;
1161 }
1162 p1 += src->linesize[0];
1163 lum1 += dst->linesize[0];
1164 cb1 += dst->linesize[1];
1165 cr1 += dst->linesize[2];
1166 }
1167}
ebb177dd
TK
1168
1169
dc02fc6a 1170static void yuv420p_to_yuyv422(AVPicture *dst, const AVPicture *src,
d7e2f57f
MN
1171 int width, int height)
1172{
1173 int w, h;
1174 uint8_t *line1, *line2, *linesrc = dst->data[0];
1175 uint8_t *lum1, *lum2, *lumsrc = src->data[0];
1176 uint8_t *cb1, *cb2 = src->data[1];
1177 uint8_t *cr1, *cr2 = src->data[2];
115329f1 1178
d7e2f57f
MN
1179 for(h = height / 2; h--;) {
1180 line1 = linesrc;
1181 line2 = linesrc + dst->linesize[0];
115329f1 1182
d7e2f57f
MN
1183 lum1 = lumsrc;
1184 lum2 = lumsrc + src->linesize[0];
115329f1 1185
d7e2f57f
MN
1186 cb1 = cb2;
1187 cr1 = cr2;
115329f1 1188
d7e2f57f 1189 for(w = width / 2; w--;) {
115329f1
DB
1190 *line1++ = *lum1++; *line2++ = *lum2++;
1191 *line1++ = *line2++ = *cb1++;
1192 *line1++ = *lum1++; *line2++ = *lum2++;
d7e2f57f
MN
1193 *line1++ = *line2++ = *cr1++;
1194 }
115329f1 1195
d7e2f57f
MN
1196 linesrc += dst->linesize[0] * 2;
1197 lumsrc += src->linesize[0] * 2;
1198 cb2 += src->linesize[1];
1199 cr2 += src->linesize[2];
1200 }
1201}
1202
bac65165
LA
1203static void yuv420p_to_uyvy422(AVPicture *dst, const AVPicture *src,
1204 int width, int height)
1205{
1206 int w, h;
1207 uint8_t *line1, *line2, *linesrc = dst->data[0];
1208 uint8_t *lum1, *lum2, *lumsrc = src->data[0];
1209 uint8_t *cb1, *cb2 = src->data[1];
1210 uint8_t *cr1, *cr2 = src->data[2];
115329f1 1211
bac65165
LA
1212 for(h = height / 2; h--;) {
1213 line1 = linesrc;
1214 line2 = linesrc + dst->linesize[0];
115329f1 1215
bac65165
LA
1216 lum1 = lumsrc;
1217 lum2 = lumsrc + src->linesize[0];
115329f1 1218
bac65165
LA
1219 cb1 = cb2;
1220 cr1 = cr2;
115329f1 1221
bac65165 1222 for(w = width / 2; w--;) {
115329f1
DB
1223 *line1++ = *line2++ = *cb1++;
1224 *line1++ = *lum1++; *line2++ = *lum2++;
bac65165 1225 *line1++ = *line2++ = *cr1++;
115329f1 1226 *line1++ = *lum1++; *line2++ = *lum2++;
bac65165 1227 }
115329f1 1228
bac65165
LA
1229 linesrc += dst->linesize[0] * 2;
1230 lumsrc += src->linesize[0] * 2;
1231 cb2 += src->linesize[1];
1232 cr2 += src->linesize[2];
1233 }
1234}
1235
c50c0bc8
FB
1236static uint8_t y_ccir_to_jpeg[256];
1237static uint8_t y_jpeg_to_ccir[256];
1238static uint8_t c_ccir_to_jpeg[256];
1239static uint8_t c_jpeg_to_ccir[256];
1240
1241/* init various conversion tables */
1242static void img_convert_init(void)
b6147995 1243{
c50c0bc8 1244 int i;
55fde95e 1245 uint8_t *cm = ff_cropTbl + MAX_NEG_CROP;
b6147995 1246
c50c0bc8
FB
1247 for(i = 0;i < 256; i++) {
1248 y_ccir_to_jpeg[i] = Y_CCIR_TO_JPEG(i);
1249 y_jpeg_to_ccir[i] = Y_JPEG_TO_CCIR(i);
1250 c_ccir_to_jpeg[i] = C_CCIR_TO_JPEG(i);
1251 c_jpeg_to_ccir[i] = C_JPEG_TO_CCIR(i);
b6147995
FB
1252 }
1253}
1254
c50c0bc8 1255/* apply to each pixel the given table */
115329f1 1256static void img_apply_table(uint8_t *dst, int dst_wrap,
c50c0bc8
FB
1257 const uint8_t *src, int src_wrap,
1258 int width, int height, const uint8_t *table1)
b6147995
FB
1259{
1260 int n;
1261 const uint8_t *s;
1262 uint8_t *d;
c50c0bc8 1263 const uint8_t *table;
b6147995 1264
c50c0bc8 1265 table = table1;
b6147995
FB
1266 for(;height > 0; height--) {
1267 s = src;
1268 d = dst;
1269 n = width;
1270 while (n >= 4) {
c50c0bc8
FB
1271 d[0] = table[s[0]];
1272 d[1] = table[s[1]];
1273 d[2] = table[s[2]];
1274 d[3] = table[s[3]];
b6147995
FB
1275 d += 4;
1276 s += 4;
1277 n -= 4;
1278 }
1279 while (n > 0) {
c50c0bc8 1280 d[0] = table[s[0]];
b6147995
FB
1281 d++;
1282 s++;
1283 n--;
1284 }
1285 dst += dst_wrap;
1286 src += src_wrap;
1287 }
1288}
1289
85c242d8 1290/* XXX: use generic filter ? */
e352ff08
FB
1291/* XXX: in most cases, the sampling position is incorrect */
1292
1293/* 4x1 -> 1x1 */
115329f1 1294static void shrink41(uint8_t *dst, int dst_wrap,
e352ff08
FB
1295 const uint8_t *src, int src_wrap,
1296 int width, int height)
1297{
1298 int w;
1299 const uint8_t *s;
1300 uint8_t *d;
1301
1302 for(;height > 0; height--) {
1303 s = src;
1304 d = dst;
1305 for(w = width;w > 0; w--) {
1306 d[0] = (s[0] + s[1] + s[2] + s[3] + 2) >> 2;
1307 s += 4;
1308 d++;
1309 }
1310 src += src_wrap;
1311 dst += dst_wrap;
1312 }
1313}
1314
1315/* 2x1 -> 1x1 */
115329f1 1316static void shrink21(uint8_t *dst, int dst_wrap,
e352ff08
FB
1317 const uint8_t *src, int src_wrap,
1318 int width, int height)
1319{
1320 int w;
1321 const uint8_t *s;
1322 uint8_t *d;
1323
1324 for(;height > 0; height--) {
1325 s = src;
1326 d = dst;
1327 for(w = width;w > 0; w--) {
1328 d[0] = (s[0] + s[1]) >> 1;
1329 s += 2;
1330 d++;
1331 }
1332 src += src_wrap;
1333 dst += dst_wrap;
1334 }
1335}
1336
85c242d8 1337/* 1x2 -> 1x1 */
115329f1 1338static void shrink12(uint8_t *dst, int dst_wrap,
e352ff08
FB
1339 const uint8_t *src, int src_wrap,
1340 int width, int height)
85c242d8
FB
1341{
1342 int w;
e352ff08
FB
1343 uint8_t *d;
1344 const uint8_t *s1, *s2;
85c242d8
FB
1345
1346 for(;height > 0; height--) {
1347 s1 = src;
1348 s2 = s1 + src_wrap;
1349 d = dst;
1350 for(w = width;w >= 4; w-=4) {
1351 d[0] = (s1[0] + s2[0]) >> 1;
1352 d[1] = (s1[1] + s2[1]) >> 1;
1353 d[2] = (s1[2] + s2[2]) >> 1;
1354 d[3] = (s1[3] + s2[3]) >> 1;
1355 s1 += 4;
1356 s2 += 4;
1357 d += 4;
1358 }
1359 for(;w > 0; w--) {
1360 d[0] = (s1[0] + s2[0]) >> 1;
1361 s1++;
1362 s2++;
1363 d++;
1364 }
1365 src += 2 * src_wrap;
1366 dst += dst_wrap;
1367 }
1368}
1369
1370/* 2x2 -> 1x1 */
54009d42 1371void ff_shrink22(uint8_t *dst, int dst_wrap,
e352ff08 1372 const uint8_t *src, int src_wrap,
85c242d8
FB
1373 int width, int height)
1374{
1375 int w;
e352ff08
FB
1376 const uint8_t *s1, *s2;
1377 uint8_t *d;
85c242d8
FB
1378
1379 for(;height > 0; height--) {
1380 s1 = src;
1381 s2 = s1 + src_wrap;
1382 d = dst;
1383 for(w = width;w >= 4; w-=4) {
0a9ad8d1
FB
1384 d[0] = (s1[0] + s1[1] + s2[0] + s2[1] + 2) >> 2;
1385 d[1] = (s1[2] + s1[3] + s2[2] + s2[3] + 2) >> 2;
1386 d[2] = (s1[4] + s1[5] + s2[4] + s2[5] + 2) >> 2;
1387 d[3] = (s1[6] + s1[7] + s2[6] + s2[7] + 2) >> 2;
85c242d8
FB
1388 s1 += 8;
1389 s2 += 8;
1390 d += 4;
1391 }
1392 for(;w > 0; w--) {
0a9ad8d1 1393 d[0] = (s1[0] + s1[1] + s2[0] + s2[1] + 2) >> 2;
85c242d8
FB
1394 s1 += 2;
1395 s2 += 2;
1396 d++;
1397 }
1398 src += 2 * src_wrap;
1399 dst += dst_wrap;
1400 }
1401}
1402
e352ff08 1403/* 4x4 -> 1x1 */
54009d42 1404void ff_shrink44(uint8_t *dst, int dst_wrap,
e352ff08 1405 const uint8_t *src, int src_wrap,
6742d95d
FR
1406 int width, int height)
1407{
1408 int w;
e352ff08
FB
1409 const uint8_t *s1, *s2, *s3, *s4;
1410 uint8_t *d;
6742d95d
FR
1411
1412 for(;height > 0; height--) {
1413 s1 = src;
e352ff08
FB
1414 s2 = s1 + src_wrap;
1415 s3 = s2 + src_wrap;
1416 s4 = s3 + src_wrap;
6742d95d 1417 d = dst;
e352ff08
FB
1418 for(w = width;w > 0; w--) {
1419 d[0] = (s1[0] + s1[1] + s1[2] + s1[3] +
1420 s2[0] + s2[1] + s2[2] + s2[3] +
1421 s3[0] + s3[1] + s3[2] + s3[3] +
1422 s4[0] + s4[1] + s4[2] + s4[3] + 8) >> 4;
1423 s1 += 4;
1424 s2 += 4;
1425 s3 += 4;
1426 s4 += 4;
6742d95d
FR
1427 d++;
1428 }
e352ff08
FB
1429 src += 4 * src_wrap;
1430 dst += dst_wrap;
1431 }
1432}
1433
54009d42
MN
1434/* 8x8 -> 1x1 */
1435void ff_shrink88(uint8_t *dst, int dst_wrap,
1436 const uint8_t *src, int src_wrap,
1437 int width, int height)
1438{
1439 int w, i;
1440
1441 for(;height > 0; height--) {
1442 for(w = width;w > 0; w--) {
1443 int tmp=0;
1444 for(i=0; i<8; i++){
1445 tmp += src[0] + src[1] + src[2] + src[3] + src[4] + src[5] + src[6] + src[7];
1446 src += src_wrap;
1447 }
1448 *(dst++) = (tmp + 32)>>6;
1449 src += 8 - 8*src_wrap;
1450 }
1451 src += 8*src_wrap - 8*width;
1452 dst += dst_wrap - width;
1453 }
1454}
1455
e352ff08
FB
1456static void grow21_line(uint8_t *dst, const uint8_t *src,
1457 int width)
1458{
1459 int w;
1460 const uint8_t *s1;
1461 uint8_t *d;
1462
1463 s1 = src;
1464 d = dst;
1465 for(w = width;w >= 4; w-=4) {
1466 d[1] = d[0] = s1[0];
1467 d[3] = d[2] = s1[1];
1468 s1 += 2;
1469 d += 4;
1470 }
1471 for(;w >= 2; w -= 2) {
1472 d[1] = d[0] = s1[0];
1473 s1 ++;
1474 d += 2;
1475 }
1476 /* only needed if width is not a multiple of two */
1477 /* XXX: veryfy that */
1478 if (w) {
1479 d[0] = s1[0];
1480 }
1481}
1482
1483static void grow41_line(uint8_t *dst, const uint8_t *src,
1484 int width)
1485{
1486 int w, v;
1487 const uint8_t *s1;
1488 uint8_t *d;
1489
1490 s1 = src;
1491 d = dst;
1492 for(w = width;w >= 4; w-=4) {
1493 v = s1[0];
1494 d[0] = v;
1495 d[1] = v;
1496 d[2] = v;
1497 d[3] = v;
1498 s1 ++;
1499 d += 4;
1500 }
1501}
1502
1503/* 1x1 -> 2x1 */
1504static void grow21(uint8_t *dst, int dst_wrap,
1505 const uint8_t *src, int src_wrap,
1506 int width, int height)
1507{
1508 for(;height > 0; height--) {
1509 grow21_line(dst, src, width);
1510 src += src_wrap;
1511 dst += dst_wrap;
1512 }
1513}
1514
4196cfb7
1515/* 1x1 -> 1x2 */
1516static void grow12(uint8_t *dst, int dst_wrap,
1517 const uint8_t *src, int src_wrap,
1518 int width, int height)
1519{
1520 for(;height > 0; height-=2) {
1521 memcpy(dst, src, width);
1522 dst += dst_wrap;
1523 memcpy(dst, src, width);
1524 dst += dst_wrap;
1525 src += src_wrap;
1526 }
1527}
1528
e352ff08
FB
1529/* 1x1 -> 2x2 */
1530static void grow22(uint8_t *dst, int dst_wrap,
1531 const uint8_t *src, int src_wrap,
1532 int width, int height)
1533{
1534 for(;height > 0; height--) {
1535 grow21_line(dst, src, width);
6742d95d
FR
1536 if (height%2)
1537 src += src_wrap;
1538 dst += dst_wrap;
1539 }
1540}
1541
e352ff08
FB
1542/* 1x1 -> 4x1 */
1543static void grow41(uint8_t *dst, int dst_wrap,
1544 const uint8_t *src, int src_wrap,
1545 int width, int height)
1546{
1547 for(;height > 0; height--) {
1548 grow41_line(dst, src, width);
1549 src += src_wrap;
1550 dst += dst_wrap;
1551 }
1552}
1553
1554/* 1x1 -> 4x4 */
1555static void grow44(uint8_t *dst, int dst_wrap,
1556 const uint8_t *src, int src_wrap,
1557 int width, int height)
1558{
1559 for(;height > 0; height--) {
1560 grow41_line(dst, src, width);
1561 if ((height & 3) == 1)
1562 src += src_wrap;
1563 dst += dst_wrap;
1564 }
1565}
1566
524c6b63 1567/* 1x2 -> 2x1 */
115329f1 1568static void conv411(uint8_t *dst, int dst_wrap,
e352ff08 1569 const uint8_t *src, int src_wrap,
789587d5
FB
1570 int width, int height)
1571{
1572 int w, c;
e352ff08
FB
1573 const uint8_t *s1, *s2;
1574 uint8_t *d;
789587d5 1575
50643575
MN
1576 width>>=1;
1577
524c6b63 1578 for(;height > 0; height--) {
789587d5
FB
1579 s1 = src;
1580 s2 = src + src_wrap;
1581 d = dst;
1582 for(w = width;w > 0; w--) {
1583 c = (s1[0] + s2[0]) >> 1;
1584 d[0] = c;
1585 d[1] = c;
1586 s1++;
1587 s2++;
1588 d += 2;
1589 }
1590 src += src_wrap * 2;
1591 dst += dst_wrap;
1592 }
1593}
1594
7e7e5940
FB
1595/* XXX: add jpeg quantize code */
1596
1597#define TRANSP_INDEX (6*6*6)
1598
1599/* this is maybe slow, but allows for extensions */
1600static inline unsigned char gif_clut_index(uint8_t r, uint8_t g, uint8_t b)
85c242d8 1601{
7e7e5940 1602 return ((((r)/47)%6)*6*6+(((g)/47)%6)*6+(((b)/47)%6));
85c242d8
FB
1603}
1604
7e7e5940
FB
1605static void build_rgb_palette(uint8_t *palette, int has_alpha)
1606{
1607 uint32_t *pal;
1608 static const uint8_t pal_value[6] = { 0x00, 0x33, 0x66, 0x99, 0xcc, 0xff };
1609 int i, r, g, b;
1610
1611 pal = (uint32_t *)palette;
1612 i = 0;
1613 for(r = 0; r < 6; r++) {
1614 for(g = 0; g < 6; g++) {
1615 for(b = 0; b < 6; b++) {
115329f1 1616 pal[i++] = (0xff << 24) | (pal_value[r] << 16) |
7e7e5940
FB
1617 (pal_value[g] << 8) | pal_value[b];
1618 }
1619 }
1620 }
1621 if (has_alpha)
1622 pal[i++] = 0;
1623 while (i < 256)
1624 pal[i++] = 0xff000000;
524c6b63
FB
1625}
1626
1627/* copy bit n to bits 0 ... n - 1 */
1628static inline unsigned int bitcopy_n(unsigned int a, int n)
b71472eb 1629{
524c6b63
FB
1630 int mask;
1631 mask = (1 << n) - 1;
1632 return (a & (0xff & ~mask)) | ((-((a >> n) & 1)) & mask);
1633}
1634
1635/* rgb555 handling */
1636
7e7e5940
FB
1637#define RGB_NAME rgb555
1638
524c6b63
FB
1639#define RGB_IN(r, g, b, s)\
1640{\
0c1a9eda 1641 unsigned int v = ((const uint16_t *)(s))[0];\
524c6b63
FB
1642 r = bitcopy_n(v >> (10 - 3), 3);\
1643 g = bitcopy_n(v >> (5 - 3), 3);\
1644 b = bitcopy_n(v << 3, 3);\
1645}
1646
7e7e5940 1647
20d46c03 1648#define RGB_OUT(d, r, g, b)\
7e7e5940 1649{\
20d46c03 1650 ((uint16_t *)(d))[0] = ((r >> 3) << 10) | ((g >> 3) << 5) | (b >> 3);\
524c6b63
FB
1651}
1652
1653#define BPP 2
1654
7e7e5940 1655#include "imgconvert_template.h"
524c6b63
FB
1656
1657/* rgb565 handling */
1658
7e7e5940
FB
1659#define RGB_NAME rgb565
1660
524c6b63
FB
1661#define RGB_IN(r, g, b, s)\
1662{\
0c1a9eda 1663 unsigned int v = ((const uint16_t *)(s))[0];\
524c6b63
FB
1664 r = bitcopy_n(v >> (11 - 3), 3);\
1665 g = bitcopy_n(v >> (5 - 2), 2);\
1666 b = bitcopy_n(v << 3, 3);\
1667}
1668
1669#define RGB_OUT(d, r, g, b)\
1670{\
0c1a9eda 1671 ((uint16_t *)(d))[0] = ((r >> 3) << 11) | ((g >> 2) << 5) | (b >> 3);\
524c6b63
FB
1672}
1673
1674#define BPP 2
1675
7e7e5940 1676#include "imgconvert_template.h"
524c6b63
FB
1677
1678/* bgr24 handling */
1679
7e7e5940
FB
1680#define RGB_NAME bgr24
1681
524c6b63
FB
1682#define RGB_IN(r, g, b, s)\
1683{\
1684 b = (s)[0];\
1685 g = (s)[1];\
1686 r = (s)[2];\
1687}
1688
1689#define RGB_OUT(d, r, g, b)\
1690{\
1691 (d)[0] = b;\
1692 (d)[1] = g;\
1693 (d)[2] = r;\
1694}
1695
1696#define BPP 3
1697
7e7e5940 1698#include "imgconvert_template.h"
524c6b63
FB
1699
1700#undef RGB_IN
1701#undef RGB_OUT
1702#undef BPP
1703
1704/* rgb24 handling */
1705
7e7e5940
FB
1706#define RGB_NAME rgb24
1707#define FMT_RGB24
1708
524c6b63
FB
1709#define RGB_IN(r, g, b, s)\
1710{\
1711 r = (s)[0];\
1712 g = (s)[1];\
1713 b = (s)[2];\
1714}
1715
1716#define RGB_OUT(d, r, g, b)\
1717{\
1718 (d)[0] = r;\
1719 (d)[1] = g;\
1720 (d)[2] = b;\
1721}
1722
1723#define BPP 3
1724
7e7e5940 1725#include "imgconvert_template.h"
524c6b63 1726
3cf5b6be 1727/* rgb32 handling */
524c6b63 1728
3cf5b6be
DB
1729#define RGB_NAME rgb32
1730#define FMT_RGB32
7e7e5940 1731
524c6b63
FB
1732#define RGB_IN(r, g, b, s)\
1733{\
0c1a9eda 1734 unsigned int v = ((const uint32_t *)(s))[0];\
524c6b63
FB
1735 r = (v >> 16) & 0xff;\
1736 g = (v >> 8) & 0xff;\
1737 b = v & 0xff;\
1738}
1739
7e7e5940 1740#define RGBA_IN(r, g, b, a, s)\
524c6b63 1741{\
7e7e5940
FB
1742 unsigned int v = ((const uint32_t *)(s))[0];\
1743 a = (v >> 24) & 0xff;\
1744 r = (v >> 16) & 0xff;\
1745 g = (v >> 8) & 0xff;\
1746 b = v & 0xff;\
524c6b63
FB
1747}
1748
7e7e5940
FB
1749#define RGBA_OUT(d, r, g, b, a)\
1750{\
1751 ((uint32_t *)(d))[0] = (a << 24) | (r << 16) | (g << 8) | b;\
b71472eb
PG
1752}
1753
7e7e5940 1754#define BPP 4
524c6b63 1755
7e7e5940 1756#include "imgconvert_template.h"
b71472eb 1757
da64ecc3 1758static void mono_to_gray(AVPicture *dst, const AVPicture *src,
2a877875 1759 int width, int height, int xor_mask)
524c6b63
FB
1760{
1761 const unsigned char *p;
1762 unsigned char *q;
1763 int v, dst_wrap, src_wrap;
1764 int y, w;
1765
1766 p = src->data[0];
1767 src_wrap = src->linesize[0] - ((width + 7) >> 3);
1768
1769 q = dst->data[0];
2a877875 1770 dst_wrap = dst->linesize[0] - width;
524c6b63 1771 for(y=0;y<height;y++) {
115329f1 1772 w = width;
524c6b63 1773 while (w >= 8) {
2a877875
FB
1774 v = *p++ ^ xor_mask;
1775 q[0] = -(v >> 7);
1776 q[1] = -((v >> 6) & 1);
1777 q[2] = -((v >> 5) & 1);
1778 q[3] = -((v >> 4) & 1);
1779 q[4] = -((v >> 3) & 1);
1780 q[5] = -((v >> 2) & 1);
1781 q[6] = -((v >> 1) & 1);
1782 q[7] = -((v >> 0) & 1);
524c6b63 1783 w -= 8;
2a877875 1784 q += 8;
524c6b63
FB
1785 }
1786 if (w > 0) {
2a877875 1787 v = *p++ ^ xor_mask;
524c6b63 1788 do {
2a877875
FB
1789 q[0] = -((v >> 7) & 1);
1790 q++;
524c6b63
FB
1791 v <<= 1;
1792 } while (--w);
85c242d8 1793 }
524c6b63
FB
1794 p += src_wrap;
1795 q += dst_wrap;
85c242d8
FB
1796 }
1797}
1798
da64ecc3 1799static void monowhite_to_gray(AVPicture *dst, const AVPicture *src,
524c6b63
FB
1800 int width, int height)
1801{
2a877875
FB
1802 mono_to_gray(dst, src, width, height, 0xff);
1803}
524c6b63 1804
da64ecc3 1805static void monoblack_to_gray(AVPicture *dst, const AVPicture *src,
2a877875
FB
1806 int width, int height)
1807{
1808 mono_to_gray(dst, src, width, height, 0x00);
1809}
524c6b63 1810
da64ecc3 1811static void gray_to_mono(AVPicture *dst, const AVPicture *src,
2a877875
FB
1812 int width, int height, int xor_mask)
1813{
1814 int n;
0c1a9eda
ZK
1815 const uint8_t *s;
1816 uint8_t *d;
2a877875
FB
1817 int j, b, v, n1, src_wrap, dst_wrap, y;
1818
1819 s = src->data[0];
1820 src_wrap = src->linesize[0] - width;
1821
1822 d = dst->data[0];
1823 dst_wrap = dst->linesize[0] - ((width + 7) >> 3);
524c6b63
FB
1824
1825 for(y=0;y<height;y++) {
2a877875
FB
1826 n = width;
1827 while (n >= 8) {
1828 v = 0;
1829 for(j=0;j<8;j++) {
1830 b = s[0];
1831 s++;
1832 v = (v << 1) | (b >> 7);
1833 }
1834 d[0] = v ^ xor_mask;
1835 d++;
1836 n -= 8;
524c6b63 1837 }
2a877875
FB
1838 if (n > 0) {
1839 n1 = n;
1840 v = 0;
1841 while (n > 0) {
1842 b = s[0];
1843 s++;
1844 v = (v << 1) | (b >> 7);
1845 n--;
1846 }
1847 d[0] = (v << (8 - (n1 & 7))) ^ xor_mask;
1848 d++;
524c6b63 1849 }
2a877875
FB
1850 s += src_wrap;
1851 d += dst_wrap;
524c6b63
FB
1852 }
1853}
1854
da64ecc3 1855static void gray_to_monowhite(AVPicture *dst, const AVPicture *src,
2a877875
FB
1856 int width, int height)
1857{
1858 gray_to_mono(dst, src, width, height, 0xff);
1859}
1860
da64ecc3 1861static void gray_to_monoblack(AVPicture *dst, const AVPicture *src,
2a877875
FB
1862 int width, int height)
1863{
1864 gray_to_mono(dst, src, width, height, 0x00);
1865}
1866
34380af0
KS
1867static void gray_to_gray16(AVPicture *dst, const AVPicture *src,
1868 int width, int height)
1869{
1870 int x, y, src_wrap, dst_wrap;
1871 uint8_t *s, *d;
1872 s = src->data[0];
1873 src_wrap = src->linesize[0] - width;
1874 d = dst->data[0];
1875 dst_wrap = dst->linesize[0] - width * 2;
1876 for(y=0; y<height; y++){
1877 for(x=0; x<width; x++){
1878 *d++ = *s;
1879 *d++ = *s++;
1880 }
1881 s += src_wrap;
1882 d += dst_wrap;
1883 }
1884}
1885
1886static void gray16_to_gray(AVPicture *dst, const AVPicture *src,
1887 int width, int height)
1888{
1889 int x, y, src_wrap, dst_wrap;
1890 uint8_t *s, *d;
1891 s = src->data[0];
1892 src_wrap = src->linesize[0] - width * 2;
1893 d = dst->data[0];
1894 dst_wrap = dst->linesize[0] - width;
1895 for(y=0; y<height; y++){
1896 for(x=0; x<width; x++){
1897 *d++ = *s;
1898 s += 2;
1899 }
1900 s += src_wrap;
1901 d += dst_wrap;
1902 }
1903}
1904
1905static void gray16be_to_gray(AVPicture *dst, const AVPicture *src,
1906 int width, int height)
1907{
1908 gray16_to_gray(dst, src, width, height);
1909}
1910
1911static void gray16le_to_gray(AVPicture *dst, const AVPicture *src,
1912 int width, int height)
1913{
e5b51496
IP
1914 AVPicture tmpsrc = *src;
1915 tmpsrc.data[0]++;
1916 gray16_to_gray(dst, &tmpsrc, width, height);
34380af0
KS
1917}
1918
1919static void gray16_to_gray16(AVPicture *dst, const AVPicture *src,
1920 int width, int height)
1921{
1922 int x, y, src_wrap, dst_wrap;
1923 uint16_t *s, *d;
e151e272 1924 s = (uint16_t*)src->data[0];
34380af0 1925 src_wrap = (src->linesize[0] - width * 2)/2;
e151e272 1926 d = (uint16_t*)dst->data[0];
34380af0
KS
1927 dst_wrap = (dst->linesize[0] - width * 2)/2;
1928 for(y=0; y<height; y++){
1929 for(x=0; x<width; x++){
1930 *d++ = bswap_16(*s++);
1931 }
1932 s += src_wrap;
1933 d += dst_wrap;
1934 }
1935}
1936
1937
524c6b63 1938typedef struct ConvertEntry {
da64ecc3 1939 void (*convert)(AVPicture *dst,
bb270c08 1940 const AVPicture *src, int width, int height);
524c6b63
FB
1941} ConvertEntry;
1942
f1ea5c2a 1943/* Add each new conversion function in this table. In order to be able
c50c0bc8
FB
1944 to convert from any format to any format, the following constraints
1945 must be satisfied:
1946
115329f1 1947 - all FF_COLOR_RGB formats must convert to and from PIX_FMT_RGB24
c50c0bc8
FB
1948
1949 - all FF_COLOR_GRAY formats must convert to and from PIX_FMT_GRAY8
1950
71e445fc 1951 - all FF_COLOR_RGB formats with alpha must convert to and from PIX_FMT_RGB32
c50c0bc8 1952
e352ff08 1953 - PIX_FMT_YUV444P and PIX_FMT_YUVJ444P must convert to and from
c50c0bc8
FB
1954 PIX_FMT_RGB24.
1955
1956 - PIX_FMT_422 must convert to and from PIX_FMT_422P.
e352ff08 1957
52b541ad 1958 The other conversion functions are just optimizations for common cases.
524c6b63 1959*/
62a05b5b 1960static const ConvertEntry convert_table[PIX_FMT_NB][PIX_FMT_NB] = {
524c6b63 1961 [PIX_FMT_YUV420P] = {
71e445fc 1962 [PIX_FMT_YUYV422] = {
dc02fc6a 1963 .convert = yuv420p_to_yuyv422,
d7e2f57f 1964 },
115329f1 1965 [PIX_FMT_RGB555] = {
ef9f7306 1966 .convert = yuv420p_to_rgb555
524c6b63 1967 },
115329f1 1968 [PIX_FMT_RGB565] = {
ef9f7306 1969 .convert = yuv420p_to_rgb565
524c6b63 1970 },
115329f1 1971 [PIX_FMT_BGR24] = {
ef9f7306 1972 .convert = yuv420p_to_bgr24
524c6b63 1973 },
115329f1 1974 [PIX_FMT_RGB24] = {
ef9f7306 1975 .convert = yuv420p_to_rgb24
524c6b63 1976 },
71e445fc 1977 [PIX_FMT_RGB32] = {
3cf5b6be 1978 .convert = yuv420p_to_rgb32
524c6b63 1979 },
bb270c08 1980 [PIX_FMT_UYVY422] = {
bac65165
LA
1981 .convert = yuv420p_to_uyvy422,
1982 },
524c6b63 1983 },
115329f1 1984 [PIX_FMT_YUV422P] = {
71e445fc 1985 [PIX_FMT_YUYV422] = {
dc02fc6a 1986 .convert = yuv422p_to_yuyv422,
c50c0bc8 1987 },
115329f1 1988 [PIX_FMT_UYVY422] = {
ebb177dd
TK
1989 .convert = yuv422p_to_uyvy422,
1990 },
c50c0bc8 1991 },
115329f1
DB
1992 [PIX_FMT_YUV444P] = {
1993 [PIX_FMT_RGB24] = {
c50c0bc8
FB
1994 .convert = yuv444p_to_rgb24
1995 },
1996 },
1997 [PIX_FMT_YUVJ420P] = {
115329f1 1998 [PIX_FMT_RGB555] = {
c50c0bc8 1999 .convert = yuvj420p_to_rgb555
524c6b63 2000 },
115329f1 2001 [PIX_FMT_RGB565] = {
c50c0bc8 2002 .convert = yuvj420p_to_rgb565
524c6b63 2003 },
115329f1 2004 [PIX_FMT_BGR24] = {
c50c0bc8 2005 .convert = yuvj420p_to_bgr24
524c6b63 2006 },
115329f1 2007 [PIX_FMT_RGB24] = {
c50c0bc8 2008 .convert = yuvj420p_to_rgb24
524c6b63 2009 },
71e445fc 2010 [PIX_FMT_RGB32] = {
3cf5b6be 2011 .convert = yuvj420p_to_rgb32
c50c0bc8
FB
2012 },
2013 },
115329f1
DB
2014 [PIX_FMT_YUVJ444P] = {
2015 [PIX_FMT_RGB24] = {
c50c0bc8 2016 .convert = yuvj444p_to_rgb24
524c6b63
FB
2017 },
2018 },
71e445fc 2019 [PIX_FMT_YUYV422] = {
115329f1 2020 [PIX_FMT_YUV420P] = {
dc02fc6a 2021 .convert = yuyv422_to_yuv420p,
524c6b63 2022 },
115329f1 2023 [PIX_FMT_YUV422P] = {
dc02fc6a 2024 .convert = yuyv422_to_yuv422p,
c50c0bc8 2025 },
524c6b63 2026 },
115329f1
DB
2027 [PIX_FMT_UYVY422] = {
2028 [PIX_FMT_YUV420P] = {
ebb177dd
TK
2029 .convert = uyvy422_to_yuv420p,
2030 },
115329f1 2031 [PIX_FMT_YUV422P] = {
ebb177dd
TK
2032 .convert = uyvy422_to_yuv422p,
2033 },
2034 },
524c6b63 2035 [PIX_FMT_RGB24] = {
115329f1 2036 [PIX_FMT_YUV420P] = {
ef9f7306 2037 .convert = rgb24_to_yuv420p
524c6b63 2038 },
115329f1 2039 [PIX_FMT_RGB565] = {
ef9f7306 2040 .convert = rgb24_to_rgb565
524c6b63 2041 },
115329f1 2042 [PIX_FMT_RGB555] = {
ef9f7306 2043 .convert = rgb24_to_rgb555
524c6b63 2044 },
71e445fc 2045 [PIX_FMT_RGB32] = {
3cf5b6be 2046 .convert = rgb24_to_rgb32
7e7e5940 2047 },
115329f1 2048 [PIX_FMT_BGR24] = {
7e7e5940
FB
2049 .convert = rgb24_to_bgr24
2050 },
115329f1 2051 [PIX_FMT_GRAY8] = {
ef9f7306 2052 .convert = rgb24_to_gray
524c6b63 2053 },
7e7e5940 2054 [PIX_FMT_PAL8] = {
7e6d70d0
FB
2055 .convert = rgb24_to_pal8
2056 },
115329f1 2057 [PIX_FMT_YUV444P] = {
c50c0bc8
FB
2058 .convert = rgb24_to_yuv444p
2059 },
115329f1 2060 [PIX_FMT_YUVJ420P] = {
c50c0bc8
FB
2061 .convert = rgb24_to_yuvj420p
2062 },
115329f1 2063 [PIX_FMT_YUVJ444P] = {
c50c0bc8
FB
2064 .convert = rgb24_to_yuvj444p
2065 },
524c6b63 2066 },
71e445fc 2067 [PIX_FMT_RGB32] = {
115329f1 2068 [PIX_FMT_RGB24] = {
3cf5b6be 2069 .convert = rgb32_to_rgb24
7e7e5940 2070 },
b3625676 2071 [PIX_FMT_BGR24] = {
3cf5b6be 2072 .convert = rgb32_to_bgr24
b3625676
AB
2073 },
2074 [PIX_FMT_RGB565] = {
3cf5b6be 2075 .convert = rgb32_to_rgb565
b3625676 2076 },
115329f1 2077 [PIX_FMT_RGB555] = {
3cf5b6be 2078 .convert = rgb32_to_rgb555
7e7e5940 2079 },
115329f1 2080 [PIX_FMT_PAL8] = {
3cf5b6be 2081 .convert = rgb32_to_pal8
7e7e5940 2082 },
115329f1 2083 [PIX_FMT_YUV420P] = {
3cf5b6be 2084 .convert = rgb32_to_yuv420p
524c6b63 2085 },
115329f1 2086 [PIX_FMT_GRAY8] = {
3cf5b6be 2087 .convert = rgb32_to_gray
69572401 2088 },
524c6b63
FB
2089 },
2090 [PIX_FMT_BGR24] = {
71e445fc 2091 [PIX_FMT_RGB32] = {
3cf5b6be 2092 .convert = bgr24_to_rgb32
b3625676 2093 },
115329f1 2094 [PIX_FMT_RGB24] = {
7e7e5940
FB
2095 .convert = bgr24_to_rgb24
2096 },
115329f1 2097 [PIX_FMT_YUV420P] = {
ef9f7306 2098 .convert = bgr24_to_yuv420p
524c6b63 2099 },
115329f1 2100 [PIX_FMT_GRAY8] = {
69572401
FB
2101 .convert = bgr24_to_gray
2102 },
524c6b63
FB
2103 },
2104 [PIX_FMT_RGB555] = {
115329f1 2105 [PIX_FMT_RGB24] = {
7e7e5940
FB
2106 .convert = rgb555_to_rgb24
2107 },
71e445fc 2108 [PIX_FMT_RGB32] = {
3cf5b6be 2109 .convert = rgb555_to_rgb32
7e7e5940 2110 },
115329f1 2111 [PIX_FMT_YUV420P] = {
ef9f7306 2112 .convert = rgb555_to_yuv420p
524c6b63 2113 },
115329f1 2114 [PIX_FMT_GRAY8] = {
69572401
FB
2115 .convert = rgb555_to_gray
2116 },
524c6b63
FB
2117 },
2118 [PIX_FMT_RGB565] = {
71e445fc 2119 [PIX_FMT_RGB32] = {
3cf5b6be 2120 .convert = rgb565_to_rgb32
b3625676 2121 },
115329f1 2122 [PIX_FMT_RGB24] = {
7e7e5940
FB
2123 .convert = rgb565_to_rgb24
2124 },
115329f1 2125 [PIX_FMT_YUV420P] = {
ef9f7306 2126 .convert = rgb565_to_yuv420p
524c6b63 2127 },
115329f1 2128 [PIX_FMT_GRAY8] = {
69572401
FB
2129 .convert = rgb565_to_gray
2130 },
524c6b63 2131 },
34380af0
KS
2132 [PIX_FMT_GRAY16BE] = {
2133 [PIX_FMT_GRAY8] = {
2134 .convert = gray16be_to_gray
2135 },
2136 [PIX_FMT_GRAY16LE] = {
2137 .convert = gray16_to_gray16
2138 },
2139 },
2140 [PIX_FMT_GRAY16LE] = {
2141 [PIX_FMT_GRAY8] = {
2142 .convert = gray16le_to_gray
2143 },
2144 [PIX_FMT_GRAY16BE] = {
2145 .convert = gray16_to_gray16
2146 },
2147 },
524c6b63 2148 [PIX_FMT_GRAY8] = {
115329f1 2149 [PIX_FMT_RGB555] = {
69572401
FB
2150 .convert = gray_to_rgb555
2151 },
115329f1 2152 [PIX_FMT_RGB565] = {
69572401
FB
2153 .convert = gray_to_rgb565
2154 },
115329f1 2155 [PIX_FMT_RGB24] = {
ef9f7306 2156 .convert = gray_to_rgb24
524c6b63 2157 },
115329f1 2158 [PIX_FMT_BGR24] = {
69572401
FB
2159 .convert = gray_to_bgr24
2160 },
71e445fc 2161 [PIX_FMT_RGB32] = {
3cf5b6be 2162 .convert = gray_to_rgb32
69572401 2163 },
115329f1 2164 [PIX_FMT_MONOWHITE] = {
ef9f7306 2165 .convert = gray_to_monowhite
2a877875 2166 },
115329f1 2167 [PIX_FMT_MONOBLACK] = {
ef9f7306 2168 .convert = gray_to_monoblack
2a877875 2169 },
34380af0
KS
2170 [PIX_FMT_GRAY16LE] = {
2171 .convert = gray_to_gray16
2172 },
2173 [PIX_FMT_GRAY16BE] = {
2174 .convert = gray_to_gray16
2175 },
524c6b63
FB
2176 },
2177 [PIX_FMT_MONOWHITE] = {
115329f1 2178 [PIX_FMT_GRAY8] = {
ef9f7306 2179 .convert = monowhite_to_gray
524c6b63
FB
2180 },
2181 },
2182 [PIX_FMT_MONOBLACK] = {
115329f1 2183 [PIX_FMT_GRAY8] = {
ef9f7306 2184 .convert = monoblack_to_gray
524c6b63
FB
2185 },
2186 },
7e6d70d0 2187 [PIX_FMT_PAL8] = {
115329f1 2188 [PIX_FMT_RGB555] = {
7e6d70d0
FB
2189 .convert = pal8_to_rgb555
2190 },
115329f1 2191 [PIX_FMT_RGB565] = {
7e6d70d0
FB
2192 .convert = pal8_to_rgb565
2193 },
115329f1 2194 [PIX_FMT_BGR24] = {
7e6d70d0
FB
2195 .convert = pal8_to_bgr24
2196 },
115329f1 2197 [PIX_FMT_RGB24] = {
7e6d70d0
FB
2198 .convert = pal8_to_rgb24
2199 },
71e445fc 2200 [PIX_FMT_RGB32] = {
3cf5b6be 2201 .convert = pal8_to_rgb32
7e6d70d0
FB
2202 },
2203 },
71e445fc 2204 [PIX_FMT_UYYVYY411] = {
115329f1 2205 [PIX_FMT_YUV411P] = {
9ac529a5 2206 .convert = uyyvyy411_to_yuv411p,
f02be79d
RS
2207 },
2208 },
2209
524c6b63
FB
2210};
2211
75917b88 2212int avpicture_alloc(AVPicture *picture,
524c6b63
FB
2213 int pix_fmt, int width, int height)
2214{
2d5545c3 2215 int size;
524c6b63
FB
2216 void *ptr;
2217
2218 size = avpicture_get_size(pix_fmt, width, height);
0ecca7a4
MN
2219 if(size<0)
2220 goto fail;
524c6b63
FB
2221 ptr = av_malloc(size);
2222 if (!ptr)
2223 goto fail;
2224 avpicture_fill(picture, ptr, pix_fmt, width, height);
2225 return 0;
2226 fail:
2227 memset(picture, 0, sizeof(AVPicture));
2228 return -1;
2229}
2230
75917b88 2231void avpicture_free(AVPicture *picture)
524c6b63 2232{
8e1e6f31 2233 av_free(picture->data[0]);
524c6b63
FB
2234}
2235
c50c0bc8 2236/* return true if yuv planar */
62a05b5b 2237static inline int is_yuv_planar(const PixFmtInfo *ps)
c50c0bc8
FB
2238{
2239 return (ps->color_type == FF_COLOR_YUV ||
115329f1 2240 ps->color_type == FF_COLOR_YUV_JPEG) &&
7e7e5940 2241 ps->pixel_type == FF_PIXEL_PLANAR;
c50c0bc8
FB
2242}
2243
636d6a4a 2244int av_picture_crop(AVPicture *dst, const AVPicture *src,
f2651e7a
BC
2245 int pix_fmt, int top_band, int left_band)
2246{
2247 int y_shift;
2248 int x_shift;
2249
2250 if (pix_fmt < 0 || pix_fmt >= PIX_FMT_NB || !is_yuv_planar(&pix_fmt_info[pix_fmt]))
2251 return -1;
2252
2253 y_shift = pix_fmt_info[pix_fmt].y_chroma_shift;
2254 x_shift = pix_fmt_info[pix_fmt].x_chroma_shift;
2255
2256 dst->data[0] = src->data[0] + (top_band * src->linesize[0]) + left_band;
2257 dst->data[1] = src->data[1] + ((top_band >> y_shift) * src->linesize[1]) + (left_band >> x_shift);
2258 dst->data[2] = src->data[2] + ((top_band >> y_shift) * src->linesize[2]) + (left_band >> x_shift);
2259
2260 dst->linesize[0] = src->linesize[0];
2261 dst->linesize[1] = src->linesize[1];
2262 dst->linesize[2] = src->linesize[2];
2263 return 0;
2264}
2265
636d6a4a 2266int av_picture_pad(AVPicture *dst, const AVPicture *src, int height, int width,
6845801f
LB
2267 int pix_fmt, int padtop, int padbottom, int padleft, int padright,
2268 int *color)
5341c209 2269{
79acfb0e 2270 uint8_t *optr;
5341c209
LA
2271 int y_shift;
2272 int x_shift;
2273 int yheight;
2274 int i, y;
2275
6845801f
LB
2276 if (pix_fmt < 0 || pix_fmt >= PIX_FMT_NB ||
2277 !is_yuv_planar(&pix_fmt_info[pix_fmt])) return -1;
5341c209
LA
2278
2279 for (i = 0; i < 3; i++) {
2280 x_shift = i ? pix_fmt_info[pix_fmt].x_chroma_shift : 0;
2281 y_shift = i ? pix_fmt_info[pix_fmt].y_chroma_shift : 0;
2282
2283 if (padtop || padleft) {
6845801f
LB
2284 memset(dst->data[i], color[i],
2285 dst->linesize[i] * (padtop >> y_shift) + (padleft >> x_shift));
5341c209
LA
2286 }
2287
79acfb0e
LB
2288 if (padleft || padright) {
2289 optr = dst->data[i] + dst->linesize[i] * (padtop >> y_shift) +
2290 (dst->linesize[i] - (padright >> x_shift));
2291 yheight = (height - 1 - (padtop + padbottom)) >> y_shift;
2292 for (y = 0; y < yheight; y++) {
2293 memset(optr, color[i], (padleft + padright) >> x_shift);
2294 optr += dst->linesize[i];
5341c209 2295 }
79acfb0e
LB
2296 }
2297
2298 if (src) { /* first line */
2299 uint8_t *iptr = src->data[i];
2300 optr = dst->data[i] + dst->linesize[i] * (padtop >> y_shift) +
2301 (padleft >> x_shift);
2302 memcpy(optr, iptr, src->linesize[i]);
2303 iptr += src->linesize[i];
6845801f
LB
2304 optr = dst->data[i] + dst->linesize[i] * (padtop >> y_shift) +
2305 (dst->linesize[i] - (padright >> x_shift));
5341c209
LA
2306 yheight = (height - 1 - (padtop + padbottom)) >> y_shift;
2307 for (y = 0; y < yheight; y++) {
2308 memset(optr, color[i], (padleft + padright) >> x_shift);
79acfb0e
LB
2309 memcpy(optr + ((padleft + padright) >> x_shift), iptr,
2310 src->linesize[i]);
2311 iptr += src->linesize[i];
5341c209
LA
2312 optr += dst->linesize[i];
2313 }
2314 }
2315
2316 if (padbottom || padright) {
6845801f
LB
2317 optr = dst->data[i] + dst->linesize[i] *
2318 ((height - padbottom) >> y_shift) - (padright >> x_shift);
2319 memset(optr, color[i],dst->linesize[i] *
2320 (padbottom >> y_shift) + (padright >> x_shift));
5341c209
LA
2321 }
2322 }
2323 return 0;
2324}
2325
636d6a4a
PI
2326#if LIBAVCODEC_VERSION_INT < ((52<<16)+(0<<8)+0)
2327void img_copy(AVPicture *dst, const AVPicture *src,
2328 int pix_fmt, int width, int height)
2329{
2330 av_picture_copy(dst, src, pix_fmt, width, height);
2331}
2332
2333int img_crop(AVPicture *dst, const AVPicture *src,
2334 int pix_fmt, int top_band, int left_band)
2335{
2336 return av_picture_crop(dst, src, pix_fmt, top_band, left_band);
2337}
2338
2339int img_pad(AVPicture *dst, const AVPicture *src, int height, int width,
2340 int pix_fmt, int padtop, int padbottom, int padleft, int padright,
2341 int *color)
2342{
2343 return av_picture_pad(dst, src, height, width, pix_fmt, padtop, padbottom, padleft, padright, color);
2344}
2345#endif
2346
790c9ca7 2347#ifndef CONFIG_SWSCALER
85c242d8
FB
2348/* XXX: always use linesize. Return -1 if not supported */
2349int img_convert(AVPicture *dst, int dst_pix_fmt,
115329f1 2350 const AVPicture *src, int src_pix_fmt,
524c6b63 2351 int src_width, int src_height)
85c242d8 2352{
c50c0bc8 2353 static int inited;
2a877875 2354 int i, ret, dst_width, dst_height, int_pix_fmt;
62a05b5b
SH
2355 const PixFmtInfo *src_pix, *dst_pix;
2356 const ConvertEntry *ce;
524c6b63
FB
2357 AVPicture tmp1, *tmp = &tmp1;
2358
2359 if (src_pix_fmt < 0 || src_pix_fmt >= PIX_FMT_NB ||
2360 dst_pix_fmt < 0 || dst_pix_fmt >= PIX_FMT_NB)
2361 return -1;
2362 if (src_width <= 0 || src_height <= 0)
2363 return 0;
69572401 2364
c50c0bc8
FB
2365 if (!inited) {
2366 inited = 1;
2367 img_convert_init();
2368 }
2369
524c6b63
FB
2370 dst_width = src_width;
2371 dst_height = src_height;
69572401 2372
524c6b63
FB
2373 dst_pix = &pix_fmt_info[dst_pix_fmt];
2374 src_pix = &pix_fmt_info[src_pix_fmt];
2375 if (src_pix_fmt == dst_pix_fmt) {
7e7e5940 2376 /* no conversion needed: just copy */
636d6a4a 2377 av_picture_copy(dst, src, dst_pix_fmt, dst_width, dst_height);
524c6b63
FB
2378 return 0;
2379 }
2380
2381 ce = &convert_table[src_pix_fmt][dst_pix_fmt];
2382 if (ce->convert) {
ebb177dd 2383 /* specific conversion routine */
524c6b63
FB
2384 ce->convert(dst, src, dst_width, dst_height);
2385 return 0;
2386 }
2387
524c6b63 2388 /* gray to YUV */
c50c0bc8 2389 if (is_yuv_planar(dst_pix) &&
b6147995 2390 src_pix_fmt == PIX_FMT_GRAY8) {
524c6b63
FB
2391 int w, h, y;
2392 uint8_t *d;
2393
b6147995 2394 if (dst_pix->color_type == FF_COLOR_YUV_JPEG) {
54009d42 2395 ff_img_copy_plane(dst->data[0], dst->linesize[0],
b6147995
FB
2396 src->data[0], src->linesize[0],
2397 dst_width, dst_height);
2398 } else {
c50c0bc8
FB
2399 img_apply_table(dst->data[0], dst->linesize[0],
2400 src->data[0], src->linesize[0],
2401 dst_width, dst_height,
2402 y_jpeg_to_ccir);
b6147995 2403 }
524c6b63
FB
2404 /* fill U and V with 128 */
2405 w = dst_width;
2406 h = dst_height;
2407 w >>= dst_pix->x_chroma_shift;
2408 h >>= dst_pix->y_chroma_shift;
2409 for(i = 1; i <= 2; i++) {
2410 d = dst->data[i];
2a877875
FB
2411 for(y = 0; y< h; y++) {
2412 memset(d, 128, w);
524c6b63
FB
2413 d += dst->linesize[i];
2414 }
b71472eb 2415 }
524c6b63
FB
2416 return 0;
2417 }
2418
2419 /* YUV to gray */
115329f1 2420 if (is_yuv_planar(src_pix) &&
b6147995
FB
2421 dst_pix_fmt == PIX_FMT_GRAY8) {
2422 if (src_pix->color_type == FF_COLOR_YUV_JPEG) {
54009d42 2423 ff_img_copy_plane(dst->data[0], dst->linesize[0],
b6147995
FB
2424 src->data[0], src->linesize[0],
2425 dst_width, dst_height);
2426 } else {
c50c0bc8
FB
2427 img_apply_table(dst->data[0], dst->linesize[0],
2428 src->data[0], src->linesize[0],
2429 dst_width, dst_height,
2430 y_ccir_to_jpeg);
b6147995 2431 }
524c6b63
FB
2432 return 0;
2433 }
2434
c50c0bc8
FB
2435 /* YUV to YUV planar */
2436 if (is_yuv_planar(dst_pix) && is_yuv_planar(src_pix)) {
e352ff08 2437 int x_shift, y_shift, w, h, xy_shift;
115329f1 2438 void (*resize_func)(uint8_t *dst, int dst_wrap,
e352ff08 2439 const uint8_t *src, int src_wrap,
524c6b63
FB
2440 int width, int height);
2441
2442 /* compute chroma size of the smallest dimensions */
2443 w = dst_width;
2444 h = dst_height;
2445 if (dst_pix->x_chroma_shift >= src_pix->x_chroma_shift)
2446 w >>= dst_pix->x_chroma_shift;
2447 else
2448 w >>= src_pix->x_chroma_shift;
2449 if (dst_pix->y_chroma_shift >= src_pix->y_chroma_shift)
2450 h >>= dst_pix->y_chroma_shift;
2451 else
2452 h >>= src_pix->y_chroma_shift;
2453
2454 x_shift = (dst_pix->x_chroma_shift - src_pix->x_chroma_shift);
2455 y_shift = (dst_pix->y_chroma_shift - src_pix->y_chroma_shift);
e352ff08
FB
2456 xy_shift = ((x_shift & 0xf) << 4) | (y_shift & 0xf);
2457 /* there must be filters for conversion at least from and to
2458 YUV444 format */
2459 switch(xy_shift) {
2460 case 0x00:
54009d42 2461 resize_func = ff_img_copy_plane;
e352ff08
FB
2462 break;
2463 case 0x10:
2464 resize_func = shrink21;
2465 break;
2466 case 0x20:
2467 resize_func = shrink41;
2468 break;
2469 case 0x01:
2470 resize_func = shrink12;
2471 break;
2472 case 0x11:
54009d42 2473 resize_func = ff_shrink22;
e352ff08
FB
2474 break;
2475 case 0x22:
54009d42 2476 resize_func = ff_shrink44;
e352ff08
FB
2477 break;
2478 case 0xf0:
2479 resize_func = grow21;
2480 break;
4196cfb7
2481 case 0x0f:
2482 resize_func = grow12;
2483 break;
e352ff08
FB
2484 case 0xe0:
2485 resize_func = grow41;
2486 break;
2487 case 0xff:
524c6b63 2488 resize_func = grow22;
e352ff08
FB
2489 break;
2490 case 0xee:
2491 resize_func = grow44;
2492 break;
2493 case 0xf1:
524c6b63 2494 resize_func = conv411;
e352ff08
FB
2495 break;
2496 default:
524c6b63 2497 /* currently not handled */
e352ff08 2498 goto no_chroma_filter;
85c242d8 2499 }
524c6b63 2500
54009d42 2501 ff_img_copy_plane(dst->data[0], dst->linesize[0],
7e7e5940
FB
2502 src->data[0], src->linesize[0],
2503 dst_width, dst_height);
566986ee 2504
524c6b63 2505 for(i = 1;i <= 2; i++)
566986ee
MK
2506 resize_func(dst->data[i], dst->linesize[i],
2507 src->data[i], src->linesize[i],
185fdc54 2508 dst_width>>dst_pix->x_chroma_shift, dst_height>>dst_pix->y_chroma_shift);
c50c0bc8
FB
2509 /* if yuv color space conversion is needed, we do it here on
2510 the destination image */
2511 if (dst_pix->color_type != src_pix->color_type) {
2512 const uint8_t *y_table, *c_table;
2513 if (dst_pix->color_type == FF_COLOR_YUV) {
2514 y_table = y_jpeg_to_ccir;
2515 c_table = c_jpeg_to_ccir;
2516 } else {
2517 y_table = y_ccir_to_jpeg;
2518 c_table = c_ccir_to_jpeg;
2519 }
2520 img_apply_table(dst->data[0], dst->linesize[0],
2521 dst->data[0], dst->linesize[0],
2522 dst_width, dst_height,
2523 y_table);
2524
2525 for(i = 1;i <= 2; i++)
2526 img_apply_table(dst->data[i], dst->linesize[i],
2527 dst->data[i], dst->linesize[i],
115329f1 2528 dst_width>>dst_pix->x_chroma_shift,
c50c0bc8
FB
2529 dst_height>>dst_pix->y_chroma_shift,
2530 c_table);
2531 }
2532 return 0;
85c242d8 2533 }
e352ff08 2534 no_chroma_filter:
524c6b63 2535
2a877875 2536 /* try to use an intermediate format */
71e445fc
DB
2537 if (src_pix_fmt == PIX_FMT_YUYV422 ||
2538 dst_pix_fmt == PIX_FMT_YUYV422) {
c50c0bc8
FB
2539 /* specific case: convert to YUV422P first */
2540 int_pix_fmt = PIX_FMT_YUV422P;
ebb177dd
TK
2541 } else if (src_pix_fmt == PIX_FMT_UYVY422 ||
2542 dst_pix_fmt == PIX_FMT_UYVY422) {
2543 /* specific case: convert to YUV422P first */
2544 int_pix_fmt = PIX_FMT_YUV422P;
71e445fc
DB
2545 } else if (src_pix_fmt == PIX_FMT_UYYVYY411 ||
2546 dst_pix_fmt == PIX_FMT_UYYVYY411) {
f02be79d
RS
2547 /* specific case: convert to YUV411P first */
2548 int_pix_fmt = PIX_FMT_YUV411P;
c50c0bc8 2549 } else if ((src_pix->color_type == FF_COLOR_GRAY &&
115329f1 2550 src_pix_fmt != PIX_FMT_GRAY8) ||
c50c0bc8
FB
2551 (dst_pix->color_type == FF_COLOR_GRAY &&
2552 dst_pix_fmt != PIX_FMT_GRAY8)) {
2553 /* gray8 is the normalized format */
2a877875 2554 int_pix_fmt = PIX_FMT_GRAY8;
115329f1 2555 } else if ((is_yuv_planar(src_pix) &&
c50c0bc8
FB
2556 src_pix_fmt != PIX_FMT_YUV444P &&
2557 src_pix_fmt != PIX_FMT_YUVJ444P)) {
2558 /* yuv444 is the normalized format */
2559 if (src_pix->color_type == FF_COLOR_YUV_JPEG)
2560 int_pix_fmt = PIX_FMT_YUVJ444P;
2561 else
2562 int_pix_fmt = PIX_FMT_YUV444P;
115329f1 2563 } else if ((is_yuv_planar(dst_pix) &&
c50c0bc8
FB
2564 dst_pix_fmt != PIX_FMT_YUV444P &&
2565 dst_pix_fmt != PIX_FMT_YUVJ444P)) {
2566 /* yuv444 is the normalized format */
2567 if (dst_pix->color_type == FF_COLOR_YUV_JPEG)
2568 int_pix_fmt = PIX_FMT_YUVJ444P;
2569 else
2570 int_pix_fmt = PIX_FMT_YUV444P;
2a877875 2571 } else {
c50c0bc8
FB
2572 /* the two formats are rgb or gray8 or yuv[j]444p */
2573 if (src_pix->is_alpha && dst_pix->is_alpha)
71e445fc 2574 int_pix_fmt = PIX_FMT_RGB32;
c50c0bc8
FB
2575 else
2576 int_pix_fmt = PIX_FMT_RGB24;
2a877875 2577 }
86404ffb
BC
2578 if (src_pix_fmt == int_pix_fmt)
2579 return -1;
2a877875
FB
2580 if (avpicture_alloc(tmp, int_pix_fmt, dst_width, dst_height) < 0)
2581 return -1;
2582 ret = -1;
2583 if (img_convert(tmp, int_pix_fmt,
2584 src, src_pix_fmt, src_width, src_height) < 0)
2585 goto fail1;
2586 if (img_convert(dst, dst_pix_fmt,
2587 tmp, int_pix_fmt, dst_width, dst_height) < 0)
2588 goto fail1;
2589 ret = 0;
2590 fail1:
2591 avpicture_free(tmp);
2592 return ret;
85c242d8 2593}
790c9ca7 2594#endif
85c242d8 2595
0469baf1 2596/* NOTE: we scan all the pixels to have an exact information */
da64ecc3 2597static int get_alpha_info_pal8(const AVPicture *src, int width, int height)
0469baf1
FB
2598{
2599 const unsigned char *p;
2600 int src_wrap, ret, x, y;
2601 unsigned int a;
2602 uint32_t *palette = (uint32_t *)src->data[1];
115329f1 2603
0469baf1
FB
2604 p = src->data[0];
2605 src_wrap = src->linesize[0] - width;
2606 ret = 0;
2607 for(y=0;y<height;y++) {
2608 for(x=0;x<width;x++) {
2609 a = palette[p[0]] >> 24;
2610 if (a == 0x00) {
2611 ret |= FF_ALPHA_TRANSP;
2612 } else if (a != 0xff) {
2613 ret |= FF_ALPHA_SEMI_TRANSP;
2614 }
2615 p++;
2616 }
2617 p += src_wrap;
2618 }
2619 return ret;
2620}
2621
da64ecc3 2622int img_get_alpha_info(const AVPicture *src,
bb270c08 2623 int pix_fmt, int width, int height)
0469baf1 2624{
62a05b5b 2625 const PixFmtInfo *pf = &pix_fmt_info[pix_fmt];
0469baf1
FB
2626 int ret;
2627
2628 pf = &pix_fmt_info[pix_fmt];
2629 /* no alpha can be represented in format */
2630 if (!pf->is_alpha)
2631 return 0;
2632 switch(pix_fmt) {
71e445fc 2633 case PIX_FMT_RGB32:
3cf5b6be 2634 ret = get_alpha_info_rgb32(src, width, height);
0469baf1 2635 break;
0469baf1
FB
2636 case PIX_FMT_PAL8:
2637 ret = get_alpha_info_pal8(src, width, height);
2638 break;
2639 default:
2640 /* we do not know, so everything is indicated */
2641 ret = FF_ALPHA_TRANSP | FF_ALPHA_SEMI_TRANSP;
2642 break;
2643 }
2644 return ret;
2645}
5981f4e6
F
2646
2647#ifdef HAVE_MMX
2648#define DEINT_INPLACE_LINE_LUM \
2649 movd_m2r(lum_m4[0],mm0);\
2650 movd_m2r(lum_m3[0],mm1);\
2651 movd_m2r(lum_m2[0],mm2);\
2652 movd_m2r(lum_m1[0],mm3);\
2653 movd_m2r(lum[0],mm4);\
2654 punpcklbw_r2r(mm7,mm0);\
2655 movd_r2m(mm2,lum_m4[0]);\
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,lum_m2[0]);
2670
2671#define DEINT_LINE_LUM \
2672 movd_m2r(lum_m4[0],mm0);\
2673 movd_m2r(lum_m3[0],mm1);\
2674 movd_m2r(lum_m2[0],mm2);\
2675 movd_m2r(lum_m1[0],mm3);\
2676 movd_m2r(lum[0],mm4);\
2677 punpcklbw_r2r(mm7,mm0);\
2678 punpcklbw_r2r(mm7,mm1);\
2679 punpcklbw_r2r(mm7,mm2);\
2680 punpcklbw_r2r(mm7,mm3);\
2681 punpcklbw_r2r(mm7,mm4);\
2682 paddw_r2r(mm3,mm1);\
2683 psllw_i2r(1,mm2);\
2684 paddw_r2r(mm4,mm0);\
2685 psllw_i2r(2,mm1);\
2686 paddw_r2r(mm6,mm2);\
2687 paddw_r2r(mm2,mm1);\
2688 psubusw_r2r(mm0,mm1);\
2689 psrlw_i2r(3,mm1);\
2690 packuswb_r2r(mm7,mm1);\
2691 movd_r2m(mm1,dst[0]);
2692#endif
2693
85c242d8 2694/* filter parameters: [-1 4 2 4 -1] // 8 */
115329f1 2695static void deinterlace_line(uint8_t *dst,
bb270c08
DB
2696 const uint8_t *lum_m4, const uint8_t *lum_m3,
2697 const uint8_t *lum_m2, const uint8_t *lum_m1,
2698 const uint8_t *lum,
2699 int size)
85c242d8 2700{
5981f4e6 2701#ifndef HAVE_MMX
55fde95e 2702 uint8_t *cm = ff_cropTbl + MAX_NEG_CROP;
85c242d8 2703 int sum;
85c242d8
FB
2704
2705 for(;size > 0;size--) {
5981f4e6
F
2706 sum = -lum_m4[0];
2707 sum += lum_m3[0] << 2;
2708 sum += lum_m2[0] << 1;
2709 sum += lum_m1[0] << 2;
2710 sum += -lum[0];
85c242d8 2711 dst[0] = cm[(sum + 4) >> 3];
5981f4e6
F
2712 lum_m4++;
2713 lum_m3++;
2714 lum_m2++;
2715 lum_m1++;
2716 lum++;
85c242d8 2717 dst++;
85c242d8 2718 }
5981f4e6
F
2719#else
2720
782c5984
MN
2721 {
2722 mmx_t rounder;
2723 rounder.uw[0]=4;
2724 rounder.uw[1]=4;
2725 rounder.uw[2]=4;
2726 rounder.uw[3]=4;
2727 pxor_r2r(mm7,mm7);
2728 movq_m2r(rounder,mm6);
2729 }
5981f4e6
F
2730 for (;size > 3; size-=4) {
2731 DEINT_LINE_LUM
2732 lum_m4+=4;
2733 lum_m3+=4;
2734 lum_m2+=4;
2735 lum_m1+=4;
2736 lum+=4;
2737 dst+=4;
2738 }
2739#endif
2740}
0c1a9eda 2741static 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
2742 int size)
2743{
2744#ifndef HAVE_MMX
55fde95e 2745 uint8_t *cm = ff_cropTbl + MAX_NEG_CROP;
5981f4e6
F
2746 int sum;
2747
2748 for(;size > 0;size--) {
2749 sum = -lum_m4[0];
2750 sum += lum_m3[0] << 2;
2751 sum += lum_m2[0] << 1;
2752 lum_m4[0]=lum_m2[0];
2753 sum += lum_m1[0] << 2;
2754 sum += -lum[0];
2755 lum_m2[0] = cm[(sum + 4) >> 3];
2756 lum_m4++;
2757 lum_m3++;
2758 lum_m2++;
2759 lum_m1++;
2760 lum++;
2761 }
2762#else
2763
782c5984
MN
2764 {
2765 mmx_t rounder;
2766 rounder.uw[0]=4;
2767 rounder.uw[1]=4;
2768 rounder.uw[2]=4;
2769 rounder.uw[3]=4;
2770 pxor_r2r(mm7,mm7);
2771 movq_m2r(rounder,mm6);
2772 }
5981f4e6
F
2773 for (;size > 3; size-=4) {
2774 DEINT_INPLACE_LINE_LUM
2775 lum_m4+=4;
2776 lum_m3+=4;
2777 lum_m2+=4;
2778 lum_m1+=4;
2779 lum+=4;
2780 }
2781#endif
85c242d8
FB
2782}
2783
2784/* deinterlacing : 2 temporal taps, 3 spatial taps linear filter. The
2785 top field is copied as is, but the bottom field is deinterlaced
2786 against the top field. */
0c1a9eda 2787static void deinterlace_bottom_field(uint8_t *dst, int dst_wrap,
da64ecc3 2788 const uint8_t *src1, int src_wrap,
5981f4e6 2789 int width, int height)
85c242d8 2790{
da64ecc3 2791 const uint8_t *src_m2, *src_m1, *src_0, *src_p1, *src_p2;
5981f4e6
F
2792 int y;
2793
2794 src_m2 = src1;
2795 src_m1 = src1;
2796 src_0=&src_m1[src_wrap];
2797 src_p1=&src_0[src_wrap];
2798 src_p2=&src_p1[src_wrap];
2799 for(y=0;y<(height-2);y+=2) {
2800 memcpy(dst,src_m1,width);
85c242d8 2801 dst += dst_wrap;
5981f4e6
F
2802 deinterlace_line(dst,src_m2,src_m1,src_0,src_p1,src_p2,width);
2803 src_m2 = src_0;
2804 src_m1 = src_p1;
2805 src_0 = src_p2;
2806 src_p1 += 2*src_wrap;
2807 src_p2 += 2*src_wrap;
85c242d8 2808 dst += dst_wrap;
85c242d8 2809 }
5981f4e6
F
2810 memcpy(dst,src_m1,width);
2811 dst += dst_wrap;
2812 /* do last line */
2813 deinterlace_line(dst,src_m2,src_m1,src_0,src_0,src_0,width);
2814}
2815
0c1a9eda 2816static void deinterlace_bottom_field_inplace(uint8_t *src1, int src_wrap,
bb270c08 2817 int width, int height)
5981f4e6 2818{
0c1a9eda 2819 uint8_t *src_m1, *src_0, *src_p1, *src_p2;
5981f4e6 2820 int y;
0c1a9eda
ZK
2821 uint8_t *buf;
2822 buf = (uint8_t*)av_malloc(width);
5981f4e6
F
2823
2824 src_m1 = src1;
2825 memcpy(buf,src_m1,width);
2826 src_0=&src_m1[src_wrap];
2827 src_p1=&src_0[src_wrap];
2828 src_p2=&src_p1[src_wrap];
2829 for(y=0;y<(height-2);y+=2) {
2830 deinterlace_line_inplace(buf,src_m1,src_0,src_p1,src_p2,width);
2831 src_m1 = src_p1;
2832 src_0 = src_p2;
2833 src_p1 += 2*src_wrap;
2834 src_p2 += 2*src_wrap;
2835 }
2836 /* do last line */
2837 deinterlace_line_inplace(buf,src_m1,src_0,src_0,src_0,width);
6000abfa 2838 av_free(buf);
85c242d8
FB
2839}
2840
da64ecc3 2841int avpicture_deinterlace(AVPicture *dst, const AVPicture *src,
de6d9b64
FB
2842 int pix_fmt, int width, int height)
2843{
85c242d8
FB
2844 int i;
2845
2846 if (pix_fmt != PIX_FMT_YUV420P &&
2847 pix_fmt != PIX_FMT_YUV422P &&
47017dd8 2848 pix_fmt != PIX_FMT_YUV444P &&
2a7feb18
AG
2849 pix_fmt != PIX_FMT_YUV411P &&
2850 pix_fmt != PIX_FMT_GRAY8)
85c242d8 2851 return -1;
5981f4e6 2852 if ((width & 3) != 0 || (height & 3) != 0)
85c242d8 2853 return -1;
5981f4e6 2854
85c242d8
FB
2855 for(i=0;i<3;i++) {
2856 if (i == 1) {
2857 switch(pix_fmt) {
2858 case PIX_FMT_YUV420P:
2859 width >>= 1;
2860 height >>= 1;
2861 break;
2862 case PIX_FMT_YUV422P:
2863 width >>= 1;
2864 break;
47017dd8
RS
2865 case PIX_FMT_YUV411P:
2866 width >>= 2;
2867 break;
85c242d8
FB
2868 default:
2869 break;
2870 }
2a7feb18
AG
2871 if (pix_fmt == PIX_FMT_GRAY8) {
2872 break;
2873 }
85c242d8 2874 }
5981f4e6 2875 if (src == dst) {
da64ecc3 2876 deinterlace_bottom_field_inplace(dst->data[i], dst->linesize[i],
85c242d8 2877 width, height);
5981f4e6
F
2878 } else {
2879 deinterlace_bottom_field(dst->data[i],dst->linesize[i],
2880 src->data[i], src->linesize[i],
2881 width, height);
2882 }
de6d9b64 2883 }
55ffe9df 2884 emms_c();
85c242d8 2885 return 0;
de6d9b64 2886}
cd4af68a 2887