Statistics
| Branch: | Revision:

ffmpeg / libavcodec / imgconvert.c @ 5509bffa

History | View | Annotate | Download (66.1 KB)

1 de6d9b64 Fabrice Bellard
/*
2
 * Misc image convertion routines
3 524c6b63 Fabrice Bellard
 * Copyright (c) 2001, 2002, 2003 Fabrice Bellard.
4 de6d9b64 Fabrice Bellard
 *
5 ff4ec49e Fabrice Bellard
 * This library is free software; you can redistribute it and/or
6
 * modify it under the terms of the GNU Lesser General Public
7
 * License as published by the Free Software Foundation; either
8
 * version 2 of the License, or (at your option) any later version.
9 de6d9b64 Fabrice Bellard
 *
10 ff4ec49e Fabrice Bellard
 * This library is distributed in the hope that it will be useful,
11 de6d9b64 Fabrice Bellard
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 ff4ec49e Fabrice Bellard
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13
 * Lesser General Public License for more details.
14 de6d9b64 Fabrice Bellard
 *
15 ff4ec49e Fabrice Bellard
 * You should have received a copy of the GNU Lesser General Public
16
 * License along with this library; if not, write to the Free Software
17 5509bffa Diego Biurrun
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18 de6d9b64 Fabrice Bellard
 */
19 983e3246 Michael Niedermayer
20
/**
21 1ab3d669 Michael Niedermayer
 * @file imgconvert.c
22 983e3246 Michael Niedermayer
 * Misc image convertion routines.
23
 */
24
25 c50c0bc8 Fabrice Bellard
/* TODO:
26
 * - write 'ffimg' program to test all the image related stuff
27
 * - move all api to slice based system
28
 * - integrate deinterlacing, postprocessing and scaling in the conversion process
29
 */
30 983e3246 Michael Niedermayer
31 de6d9b64 Fabrice Bellard
#include "avcodec.h"
32 85c242d8 Fabrice Bellard
#include "dsputil.h"
33 de6d9b64 Fabrice Bellard
34 54329dd5 Nick Kurshev
#ifdef USE_FASTMEMCPY
35
#include "fastmemcpy.h"
36
#endif
37 5981f4e6 Fred
38
#ifdef HAVE_MMX
39
#include "i386/mmx.h"
40
#endif
41 524c6b63 Fabrice Bellard
42 7e7e5940 Fabrice Bellard
#define xglue(x, y) x ## y
43
#define glue(x, y) xglue(x, y)
44
45 b6147995 Fabrice Bellard
#define FF_COLOR_RGB      0 /* RGB color space */
46
#define FF_COLOR_GRAY     1 /* gray color space */
47
#define FF_COLOR_YUV      2 /* YUV color space. 16 <= Y <= 235, 16 <= U, V <= 240 */
48
#define FF_COLOR_YUV_JPEG 3 /* YUV color space. 0 <= Y <= 255, 0 <= U, V <= 255 */
49
50 7e7e5940 Fabrice Bellard
#define FF_PIXEL_PLANAR   0 /* each channel has one component in AVPicture */
51
#define FF_PIXEL_PACKED   1 /* only one components containing all the channels */
52
#define FF_PIXEL_PALETTE  2  /* one components containing indexes for a palette */
53
54 524c6b63 Fabrice Bellard
typedef struct PixFmtInfo {
55
    const char *name;
56 7e7e5940 Fabrice Bellard
    uint8_t nb_channels;     /* number of channels (including alpha) */
57
    uint8_t color_type;      /* color type (see FF_COLOR_xxx constants) */
58
    uint8_t pixel_type;      /* pixel storage type (see FF_PIXEL_xxx constants) */
59 0c1a9eda Zdenek Kabelac
    uint8_t is_alpha : 1;    /* true if alpha can be specified */
60 7e7e5940 Fabrice Bellard
    uint8_t x_chroma_shift;  /* X chroma subsampling factor is 2 ^ shift */
61
    uint8_t y_chroma_shift;  /* Y chroma subsampling factor is 2 ^ shift */
62
    uint8_t depth;           /* bit depth of the color components */
63 524c6b63 Fabrice Bellard
} PixFmtInfo;
64
65
/* this table gives more information about formats */
66
static PixFmtInfo pix_fmt_info[PIX_FMT_NB] = {
67
    /* YUV formats */
68
    [PIX_FMT_YUV420P] = {
69 ef9f7306 Måns Rullgård
        .name = "yuv420p",
70 7e7e5940 Fabrice Bellard
        .nb_channels = 3,
71 b6147995 Fabrice Bellard
        .color_type = FF_COLOR_YUV,
72 7e7e5940 Fabrice Bellard
        .pixel_type = FF_PIXEL_PLANAR,
73 b6147995 Fabrice Bellard
        .depth = 8,
74 115329f1 Diego Biurrun
        .x_chroma_shift = 1, .y_chroma_shift = 1,
75 524c6b63 Fabrice Bellard
    },
76
    [PIX_FMT_YUV422P] = {
77 ef9f7306 Måns Rullgård
        .name = "yuv422p",
78 7e7e5940 Fabrice Bellard
        .nb_channels = 3,
79 b6147995 Fabrice Bellard
        .color_type = FF_COLOR_YUV,
80 7e7e5940 Fabrice Bellard
        .pixel_type = FF_PIXEL_PLANAR,
81 b6147995 Fabrice Bellard
        .depth = 8,
82 115329f1 Diego Biurrun
        .x_chroma_shift = 1, .y_chroma_shift = 0,
83 524c6b63 Fabrice Bellard
    },
84
    [PIX_FMT_YUV444P] = {
85 ef9f7306 Måns Rullgård
        .name = "yuv444p",
86 7e7e5940 Fabrice Bellard
        .nb_channels = 3,
87 b6147995 Fabrice Bellard
        .color_type = FF_COLOR_YUV,
88 7e7e5940 Fabrice Bellard
        .pixel_type = FF_PIXEL_PLANAR,
89 b6147995 Fabrice Bellard
        .depth = 8,
90 115329f1 Diego Biurrun
        .x_chroma_shift = 0, .y_chroma_shift = 0,
91 524c6b63 Fabrice Bellard
    },
92
    [PIX_FMT_YUV422] = {
93 ef9f7306 Måns Rullgård
        .name = "yuv422",
94 7e7e5940 Fabrice Bellard
        .nb_channels = 1,
95 b6147995 Fabrice Bellard
        .color_type = FF_COLOR_YUV,
96 7e7e5940 Fabrice Bellard
        .pixel_type = FF_PIXEL_PACKED,
97 b6147995 Fabrice Bellard
        .depth = 8,
98 ef9f7306 Måns Rullgård
        .x_chroma_shift = 1, .y_chroma_shift = 0,
99 524c6b63 Fabrice Bellard
    },
100 ebb177dd Todd Kirby
    [PIX_FMT_UYVY422] = {
101
        .name = "uyvy422",
102
        .nb_channels = 1,
103
        .color_type = FF_COLOR_YUV,
104
        .pixel_type = FF_PIXEL_PACKED,
105
        .depth = 8,
106
        .x_chroma_shift = 1, .y_chroma_shift = 0,
107
    },
108 524c6b63 Fabrice Bellard
    [PIX_FMT_YUV410P] = {
109 ef9f7306 Måns Rullgård
        .name = "yuv410p",
110 7e7e5940 Fabrice Bellard
        .nb_channels = 3,
111 b6147995 Fabrice Bellard
        .color_type = FF_COLOR_YUV,
112 7e7e5940 Fabrice Bellard
        .pixel_type = FF_PIXEL_PLANAR,
113 b6147995 Fabrice Bellard
        .depth = 8,
114 ef9f7306 Måns Rullgård
        .x_chroma_shift = 2, .y_chroma_shift = 2,
115 524c6b63 Fabrice Bellard
    },
116
    [PIX_FMT_YUV411P] = {
117 ef9f7306 Måns Rullgård
        .name = "yuv411p",
118 7e7e5940 Fabrice Bellard
        .nb_channels = 3,
119 b6147995 Fabrice Bellard
        .color_type = FF_COLOR_YUV,
120 7e7e5940 Fabrice Bellard
        .pixel_type = FF_PIXEL_PLANAR,
121 b6147995 Fabrice Bellard
        .depth = 8,
122 ef9f7306 Måns Rullgård
        .x_chroma_shift = 2, .y_chroma_shift = 0,
123 524c6b63 Fabrice Bellard
    },
124
125 b6147995 Fabrice Bellard
    /* JPEG YUV */
126
    [PIX_FMT_YUVJ420P] = {
127
        .name = "yuvj420p",
128 7e7e5940 Fabrice Bellard
        .nb_channels = 3,
129 b6147995 Fabrice Bellard
        .color_type = FF_COLOR_YUV_JPEG,
130 7e7e5940 Fabrice Bellard
        .pixel_type = FF_PIXEL_PLANAR,
131 b6147995 Fabrice Bellard
        .depth = 8,
132 115329f1 Diego Biurrun
        .x_chroma_shift = 1, .y_chroma_shift = 1,
133 b6147995 Fabrice Bellard
    },
134
    [PIX_FMT_YUVJ422P] = {
135
        .name = "yuvj422p",
136 7e7e5940 Fabrice Bellard
        .nb_channels = 3,
137 b6147995 Fabrice Bellard
        .color_type = FF_COLOR_YUV_JPEG,
138 7e7e5940 Fabrice Bellard
        .pixel_type = FF_PIXEL_PLANAR,
139 b6147995 Fabrice Bellard
        .depth = 8,
140 115329f1 Diego Biurrun
        .x_chroma_shift = 1, .y_chroma_shift = 0,
141 b6147995 Fabrice Bellard
    },
142
    [PIX_FMT_YUVJ444P] = {
143
        .name = "yuvj444p",
144 7e7e5940 Fabrice Bellard
        .nb_channels = 3,
145 b6147995 Fabrice Bellard
        .color_type = FF_COLOR_YUV_JPEG,
146 7e7e5940 Fabrice Bellard
        .pixel_type = FF_PIXEL_PLANAR,
147 b6147995 Fabrice Bellard
        .depth = 8,
148 115329f1 Diego Biurrun
        .x_chroma_shift = 0, .y_chroma_shift = 0,
149 b6147995 Fabrice Bellard
    },
150
151 524c6b63 Fabrice Bellard
    /* RGB formats */
152
    [PIX_FMT_RGB24] = {
153 ef9f7306 Måns Rullgård
        .name = "rgb24",
154 7e7e5940 Fabrice Bellard
        .nb_channels = 3,
155 b6147995 Fabrice Bellard
        .color_type = FF_COLOR_RGB,
156 7e7e5940 Fabrice Bellard
        .pixel_type = FF_PIXEL_PACKED,
157 b6147995 Fabrice Bellard
        .depth = 8,
158 2cbb7820 Michael Niedermayer
        .x_chroma_shift = 0, .y_chroma_shift = 0,
159 524c6b63 Fabrice Bellard
    },
160
    [PIX_FMT_BGR24] = {
161 ef9f7306 Måns Rullgård
        .name = "bgr24",
162 7e7e5940 Fabrice Bellard
        .nb_channels = 3,
163 b6147995 Fabrice Bellard
        .color_type = FF_COLOR_RGB,
164 7e7e5940 Fabrice Bellard
        .pixel_type = FF_PIXEL_PACKED,
165 b6147995 Fabrice Bellard
        .depth = 8,
166 2cbb7820 Michael Niedermayer
        .x_chroma_shift = 0, .y_chroma_shift = 0,
167 524c6b63 Fabrice Bellard
    },
168
    [PIX_FMT_RGBA32] = {
169 ef9f7306 Måns Rullgård
        .name = "rgba32",
170 7e7e5940 Fabrice Bellard
        .nb_channels = 4, .is_alpha = 1,
171 b6147995 Fabrice Bellard
        .color_type = FF_COLOR_RGB,
172 7e7e5940 Fabrice Bellard
        .pixel_type = FF_PIXEL_PACKED,
173 b6147995 Fabrice Bellard
        .depth = 8,
174 2cbb7820 Michael Niedermayer
        .x_chroma_shift = 0, .y_chroma_shift = 0,
175 524c6b63 Fabrice Bellard
    },
176
    [PIX_FMT_RGB565] = {
177 ef9f7306 Måns Rullgård
        .name = "rgb565",
178 7e7e5940 Fabrice Bellard
        .nb_channels = 3,
179 b6147995 Fabrice Bellard
        .color_type = FF_COLOR_RGB,
180 7e7e5940 Fabrice Bellard
        .pixel_type = FF_PIXEL_PACKED,
181 b6147995 Fabrice Bellard
        .depth = 5,
182 2cbb7820 Michael Niedermayer
        .x_chroma_shift = 0, .y_chroma_shift = 0,
183 524c6b63 Fabrice Bellard
    },
184
    [PIX_FMT_RGB555] = {
185 ef9f7306 Måns Rullgård
        .name = "rgb555",
186 7e7e5940 Fabrice Bellard
        .nb_channels = 4, .is_alpha = 1,
187 b6147995 Fabrice Bellard
        .color_type = FF_COLOR_RGB,
188 7e7e5940 Fabrice Bellard
        .pixel_type = FF_PIXEL_PACKED,
189 b6147995 Fabrice Bellard
        .depth = 5,
190 2cbb7820 Michael Niedermayer
        .x_chroma_shift = 0, .y_chroma_shift = 0,
191 524c6b63 Fabrice Bellard
    },
192
193
    /* gray / mono formats */
194
    [PIX_FMT_GRAY8] = {
195 ef9f7306 Måns Rullgård
        .name = "gray",
196 7e7e5940 Fabrice Bellard
        .nb_channels = 1,
197 b6147995 Fabrice Bellard
        .color_type = FF_COLOR_GRAY,
198 7e7e5940 Fabrice Bellard
        .pixel_type = FF_PIXEL_PLANAR,
199 b6147995 Fabrice Bellard
        .depth = 8,
200 524c6b63 Fabrice Bellard
    },
201
    [PIX_FMT_MONOWHITE] = {
202 ef9f7306 Måns Rullgård
        .name = "monow",
203 7e7e5940 Fabrice Bellard
        .nb_channels = 1,
204 b6147995 Fabrice Bellard
        .color_type = FF_COLOR_GRAY,
205 7e7e5940 Fabrice Bellard
        .pixel_type = FF_PIXEL_PLANAR,
206 b6147995 Fabrice Bellard
        .depth = 1,
207 524c6b63 Fabrice Bellard
    },
208
    [PIX_FMT_MONOBLACK] = {
209 ef9f7306 Måns Rullgård
        .name = "monob",
210 7e7e5940 Fabrice Bellard
        .nb_channels = 1,
211 b6147995 Fabrice Bellard
        .color_type = FF_COLOR_GRAY,
212 7e7e5940 Fabrice Bellard
        .pixel_type = FF_PIXEL_PLANAR,
213 b6147995 Fabrice Bellard
        .depth = 1,
214 524c6b63 Fabrice Bellard
    },
215 7e6d70d0 Fabrice Bellard
216
    /* paletted formats */
217
    [PIX_FMT_PAL8] = {
218
        .name = "pal8",
219 7e7e5940 Fabrice Bellard
        .nb_channels = 4, .is_alpha = 1,
220 b6147995 Fabrice Bellard
        .color_type = FF_COLOR_RGB,
221 7e7e5940 Fabrice Bellard
        .pixel_type = FF_PIXEL_PALETTE,
222 b6147995 Fabrice Bellard
        .depth = 8,
223 7e6d70d0 Fabrice Bellard
    },
224 eab895aa Todd Kirby
    [PIX_FMT_XVMC_MPEG2_MC] = {
225
        .name = "xvmcmc",
226
    },
227
    [PIX_FMT_XVMC_MPEG2_IDCT] = {
228
        .name = "xvmcidct",
229
    },
230 f02be79d Roman Shaposhnik
    [PIX_FMT_UYVY411] = {
231
        .name = "uyvy411",
232
        .nb_channels = 1,
233
        .color_type = FF_COLOR_YUV,
234
        .pixel_type = FF_PIXEL_PACKED,
235
        .depth = 8,
236
        .x_chroma_shift = 2, .y_chroma_shift = 0,
237
    },
238 524c6b63 Fabrice Bellard
};
239
240
void avcodec_get_chroma_sub_sample(int pix_fmt, int *h_shift, int *v_shift)
241
{
242 b6147995 Fabrice Bellard
    *h_shift = pix_fmt_info[pix_fmt].x_chroma_shift;
243
    *v_shift = pix_fmt_info[pix_fmt].y_chroma_shift;
244 524c6b63 Fabrice Bellard
}
245
246
const char *avcodec_get_pix_fmt_name(int pix_fmt)
247
{
248
    if (pix_fmt < 0 || pix_fmt >= PIX_FMT_NB)
249
        return "???";
250
    else
251
        return pix_fmt_info[pix_fmt].name;
252
}
253
254 63167088 Roman Shaposhnik
enum PixelFormat avcodec_get_pix_fmt(const char* name)
255
{
256 115329f1 Diego Biurrun
    int i;
257
258 63167088 Roman Shaposhnik
    for (i=0; i < PIX_FMT_NB; i++)
259
         if (!strcmp(pix_fmt_info[i].name, name))
260 bb270c08 Diego Biurrun
             break;
261 63167088 Roman Shaposhnik
    return i;
262
}
263
264 2a877875 Fabrice Bellard
/* Picture field are filled with 'ptr' addresses. Also return size */
265 0c1a9eda Zdenek Kabelac
int avpicture_fill(AVPicture *picture, uint8_t *ptr,
266 bb270c08 Diego Biurrun
                   int pix_fmt, int width, int height)
267 2a877875 Fabrice Bellard
{
268 4c7e8619 Fabrice Bellard
    int size, w2, h2, size2;
269
    PixFmtInfo *pinfo;
270 115329f1 Diego Biurrun
271 0ecca7a4 Michael Niedermayer
    if(avcodec_check_dimensions(NULL, width, height))
272
        goto fail;
273
274 4c7e8619 Fabrice Bellard
    pinfo = &pix_fmt_info[pix_fmt];
275 2a877875 Fabrice Bellard
    size = width * height;
276
    switch(pix_fmt) {
277
    case PIX_FMT_YUV420P:
278 4c7e8619 Fabrice Bellard
    case PIX_FMT_YUV422P:
279
    case PIX_FMT_YUV444P:
280
    case PIX_FMT_YUV410P:
281
    case PIX_FMT_YUV411P:
282 c50c0bc8 Fabrice Bellard
    case PIX_FMT_YUVJ420P:
283
    case PIX_FMT_YUVJ422P:
284
    case PIX_FMT_YUVJ444P:
285 4c7e8619 Fabrice Bellard
        w2 = (width + (1 << pinfo->x_chroma_shift) - 1) >> pinfo->x_chroma_shift;
286
        h2 = (height + (1 << pinfo->y_chroma_shift) - 1) >> pinfo->y_chroma_shift;
287
        size2 = w2 * h2;
288 2a877875 Fabrice Bellard
        picture->data[0] = ptr;
289
        picture->data[1] = picture->data[0] + size;
290 4c7e8619 Fabrice Bellard
        picture->data[2] = picture->data[1] + size2;
291 2a877875 Fabrice Bellard
        picture->linesize[0] = width;
292 4c7e8619 Fabrice Bellard
        picture->linesize[1] = w2;
293
        picture->linesize[2] = w2;
294
        return size + 2 * size2;
295 2a877875 Fabrice Bellard
    case PIX_FMT_RGB24:
296
    case PIX_FMT_BGR24:
297
        picture->data[0] = ptr;
298
        picture->data[1] = NULL;
299
        picture->data[2] = NULL;
300
        picture->linesize[0] = width * 3;
301
        return size * 3;
302
    case PIX_FMT_RGBA32:
303
        picture->data[0] = ptr;
304
        picture->data[1] = NULL;
305
        picture->data[2] = NULL;
306
        picture->linesize[0] = width * 4;
307
        return size * 4;
308
    case PIX_FMT_RGB555:
309
    case PIX_FMT_RGB565:
310
    case PIX_FMT_YUV422:
311
        picture->data[0] = ptr;
312
        picture->data[1] = NULL;
313
        picture->data[2] = NULL;
314
        picture->linesize[0] = width * 2;
315
        return size * 2;
316 ebb177dd Todd Kirby
    case PIX_FMT_UYVY422:
317
        picture->data[0] = ptr;
318
        picture->data[1] = NULL;
319
        picture->data[2] = NULL;
320
        picture->linesize[0] = width * 2;
321
        return size * 2;
322 f02be79d Roman Shaposhnik
    case PIX_FMT_UYVY411:
323
        picture->data[0] = ptr;
324
        picture->data[1] = NULL;
325
        picture->data[2] = NULL;
326
        picture->linesize[0] = width + width/2;
327
        return size + size/2;
328 2a877875 Fabrice Bellard
    case PIX_FMT_GRAY8:
329
        picture->data[0] = ptr;
330
        picture->data[1] = NULL;
331
        picture->data[2] = NULL;
332
        picture->linesize[0] = width;
333
        return size;
334
    case PIX_FMT_MONOWHITE:
335
    case PIX_FMT_MONOBLACK:
336
        picture->data[0] = ptr;
337
        picture->data[1] = NULL;
338
        picture->data[2] = NULL;
339
        picture->linesize[0] = (width + 7) >> 3;
340
        return picture->linesize[0] * height;
341 7e6d70d0 Fabrice Bellard
    case PIX_FMT_PAL8:
342
        size2 = (size + 3) & ~3;
343
        picture->data[0] = ptr;
344
        picture->data[1] = ptr + size2; /* palette is stored here as 256 32 bit words */
345
        picture->data[2] = NULL;
346
        picture->linesize[0] = width;
347
        picture->linesize[1] = 4;
348
        return size2 + 256 * 4;
349 2a877875 Fabrice Bellard
    default:
350 0ecca7a4 Michael Niedermayer
fail:
351 2a877875 Fabrice Bellard
        picture->data[0] = NULL;
352
        picture->data[1] = NULL;
353
        picture->data[2] = NULL;
354 7e6d70d0 Fabrice Bellard
        picture->data[3] = NULL;
355 2a877875 Fabrice Bellard
        return -1;
356
    }
357
}
358
359 da64ecc3 Drew Hess
int avpicture_layout(const AVPicture* src, int pix_fmt, int width, int height,
360 63167088 Roman Shaposhnik
                     unsigned char *dest, int dest_size)
361
{
362
    PixFmtInfo* pf = &pix_fmt_info[pix_fmt];
363
    int i, j, w, h, data_planes;
364 115329f1 Diego Biurrun
    const unsigned char* s;
365 63167088 Roman Shaposhnik
    int size = avpicture_get_size(pix_fmt, width, height);
366
367 0ecca7a4 Michael Niedermayer
    if (size > dest_size || size < 0)
368 63167088 Roman Shaposhnik
        return -1;
369
370 affd55a1 Roman Shaposhnik
    if (pf->pixel_type == FF_PIXEL_PACKED || pf->pixel_type == FF_PIXEL_PALETTE) {
371 115329f1 Diego Biurrun
        if (pix_fmt == PIX_FMT_YUV422 ||
372
            pix_fmt == PIX_FMT_UYVY422 ||
373 ebb177dd Todd Kirby
            pix_fmt == PIX_FMT_RGB565 ||
374
            pix_fmt == PIX_FMT_RGB555)
375
            w = width * 2;
376 bb270c08 Diego Biurrun
        else if (pix_fmt == PIX_FMT_UYVY411)
377
          w = width + width/2;
378
        else if (pix_fmt == PIX_FMT_PAL8)
379
          w = width;
380
        else
381
          w = width * (pf->depth * pf->nb_channels / 8);
382
383
        data_planes = 1;
384
        h = height;
385 63167088 Roman Shaposhnik
    } else {
386
        data_planes = pf->nb_channels;
387 bb270c08 Diego Biurrun
        w = (width*pf->depth + 7)/8;
388
        h = height;
389 63167088 Roman Shaposhnik
    }
390 115329f1 Diego Biurrun
391 63167088 Roman Shaposhnik
    for (i=0; i<data_planes; i++) {
392
         if (i == 1) {
393 bb270c08 Diego Biurrun
             w = width >> pf->x_chroma_shift;
394
             h = height >> pf->y_chroma_shift;
395
         }
396 63167088 Roman Shaposhnik
         s = src->data[i];
397 bb270c08 Diego Biurrun
         for(j=0; j<h; j++) {
398
             memcpy(dest, s, w);
399
             dest += w;
400
             s += src->linesize[i];
401
         }
402 63167088 Roman Shaposhnik
    }
403 115329f1 Diego Biurrun
404 affd55a1 Roman Shaposhnik
    if (pf->pixel_type == FF_PIXEL_PALETTE)
405 bb270c08 Diego Biurrun
        memcpy((unsigned char *)(((size_t)dest + 3) & ~3), src->data[1], 256 * 4);
406 115329f1 Diego Biurrun
407 63167088 Roman Shaposhnik
    return size;
408
}
409
410 2a877875 Fabrice Bellard
int avpicture_get_size(int pix_fmt, int width, int height)
411
{
412
    AVPicture dummy_pict;
413
    return avpicture_fill(&dummy_pict, NULL, pix_fmt, width, height);
414
}
415
416 b6147995 Fabrice Bellard
/**
417 115329f1 Diego Biurrun
 * compute the loss when converting from a pixel format to another
418 b6147995 Fabrice Bellard
 */
419
int avcodec_get_pix_fmt_loss(int dst_pix_fmt, int src_pix_fmt,
420
                             int has_alpha)
421
{
422
    const PixFmtInfo *pf, *ps;
423
    int loss;
424
425
    ps = &pix_fmt_info[src_pix_fmt];
426
    pf = &pix_fmt_info[dst_pix_fmt];
427
428
    /* compute loss */
429
    loss = 0;
430
    pf = &pix_fmt_info[dst_pix_fmt];
431 0a9ad8d1 Fabrice Bellard
    if (pf->depth < ps->depth ||
432
        (dst_pix_fmt == PIX_FMT_RGB555 && src_pix_fmt == PIX_FMT_RGB565))
433 b6147995 Fabrice Bellard
        loss |= FF_LOSS_DEPTH;
434 0a9ad8d1 Fabrice Bellard
    if (pf->x_chroma_shift > ps->x_chroma_shift ||
435
        pf->y_chroma_shift > ps->y_chroma_shift)
436 b6147995 Fabrice Bellard
        loss |= FF_LOSS_RESOLUTION;
437
    switch(pf->color_type) {
438
    case FF_COLOR_RGB:
439
        if (ps->color_type != FF_COLOR_RGB &&
440
            ps->color_type != FF_COLOR_GRAY)
441
            loss |= FF_LOSS_COLORSPACE;
442
        break;
443
    case FF_COLOR_GRAY:
444
        if (ps->color_type != FF_COLOR_GRAY)
445
            loss |= FF_LOSS_COLORSPACE;
446
        break;
447
    case FF_COLOR_YUV:
448
        if (ps->color_type != FF_COLOR_YUV)
449
            loss |= FF_LOSS_COLORSPACE;
450
        break;
451
    case FF_COLOR_YUV_JPEG:
452
        if (ps->color_type != FF_COLOR_YUV_JPEG &&
453 115329f1 Diego Biurrun
            ps->color_type != FF_COLOR_YUV &&
454 0a9ad8d1 Fabrice Bellard
            ps->color_type != FF_COLOR_GRAY)
455 b6147995 Fabrice Bellard
            loss |= FF_LOSS_COLORSPACE;
456
        break;
457
    default:
458
        /* fail safe test */
459
        if (ps->color_type != pf->color_type)
460
            loss |= FF_LOSS_COLORSPACE;
461
        break;
462
    }
463
    if (pf->color_type == FF_COLOR_GRAY &&
464
        ps->color_type != FF_COLOR_GRAY)
465
        loss |= FF_LOSS_CHROMA;
466
    if (!pf->is_alpha && (ps->is_alpha && has_alpha))
467
        loss |= FF_LOSS_ALPHA;
468 115329f1 Diego Biurrun
    if (pf->pixel_type == FF_PIXEL_PALETTE &&
469 7e7e5940 Fabrice Bellard
        (ps->pixel_type != FF_PIXEL_PALETTE && ps->color_type != FF_COLOR_GRAY))
470 b6147995 Fabrice Bellard
        loss |= FF_LOSS_COLORQUANT;
471
    return loss;
472
}
473
474
static int avg_bits_per_pixel(int pix_fmt)
475
{
476
    int bits;
477
    const PixFmtInfo *pf;
478
479
    pf = &pix_fmt_info[pix_fmt];
480 7e7e5940 Fabrice Bellard
    switch(pf->pixel_type) {
481
    case FF_PIXEL_PACKED:
482 b6147995 Fabrice Bellard
        switch(pix_fmt) {
483 7e7e5940 Fabrice Bellard
        case PIX_FMT_YUV422:
484 ebb177dd Todd Kirby
        case PIX_FMT_UYVY422:
485 b6147995 Fabrice Bellard
        case PIX_FMT_RGB565:
486
        case PIX_FMT_RGB555:
487
            bits = 16;
488
            break;
489 bb270c08 Diego Biurrun
        case PIX_FMT_UYVY411:
490
            bits = 12;
491
            break;
492 b6147995 Fabrice Bellard
        default:
493 7e7e5940 Fabrice Bellard
            bits = pf->depth * pf->nb_channels;
494 b6147995 Fabrice Bellard
            break;
495
        }
496 7e7e5940 Fabrice Bellard
        break;
497
    case FF_PIXEL_PLANAR:
498
        if (pf->x_chroma_shift == 0 && pf->y_chroma_shift == 0) {
499
            bits = pf->depth * pf->nb_channels;
500
        } else {
501 115329f1 Diego Biurrun
            bits = pf->depth + ((2 * pf->depth) >>
502 7e7e5940 Fabrice Bellard
                                (pf->x_chroma_shift + pf->y_chroma_shift));
503
        }
504
        break;
505
    case FF_PIXEL_PALETTE:
506
        bits = 8;
507
        break;
508
    default:
509
        bits = -1;
510
        break;
511 b6147995 Fabrice Bellard
    }
512
    return bits;
513
}
514
515 115329f1 Diego Biurrun
static int avcodec_find_best_pix_fmt1(int pix_fmt_mask,
516 b6147995 Fabrice Bellard
                                      int src_pix_fmt,
517
                                      int has_alpha,
518
                                      int loss_mask)
519
{
520
    int dist, i, loss, min_dist, dst_pix_fmt;
521
522
    /* find exact color match with smallest size */
523
    dst_pix_fmt = -1;
524
    min_dist = 0x7fffffff;
525
    for(i = 0;i < PIX_FMT_NB; i++) {
526
        if (pix_fmt_mask & (1 << i)) {
527
            loss = avcodec_get_pix_fmt_loss(i, src_pix_fmt, has_alpha) & loss_mask;
528
            if (loss == 0) {
529
                dist = avg_bits_per_pixel(i);
530
                if (dist < min_dist) {
531
                    min_dist = dist;
532
                    dst_pix_fmt = i;
533
                }
534
            }
535
        }
536
    }
537
    return dst_pix_fmt;
538
}
539
540 115329f1 Diego Biurrun
/**
541
 * find best pixel format to convert to. Return -1 if none found
542 b6147995 Fabrice Bellard
 */
543
int avcodec_find_best_pix_fmt(int pix_fmt_mask, int src_pix_fmt,
544
                              int has_alpha, int *loss_ptr)
545
{
546
    int dst_pix_fmt, loss_mask, i;
547
    static const int loss_mask_order[] = {
548
        ~0, /* no loss first */
549
        ~FF_LOSS_ALPHA,
550
        ~FF_LOSS_RESOLUTION,
551
        ~(FF_LOSS_COLORSPACE | FF_LOSS_RESOLUTION),
552
        ~FF_LOSS_COLORQUANT,
553
        ~FF_LOSS_DEPTH,
554
        0,
555
    };
556
557
    /* try with successive loss */
558
    i = 0;
559
    for(;;) {
560
        loss_mask = loss_mask_order[i++];
561 115329f1 Diego Biurrun
        dst_pix_fmt = avcodec_find_best_pix_fmt1(pix_fmt_mask, src_pix_fmt,
562 b6147995 Fabrice Bellard
                                                 has_alpha, loss_mask);
563
        if (dst_pix_fmt >= 0)
564
            goto found;
565
        if (loss_mask == 0)
566
            break;
567
    }
568
    return -1;
569
 found:
570
    if (loss_ptr)
571
        *loss_ptr = avcodec_get_pix_fmt_loss(dst_pix_fmt, src_pix_fmt, has_alpha);
572
    return dst_pix_fmt;
573
}
574
575 115329f1 Diego Biurrun
static void img_copy_plane(uint8_t *dst, int dst_wrap,
576 e352ff08 Fabrice Bellard
                           const uint8_t *src, int src_wrap,
577
                           int width, int height)
578 7e7e5940 Fabrice Bellard
{
579 115329f1 Diego Biurrun
    if((!dst) || (!src))
580 5b2ad9f5 Michael Niedermayer
        return;
581 7e7e5940 Fabrice Bellard
    for(;height > 0; height--) {
582
        memcpy(dst, src, width);
583
        dst += dst_wrap;
584
        src += src_wrap;
585
    }
586
}
587
588 0469baf1 Fabrice Bellard
/**
589
 * Copy image 'src' to 'dst'.
590
 */
591 da64ecc3 Drew Hess
void img_copy(AVPicture *dst, const AVPicture *src,
592 7e7e5940 Fabrice Bellard
              int pix_fmt, int width, int height)
593
{
594
    int bwidth, bits, i;
595
    PixFmtInfo *pf = &pix_fmt_info[pix_fmt];
596 115329f1 Diego Biurrun
597 7e7e5940 Fabrice Bellard
    pf = &pix_fmt_info[pix_fmt];
598
    switch(pf->pixel_type) {
599
    case FF_PIXEL_PACKED:
600
        switch(pix_fmt) {
601
        case PIX_FMT_YUV422:
602 ebb177dd Todd Kirby
        case PIX_FMT_UYVY422:
603 7e7e5940 Fabrice Bellard
        case PIX_FMT_RGB565:
604
        case PIX_FMT_RGB555:
605
            bits = 16;
606
            break;
607 bb270c08 Diego Biurrun
        case PIX_FMT_UYVY411:
608
            bits = 12;
609
            break;
610 7e7e5940 Fabrice Bellard
        default:
611
            bits = pf->depth * pf->nb_channels;
612
            break;
613
        }
614
        bwidth = (width * bits + 7) >> 3;
615
        img_copy_plane(dst->data[0], dst->linesize[0],
616
                       src->data[0], src->linesize[0],
617
                       bwidth, height);
618
        break;
619
    case FF_PIXEL_PLANAR:
620
        for(i = 0; i < pf->nb_channels; i++) {
621
            int w, h;
622
            w = width;
623
            h = height;
624
            if (i == 1 || i == 2) {
625
                w >>= pf->x_chroma_shift;
626
                h >>= pf->y_chroma_shift;
627
            }
628
            bwidth = (w * pf->depth + 7) >> 3;
629
            img_copy_plane(dst->data[i], dst->linesize[i],
630
                           src->data[i], src->linesize[i],
631
                           bwidth, h);
632
        }
633
        break;
634
    case FF_PIXEL_PALETTE:
635
        img_copy_plane(dst->data[0], dst->linesize[0],
636
                       src->data[0], src->linesize[0],
637
                       width, height);
638
        /* copy the palette */
639
        img_copy_plane(dst->data[1], dst->linesize[1],
640
                       src->data[1], src->linesize[1],
641
                       4, 256);
642
        break;
643
    }
644
}
645 2a877875 Fabrice Bellard
646 de6d9b64 Fabrice Bellard
/* XXX: totally non optimized */
647
648 da64ecc3 Drew Hess
static void yuv422_to_yuv420p(AVPicture *dst, const AVPicture *src,
649 524c6b63 Fabrice Bellard
                              int width, int height)
650 de6d9b64 Fabrice Bellard
{
651 c50c0bc8 Fabrice Bellard
    const uint8_t *p, *p1;
652
    uint8_t *lum, *cr, *cb, *lum1, *cr1, *cb1;
653 d4f5d74a Garrick Meeker
    int w;
654 115329f1 Diego Biurrun
655 c50c0bc8 Fabrice Bellard
    p1 = src->data[0];
656
    lum1 = dst->data[0];
657 0a05e494 Fabrice Bellard
    cb1 = dst->data[1];
658
    cr1 = dst->data[2];
659 c50c0bc8 Fabrice Bellard
660 d4f5d74a Garrick Meeker
    for(;height >= 1; height -= 2) {
661 c50c0bc8 Fabrice Bellard
        p = p1;
662
        lum = lum1;
663
        cb = cb1;
664
        cr = cr1;
665 d4f5d74a Garrick Meeker
        for(w = width; w >= 2; w -= 2) {
666 e78df699 Michael Niedermayer
            lum[0] = p[0];
667
            cb[0] = p[1];
668
            lum[1] = p[2];
669
            cr[0] = p[3];
670 de6d9b64 Fabrice Bellard
            p += 4;
671
            lum += 2;
672
            cb++;
673
            cr++;
674
        }
675 d4f5d74a Garrick Meeker
        if (w) {
676 e78df699 Michael Niedermayer
            lum[0] = p[0];
677 d4f5d74a Garrick Meeker
            cb[0] = p[1];
678
            cr[0] = p[3];
679
            cb++;
680
            cr++;
681 de6d9b64 Fabrice Bellard
        }
682 c50c0bc8 Fabrice Bellard
        p1 += src->linesize[0];
683
        lum1 += dst->linesize[0];
684 d4f5d74a Garrick Meeker
        if (height>1) {
685
            p = p1;
686
            lum = lum1;
687
            for(w = width; w >= 2; w -= 2) {
688
                lum[0] = p[0];
689
                lum[1] = p[2];
690
                p += 4;
691
                lum += 2;
692
            }
693
            if (w) {
694
                lum[0] = p[0];
695
            }
696
            p1 += src->linesize[0];
697
            lum1 += dst->linesize[0];
698
        }
699 c50c0bc8 Fabrice Bellard
        cb1 += dst->linesize[1];
700
        cr1 += dst->linesize[2];
701
    }
702
}
703
704 ebb177dd Todd Kirby
static void uyvy422_to_yuv420p(AVPicture *dst, const AVPicture *src,
705
                              int width, int height)
706
{
707
    const uint8_t *p, *p1;
708
    uint8_t *lum, *cr, *cb, *lum1, *cr1, *cb1;
709
    int w;
710 115329f1 Diego Biurrun
711 ebb177dd Todd Kirby
    p1 = src->data[0];
712 115329f1 Diego Biurrun
713 ebb177dd Todd Kirby
    lum1 = dst->data[0];
714
    cb1 = dst->data[1];
715
    cr1 = dst->data[2];
716
717
    for(;height >= 1; height -= 2) {
718
        p = p1;
719
        lum = lum1;
720
        cb = cb1;
721
        cr = cr1;
722
        for(w = width; w >= 2; w -= 2) {
723
            lum[0] = p[1];
724
            cb[0] = p[0];
725
            lum[1] = p[3];
726
            cr[0] = p[2];
727
            p += 4;
728
            lum += 2;
729
            cb++;
730
            cr++;
731
        }
732
        if (w) {
733
            lum[0] = p[1];
734
            cb[0] = p[0];
735
            cr[0] = p[2];
736
            cb++;
737
            cr++;
738
        }
739
        p1 += src->linesize[0];
740
        lum1 += dst->linesize[0];
741
        if (height>1) {
742
            p = p1;
743
            lum = lum1;
744
            for(w = width; w >= 2; w -= 2) {
745
                lum[0] = p[1];
746
                lum[1] = p[3];
747
                p += 4;
748
                lum += 2;
749
            }
750
            if (w) {
751
                lum[0] = p[1];
752
            }
753
            p1 += src->linesize[0];
754
            lum1 += dst->linesize[0];
755
        }
756
        cb1 += dst->linesize[1];
757
        cr1 += dst->linesize[2];
758
    }
759
}
760
761
762
static void uyvy422_to_yuv422p(AVPicture *dst, const AVPicture *src,
763
                              int width, int height)
764
{
765
    const uint8_t *p, *p1;
766
    uint8_t *lum, *cr, *cb, *lum1, *cr1, *cb1;
767
    int w;
768
769
    p1 = src->data[0];
770
    lum1 = dst->data[0];
771
    cb1 = dst->data[1];
772
    cr1 = dst->data[2];
773
    for(;height > 0; height--) {
774
        p = p1;
775
        lum = lum1;
776
        cb = cb1;
777
        cr = cr1;
778
        for(w = width; w >= 2; w -= 2) {
779
            lum[0] = p[1];
780
            cb[0] = p[0];
781
            lum[1] = p[3];
782
            cr[0] = p[2];
783
            p += 4;
784
            lum += 2;
785
            cb++;
786
            cr++;
787
        }
788
        p1 += src->linesize[0];
789
        lum1 += dst->linesize[0];
790
        cb1 += dst->linesize[1];
791
        cr1 += dst->linesize[2];
792
    }
793
}
794
795
796 da64ecc3 Drew Hess
static void yuv422_to_yuv422p(AVPicture *dst, const AVPicture *src,
797 c50c0bc8 Fabrice Bellard
                              int width, int height)
798
{
799
    const uint8_t *p, *p1;
800
    uint8_t *lum, *cr, *cb, *lum1, *cr1, *cb1;
801
    int w;
802
803
    p1 = src->data[0];
804
    lum1 = dst->data[0];
805 0a05e494 Fabrice Bellard
    cb1 = dst->data[1];
806
    cr1 = dst->data[2];
807
    for(;height > 0; height--) {
808 c50c0bc8 Fabrice Bellard
        p = p1;
809
        lum = lum1;
810
        cb = cb1;
811
        cr = cr1;
812
        for(w = width; w >= 2; w -= 2) {
813
            lum[0] = p[0];
814
            cb[0] = p[1];
815
            lum[1] = p[2];
816
            cr[0] = p[3];
817
            p += 4;
818
            lum += 2;
819
            cb++;
820
            cr++;
821
        }
822
        p1 += src->linesize[0];
823
        lum1 += dst->linesize[0];
824
        cb1 += dst->linesize[1];
825
        cr1 += dst->linesize[2];
826 de6d9b64 Fabrice Bellard
    }
827
}
828
829 da64ecc3 Drew Hess
static void yuv422p_to_yuv422(AVPicture *dst, const AVPicture *src,
830 c50c0bc8 Fabrice Bellard
                              int width, int height)
831
{
832
    uint8_t *p, *p1;
833
    const uint8_t *lum, *cr, *cb, *lum1, *cr1, *cb1;
834
    int w;
835
836
    p1 = dst->data[0];
837
    lum1 = src->data[0];
838 0a05e494 Fabrice Bellard
    cb1 = src->data[1];
839
    cr1 = src->data[2];
840
    for(;height > 0; height--) {
841 c50c0bc8 Fabrice Bellard
        p = p1;
842
        lum = lum1;
843
        cb = cb1;
844
        cr = cr1;
845
        for(w = width; w >= 2; w -= 2) {
846
            p[0] = lum[0];
847
            p[1] = cb[0];
848
            p[2] = lum[1];
849
            p[3] = cr[0];
850
            p += 4;
851
            lum += 2;
852
            cb++;
853
            cr++;
854
        }
855 0a05e494 Fabrice Bellard
        p1 += dst->linesize[0];
856
        lum1 += src->linesize[0];
857
        cb1 += src->linesize[1];
858
        cr1 += src->linesize[2];
859 c50c0bc8 Fabrice Bellard
    }
860
}
861
862 ebb177dd Todd Kirby
static void yuv422p_to_uyvy422(AVPicture *dst, const AVPicture *src,
863
                              int width, int height)
864
{
865
    uint8_t *p, *p1;
866
    const uint8_t *lum, *cr, *cb, *lum1, *cr1, *cb1;
867
    int w;
868
869
    p1 = dst->data[0];
870
    lum1 = src->data[0];
871
    cb1 = src->data[1];
872
    cr1 = src->data[2];
873
    for(;height > 0; height--) {
874
        p = p1;
875
        lum = lum1;
876
        cb = cb1;
877
        cr = cr1;
878
        for(w = width; w >= 2; w -= 2) {
879
            p[1] = lum[0];
880
            p[0] = cb[0];
881
            p[3] = lum[1];
882
            p[2] = cr[0];
883
            p += 4;
884
            lum += 2;
885
            cb++;
886
            cr++;
887
        }
888
        p1 += dst->linesize[0];
889
        lum1 += src->linesize[0];
890
        cb1 += src->linesize[1];
891
        cr1 += src->linesize[2];
892
    }
893
}
894
895 f02be79d Roman Shaposhnik
static void uyvy411_to_yuv411p(AVPicture *dst, const AVPicture *src,
896
                              int width, int height)
897
{
898
    const uint8_t *p, *p1;
899
    uint8_t *lum, *cr, *cb, *lum1, *cr1, *cb1;
900
    int w;
901
902
    p1 = src->data[0];
903
    lum1 = dst->data[0];
904
    cb1 = dst->data[1];
905
    cr1 = dst->data[2];
906
    for(;height > 0; height--) {
907
        p = p1;
908
        lum = lum1;
909
        cb = cb1;
910
        cr = cr1;
911
        for(w = width; w >= 4; w -= 4) {
912
            cb[0] = p[0];
913 bb270c08 Diego Biurrun
            lum[0] = p[1];
914 f02be79d Roman Shaposhnik
            lum[1] = p[2];
915
            cr[0] = p[3];
916 bb270c08 Diego Biurrun
            lum[2] = p[4];
917
            lum[3] = p[5];
918 f02be79d Roman Shaposhnik
            p += 6;
919
            lum += 4;
920
            cb++;
921
            cr++;
922
        }
923
        p1 += src->linesize[0];
924
        lum1 += dst->linesize[0];
925
        cb1 += dst->linesize[1];
926
        cr1 += dst->linesize[2];
927
    }
928
}
929 ebb177dd Todd Kirby
930
931 d7e2f57f Michael Niedermayer
static void yuv420p_to_yuv422(AVPicture *dst, const AVPicture *src,
932
                              int width, int height)
933
{
934
    int w, h;
935
    uint8_t *line1, *line2, *linesrc = dst->data[0];
936
    uint8_t *lum1, *lum2, *lumsrc = src->data[0];
937
    uint8_t *cb1, *cb2 = src->data[1];
938
    uint8_t *cr1, *cr2 = src->data[2];
939 115329f1 Diego Biurrun
940 d7e2f57f Michael Niedermayer
    for(h = height / 2; h--;) {
941
        line1 = linesrc;
942
        line2 = linesrc + dst->linesize[0];
943 115329f1 Diego Biurrun
944 d7e2f57f Michael Niedermayer
        lum1 = lumsrc;
945
        lum2 = lumsrc + src->linesize[0];
946 115329f1 Diego Biurrun
947 d7e2f57f Michael Niedermayer
        cb1 = cb2;
948
        cr1 = cr2;
949 115329f1 Diego Biurrun
950 d7e2f57f Michael Niedermayer
        for(w = width / 2; w--;) {
951 115329f1 Diego Biurrun
                *line1++ = *lum1++; *line2++ = *lum2++;
952
                *line1++ =          *line2++ = *cb1++;
953
                *line1++ = *lum1++; *line2++ = *lum2++;
954 d7e2f57f Michael Niedermayer
                *line1++ =          *line2++ = *cr1++;
955
        }
956 115329f1 Diego Biurrun
957 d7e2f57f Michael Niedermayer
        linesrc += dst->linesize[0] * 2;
958
        lumsrc += src->linesize[0] * 2;
959
        cb2 += src->linesize[1];
960
        cr2 += src->linesize[2];
961
    }
962
}
963
964 bac65165 Luca Abeni
static void yuv420p_to_uyvy422(AVPicture *dst, const AVPicture *src,
965
                              int width, int height)
966
{
967
    int w, h;
968
    uint8_t *line1, *line2, *linesrc = dst->data[0];
969
    uint8_t *lum1, *lum2, *lumsrc = src->data[0];
970
    uint8_t *cb1, *cb2 = src->data[1];
971
    uint8_t *cr1, *cr2 = src->data[2];
972 115329f1 Diego Biurrun
973 bac65165 Luca Abeni
    for(h = height / 2; h--;) {
974
        line1 = linesrc;
975
        line2 = linesrc + dst->linesize[0];
976 115329f1 Diego Biurrun
977 bac65165 Luca Abeni
        lum1 = lumsrc;
978
        lum2 = lumsrc + src->linesize[0];
979 115329f1 Diego Biurrun
980 bac65165 Luca Abeni
        cb1 = cb2;
981
        cr1 = cr2;
982 115329f1 Diego Biurrun
983 bac65165 Luca Abeni
        for(w = width / 2; w--;) {
984 115329f1 Diego Biurrun
                *line1++ =          *line2++ = *cb1++;
985
                *line1++ = *lum1++; *line2++ = *lum2++;
986 bac65165 Luca Abeni
                *line1++ =          *line2++ = *cr1++;
987 115329f1 Diego Biurrun
                *line1++ = *lum1++; *line2++ = *lum2++;
988 bac65165 Luca Abeni
        }
989 115329f1 Diego Biurrun
990 bac65165 Luca Abeni
        linesrc += dst->linesize[0] * 2;
991
        lumsrc += src->linesize[0] * 2;
992
        cb2 += src->linesize[1];
993
        cr2 += src->linesize[2];
994
    }
995
}
996
997 c50c0bc8 Fabrice Bellard
#define SCALEBITS 10
998 de6d9b64 Fabrice Bellard
#define ONE_HALF  (1 << (SCALEBITS - 1))
999 bb270c08 Diego Biurrun
#define FIX(x)    ((int) ((x) * (1<<SCALEBITS) + 0.5))
1000 de6d9b64 Fabrice Bellard
1001 c50c0bc8 Fabrice Bellard
#define YUV_TO_RGB1_CCIR(cb1, cr1)\
1002
{\
1003
    cb = (cb1) - 128;\
1004
    cr = (cr1) - 128;\
1005
    r_add = FIX(1.40200*255.0/224.0) * cr + ONE_HALF;\
1006
    g_add = - FIX(0.34414*255.0/224.0) * cb - FIX(0.71414*255.0/224.0) * cr + \
1007
            ONE_HALF;\
1008
    b_add = FIX(1.77200*255.0/224.0) * cb + ONE_HALF;\
1009
}
1010 b6147995 Fabrice Bellard
1011 c50c0bc8 Fabrice Bellard
#define YUV_TO_RGB2_CCIR(r, g, b, y1)\
1012
{\
1013
    y = ((y1) - 16) * FIX(255.0/219.0);\
1014
    r = cm[(y + r_add) >> SCALEBITS];\
1015
    g = cm[(y + g_add) >> SCALEBITS];\
1016
    b = cm[(y + b_add) >> SCALEBITS];\
1017
}
1018
1019
#define YUV_TO_RGB1(cb1, cr1)\
1020
{\
1021
    cb = (cb1) - 128;\
1022
    cr = (cr1) - 128;\
1023
    r_add = FIX(1.40200) * cr + ONE_HALF;\
1024
    g_add = - FIX(0.34414) * cb - FIX(0.71414) * cr + ONE_HALF;\
1025
    b_add = FIX(1.77200) * cb + ONE_HALF;\
1026
}
1027 b6147995 Fabrice Bellard
1028
#define YUV_TO_RGB2(r, g, b, y1)\
1029
{\
1030 c50c0bc8 Fabrice Bellard
    y = (y1) << SCALEBITS;\
1031
    r = cm[(y + r_add) >> SCALEBITS];\
1032
    g = cm[(y + g_add) >> SCALEBITS];\
1033
    b = cm[(y + b_add) >> SCALEBITS];\
1034 b6147995 Fabrice Bellard
}
1035
1036 c50c0bc8 Fabrice Bellard
#define Y_CCIR_TO_JPEG(y)\
1037 b6147995 Fabrice Bellard
 cm[((y) * FIX(255.0/219.0) + (ONE_HALF - 16 * FIX(255.0/219.0))) >> SCALEBITS]
1038
1039 c50c0bc8 Fabrice Bellard
#define Y_JPEG_TO_CCIR(y)\
1040 b6147995 Fabrice Bellard
 (((y) * FIX(219.0/255.0) + (ONE_HALF + (16 << SCALEBITS))) >> SCALEBITS)
1041
1042 c50c0bc8 Fabrice Bellard
#define C_CCIR_TO_JPEG(y)\
1043
 cm[(((y) - 128) * FIX(127.0/112.0) + (ONE_HALF + (128 << SCALEBITS))) >> SCALEBITS]
1044
1045
/* NOTE: the clamp is really necessary! */
1046 4cfbf61b Falk Hüffner
static inline int C_JPEG_TO_CCIR(int y) {
1047
    y = (((y - 128) * FIX(112.0/127.0) + (ONE_HALF + (128 << SCALEBITS))) >> SCALEBITS);
1048
    if (y < 16)
1049 bb270c08 Diego Biurrun
        y = 16;
1050 4cfbf61b Falk Hüffner
    return y;
1051
}
1052
1053 c50c0bc8 Fabrice Bellard
1054 b6147995 Fabrice Bellard
#define RGB_TO_Y(r, g, b) \
1055
((FIX(0.29900) * (r) + FIX(0.58700) * (g) + \
1056
  FIX(0.11400) * (b) + ONE_HALF) >> SCALEBITS)
1057
1058 c50c0bc8 Fabrice Bellard
#define RGB_TO_U(r1, g1, b1, shift)\
1059 b6147995 Fabrice Bellard
(((- FIX(0.16874) * r1 - FIX(0.33126) * g1 +         \
1060 c50c0bc8 Fabrice Bellard
     FIX(0.50000) * b1 + (ONE_HALF << shift) - 1) >> (SCALEBITS + shift)) + 128)
1061 b6147995 Fabrice Bellard
1062 c50c0bc8 Fabrice Bellard
#define RGB_TO_V(r1, g1, b1, shift)\
1063 b6147995 Fabrice Bellard
(((FIX(0.50000) * r1 - FIX(0.41869) * g1 -           \
1064 c50c0bc8 Fabrice Bellard
   FIX(0.08131) * b1 + (ONE_HALF << shift) - 1) >> (SCALEBITS + shift)) + 128)
1065 b6147995 Fabrice Bellard
1066
#define RGB_TO_Y_CCIR(r, g, b) \
1067
((FIX(0.29900*219.0/255.0) * (r) + FIX(0.58700*219.0/255.0) * (g) + \
1068
  FIX(0.11400*219.0/255.0) * (b) + (ONE_HALF + (16 << SCALEBITS))) >> SCALEBITS)
1069
1070 c50c0bc8 Fabrice Bellard
#define RGB_TO_U_CCIR(r1, g1, b1, shift)\
1071 b6147995 Fabrice Bellard
(((- FIX(0.16874*224.0/255.0) * r1 - FIX(0.33126*224.0/255.0) * g1 +         \
1072 c50c0bc8 Fabrice Bellard
     FIX(0.50000*224.0/255.0) * b1 + (ONE_HALF << shift) - 1) >> (SCALEBITS + shift)) + 128)
1073 b6147995 Fabrice Bellard
1074 c50c0bc8 Fabrice Bellard
#define RGB_TO_V_CCIR(r1, g1, b1, shift)\
1075 b6147995 Fabrice Bellard
(((FIX(0.50000*224.0/255.0) * r1 - FIX(0.41869*224.0/255.0) * g1 -           \
1076 c50c0bc8 Fabrice Bellard
   FIX(0.08131*224.0/255.0) * b1 + (ONE_HALF << shift) - 1) >> (SCALEBITS + shift)) + 128)
1077 b6147995 Fabrice Bellard
1078 c50c0bc8 Fabrice Bellard
static uint8_t y_ccir_to_jpeg[256];
1079
static uint8_t y_jpeg_to_ccir[256];
1080
static uint8_t c_ccir_to_jpeg[256];
1081
static uint8_t c_jpeg_to_ccir[256];
1082
1083
/* init various conversion tables */
1084
static void img_convert_init(void)
1085 b6147995 Fabrice Bellard
{
1086 c50c0bc8 Fabrice Bellard
    int i;
1087 b6147995 Fabrice Bellard
    uint8_t *cm = cropTbl + MAX_NEG_CROP;
1088
1089 c50c0bc8 Fabrice Bellard
    for(i = 0;i < 256; i++) {
1090
        y_ccir_to_jpeg[i] = Y_CCIR_TO_JPEG(i);
1091
        y_jpeg_to_ccir[i] = Y_JPEG_TO_CCIR(i);
1092
        c_ccir_to_jpeg[i] = C_CCIR_TO_JPEG(i);
1093
        c_jpeg_to_ccir[i] = C_JPEG_TO_CCIR(i);
1094 b6147995 Fabrice Bellard
    }
1095
}
1096
1097 c50c0bc8 Fabrice Bellard
/* apply to each pixel the given table */
1098 115329f1 Diego Biurrun
static void img_apply_table(uint8_t *dst, int dst_wrap,
1099 c50c0bc8 Fabrice Bellard
                            const uint8_t *src, int src_wrap,
1100
                            int width, int height, const uint8_t *table1)
1101 b6147995 Fabrice Bellard
{
1102
    int n;
1103
    const uint8_t *s;
1104
    uint8_t *d;
1105 c50c0bc8 Fabrice Bellard
    const uint8_t *table;
1106 b6147995 Fabrice Bellard
1107 c50c0bc8 Fabrice Bellard
    table = table1;
1108 b6147995 Fabrice Bellard
    for(;height > 0; height--) {
1109
        s = src;
1110
        d = dst;
1111
        n = width;
1112
        while (n >= 4) {
1113 c50c0bc8 Fabrice Bellard
            d[0] = table[s[0]];
1114
            d[1] = table[s[1]];
1115
            d[2] = table[s[2]];
1116
            d[3] = table[s[3]];
1117 b6147995 Fabrice Bellard
            d += 4;
1118
            s += 4;
1119
            n -= 4;
1120
        }
1121
        while (n > 0) {
1122 c50c0bc8 Fabrice Bellard
            d[0] = table[s[0]];
1123 b6147995 Fabrice Bellard
            d++;
1124
            s++;
1125
            n--;
1126
        }
1127
        dst += dst_wrap;
1128
        src += src_wrap;
1129
    }
1130
}
1131
1132 85c242d8 Fabrice Bellard
/* XXX: use generic filter ? */
1133 e352ff08 Fabrice Bellard
/* XXX: in most cases, the sampling position is incorrect */
1134
1135
/* 4x1 -> 1x1 */
1136 115329f1 Diego Biurrun
static void shrink41(uint8_t *dst, int dst_wrap,
1137 e352ff08 Fabrice Bellard
                     const uint8_t *src, int src_wrap,
1138
                     int width, int height)
1139
{
1140
    int w;
1141
    const uint8_t *s;
1142
    uint8_t *d;
1143
1144
    for(;height > 0; height--) {
1145
        s = src;
1146
        d = dst;
1147
        for(w = width;w > 0; w--) {
1148
            d[0] = (s[0] + s[1] + s[2] + s[3] + 2) >> 2;
1149
            s += 4;
1150
            d++;
1151
        }
1152
        src += src_wrap;
1153
        dst += dst_wrap;
1154
    }
1155
}
1156
1157
/* 2x1 -> 1x1 */
1158 115329f1 Diego Biurrun
static void shrink21(uint8_t *dst, int dst_wrap,
1159 e352ff08 Fabrice Bellard
                     const uint8_t *src, int src_wrap,
1160
                     int width, int height)
1161
{
1162
    int w;
1163
    const uint8_t *s;
1164
    uint8_t *d;
1165
1166
    for(;height > 0; height--) {
1167
        s = src;
1168
        d = dst;
1169
        for(w = width;w > 0; w--) {
1170
            d[0] = (s[0] + s[1]) >> 1;
1171
            s += 2;
1172
            d++;
1173
        }
1174
        src += src_wrap;
1175
        dst += dst_wrap;
1176
    }
1177
}
1178
1179 85c242d8 Fabrice Bellard
/* 1x2 -> 1x1 */
1180 115329f1 Diego Biurrun
static void shrink12(uint8_t *dst, int dst_wrap,
1181 e352ff08 Fabrice Bellard
                     const uint8_t *src, int src_wrap,
1182
                     int width, int height)
1183 85c242d8 Fabrice Bellard
{
1184
    int w;
1185 e352ff08 Fabrice Bellard
    uint8_t *d;
1186
    const uint8_t *s1, *s2;
1187 85c242d8 Fabrice Bellard
1188
    for(;height > 0; height--) {
1189
        s1 = src;
1190
        s2 = s1 + src_wrap;
1191
        d = dst;
1192
        for(w = width;w >= 4; w-=4) {
1193
            d[0] = (s1[0] + s2[0]) >> 1;
1194
            d[1] = (s1[1] + s2[1]) >> 1;
1195
            d[2] = (s1[2] + s2[2]) >> 1;
1196
            d[3] = (s1[3] + s2[3]) >> 1;
1197
            s1 += 4;
1198
            s2 += 4;
1199
            d += 4;
1200
        }
1201
        for(;w > 0; w--) {
1202
            d[0] = (s1[0] + s2[0]) >> 1;
1203
            s1++;
1204
            s2++;
1205
            d++;
1206
        }
1207
        src += 2 * src_wrap;
1208
        dst += dst_wrap;
1209
    }
1210
}
1211
1212
/* 2x2 -> 1x1 */
1213 115329f1 Diego Biurrun
static void shrink22(uint8_t *dst, int dst_wrap,
1214 e352ff08 Fabrice Bellard
                     const uint8_t *src, int src_wrap,
1215 85c242d8 Fabrice Bellard
                     int width, int height)
1216
{
1217
    int w;
1218 e352ff08 Fabrice Bellard
    const uint8_t *s1, *s2;
1219
    uint8_t *d;
1220 85c242d8 Fabrice Bellard
1221
    for(;height > 0; height--) {
1222
        s1 = src;
1223
        s2 = s1 + src_wrap;
1224
        d = dst;
1225
        for(w = width;w >= 4; w-=4) {
1226 0a9ad8d1 Fabrice Bellard
            d[0] = (s1[0] + s1[1] + s2[0] + s2[1] + 2) >> 2;
1227
            d[1] = (s1[2] + s1[3] + s2[2] + s2[3] + 2) >> 2;
1228
            d[2] = (s1[4] + s1[5] + s2[4] + s2[5] + 2) >> 2;
1229
            d[3] = (s1[6] + s1[7] + s2[6] + s2[7] + 2) >> 2;
1230 85c242d8 Fabrice Bellard
            s1 += 8;
1231
            s2 += 8;
1232
            d += 4;
1233
        }
1234
        for(;w > 0; w--) {
1235 0a9ad8d1 Fabrice Bellard
            d[0] = (s1[0] + s1[1] + s2[0] + s2[1] + 2) >> 2;
1236 85c242d8 Fabrice Bellard
            s1 += 2;
1237
            s2 += 2;
1238
            d++;
1239
        }
1240
        src += 2 * src_wrap;
1241
        dst += dst_wrap;
1242
    }
1243
}
1244
1245 e352ff08 Fabrice Bellard
/* 4x4 -> 1x1 */
1246 115329f1 Diego Biurrun
static void shrink44(uint8_t *dst, int dst_wrap,
1247 e352ff08 Fabrice Bellard
                     const uint8_t *src, int src_wrap,
1248 6742d95d François Revol
                     int width, int height)
1249
{
1250
    int w;
1251 e352ff08 Fabrice Bellard
    const uint8_t *s1, *s2, *s3, *s4;
1252
    uint8_t *d;
1253 6742d95d François Revol
1254
    for(;height > 0; height--) {
1255
        s1 = src;
1256 e352ff08 Fabrice Bellard
        s2 = s1 + src_wrap;
1257
        s3 = s2 + src_wrap;
1258
        s4 = s3 + src_wrap;
1259 6742d95d François Revol
        d = dst;
1260 e352ff08 Fabrice Bellard
        for(w = width;w > 0; w--) {
1261
            d[0] = (s1[0] + s1[1] + s1[2] + s1[3] +
1262
                    s2[0] + s2[1] + s2[2] + s2[3] +
1263
                    s3[0] + s3[1] + s3[2] + s3[3] +
1264
                    s4[0] + s4[1] + s4[2] + s4[3] + 8) >> 4;
1265
            s1 += 4;
1266
            s2 += 4;
1267
            s3 += 4;
1268
            s4 += 4;
1269 6742d95d François Revol
            d++;
1270
        }
1271 e352ff08 Fabrice Bellard
        src += 4 * src_wrap;
1272
        dst += dst_wrap;
1273
    }
1274
}
1275
1276
static void grow21_line(uint8_t *dst, const uint8_t *src,
1277
                        int width)
1278
{
1279
    int w;
1280
    const uint8_t *s1;
1281
    uint8_t *d;
1282
1283
    s1 = src;
1284
    d = dst;
1285
    for(w = width;w >= 4; w-=4) {
1286
        d[1] = d[0] = s1[0];
1287
        d[3] = d[2] = s1[1];
1288
        s1 += 2;
1289
        d += 4;
1290
    }
1291
    for(;w >= 2; w -= 2) {
1292
        d[1] = d[0] = s1[0];
1293
        s1 ++;
1294
        d += 2;
1295
    }
1296
    /* only needed if width is not a multiple of two */
1297
    /* XXX: veryfy that */
1298
    if (w) {
1299
        d[0] = s1[0];
1300
    }
1301
}
1302
1303
static void grow41_line(uint8_t *dst, const uint8_t *src,
1304
                        int width)
1305
{
1306
    int w, v;
1307
    const uint8_t *s1;
1308
    uint8_t *d;
1309
1310
    s1 = src;
1311
    d = dst;
1312
    for(w = width;w >= 4; w-=4) {
1313
        v = s1[0];
1314
        d[0] = v;
1315
        d[1] = v;
1316
        d[2] = v;
1317
        d[3] = v;
1318
        s1 ++;
1319
        d += 4;
1320
    }
1321
}
1322
1323
/* 1x1 -> 2x1 */
1324
static void grow21(uint8_t *dst, int dst_wrap,
1325
                   const uint8_t *src, int src_wrap,
1326
                   int width, int height)
1327
{
1328
    for(;height > 0; height--) {
1329
        grow21_line(dst, src, width);
1330
        src += src_wrap;
1331
        dst += dst_wrap;
1332
    }
1333
}
1334
1335
/* 1x1 -> 2x2 */
1336
static void grow22(uint8_t *dst, int dst_wrap,
1337
                   const uint8_t *src, int src_wrap,
1338
                   int width, int height)
1339
{
1340
    for(;height > 0; height--) {
1341
        grow21_line(dst, src, width);
1342 6742d95d François Revol
        if (height%2)
1343
            src += src_wrap;
1344
        dst += dst_wrap;
1345
    }
1346
}
1347
1348 e352ff08 Fabrice Bellard
/* 1x1 -> 4x1 */
1349
static void grow41(uint8_t *dst, int dst_wrap,
1350
                   const uint8_t *src, int src_wrap,
1351
                   int width, int height)
1352
{
1353
    for(;height > 0; height--) {
1354
        grow41_line(dst, src, width);
1355
        src += src_wrap;
1356
        dst += dst_wrap;
1357
    }
1358
}
1359
1360
/* 1x1 -> 4x4 */
1361
static void grow44(uint8_t *dst, int dst_wrap,
1362
                   const uint8_t *src, int src_wrap,
1363
                   int width, int height)
1364
{
1365
    for(;height > 0; height--) {
1366
        grow41_line(dst, src, width);
1367
        if ((height & 3) == 1)
1368
            src += src_wrap;
1369
        dst += dst_wrap;
1370
    }
1371
}
1372
1373 524c6b63 Fabrice Bellard
/* 1x2 -> 2x1 */
1374 115329f1 Diego Biurrun
static void conv411(uint8_t *dst, int dst_wrap,
1375 e352ff08 Fabrice Bellard
                    const uint8_t *src, int src_wrap,
1376 789587d5 Fabrice Bellard
                    int width, int height)
1377
{
1378
    int w, c;
1379 e352ff08 Fabrice Bellard
    const uint8_t *s1, *s2;
1380
    uint8_t *d;
1381 789587d5 Fabrice Bellard
1382 50643575 Michael Niedermayer
    width>>=1;
1383
1384 524c6b63 Fabrice Bellard
    for(;height > 0; height--) {
1385 789587d5 Fabrice Bellard
        s1 = src;
1386
        s2 = src + src_wrap;
1387
        d = dst;
1388
        for(w = width;w > 0; w--) {
1389
            c = (s1[0] + s2[0]) >> 1;
1390
            d[0] = c;
1391
            d[1] = c;
1392
            s1++;
1393
            s2++;
1394
            d += 2;
1395
        }
1396
        src += src_wrap * 2;
1397
        dst += dst_wrap;
1398
    }
1399
}
1400
1401 7e7e5940 Fabrice Bellard
/* XXX: add jpeg quantize code */
1402
1403
#define TRANSP_INDEX (6*6*6)
1404
1405
/* this is maybe slow, but allows for extensions */
1406
static inline unsigned char gif_clut_index(uint8_t r, uint8_t g, uint8_t b)
1407 85c242d8 Fabrice Bellard
{
1408 7e7e5940 Fabrice Bellard
    return ((((r)/47)%6)*6*6+(((g)/47)%6)*6+(((b)/47)%6));
1409 85c242d8 Fabrice Bellard
}
1410
1411 7e7e5940 Fabrice Bellard
static void build_rgb_palette(uint8_t *palette, int has_alpha)
1412
{
1413
    uint32_t *pal;
1414
    static const uint8_t pal_value[6] = { 0x00, 0x33, 0x66, 0x99, 0xcc, 0xff };
1415
    int i, r, g, b;
1416
1417
    pal = (uint32_t *)palette;
1418
    i = 0;
1419
    for(r = 0; r < 6; r++) {
1420
        for(g = 0; g < 6; g++) {
1421
            for(b = 0; b < 6; b++) {
1422 115329f1 Diego Biurrun
                pal[i++] = (0xff << 24) | (pal_value[r] << 16) |
1423 7e7e5940 Fabrice Bellard
                    (pal_value[g] << 8) | pal_value[b];
1424
            }
1425
        }
1426
    }
1427
    if (has_alpha)
1428
        pal[i++] = 0;
1429
    while (i < 256)
1430
        pal[i++] = 0xff000000;
1431 524c6b63 Fabrice Bellard
}
1432
1433
/* copy bit n to bits 0 ... n - 1 */
1434
static inline unsigned int bitcopy_n(unsigned int a, int n)
1435 b71472eb Philip Gladstone
{
1436 524c6b63 Fabrice Bellard
    int mask;
1437
    mask = (1 << n) - 1;
1438
    return (a & (0xff & ~mask)) | ((-((a >> n) & 1)) & mask);
1439
}
1440
1441
/* rgb555 handling */
1442
1443 7e7e5940 Fabrice Bellard
#define RGB_NAME rgb555
1444
1445 524c6b63 Fabrice Bellard
#define RGB_IN(r, g, b, s)\
1446
{\
1447 0c1a9eda Zdenek Kabelac
    unsigned int v = ((const uint16_t *)(s))[0];\
1448 524c6b63 Fabrice Bellard
    r = bitcopy_n(v >> (10 - 3), 3);\
1449
    g = bitcopy_n(v >> (5 - 3), 3);\
1450
    b = bitcopy_n(v << 3, 3);\
1451
}
1452
1453 7e7e5940 Fabrice Bellard
#define RGBA_IN(r, g, b, a, s)\
1454 524c6b63 Fabrice Bellard
{\
1455 7e7e5940 Fabrice Bellard
    unsigned int v = ((const uint16_t *)(s))[0];\
1456
    r = bitcopy_n(v >> (10 - 3), 3);\
1457
    g = bitcopy_n(v >> (5 - 3), 3);\
1458
    b = bitcopy_n(v << 3, 3);\
1459 b5ff5e22 Fabrice Bellard
    a = (-(v >> 15)) & 0xff;\
1460 7e7e5940 Fabrice Bellard
}
1461
1462
#define RGBA_OUT(d, r, g, b, a)\
1463
{\
1464
    ((uint16_t *)(d))[0] = ((r >> 3) << 10) | ((g >> 3) << 5) | (b >> 3) | \
1465
                           ((a << 8) & 0x8000);\
1466 524c6b63 Fabrice Bellard
}
1467
1468
#define BPP 2
1469
1470 7e7e5940 Fabrice Bellard
#include "imgconvert_template.h"
1471 524c6b63 Fabrice Bellard
1472
/* rgb565 handling */
1473
1474 7e7e5940 Fabrice Bellard
#define RGB_NAME rgb565
1475
1476 524c6b63 Fabrice Bellard
#define RGB_IN(r, g, b, s)\
1477
{\
1478 0c1a9eda Zdenek Kabelac
    unsigned int v = ((const uint16_t *)(s))[0];\
1479 524c6b63 Fabrice Bellard
    r = bitcopy_n(v >> (11 - 3), 3);\
1480
    g = bitcopy_n(v >> (5 - 2), 2);\
1481
    b = bitcopy_n(v << 3, 3);\
1482
}
1483
1484
#define RGB_OUT(d, r, g, b)\
1485
{\
1486 0c1a9eda Zdenek Kabelac
    ((uint16_t *)(d))[0] = ((r >> 3) << 11) | ((g >> 2) << 5) | (b >> 3);\
1487 524c6b63 Fabrice Bellard
}
1488
1489
#define BPP 2
1490
1491 7e7e5940 Fabrice Bellard
#include "imgconvert_template.h"
1492 524c6b63 Fabrice Bellard
1493
/* bgr24 handling */
1494
1495 7e7e5940 Fabrice Bellard
#define RGB_NAME bgr24
1496
1497 524c6b63 Fabrice Bellard
#define RGB_IN(r, g, b, s)\
1498
{\
1499
    b = (s)[0];\
1500
    g = (s)[1];\
1501
    r = (s)[2];\
1502
}
1503
1504
#define RGB_OUT(d, r, g, b)\
1505
{\
1506
    (d)[0] = b;\
1507
    (d)[1] = g;\
1508
    (d)[2] = r;\
1509
}
1510
1511
#define BPP 3
1512
1513 7e7e5940 Fabrice Bellard
#include "imgconvert_template.h"
1514 524c6b63 Fabrice Bellard
1515
#undef RGB_IN
1516
#undef RGB_OUT
1517
#undef BPP
1518
1519
/* rgb24 handling */
1520
1521 7e7e5940 Fabrice Bellard
#define RGB_NAME rgb24
1522
#define FMT_RGB24
1523
1524 524c6b63 Fabrice Bellard
#define RGB_IN(r, g, b, s)\
1525
{\
1526
    r = (s)[0];\
1527
    g = (s)[1];\
1528
    b = (s)[2];\
1529
}
1530
1531
#define RGB_OUT(d, r, g, b)\
1532
{\
1533
    (d)[0] = r;\
1534
    (d)[1] = g;\
1535
    (d)[2] = b;\
1536
}
1537
1538
#define BPP 3
1539
1540 7e7e5940 Fabrice Bellard
#include "imgconvert_template.h"
1541 524c6b63 Fabrice Bellard
1542
/* rgba32 handling */
1543
1544 7e7e5940 Fabrice Bellard
#define RGB_NAME rgba32
1545
#define FMT_RGBA32
1546
1547 524c6b63 Fabrice Bellard
#define RGB_IN(r, g, b, s)\
1548
{\
1549 0c1a9eda Zdenek Kabelac
    unsigned int v = ((const uint32_t *)(s))[0];\
1550 524c6b63 Fabrice Bellard
    r = (v >> 16) & 0xff;\
1551
    g = (v >> 8) & 0xff;\
1552
    b = v & 0xff;\
1553
}
1554
1555 7e7e5940 Fabrice Bellard
#define RGBA_IN(r, g, b, a, s)\
1556 524c6b63 Fabrice Bellard
{\
1557 7e7e5940 Fabrice Bellard
    unsigned int v = ((const uint32_t *)(s))[0];\
1558
    a = (v >> 24) & 0xff;\
1559
    r = (v >> 16) & 0xff;\
1560
    g = (v >> 8) & 0xff;\
1561
    b = v & 0xff;\
1562 524c6b63 Fabrice Bellard
}
1563
1564 7e7e5940 Fabrice Bellard
#define RGBA_OUT(d, r, g, b, a)\
1565
{\
1566
    ((uint32_t *)(d))[0] = (a << 24) | (r << 16) | (g << 8) | b;\
1567 b71472eb Philip Gladstone
}
1568
1569 7e7e5940 Fabrice Bellard
#define BPP 4
1570 524c6b63 Fabrice Bellard
1571 7e7e5940 Fabrice Bellard
#include "imgconvert_template.h"
1572 b71472eb Philip Gladstone
1573 da64ecc3 Drew Hess
static void mono_to_gray(AVPicture *dst, const AVPicture *src,
1574 2a877875 Fabrice Bellard
                         int width, int height, int xor_mask)
1575 524c6b63 Fabrice Bellard
{
1576
    const unsigned char *p;
1577
    unsigned char *q;
1578
    int v, dst_wrap, src_wrap;
1579
    int y, w;
1580
1581
    p = src->data[0];
1582
    src_wrap = src->linesize[0] - ((width + 7) >> 3);
1583
1584
    q = dst->data[0];
1585 2a877875 Fabrice Bellard
    dst_wrap = dst->linesize[0] - width;
1586 524c6b63 Fabrice Bellard
    for(y=0;y<height;y++) {
1587 115329f1 Diego Biurrun
        w = width;
1588 524c6b63 Fabrice Bellard
        while (w >= 8) {
1589 2a877875 Fabrice Bellard
            v = *p++ ^ xor_mask;
1590
            q[0] = -(v >> 7);
1591
            q[1] = -((v >> 6) & 1);
1592
            q[2] = -((v >> 5) & 1);
1593
            q[3] = -((v >> 4) & 1);
1594
            q[4] = -((v >> 3) & 1);
1595
            q[5] = -((v >> 2) & 1);
1596
            q[6] = -((v >> 1) & 1);
1597
            q[7] = -((v >> 0) & 1);
1598 524c6b63 Fabrice Bellard
            w -= 8;
1599 2a877875 Fabrice Bellard
            q += 8;
1600 524c6b63 Fabrice Bellard
        }
1601
        if (w > 0) {
1602 2a877875 Fabrice Bellard
            v = *p++ ^ xor_mask;
1603 524c6b63 Fabrice Bellard
            do {
1604 2a877875 Fabrice Bellard
                q[0] = -((v >> 7) & 1);
1605
                q++;
1606 524c6b63 Fabrice Bellard
                v <<= 1;
1607
            } while (--w);
1608 85c242d8 Fabrice Bellard
        }
1609 524c6b63 Fabrice Bellard
        p += src_wrap;
1610
        q += dst_wrap;
1611 85c242d8 Fabrice Bellard
    }
1612
}
1613
1614 da64ecc3 Drew Hess
static void monowhite_to_gray(AVPicture *dst, const AVPicture *src,
1615 524c6b63 Fabrice Bellard
                               int width, int height)
1616
{
1617 2a877875 Fabrice Bellard
    mono_to_gray(dst, src, width, height, 0xff);
1618
}
1619 524c6b63 Fabrice Bellard
1620 da64ecc3 Drew Hess
static void monoblack_to_gray(AVPicture *dst, const AVPicture *src,
1621 2a877875 Fabrice Bellard
                               int width, int height)
1622
{
1623
    mono_to_gray(dst, src, width, height, 0x00);
1624
}
1625 524c6b63 Fabrice Bellard
1626 da64ecc3 Drew Hess
static void gray_to_mono(AVPicture *dst, const AVPicture *src,
1627 2a877875 Fabrice Bellard
                         int width, int height, int xor_mask)
1628
{
1629
    int n;
1630 0c1a9eda Zdenek Kabelac
    const uint8_t *s;
1631
    uint8_t *d;
1632 2a877875 Fabrice Bellard
    int j, b, v, n1, src_wrap, dst_wrap, y;
1633
1634
    s = src->data[0];
1635
    src_wrap = src->linesize[0] - width;
1636
1637
    d = dst->data[0];
1638
    dst_wrap = dst->linesize[0] - ((width + 7) >> 3);
1639 524c6b63 Fabrice Bellard
1640
    for(y=0;y<height;y++) {
1641 2a877875 Fabrice Bellard
        n = width;
1642
        while (n >= 8) {
1643
            v = 0;
1644
            for(j=0;j<8;j++) {
1645
                b = s[0];
1646
                s++;
1647
                v = (v << 1) | (b >> 7);
1648
            }
1649
            d[0] = v ^ xor_mask;
1650
            d++;
1651
            n -= 8;
1652 524c6b63 Fabrice Bellard
        }
1653 2a877875 Fabrice Bellard
        if (n > 0) {
1654
            n1 = n;
1655
            v = 0;
1656
            while (n > 0) {
1657
                b = s[0];
1658
                s++;
1659
                v = (v << 1) | (b >> 7);
1660
                n--;
1661
            }
1662
            d[0] = (v << (8 - (n1 & 7))) ^ xor_mask;
1663
            d++;
1664 524c6b63 Fabrice Bellard
        }
1665 2a877875 Fabrice Bellard
        s += src_wrap;
1666
        d += dst_wrap;
1667 524c6b63 Fabrice Bellard
    }
1668
}
1669
1670 da64ecc3 Drew Hess
static void gray_to_monowhite(AVPicture *dst, const AVPicture *src,
1671 2a877875 Fabrice Bellard
                              int width, int height)
1672
{
1673
    gray_to_mono(dst, src, width, height, 0xff);
1674
}
1675
1676 da64ecc3 Drew Hess
static void gray_to_monoblack(AVPicture *dst, const AVPicture *src,
1677 2a877875 Fabrice Bellard
                              int width, int height)
1678
{
1679
    gray_to_mono(dst, src, width, height, 0x00);
1680
}
1681
1682 524c6b63 Fabrice Bellard
typedef struct ConvertEntry {
1683 da64ecc3 Drew Hess
    void (*convert)(AVPicture *dst,
1684 bb270c08 Diego Biurrun
                    const AVPicture *src, int width, int height);
1685 524c6b63 Fabrice Bellard
} ConvertEntry;
1686
1687 c50c0bc8 Fabrice Bellard
/* Add each new convertion function in this table. In order to be able
1688
   to convert from any format to any format, the following constraints
1689
   must be satisfied:
1690

1691 115329f1 Diego Biurrun
   - all FF_COLOR_RGB formats must convert to and from PIX_FMT_RGB24
1692 c50c0bc8 Fabrice Bellard

1693
   - all FF_COLOR_GRAY formats must convert to and from PIX_FMT_GRAY8
1694

1695
   - all FF_COLOR_RGB formats with alpha must convert to and from PIX_FMT_RGBA32
1696

1697 e352ff08 Fabrice Bellard
   - PIX_FMT_YUV444P and PIX_FMT_YUVJ444P must convert to and from
1698 c50c0bc8 Fabrice Bellard
     PIX_FMT_RGB24.
1699

1700
   - PIX_FMT_422 must convert to and from PIX_FMT_422P.
1701 e352ff08 Fabrice Bellard

1702
   The other conversion functions are just optimisations for common cases.
1703 524c6b63 Fabrice Bellard
*/
1704
static ConvertEntry convert_table[PIX_FMT_NB][PIX_FMT_NB] = {
1705
    [PIX_FMT_YUV420P] = {
1706 d7e2f57f Michael Niedermayer
        [PIX_FMT_YUV422] = {
1707
            .convert = yuv420p_to_yuv422,
1708
        },
1709 115329f1 Diego Biurrun
        [PIX_FMT_RGB555] = {
1710 ef9f7306 Måns Rullgård
            .convert = yuv420p_to_rgb555
1711 524c6b63 Fabrice Bellard
        },
1712 115329f1 Diego Biurrun
        [PIX_FMT_RGB565] = {
1713 ef9f7306 Måns Rullgård
            .convert = yuv420p_to_rgb565
1714 524c6b63 Fabrice Bellard
        },
1715 115329f1 Diego Biurrun
        [PIX_FMT_BGR24] = {
1716 ef9f7306 Måns Rullgård
            .convert = yuv420p_to_bgr24
1717 524c6b63 Fabrice Bellard
        },
1718 115329f1 Diego Biurrun
        [PIX_FMT_RGB24] = {
1719 ef9f7306 Måns Rullgård
            .convert = yuv420p_to_rgb24
1720 524c6b63 Fabrice Bellard
        },
1721 115329f1 Diego Biurrun
        [PIX_FMT_RGBA32] = {
1722 ef9f7306 Måns Rullgård
            .convert = yuv420p_to_rgba32
1723 524c6b63 Fabrice Bellard
        },
1724 bb270c08 Diego Biurrun
        [PIX_FMT_UYVY422] = {
1725 bac65165 Luca Abeni
            .convert = yuv420p_to_uyvy422,
1726
        },
1727 524c6b63 Fabrice Bellard
    },
1728 115329f1 Diego Biurrun
    [PIX_FMT_YUV422P] = {
1729
        [PIX_FMT_YUV422] = {
1730 c50c0bc8 Fabrice Bellard
            .convert = yuv422p_to_yuv422,
1731
        },
1732 115329f1 Diego Biurrun
        [PIX_FMT_UYVY422] = {
1733 ebb177dd Todd Kirby
            .convert = yuv422p_to_uyvy422,
1734
        },
1735 c50c0bc8 Fabrice Bellard
    },
1736 115329f1 Diego Biurrun
    [PIX_FMT_YUV444P] = {
1737
        [PIX_FMT_RGB24] = {
1738 c50c0bc8 Fabrice Bellard
            .convert = yuv444p_to_rgb24
1739
        },
1740
    },
1741
    [PIX_FMT_YUVJ420P] = {
1742 115329f1 Diego Biurrun
        [PIX_FMT_RGB555] = {
1743 c50c0bc8 Fabrice Bellard
            .convert = yuvj420p_to_rgb555
1744 524c6b63 Fabrice Bellard
        },
1745 115329f1 Diego Biurrun
        [PIX_FMT_RGB565] = {
1746 c50c0bc8 Fabrice Bellard
            .convert = yuvj420p_to_rgb565
1747 524c6b63 Fabrice Bellard
        },
1748 115329f1 Diego Biurrun
        [PIX_FMT_BGR24] = {
1749 c50c0bc8 Fabrice Bellard
            .convert = yuvj420p_to_bgr24
1750 524c6b63 Fabrice Bellard
        },
1751 115329f1 Diego Biurrun
        [PIX_FMT_RGB24] = {
1752 c50c0bc8 Fabrice Bellard
            .convert = yuvj420p_to_rgb24
1753 524c6b63 Fabrice Bellard
        },
1754 115329f1 Diego Biurrun
        [PIX_FMT_RGBA32] = {
1755 c50c0bc8 Fabrice Bellard
            .convert = yuvj420p_to_rgba32
1756
        },
1757
    },
1758 115329f1 Diego Biurrun
    [PIX_FMT_YUVJ444P] = {
1759
        [PIX_FMT_RGB24] = {
1760 c50c0bc8 Fabrice Bellard
            .convert = yuvj444p_to_rgb24
1761 524c6b63 Fabrice Bellard
        },
1762
    },
1763 115329f1 Diego Biurrun
    [PIX_FMT_YUV422] = {
1764
        [PIX_FMT_YUV420P] = {
1765 ef9f7306 Måns Rullgård
            .convert = yuv422_to_yuv420p,
1766 524c6b63 Fabrice Bellard
        },
1767 115329f1 Diego Biurrun
        [PIX_FMT_YUV422P] = {
1768 c50c0bc8 Fabrice Bellard
            .convert = yuv422_to_yuv422p,
1769
        },
1770 524c6b63 Fabrice Bellard
    },
1771 115329f1 Diego Biurrun
    [PIX_FMT_UYVY422] = {
1772
        [PIX_FMT_YUV420P] = {
1773 ebb177dd Todd Kirby
            .convert = uyvy422_to_yuv420p,
1774
        },
1775 115329f1 Diego Biurrun
        [PIX_FMT_YUV422P] = {
1776 ebb177dd Todd Kirby
            .convert = uyvy422_to_yuv422p,
1777
        },
1778
    },
1779 524c6b63 Fabrice Bellard
    [PIX_FMT_RGB24] = {
1780 115329f1 Diego Biurrun
        [PIX_FMT_YUV420P] = {
1781 ef9f7306 Måns Rullgård
            .convert = rgb24_to_yuv420p
1782 524c6b63 Fabrice Bellard
        },
1783 115329f1 Diego Biurrun
        [PIX_FMT_RGB565] = {
1784 ef9f7306 Måns Rullgård
            .convert = rgb24_to_rgb565
1785 524c6b63 Fabrice Bellard
        },
1786 115329f1 Diego Biurrun
        [PIX_FMT_RGB555] = {
1787 ef9f7306 Måns Rullgård
            .convert = rgb24_to_rgb555
1788 524c6b63 Fabrice Bellard
        },
1789 115329f1 Diego Biurrun
        [PIX_FMT_RGBA32] = {
1790 7e7e5940 Fabrice Bellard
            .convert = rgb24_to_rgba32
1791
        },
1792 115329f1 Diego Biurrun
        [PIX_FMT_BGR24] = {
1793 7e7e5940 Fabrice Bellard
            .convert = rgb24_to_bgr24
1794
        },
1795 115329f1 Diego Biurrun
        [PIX_FMT_GRAY8] = {
1796 ef9f7306 Måns Rullgård
            .convert = rgb24_to_gray
1797 524c6b63 Fabrice Bellard
        },
1798 7e7e5940 Fabrice Bellard
        [PIX_FMT_PAL8] = {
1799 7e6d70d0 Fabrice Bellard
            .convert = rgb24_to_pal8
1800
        },
1801 115329f1 Diego Biurrun
        [PIX_FMT_YUV444P] = {
1802 c50c0bc8 Fabrice Bellard
            .convert = rgb24_to_yuv444p
1803
        },
1804 115329f1 Diego Biurrun
        [PIX_FMT_YUVJ420P] = {
1805 c50c0bc8 Fabrice Bellard
            .convert = rgb24_to_yuvj420p
1806
        },
1807 115329f1 Diego Biurrun
        [PIX_FMT_YUVJ444P] = {
1808 c50c0bc8 Fabrice Bellard
            .convert = rgb24_to_yuvj444p
1809
        },
1810 524c6b63 Fabrice Bellard
    },
1811
    [PIX_FMT_RGBA32] = {
1812 115329f1 Diego Biurrun
        [PIX_FMT_RGB24] = {
1813 7e7e5940 Fabrice Bellard
            .convert = rgba32_to_rgb24
1814
        },
1815 115329f1 Diego Biurrun
        [PIX_FMT_RGB555] = {
1816 7e7e5940 Fabrice Bellard
            .convert = rgba32_to_rgb555
1817
        },
1818 115329f1 Diego Biurrun
        [PIX_FMT_PAL8] = {
1819 7e7e5940 Fabrice Bellard
            .convert = rgba32_to_pal8
1820
        },
1821 115329f1 Diego Biurrun
        [PIX_FMT_YUV420P] = {
1822 ef9f7306 Måns Rullgård
            .convert = rgba32_to_yuv420p
1823 524c6b63 Fabrice Bellard
        },
1824 115329f1 Diego Biurrun
        [PIX_FMT_GRAY8] = {
1825 69572401 Fabrice Bellard
            .convert = rgba32_to_gray
1826
        },
1827 524c6b63 Fabrice Bellard
    },
1828
    [PIX_FMT_BGR24] = {
1829 115329f1 Diego Biurrun
        [PIX_FMT_RGB24] = {
1830 7e7e5940 Fabrice Bellard
            .convert = bgr24_to_rgb24
1831
        },
1832 115329f1 Diego Biurrun
        [PIX_FMT_YUV420P] = {
1833 ef9f7306 Måns Rullgård
            .convert = bgr24_to_yuv420p
1834 524c6b63 Fabrice Bellard
        },
1835 115329f1 Diego Biurrun
        [PIX_FMT_GRAY8] = {
1836 69572401 Fabrice Bellard
            .convert = bgr24_to_gray
1837
        },
1838 524c6b63 Fabrice Bellard
    },
1839
    [PIX_FMT_RGB555] = {
1840 115329f1 Diego Biurrun
        [PIX_FMT_RGB24] = {
1841 7e7e5940 Fabrice Bellard
            .convert = rgb555_to_rgb24
1842
        },
1843 115329f1 Diego Biurrun
        [PIX_FMT_RGBA32] = {
1844 7e7e5940 Fabrice Bellard
            .convert = rgb555_to_rgba32
1845
        },
1846 115329f1 Diego Biurrun
        [PIX_FMT_YUV420P] = {
1847 ef9f7306 Måns Rullgård
            .convert = rgb555_to_yuv420p
1848 524c6b63 Fabrice Bellard
        },
1849 115329f1 Diego Biurrun
        [PIX_FMT_GRAY8] = {
1850 69572401 Fabrice Bellard
            .convert = rgb555_to_gray
1851
        },
1852 524c6b63 Fabrice Bellard
    },
1853
    [PIX_FMT_RGB565] = {
1854 115329f1 Diego Biurrun
        [PIX_FMT_RGB24] = {
1855 7e7e5940 Fabrice Bellard
            .convert = rgb565_to_rgb24
1856
        },
1857 115329f1 Diego Biurrun
        [PIX_FMT_YUV420P] = {
1858 ef9f7306 Måns Rullgård
            .convert = rgb565_to_yuv420p
1859 524c6b63 Fabrice Bellard
        },
1860 115329f1 Diego Biurrun
        [PIX_FMT_GRAY8] = {
1861 69572401 Fabrice Bellard
            .convert = rgb565_to_gray
1862
        },
1863 524c6b63 Fabrice Bellard
    },
1864
    [PIX_FMT_GRAY8] = {
1865 115329f1 Diego Biurrun
        [PIX_FMT_RGB555] = {
1866 69572401 Fabrice Bellard
            .convert = gray_to_rgb555
1867
        },
1868 115329f1 Diego Biurrun
        [PIX_FMT_RGB565] = {
1869 69572401 Fabrice Bellard
            .convert = gray_to_rgb565
1870
        },
1871 115329f1 Diego Biurrun
        [PIX_FMT_RGB24] = {
1872 ef9f7306 Måns Rullgård
            .convert = gray_to_rgb24
1873 524c6b63 Fabrice Bellard
        },
1874 115329f1 Diego Biurrun
        [PIX_FMT_BGR24] = {
1875 69572401 Fabrice Bellard
            .convert = gray_to_bgr24
1876
        },
1877 115329f1 Diego Biurrun
        [PIX_FMT_RGBA32] = {
1878 69572401 Fabrice Bellard
            .convert = gray_to_rgba32
1879
        },
1880 115329f1 Diego Biurrun
        [PIX_FMT_MONOWHITE] = {
1881 ef9f7306 Måns Rullgård
            .convert = gray_to_monowhite
1882 2a877875 Fabrice Bellard
        },
1883 115329f1 Diego Biurrun
        [PIX_FMT_MONOBLACK] = {
1884 ef9f7306 Måns Rullgård
            .convert = gray_to_monoblack
1885 2a877875 Fabrice Bellard
        },
1886 524c6b63 Fabrice Bellard
    },
1887
    [PIX_FMT_MONOWHITE] = {
1888 115329f1 Diego Biurrun
        [PIX_FMT_GRAY8] = {
1889 ef9f7306 Måns Rullgård
            .convert = monowhite_to_gray
1890 524c6b63 Fabrice Bellard
        },
1891
    },
1892
    [PIX_FMT_MONOBLACK] = {
1893 115329f1 Diego Biurrun
        [PIX_FMT_GRAY8] = {
1894 ef9f7306 Måns Rullgård
            .convert = monoblack_to_gray
1895 524c6b63 Fabrice Bellard
        },
1896
    },
1897 7e6d70d0 Fabrice Bellard
    [PIX_FMT_PAL8] = {
1898 115329f1 Diego Biurrun
        [PIX_FMT_RGB555] = {
1899 7e6d70d0 Fabrice Bellard
            .convert = pal8_to_rgb555
1900
        },
1901 115329f1 Diego Biurrun
        [PIX_FMT_RGB565] = {
1902 7e6d70d0 Fabrice Bellard
            .convert = pal8_to_rgb565
1903
        },
1904 115329f1 Diego Biurrun
        [PIX_FMT_BGR24] = {
1905 7e6d70d0 Fabrice Bellard
            .convert = pal8_to_bgr24
1906
        },
1907 115329f1 Diego Biurrun
        [PIX_FMT_RGB24] = {
1908 7e6d70d0 Fabrice Bellard
            .convert = pal8_to_rgb24
1909
        },
1910 115329f1 Diego Biurrun
        [PIX_FMT_RGBA32] = {
1911 7e6d70d0 Fabrice Bellard
            .convert = pal8_to_rgba32
1912
        },
1913
    },
1914 115329f1 Diego Biurrun
    [PIX_FMT_UYVY411] = {
1915
        [PIX_FMT_YUV411P] = {
1916 f02be79d Roman Shaposhnik
            .convert = uyvy411_to_yuv411p,
1917
        },
1918
    },
1919
1920 524c6b63 Fabrice Bellard
};
1921
1922 75917b88 Drew Hess
int avpicture_alloc(AVPicture *picture,
1923 524c6b63 Fabrice Bellard
                           int pix_fmt, int width, int height)
1924
{
1925 5c91a675 Zdenek Kabelac
    unsigned int size;
1926 524c6b63 Fabrice Bellard
    void *ptr;
1927
1928
    size = avpicture_get_size(pix_fmt, width, height);
1929 0ecca7a4 Michael Niedermayer
    if(size<0)
1930
        goto fail;
1931 524c6b63 Fabrice Bellard
    ptr = av_malloc(size);
1932
    if (!ptr)
1933
        goto fail;
1934
    avpicture_fill(picture, ptr, pix_fmt, width, height);
1935
    return 0;
1936
 fail:
1937
    memset(picture, 0, sizeof(AVPicture));
1938
    return -1;
1939
}
1940
1941 75917b88 Drew Hess
void avpicture_free(AVPicture *picture)
1942 524c6b63 Fabrice Bellard
{
1943 8e1e6f31 Fabrice Bellard
    av_free(picture->data[0]);
1944 524c6b63 Fabrice Bellard
}
1945
1946 c50c0bc8 Fabrice Bellard
/* return true if yuv planar */
1947
static inline int is_yuv_planar(PixFmtInfo *ps)
1948
{
1949
    return (ps->color_type == FF_COLOR_YUV ||
1950 115329f1 Diego Biurrun
            ps->color_type == FF_COLOR_YUV_JPEG) &&
1951 7e7e5940 Fabrice Bellard
        ps->pixel_type == FF_PIXEL_PLANAR;
1952 c50c0bc8 Fabrice Bellard
}
1953
1954 85c242d8 Fabrice Bellard
/* XXX: always use linesize. Return -1 if not supported */
1955
int img_convert(AVPicture *dst, int dst_pix_fmt,
1956 115329f1 Diego Biurrun
                const AVPicture *src, int src_pix_fmt,
1957 524c6b63 Fabrice Bellard
                int src_width, int src_height)
1958 85c242d8 Fabrice Bellard
{
1959 c50c0bc8 Fabrice Bellard
    static int inited;
1960 2a877875 Fabrice Bellard
    int i, ret, dst_width, dst_height, int_pix_fmt;
1961 524c6b63 Fabrice Bellard
    PixFmtInfo *src_pix, *dst_pix;
1962
    ConvertEntry *ce;
1963
    AVPicture tmp1, *tmp = &tmp1;
1964
1965
    if (src_pix_fmt < 0 || src_pix_fmt >= PIX_FMT_NB ||
1966
        dst_pix_fmt < 0 || dst_pix_fmt >= PIX_FMT_NB)
1967
        return -1;
1968
    if (src_width <= 0 || src_height <= 0)
1969
        return 0;
1970 69572401 Fabrice Bellard
1971 c50c0bc8 Fabrice Bellard
    if (!inited) {
1972
        inited = 1;
1973
        img_convert_init();
1974
    }
1975
1976 524c6b63 Fabrice Bellard
    dst_width = src_width;
1977
    dst_height = src_height;
1978 69572401 Fabrice Bellard
1979 524c6b63 Fabrice Bellard
    dst_pix = &pix_fmt_info[dst_pix_fmt];
1980
    src_pix = &pix_fmt_info[src_pix_fmt];
1981
    if (src_pix_fmt == dst_pix_fmt) {
1982 7e7e5940 Fabrice Bellard
        /* no conversion needed: just copy */
1983
        img_copy(dst, src, dst_pix_fmt, dst_width, dst_height);
1984 524c6b63 Fabrice Bellard
        return 0;
1985
    }
1986
1987
    ce = &convert_table[src_pix_fmt][dst_pix_fmt];
1988
    if (ce->convert) {
1989 ebb177dd Todd Kirby
        /* specific conversion routine */
1990 524c6b63 Fabrice Bellard
        ce->convert(dst, src, dst_width, dst_height);
1991
        return 0;
1992
    }
1993
1994
    /* gray to YUV */
1995 c50c0bc8 Fabrice Bellard
    if (is_yuv_planar(dst_pix) &&
1996 b6147995 Fabrice Bellard
        src_pix_fmt == PIX_FMT_GRAY8) {
1997 524c6b63 Fabrice Bellard
        int w, h, y;
1998
        uint8_t *d;
1999
2000 b6147995 Fabrice Bellard
        if (dst_pix->color_type == FF_COLOR_YUV_JPEG) {
2001 7e7e5940 Fabrice Bellard
            img_copy_plane(dst->data[0], dst->linesize[0],
2002 b6147995 Fabrice Bellard
                     src->data[0], src->linesize[0],
2003
                     dst_width, dst_height);
2004
        } else {
2005 c50c0bc8 Fabrice Bellard
            img_apply_table(dst->data[0], dst->linesize[0],
2006
                            src->data[0], src->linesize[0],
2007
                            dst_width, dst_height,
2008
                            y_jpeg_to_ccir);
2009 b6147995 Fabrice Bellard
        }
2010 524c6b63 Fabrice Bellard
        /* fill U and V with 128 */
2011
        w = dst_width;
2012
        h = dst_height;
2013
        w >>= dst_pix->x_chroma_shift;
2014
        h >>= dst_pix->y_chroma_shift;
2015
        for(i = 1; i <= 2; i++) {
2016
            d = dst->data[i];
2017 2a877875 Fabrice Bellard
            for(y = 0; y< h; y++) {
2018
                memset(d, 128, w);
2019 524c6b63 Fabrice Bellard
                d += dst->linesize[i];
2020
            }
2021 b71472eb Philip Gladstone
        }
2022 524c6b63 Fabrice Bellard
        return 0;
2023
    }
2024
2025
    /* YUV to gray */
2026 115329f1 Diego Biurrun
    if (is_yuv_planar(src_pix) &&
2027 b6147995 Fabrice Bellard
        dst_pix_fmt == PIX_FMT_GRAY8) {
2028
        if (src_pix->color_type == FF_COLOR_YUV_JPEG) {
2029 7e7e5940 Fabrice Bellard
            img_copy_plane(dst->data[0], dst->linesize[0],
2030 b6147995 Fabrice Bellard
                     src->data[0], src->linesize[0],
2031
                     dst_width, dst_height);
2032
        } else {
2033 c50c0bc8 Fabrice Bellard
            img_apply_table(dst->data[0], dst->linesize[0],
2034
                            src->data[0], src->linesize[0],
2035
                            dst_width, dst_height,
2036
                            y_ccir_to_jpeg);
2037 b6147995 Fabrice Bellard
        }
2038 524c6b63 Fabrice Bellard
        return 0;
2039
    }
2040
2041 c50c0bc8 Fabrice Bellard
    /* YUV to YUV planar */
2042
    if (is_yuv_planar(dst_pix) && is_yuv_planar(src_pix)) {
2043 e352ff08 Fabrice Bellard
        int x_shift, y_shift, w, h, xy_shift;
2044 115329f1 Diego Biurrun
        void (*resize_func)(uint8_t *dst, int dst_wrap,
2045 e352ff08 Fabrice Bellard
                            const uint8_t *src, int src_wrap,
2046 524c6b63 Fabrice Bellard
                            int width, int height);
2047
2048
        /* compute chroma size of the smallest dimensions */
2049
        w = dst_width;
2050
        h = dst_height;
2051
        if (dst_pix->x_chroma_shift >= src_pix->x_chroma_shift)
2052
            w >>= dst_pix->x_chroma_shift;
2053
        else
2054
            w >>= src_pix->x_chroma_shift;
2055
        if (dst_pix->y_chroma_shift >= src_pix->y_chroma_shift)
2056
            h >>= dst_pix->y_chroma_shift;
2057
        else
2058
            h >>= src_pix->y_chroma_shift;
2059
2060
        x_shift = (dst_pix->x_chroma_shift - src_pix->x_chroma_shift);
2061
        y_shift = (dst_pix->y_chroma_shift - src_pix->y_chroma_shift);
2062 e352ff08 Fabrice Bellard
        xy_shift = ((x_shift & 0xf) << 4) | (y_shift & 0xf);
2063
        /* there must be filters for conversion at least from and to
2064
           YUV444 format */
2065
        switch(xy_shift) {
2066
        case 0x00:
2067 7e7e5940 Fabrice Bellard
            resize_func = img_copy_plane;
2068 e352ff08 Fabrice Bellard
            break;
2069
        case 0x10:
2070
            resize_func = shrink21;
2071
            break;
2072
        case 0x20:
2073
            resize_func = shrink41;
2074
            break;
2075
        case 0x01:
2076
            resize_func = shrink12;
2077
            break;
2078
        case 0x11:
2079 524c6b63 Fabrice Bellard
            resize_func = shrink22;
2080 e352ff08 Fabrice Bellard
            break;
2081
        case 0x22:
2082
            resize_func = shrink44;
2083
            break;
2084
        case 0xf0:
2085
            resize_func = grow21;
2086
            break;
2087
        case 0xe0:
2088
            resize_func = grow41;
2089
            break;
2090
        case 0xff:
2091 524c6b63 Fabrice Bellard
            resize_func = grow22;
2092 e352ff08 Fabrice Bellard
            break;
2093
        case 0xee:
2094
            resize_func = grow44;
2095
            break;
2096
        case 0xf1:
2097 524c6b63 Fabrice Bellard
            resize_func = conv411;
2098 e352ff08 Fabrice Bellard
            break;
2099
        default:
2100 524c6b63 Fabrice Bellard
            /* currently not handled */
2101 e352ff08 Fabrice Bellard
            goto no_chroma_filter;
2102 85c242d8 Fabrice Bellard
        }
2103 524c6b63 Fabrice Bellard
2104 7e7e5940 Fabrice Bellard
        img_copy_plane(dst->data[0], dst->linesize[0],
2105
                       src->data[0], src->linesize[0],
2106
                       dst_width, dst_height);
2107 566986ee Max Krasnyansky
2108 524c6b63 Fabrice Bellard
        for(i = 1;i <= 2; i++)
2109 566986ee Max Krasnyansky
            resize_func(dst->data[i], dst->linesize[i],
2110
                        src->data[i], src->linesize[i],
2111 185fdc54 Michael Niedermayer
                        dst_width>>dst_pix->x_chroma_shift, dst_height>>dst_pix->y_chroma_shift);
2112 c50c0bc8 Fabrice Bellard
        /* if yuv color space conversion is needed, we do it here on
2113
           the destination image */
2114
        if (dst_pix->color_type != src_pix->color_type) {
2115
            const uint8_t *y_table, *c_table;
2116
            if (dst_pix->color_type == FF_COLOR_YUV) {
2117
                y_table = y_jpeg_to_ccir;
2118
                c_table = c_jpeg_to_ccir;
2119
            } else {
2120
                y_table = y_ccir_to_jpeg;
2121
                c_table = c_ccir_to_jpeg;
2122
            }
2123
            img_apply_table(dst->data[0], dst->linesize[0],
2124
                            dst->data[0], dst->linesize[0],
2125
                            dst_width, dst_height,
2126
                            y_table);
2127
2128
            for(i = 1;i <= 2; i++)
2129
                img_apply_table(dst->data[i], dst->linesize[i],
2130
                                dst->data[i], dst->linesize[i],
2131 115329f1 Diego Biurrun
                                dst_width>>dst_pix->x_chroma_shift,
2132 c50c0bc8 Fabrice Bellard
                                dst_height>>dst_pix->y_chroma_shift,
2133
                                c_table);
2134
        }
2135
        return 0;
2136 85c242d8 Fabrice Bellard
    }
2137 e352ff08 Fabrice Bellard
 no_chroma_filter:
2138 524c6b63 Fabrice Bellard
2139 2a877875 Fabrice Bellard
    /* try to use an intermediate format */
2140 c50c0bc8 Fabrice Bellard
    if (src_pix_fmt == PIX_FMT_YUV422 ||
2141
        dst_pix_fmt == PIX_FMT_YUV422) {
2142
        /* specific case: convert to YUV422P first */
2143
        int_pix_fmt = PIX_FMT_YUV422P;
2144 ebb177dd Todd Kirby
    } else if (src_pix_fmt == PIX_FMT_UYVY422 ||
2145
        dst_pix_fmt == PIX_FMT_UYVY422) {
2146
        /* specific case: convert to YUV422P first */
2147
        int_pix_fmt = PIX_FMT_YUV422P;
2148 f02be79d Roman Shaposhnik
    } else if (src_pix_fmt == PIX_FMT_UYVY411 ||
2149
        dst_pix_fmt == PIX_FMT_UYVY411) {
2150
        /* specific case: convert to YUV411P first */
2151
        int_pix_fmt = PIX_FMT_YUV411P;
2152 c50c0bc8 Fabrice Bellard
    } else if ((src_pix->color_type == FF_COLOR_GRAY &&
2153 115329f1 Diego Biurrun
                src_pix_fmt != PIX_FMT_GRAY8) ||
2154 c50c0bc8 Fabrice Bellard
               (dst_pix->color_type == FF_COLOR_GRAY &&
2155
                dst_pix_fmt != PIX_FMT_GRAY8)) {
2156
        /* gray8 is the normalized format */
2157 2a877875 Fabrice Bellard
        int_pix_fmt = PIX_FMT_GRAY8;
2158 115329f1 Diego Biurrun
    } else if ((is_yuv_planar(src_pix) &&
2159 c50c0bc8 Fabrice Bellard
                src_pix_fmt != PIX_FMT_YUV444P &&
2160
                src_pix_fmt != PIX_FMT_YUVJ444P)) {
2161
        /* yuv444 is the normalized format */
2162
        if (src_pix->color_type == FF_COLOR_YUV_JPEG)
2163
            int_pix_fmt = PIX_FMT_YUVJ444P;
2164
        else
2165
            int_pix_fmt = PIX_FMT_YUV444P;
2166 115329f1 Diego Biurrun
    } else if ((is_yuv_planar(dst_pix) &&
2167 c50c0bc8 Fabrice Bellard
                dst_pix_fmt != PIX_FMT_YUV444P &&
2168
                dst_pix_fmt != PIX_FMT_YUVJ444P)) {
2169
        /* yuv444 is the normalized format */
2170
        if (dst_pix->color_type == FF_COLOR_YUV_JPEG)
2171
            int_pix_fmt = PIX_FMT_YUVJ444P;
2172
        else
2173
            int_pix_fmt = PIX_FMT_YUV444P;
2174 2a877875 Fabrice Bellard
    } else {
2175 c50c0bc8 Fabrice Bellard
        /* the two formats are rgb or gray8 or yuv[j]444p */
2176
        if (src_pix->is_alpha && dst_pix->is_alpha)
2177
            int_pix_fmt = PIX_FMT_RGBA32;
2178
        else
2179
            int_pix_fmt = PIX_FMT_RGB24;
2180 2a877875 Fabrice Bellard
    }
2181
    if (avpicture_alloc(tmp, int_pix_fmt, dst_width, dst_height) < 0)
2182
        return -1;
2183
    ret = -1;
2184
    if (img_convert(tmp, int_pix_fmt,
2185
                    src, src_pix_fmt, src_width, src_height) < 0)
2186
        goto fail1;
2187
    if (img_convert(dst, dst_pix_fmt,
2188
                    tmp, int_pix_fmt, dst_width, dst_height) < 0)
2189
        goto fail1;
2190
    ret = 0;
2191
 fail1:
2192
    avpicture_free(tmp);
2193
    return ret;
2194 85c242d8 Fabrice Bellard
}
2195
2196 0469baf1 Fabrice Bellard
/* NOTE: we scan all the pixels to have an exact information */
2197 da64ecc3 Drew Hess
static int get_alpha_info_pal8(const AVPicture *src, int width, int height)
2198 0469baf1 Fabrice Bellard
{
2199
    const unsigned char *p;
2200
    int src_wrap, ret, x, y;
2201
    unsigned int a;
2202
    uint32_t *palette = (uint32_t *)src->data[1];
2203 115329f1 Diego Biurrun
2204 0469baf1 Fabrice Bellard
    p = src->data[0];
2205
    src_wrap = src->linesize[0] - width;
2206
    ret = 0;
2207
    for(y=0;y<height;y++) {
2208
        for(x=0;x<width;x++) {
2209
            a = palette[p[0]] >> 24;
2210
            if (a == 0x00) {
2211
                ret |= FF_ALPHA_TRANSP;
2212
            } else if (a != 0xff) {
2213
                ret |= FF_ALPHA_SEMI_TRANSP;
2214
            }
2215
            p++;
2216
        }
2217
        p += src_wrap;
2218
    }
2219
    return ret;
2220
}
2221
2222
/**
2223
 * Tell if an image really has transparent alpha values.
2224
 * @return ored mask of FF_ALPHA_xxx constants
2225
 */
2226 da64ecc3 Drew Hess
int img_get_alpha_info(const AVPicture *src,
2227 bb270c08 Diego Biurrun
                       int pix_fmt, int width, int height)
2228 0469baf1 Fabrice Bellard
{
2229
    PixFmtInfo *pf = &pix_fmt_info[pix_fmt];
2230
    int ret;
2231
2232
    pf = &pix_fmt_info[pix_fmt];
2233
    /* no alpha can be represented in format */
2234
    if (!pf->is_alpha)
2235
        return 0;
2236
    switch(pix_fmt) {
2237
    case PIX_FMT_RGBA32:
2238
        ret = get_alpha_info_rgba32(src, width, height);
2239
        break;
2240
    case PIX_FMT_RGB555:
2241
        ret = get_alpha_info_rgb555(src, width, height);
2242
        break;
2243
    case PIX_FMT_PAL8:
2244
        ret = get_alpha_info_pal8(src, width, height);
2245
        break;
2246
    default:
2247
        /* we do not know, so everything is indicated */
2248
        ret = FF_ALPHA_TRANSP | FF_ALPHA_SEMI_TRANSP;
2249
        break;
2250
    }
2251
    return ret;
2252
}
2253 5981f4e6 Fred
2254
#ifdef HAVE_MMX
2255
#define DEINT_INPLACE_LINE_LUM \
2256
                    movd_m2r(lum_m4[0],mm0);\
2257
                    movd_m2r(lum_m3[0],mm1);\
2258
                    movd_m2r(lum_m2[0],mm2);\
2259
                    movd_m2r(lum_m1[0],mm3);\
2260
                    movd_m2r(lum[0],mm4);\
2261
                    punpcklbw_r2r(mm7,mm0);\
2262
                    movd_r2m(mm2,lum_m4[0]);\
2263
                    punpcklbw_r2r(mm7,mm1);\
2264
                    punpcklbw_r2r(mm7,mm2);\
2265
                    punpcklbw_r2r(mm7,mm3);\
2266
                    punpcklbw_r2r(mm7,mm4);\
2267
                    paddw_r2r(mm3,mm1);\
2268
                    psllw_i2r(1,mm2);\
2269
                    paddw_r2r(mm4,mm0);\
2270
                    psllw_i2r(2,mm1);\
2271
                    paddw_r2r(mm6,mm2);\
2272
                    paddw_r2r(mm2,mm1);\
2273
                    psubusw_r2r(mm0,mm1);\
2274
                    psrlw_i2r(3,mm1);\
2275
                    packuswb_r2r(mm7,mm1);\
2276
                    movd_r2m(mm1,lum_m2[0]);
2277
2278
#define DEINT_LINE_LUM \
2279
                    movd_m2r(lum_m4[0],mm0);\
2280
                    movd_m2r(lum_m3[0],mm1);\
2281
                    movd_m2r(lum_m2[0],mm2);\
2282
                    movd_m2r(lum_m1[0],mm3);\
2283
                    movd_m2r(lum[0],mm4);\
2284
                    punpcklbw_r2r(mm7,mm0);\
2285
                    punpcklbw_r2r(mm7,mm1);\
2286
                    punpcklbw_r2r(mm7,mm2);\
2287
                    punpcklbw_r2r(mm7,mm3);\
2288
                    punpcklbw_r2r(mm7,mm4);\
2289
                    paddw_r2r(mm3,mm1);\
2290
                    psllw_i2r(1,mm2);\
2291
                    paddw_r2r(mm4,mm0);\
2292
                    psllw_i2r(2,mm1);\
2293
                    paddw_r2r(mm6,mm2);\
2294
                    paddw_r2r(mm2,mm1);\
2295
                    psubusw_r2r(mm0,mm1);\
2296
                    psrlw_i2r(3,mm1);\
2297
                    packuswb_r2r(mm7,mm1);\
2298
                    movd_r2m(mm1,dst[0]);
2299
#endif
2300
2301 85c242d8 Fabrice Bellard
/* filter parameters: [-1 4 2 4 -1] // 8 */
2302 115329f1 Diego Biurrun
static void deinterlace_line(uint8_t *dst,
2303 bb270c08 Diego Biurrun
                             const uint8_t *lum_m4, const uint8_t *lum_m3,
2304
                             const uint8_t *lum_m2, const uint8_t *lum_m1,
2305
                             const uint8_t *lum,
2306
                             int size)
2307 85c242d8 Fabrice Bellard
{
2308 5981f4e6 Fred
#ifndef HAVE_MMX
2309 0c1a9eda Zdenek Kabelac
    uint8_t *cm = cropTbl + MAX_NEG_CROP;
2310 85c242d8 Fabrice Bellard
    int sum;
2311
2312
    for(;size > 0;size--) {
2313 5981f4e6 Fred
        sum = -lum_m4[0];
2314
        sum += lum_m3[0] << 2;
2315
        sum += lum_m2[0] << 1;
2316
        sum += lum_m1[0] << 2;
2317
        sum += -lum[0];
2318 85c242d8 Fabrice Bellard
        dst[0] = cm[(sum + 4) >> 3];
2319 5981f4e6 Fred
        lum_m4++;
2320
        lum_m3++;
2321
        lum_m2++;
2322
        lum_m1++;
2323
        lum++;
2324 85c242d8 Fabrice Bellard
        dst++;
2325
    }
2326 5981f4e6 Fred
#else
2327
2328 782c5984 Michael Niedermayer
    {
2329
        mmx_t rounder;
2330
        rounder.uw[0]=4;
2331
        rounder.uw[1]=4;
2332
        rounder.uw[2]=4;
2333
        rounder.uw[3]=4;
2334
        pxor_r2r(mm7,mm7);
2335
        movq_m2r(rounder,mm6);
2336
    }
2337 5981f4e6 Fred
    for (;size > 3; size-=4) {
2338
        DEINT_LINE_LUM
2339
        lum_m4+=4;
2340
        lum_m3+=4;
2341
        lum_m2+=4;
2342
        lum_m1+=4;
2343
        lum+=4;
2344
        dst+=4;
2345
    }
2346
#endif
2347
}
2348 0c1a9eda Zdenek Kabelac
static void deinterlace_line_inplace(uint8_t *lum_m4, uint8_t *lum_m3, uint8_t *lum_m2, uint8_t *lum_m1, uint8_t *lum,
2349 5981f4e6 Fred
                             int size)
2350
{
2351
#ifndef HAVE_MMX
2352 0c1a9eda Zdenek Kabelac
    uint8_t *cm = cropTbl + MAX_NEG_CROP;
2353 5981f4e6 Fred
    int sum;
2354
2355
    for(;size > 0;size--) {
2356
        sum = -lum_m4[0];
2357
        sum += lum_m3[0] << 2;
2358
        sum += lum_m2[0] << 1;
2359
        lum_m4[0]=lum_m2[0];
2360
        sum += lum_m1[0] << 2;
2361
        sum += -lum[0];
2362
        lum_m2[0] = cm[(sum + 4) >> 3];
2363
        lum_m4++;
2364
        lum_m3++;
2365
        lum_m2++;
2366
        lum_m1++;
2367
        lum++;
2368
    }
2369
#else
2370
2371 782c5984 Michael Niedermayer
    {
2372
        mmx_t rounder;
2373
        rounder.uw[0]=4;
2374
        rounder.uw[1]=4;
2375
        rounder.uw[2]=4;
2376
        rounder.uw[3]=4;
2377
        pxor_r2r(mm7,mm7);
2378
        movq_m2r(rounder,mm6);
2379
    }
2380 5981f4e6 Fred
    for (;size > 3; size-=4) {
2381
        DEINT_INPLACE_LINE_LUM
2382
        lum_m4+=4;
2383
        lum_m3+=4;
2384
        lum_m2+=4;
2385
        lum_m1+=4;
2386
        lum+=4;
2387
    }
2388
#endif
2389 85c242d8 Fabrice Bellard
}
2390
2391
/* deinterlacing : 2 temporal taps, 3 spatial taps linear filter. The
2392
   top field is copied as is, but the bottom field is deinterlaced
2393
   against the top field. */
2394 0c1a9eda Zdenek Kabelac
static void deinterlace_bottom_field(uint8_t *dst, int dst_wrap,
2395 da64ecc3 Drew Hess
                                    const uint8_t *src1, int src_wrap,
2396 5981f4e6 Fred
                                    int width, int height)
2397 85c242d8 Fabrice Bellard
{
2398 da64ecc3 Drew Hess
    const uint8_t *src_m2, *src_m1, *src_0, *src_p1, *src_p2;
2399 5981f4e6 Fred
    int y;
2400
2401
    src_m2 = src1;
2402
    src_m1 = src1;
2403
    src_0=&src_m1[src_wrap];
2404
    src_p1=&src_0[src_wrap];
2405
    src_p2=&src_p1[src_wrap];
2406
    for(y=0;y<(height-2);y+=2) {
2407
        memcpy(dst,src_m1,width);
2408 85c242d8 Fabrice Bellard
        dst += dst_wrap;
2409 5981f4e6 Fred
        deinterlace_line(dst,src_m2,src_m1,src_0,src_p1,src_p2,width);
2410
        src_m2 = src_0;
2411
        src_m1 = src_p1;
2412
        src_0 = src_p2;
2413
        src_p1 += 2*src_wrap;
2414
        src_p2 += 2*src_wrap;
2415 85c242d8 Fabrice Bellard
        dst += dst_wrap;
2416
    }
2417 5981f4e6 Fred
    memcpy(dst,src_m1,width);
2418
    dst += dst_wrap;
2419
    /* do last line */
2420
    deinterlace_line(dst,src_m2,src_m1,src_0,src_0,src_0,width);
2421
}
2422
2423 0c1a9eda Zdenek Kabelac
static void deinterlace_bottom_field_inplace(uint8_t *src1, int src_wrap,
2424 bb270c08 Diego Biurrun
                                             int width, int height)
2425 5981f4e6 Fred
{
2426 0c1a9eda Zdenek Kabelac
    uint8_t *src_m1, *src_0, *src_p1, *src_p2;
2427 5981f4e6 Fred
    int y;
2428 0c1a9eda Zdenek Kabelac
    uint8_t *buf;
2429
    buf = (uint8_t*)av_malloc(width);
2430 5981f4e6 Fred
2431
    src_m1 = src1;
2432
    memcpy(buf,src_m1,width);
2433
    src_0=&src_m1[src_wrap];
2434
    src_p1=&src_0[src_wrap];
2435
    src_p2=&src_p1[src_wrap];
2436
    for(y=0;y<(height-2);y+=2) {
2437
        deinterlace_line_inplace(buf,src_m1,src_0,src_p1,src_p2,width);
2438
        src_m1 = src_p1;
2439
        src_0 = src_p2;
2440
        src_p1 += 2*src_wrap;
2441
        src_p2 += 2*src_wrap;
2442
    }
2443
    /* do last line */
2444
    deinterlace_line_inplace(buf,src_m1,src_0,src_0,src_0,width);
2445 6000abfa Fabrice Bellard
    av_free(buf);
2446 85c242d8 Fabrice Bellard
}
2447
2448
2449 5981f4e6 Fred
/* deinterlace - if not supported return -1 */
2450 da64ecc3 Drew Hess
int avpicture_deinterlace(AVPicture *dst, const AVPicture *src,
2451 de6d9b64 Fabrice Bellard
                          int pix_fmt, int width, int height)
2452
{
2453 85c242d8 Fabrice Bellard
    int i;
2454
2455
    if (pix_fmt != PIX_FMT_YUV420P &&
2456
        pix_fmt != PIX_FMT_YUV422P &&
2457 47017dd8 Roman Shaposhnik
        pix_fmt != PIX_FMT_YUV444P &&
2458 bb270c08 Diego Biurrun
        pix_fmt != PIX_FMT_YUV411P)
2459 85c242d8 Fabrice Bellard
        return -1;
2460 5981f4e6 Fred
    if ((width & 3) != 0 || (height & 3) != 0)
2461 85c242d8 Fabrice Bellard
        return -1;
2462 5981f4e6 Fred
2463 85c242d8 Fabrice Bellard
    for(i=0;i<3;i++) {
2464
        if (i == 1) {
2465
            switch(pix_fmt) {
2466
            case PIX_FMT_YUV420P:
2467
                width >>= 1;
2468
                height >>= 1;
2469
                break;
2470
            case PIX_FMT_YUV422P:
2471
                width >>= 1;
2472
                break;
2473 47017dd8 Roman Shaposhnik
            case PIX_FMT_YUV411P:
2474
                width >>= 2;
2475
                break;
2476 85c242d8 Fabrice Bellard
            default:
2477
                break;
2478
            }
2479
        }
2480 5981f4e6 Fred
        if (src == dst) {
2481 da64ecc3 Drew Hess
            deinterlace_bottom_field_inplace(dst->data[i], dst->linesize[i],
2482 85c242d8 Fabrice Bellard
                                 width, height);
2483 5981f4e6 Fred
        } else {
2484
            deinterlace_bottom_field(dst->data[i],dst->linesize[i],
2485
                                        src->data[i], src->linesize[i],
2486
                                        width, height);
2487
        }
2488 de6d9b64 Fabrice Bellard
    }
2489 5981f4e6 Fred
#ifdef HAVE_MMX
2490
    emms();
2491
#endif
2492 85c242d8 Fabrice Bellard
    return 0;
2493 de6d9b64 Fabrice Bellard
}
2494 cd4af68a Zdenek Kabelac
2495
#undef FIX