Statistics
| Branch: | Revision:

ffmpeg / libavcodec / imgconvert.c @ 8a01fc47

History | View | Annotate | Download (64.8 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
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  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 ef9f7306 Måns Rullgård
        .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 ef9f7306 Måns Rullgård
        .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 ef9f7306 Måns Rullgård
        .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
        .x_chroma_shift = 1, .y_chroma_shift = 1, 
133
    },
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
        .x_chroma_shift = 1, .y_chroma_shift = 0, 
141
    },
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
        .x_chroma_shift = 0, .y_chroma_shift = 0, 
149
    },
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
    int i; 
257
    
258
    for (i=0; i < PIX_FMT_NB; i++)
259
         if (!strcmp(pix_fmt_info[i].name, name))
260
             break;
261
    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 da64ecc3 Drew Hess
                   int pix_fmt, int width, int height)
267 2a877875 Fabrice Bellard
{
268 4c7e8619 Fabrice Bellard
    int size, w2, h2, size2;
269
    PixFmtInfo *pinfo;
270
    
271
    pinfo = &pix_fmt_info[pix_fmt];
272 2a877875 Fabrice Bellard
    size = width * height;
273
    switch(pix_fmt) {
274
    case PIX_FMT_YUV420P:
275 4c7e8619 Fabrice Bellard
    case PIX_FMT_YUV422P:
276
    case PIX_FMT_YUV444P:
277
    case PIX_FMT_YUV410P:
278
    case PIX_FMT_YUV411P:
279 c50c0bc8 Fabrice Bellard
    case PIX_FMT_YUVJ420P:
280
    case PIX_FMT_YUVJ422P:
281
    case PIX_FMT_YUVJ444P:
282 4c7e8619 Fabrice Bellard
        w2 = (width + (1 << pinfo->x_chroma_shift) - 1) >> pinfo->x_chroma_shift;
283
        h2 = (height + (1 << pinfo->y_chroma_shift) - 1) >> pinfo->y_chroma_shift;
284
        size2 = w2 * h2;
285 2a877875 Fabrice Bellard
        picture->data[0] = ptr;
286
        picture->data[1] = picture->data[0] + size;
287 4c7e8619 Fabrice Bellard
        picture->data[2] = picture->data[1] + size2;
288 2a877875 Fabrice Bellard
        picture->linesize[0] = width;
289 4c7e8619 Fabrice Bellard
        picture->linesize[1] = w2;
290
        picture->linesize[2] = w2;
291
        return size + 2 * size2;
292 2a877875 Fabrice Bellard
    case PIX_FMT_RGB24:
293
    case PIX_FMT_BGR24:
294
        picture->data[0] = ptr;
295
        picture->data[1] = NULL;
296
        picture->data[2] = NULL;
297
        picture->linesize[0] = width * 3;
298
        return size * 3;
299
    case PIX_FMT_RGBA32:
300
        picture->data[0] = ptr;
301
        picture->data[1] = NULL;
302
        picture->data[2] = NULL;
303
        picture->linesize[0] = width * 4;
304
        return size * 4;
305
    case PIX_FMT_RGB555:
306
    case PIX_FMT_RGB565:
307
    case PIX_FMT_YUV422:
308
        picture->data[0] = ptr;
309
        picture->data[1] = NULL;
310
        picture->data[2] = NULL;
311
        picture->linesize[0] = width * 2;
312
        return size * 2;
313 ebb177dd Todd Kirby
    case PIX_FMT_UYVY422:
314
        picture->data[0] = ptr;
315
        picture->data[1] = NULL;
316
        picture->data[2] = NULL;
317
        picture->linesize[0] = width * 2;
318
        return size * 2;
319 f02be79d Roman Shaposhnik
    case PIX_FMT_UYVY411:
320
        picture->data[0] = ptr;
321
        picture->data[1] = NULL;
322
        picture->data[2] = NULL;
323
        picture->linesize[0] = width + width/2;
324
        return size + size/2;
325 2a877875 Fabrice Bellard
    case PIX_FMT_GRAY8:
326
        picture->data[0] = ptr;
327
        picture->data[1] = NULL;
328
        picture->data[2] = NULL;
329
        picture->linesize[0] = width;
330
        return size;
331
    case PIX_FMT_MONOWHITE:
332
    case PIX_FMT_MONOBLACK:
333
        picture->data[0] = ptr;
334
        picture->data[1] = NULL;
335
        picture->data[2] = NULL;
336
        picture->linesize[0] = (width + 7) >> 3;
337
        return picture->linesize[0] * height;
338 7e6d70d0 Fabrice Bellard
    case PIX_FMT_PAL8:
339
        size2 = (size + 3) & ~3;
340
        picture->data[0] = ptr;
341
        picture->data[1] = ptr + size2; /* palette is stored here as 256 32 bit words */
342
        picture->data[2] = NULL;
343
        picture->linesize[0] = width;
344
        picture->linesize[1] = 4;
345
        return size2 + 256 * 4;
346 2a877875 Fabrice Bellard
    default:
347
        picture->data[0] = NULL;
348
        picture->data[1] = NULL;
349
        picture->data[2] = NULL;
350 7e6d70d0 Fabrice Bellard
        picture->data[3] = NULL;
351 2a877875 Fabrice Bellard
        return -1;
352
    }
353
}
354
355 da64ecc3 Drew Hess
int avpicture_layout(const AVPicture* src, int pix_fmt, int width, int height,
356 63167088 Roman Shaposhnik
                     unsigned char *dest, int dest_size)
357
{
358
    PixFmtInfo* pf = &pix_fmt_info[pix_fmt];
359
    int i, j, w, h, data_planes;
360 da64ecc3 Drew Hess
    const unsigned char* s; 
361 63167088 Roman Shaposhnik
    int size = avpicture_get_size(pix_fmt, width, height);
362
363
    if (size > dest_size)
364
        return -1;
365
366 affd55a1 Roman Shaposhnik
    if (pf->pixel_type == FF_PIXEL_PACKED || pf->pixel_type == FF_PIXEL_PALETTE) {
367 ebb177dd Todd Kirby
        if (pix_fmt == PIX_FMT_YUV422 || 
368
            pix_fmt == PIX_FMT_UYVY422 || 
369
            pix_fmt == PIX_FMT_RGB565 ||
370
            pix_fmt == PIX_FMT_RGB555)
371
            w = width * 2;
372 f02be79d Roman Shaposhnik
        else if (pix_fmt == PIX_FMT_UYVY411)
373
          w = width + width/2;
374 affd55a1 Roman Shaposhnik
        else if (pix_fmt == PIX_FMT_PAL8)
375
          w = width;
376 63167088 Roman Shaposhnik
        else
377
          w = width * (pf->depth * pf->nb_channels / 8);
378 affd55a1 Roman Shaposhnik
          
379 63167088 Roman Shaposhnik
        data_planes = 1;
380
        h = height;
381
    } else {
382
        data_planes = pf->nb_channels;
383 ed2cea42 Wolfram Gloger
        w = (width*pf->depth + 7)/8;
384 63167088 Roman Shaposhnik
        h = height;
385
    }
386
    
387
    for (i=0; i<data_planes; i++) {
388
         if (i == 1) {
389
             w = width >> pf->x_chroma_shift;
390
             h = height >> pf->y_chroma_shift;
391
         }
392
         s = src->data[i];
393
         for(j=0; j<h; j++) {
394
             memcpy(dest, s, w);
395
             dest += w;
396
             s += src->linesize[i];
397
         }
398
    }
399 affd55a1 Roman Shaposhnik
    
400
    if (pf->pixel_type == FF_PIXEL_PALETTE)
401
        memcpy((unsigned char *)(((size_t)dest + 3) & ~3), src->data[1], 256 * 4);
402
    
403 63167088 Roman Shaposhnik
    return size;
404
}
405
406 2a877875 Fabrice Bellard
int avpicture_get_size(int pix_fmt, int width, int height)
407
{
408
    AVPicture dummy_pict;
409
    return avpicture_fill(&dummy_pict, NULL, pix_fmt, width, height);
410
}
411
412 b6147995 Fabrice Bellard
/**
413
 * compute the loss when converting from a pixel format to another 
414
 */
415
int avcodec_get_pix_fmt_loss(int dst_pix_fmt, int src_pix_fmt,
416
                             int has_alpha)
417
{
418
    const PixFmtInfo *pf, *ps;
419
    int loss;
420
421
    ps = &pix_fmt_info[src_pix_fmt];
422
    pf = &pix_fmt_info[dst_pix_fmt];
423
424
    /* compute loss */
425
    loss = 0;
426
    pf = &pix_fmt_info[dst_pix_fmt];
427 0a9ad8d1 Fabrice Bellard
    if (pf->depth < ps->depth ||
428
        (dst_pix_fmt == PIX_FMT_RGB555 && src_pix_fmt == PIX_FMT_RGB565))
429 b6147995 Fabrice Bellard
        loss |= FF_LOSS_DEPTH;
430 0a9ad8d1 Fabrice Bellard
    if (pf->x_chroma_shift > ps->x_chroma_shift ||
431
        pf->y_chroma_shift > ps->y_chroma_shift)
432 b6147995 Fabrice Bellard
        loss |= FF_LOSS_RESOLUTION;
433
    switch(pf->color_type) {
434
    case FF_COLOR_RGB:
435
        if (ps->color_type != FF_COLOR_RGB &&
436
            ps->color_type != FF_COLOR_GRAY)
437
            loss |= FF_LOSS_COLORSPACE;
438
        break;
439
    case FF_COLOR_GRAY:
440
        if (ps->color_type != FF_COLOR_GRAY)
441
            loss |= FF_LOSS_COLORSPACE;
442
        break;
443
    case FF_COLOR_YUV:
444
        if (ps->color_type != FF_COLOR_YUV)
445
            loss |= FF_LOSS_COLORSPACE;
446
        break;
447
    case FF_COLOR_YUV_JPEG:
448
        if (ps->color_type != FF_COLOR_YUV_JPEG &&
449 0a9ad8d1 Fabrice Bellard
            ps->color_type != FF_COLOR_YUV && 
450
            ps->color_type != FF_COLOR_GRAY)
451 b6147995 Fabrice Bellard
            loss |= FF_LOSS_COLORSPACE;
452
        break;
453
    default:
454
        /* fail safe test */
455
        if (ps->color_type != pf->color_type)
456
            loss |= FF_LOSS_COLORSPACE;
457
        break;
458
    }
459
    if (pf->color_type == FF_COLOR_GRAY &&
460
        ps->color_type != FF_COLOR_GRAY)
461
        loss |= FF_LOSS_CHROMA;
462
    if (!pf->is_alpha && (ps->is_alpha && has_alpha))
463
        loss |= FF_LOSS_ALPHA;
464 7e7e5940 Fabrice Bellard
    if (pf->pixel_type == FF_PIXEL_PALETTE && 
465
        (ps->pixel_type != FF_PIXEL_PALETTE && ps->color_type != FF_COLOR_GRAY))
466 b6147995 Fabrice Bellard
        loss |= FF_LOSS_COLORQUANT;
467
    return loss;
468
}
469
470
static int avg_bits_per_pixel(int pix_fmt)
471
{
472
    int bits;
473
    const PixFmtInfo *pf;
474
475
    pf = &pix_fmt_info[pix_fmt];
476 7e7e5940 Fabrice Bellard
    switch(pf->pixel_type) {
477
    case FF_PIXEL_PACKED:
478 b6147995 Fabrice Bellard
        switch(pix_fmt) {
479 7e7e5940 Fabrice Bellard
        case PIX_FMT_YUV422:
480 ebb177dd Todd Kirby
        case PIX_FMT_UYVY422:
481 b6147995 Fabrice Bellard
        case PIX_FMT_RGB565:
482
        case PIX_FMT_RGB555:
483
            bits = 16;
484
            break;
485 f02be79d Roman Shaposhnik
        case PIX_FMT_UYVY411:
486
            bits = 12;
487
            break;
488 b6147995 Fabrice Bellard
        default:
489 7e7e5940 Fabrice Bellard
            bits = pf->depth * pf->nb_channels;
490 b6147995 Fabrice Bellard
            break;
491
        }
492 7e7e5940 Fabrice Bellard
        break;
493
    case FF_PIXEL_PLANAR:
494
        if (pf->x_chroma_shift == 0 && pf->y_chroma_shift == 0) {
495
            bits = pf->depth * pf->nb_channels;
496
        } else {
497
            bits = pf->depth + ((2 * pf->depth) >> 
498
                                (pf->x_chroma_shift + pf->y_chroma_shift));
499
        }
500
        break;
501
    case FF_PIXEL_PALETTE:
502
        bits = 8;
503
        break;
504
    default:
505
        bits = -1;
506
        break;
507 b6147995 Fabrice Bellard
    }
508
    return bits;
509
}
510
511
static int avcodec_find_best_pix_fmt1(int pix_fmt_mask, 
512
                                      int src_pix_fmt,
513
                                      int has_alpha,
514
                                      int loss_mask)
515
{
516
    int dist, i, loss, min_dist, dst_pix_fmt;
517
518
    /* find exact color match with smallest size */
519
    dst_pix_fmt = -1;
520
    min_dist = 0x7fffffff;
521
    for(i = 0;i < PIX_FMT_NB; i++) {
522
        if (pix_fmt_mask & (1 << i)) {
523
            loss = avcodec_get_pix_fmt_loss(i, src_pix_fmt, has_alpha) & loss_mask;
524
            if (loss == 0) {
525
                dist = avg_bits_per_pixel(i);
526
                if (dist < min_dist) {
527
                    min_dist = dist;
528
                    dst_pix_fmt = i;
529
                }
530
            }
531
        }
532
    }
533
    return dst_pix_fmt;
534
}
535
536
/** 
537
 * find best pixel format to convert to. Return -1 if none found 
538
 */
539
int avcodec_find_best_pix_fmt(int pix_fmt_mask, int src_pix_fmt,
540
                              int has_alpha, int *loss_ptr)
541
{
542
    int dst_pix_fmt, loss_mask, i;
543
    static const int loss_mask_order[] = {
544
        ~0, /* no loss first */
545
        ~FF_LOSS_ALPHA,
546
        ~FF_LOSS_RESOLUTION,
547
        ~(FF_LOSS_COLORSPACE | FF_LOSS_RESOLUTION),
548
        ~FF_LOSS_COLORQUANT,
549
        ~FF_LOSS_DEPTH,
550
        0,
551
    };
552
553
    /* try with successive loss */
554
    i = 0;
555
    for(;;) {
556
        loss_mask = loss_mask_order[i++];
557
        dst_pix_fmt = avcodec_find_best_pix_fmt1(pix_fmt_mask, src_pix_fmt, 
558
                                                 has_alpha, loss_mask);
559
        if (dst_pix_fmt >= 0)
560
            goto found;
561
        if (loss_mask == 0)
562
            break;
563
    }
564
    return -1;
565
 found:
566
    if (loss_ptr)
567
        *loss_ptr = avcodec_get_pix_fmt_loss(dst_pix_fmt, src_pix_fmt, has_alpha);
568
    return dst_pix_fmt;
569
}
570
571 7e7e5940 Fabrice Bellard
static void img_copy_plane(uint8_t *dst, int dst_wrap, 
572 e352ff08 Fabrice Bellard
                           const uint8_t *src, int src_wrap,
573
                           int width, int height)
574 7e7e5940 Fabrice Bellard
{
575
    for(;height > 0; height--) {
576
        memcpy(dst, src, width);
577
        dst += dst_wrap;
578
        src += src_wrap;
579
    }
580
}
581
582 0469baf1 Fabrice Bellard
/**
583
 * Copy image 'src' to 'dst'.
584
 */
585 da64ecc3 Drew Hess
void img_copy(AVPicture *dst, const AVPicture *src,
586 7e7e5940 Fabrice Bellard
              int pix_fmt, int width, int height)
587
{
588
    int bwidth, bits, i;
589
    PixFmtInfo *pf = &pix_fmt_info[pix_fmt];
590
    
591
    pf = &pix_fmt_info[pix_fmt];
592
    switch(pf->pixel_type) {
593
    case FF_PIXEL_PACKED:
594
        switch(pix_fmt) {
595
        case PIX_FMT_YUV422:
596 ebb177dd Todd Kirby
        case PIX_FMT_UYVY422:
597 7e7e5940 Fabrice Bellard
        case PIX_FMT_RGB565:
598
        case PIX_FMT_RGB555:
599
            bits = 16;
600
            break;
601 f02be79d Roman Shaposhnik
        case PIX_FMT_UYVY411:
602
            bits = 12;
603
            break;
604 7e7e5940 Fabrice Bellard
        default:
605
            bits = pf->depth * pf->nb_channels;
606
            break;
607
        }
608
        bwidth = (width * bits + 7) >> 3;
609
        img_copy_plane(dst->data[0], dst->linesize[0],
610
                       src->data[0], src->linesize[0],
611
                       bwidth, height);
612
        break;
613
    case FF_PIXEL_PLANAR:
614
        for(i = 0; i < pf->nb_channels; i++) {
615
            int w, h;
616
            w = width;
617
            h = height;
618
            if (i == 1 || i == 2) {
619
                w >>= pf->x_chroma_shift;
620
                h >>= pf->y_chroma_shift;
621
            }
622
            bwidth = (w * pf->depth + 7) >> 3;
623
            img_copy_plane(dst->data[i], dst->linesize[i],
624
                           src->data[i], src->linesize[i],
625
                           bwidth, h);
626
        }
627
        break;
628
    case FF_PIXEL_PALETTE:
629
        img_copy_plane(dst->data[0], dst->linesize[0],
630
                       src->data[0], src->linesize[0],
631
                       width, height);
632
        /* copy the palette */
633
        img_copy_plane(dst->data[1], dst->linesize[1],
634
                       src->data[1], src->linesize[1],
635
                       4, 256);
636
        break;
637
    }
638
}
639 2a877875 Fabrice Bellard
640 de6d9b64 Fabrice Bellard
/* XXX: totally non optimized */
641
642 da64ecc3 Drew Hess
static void yuv422_to_yuv420p(AVPicture *dst, const AVPicture *src,
643 524c6b63 Fabrice Bellard
                              int width, int height)
644 de6d9b64 Fabrice Bellard
{
645 c50c0bc8 Fabrice Bellard
    const uint8_t *p, *p1;
646
    uint8_t *lum, *cr, *cb, *lum1, *cr1, *cb1;
647 d4f5d74a Garrick Meeker
    int w;
648 524c6b63 Fabrice Bellard
 
649 c50c0bc8 Fabrice Bellard
    p1 = src->data[0];
650
    lum1 = dst->data[0];
651 0a05e494 Fabrice Bellard
    cb1 = dst->data[1];
652
    cr1 = dst->data[2];
653 c50c0bc8 Fabrice Bellard
654 d4f5d74a Garrick Meeker
    for(;height >= 1; height -= 2) {
655 c50c0bc8 Fabrice Bellard
        p = p1;
656
        lum = lum1;
657
        cb = cb1;
658
        cr = cr1;
659 d4f5d74a Garrick Meeker
        for(w = width; w >= 2; w -= 2) {
660 e78df699 Michael Niedermayer
            lum[0] = p[0];
661
            cb[0] = p[1];
662
            lum[1] = p[2];
663
            cr[0] = p[3];
664 de6d9b64 Fabrice Bellard
            p += 4;
665
            lum += 2;
666
            cb++;
667
            cr++;
668
        }
669 d4f5d74a Garrick Meeker
        if (w) {
670 e78df699 Michael Niedermayer
            lum[0] = p[0];
671 d4f5d74a Garrick Meeker
            cb[0] = p[1];
672
            cr[0] = p[3];
673
            cb++;
674
            cr++;
675 de6d9b64 Fabrice Bellard
        }
676 c50c0bc8 Fabrice Bellard
        p1 += src->linesize[0];
677
        lum1 += dst->linesize[0];
678 d4f5d74a Garrick Meeker
        if (height>1) {
679
            p = p1;
680
            lum = lum1;
681
            for(w = width; w >= 2; w -= 2) {
682
                lum[0] = p[0];
683
                lum[1] = p[2];
684
                p += 4;
685
                lum += 2;
686
            }
687
            if (w) {
688
                lum[0] = p[0];
689
            }
690
            p1 += src->linesize[0];
691
            lum1 += dst->linesize[0];
692
        }
693 c50c0bc8 Fabrice Bellard
        cb1 += dst->linesize[1];
694
        cr1 += dst->linesize[2];
695
    }
696
}
697
698 ebb177dd Todd Kirby
static void uyvy422_to_yuv420p(AVPicture *dst, const AVPicture *src,
699
                              int width, int height)
700
{
701
    const uint8_t *p, *p1;
702
    uint8_t *lum, *cr, *cb, *lum1, *cr1, *cb1;
703
    int w;
704
 
705
    p1 = src->data[0];
706
    
707
    lum1 = dst->data[0];
708
    cb1 = dst->data[1];
709
    cr1 = dst->data[2];
710
711
    for(;height >= 1; height -= 2) {
712
        p = p1;
713
        lum = lum1;
714
        cb = cb1;
715
        cr = cr1;
716
        for(w = width; w >= 2; w -= 2) {
717
            lum[0] = p[1];
718
            cb[0] = p[0];
719
            lum[1] = p[3];
720
            cr[0] = p[2];
721
            p += 4;
722
            lum += 2;
723
            cb++;
724
            cr++;
725
        }
726
        if (w) {
727
            lum[0] = p[1];
728
            cb[0] = p[0];
729
            cr[0] = p[2];
730
            cb++;
731
            cr++;
732
        }
733
        p1 += src->linesize[0];
734
        lum1 += dst->linesize[0];
735
        if (height>1) {
736
            p = p1;
737
            lum = lum1;
738
            for(w = width; w >= 2; w -= 2) {
739
                lum[0] = p[1];
740
                lum[1] = p[3];
741
                p += 4;
742
                lum += 2;
743
            }
744
            if (w) {
745
                lum[0] = p[1];
746
            }
747
            p1 += src->linesize[0];
748
            lum1 += dst->linesize[0];
749
        }
750
        cb1 += dst->linesize[1];
751
        cr1 += dst->linesize[2];
752
    }
753
}
754
755
756
static void uyvy422_to_yuv422p(AVPicture *dst, const AVPicture *src,
757
                              int width, int height)
758
{
759
    const uint8_t *p, *p1;
760
    uint8_t *lum, *cr, *cb, *lum1, *cr1, *cb1;
761
    int w;
762
763
    p1 = src->data[0];
764
    lum1 = dst->data[0];
765
    cb1 = dst->data[1];
766
    cr1 = dst->data[2];
767
    for(;height > 0; height--) {
768
        p = p1;
769
        lum = lum1;
770
        cb = cb1;
771
        cr = cr1;
772
        for(w = width; w >= 2; w -= 2) {
773
            lum[0] = p[1];
774
            cb[0] = p[0];
775
            lum[1] = p[3];
776
            cr[0] = p[2];
777
            p += 4;
778
            lum += 2;
779
            cb++;
780
            cr++;
781
        }
782
        p1 += src->linesize[0];
783
        lum1 += dst->linesize[0];
784
        cb1 += dst->linesize[1];
785
        cr1 += dst->linesize[2];
786
    }
787
}
788
789
790 da64ecc3 Drew Hess
static void yuv422_to_yuv422p(AVPicture *dst, const AVPicture *src,
791 c50c0bc8 Fabrice Bellard
                              int width, int height)
792
{
793
    const uint8_t *p, *p1;
794
    uint8_t *lum, *cr, *cb, *lum1, *cr1, *cb1;
795
    int w;
796
797
    p1 = src->data[0];
798
    lum1 = dst->data[0];
799 0a05e494 Fabrice Bellard
    cb1 = dst->data[1];
800
    cr1 = dst->data[2];
801
    for(;height > 0; height--) {
802 c50c0bc8 Fabrice Bellard
        p = p1;
803
        lum = lum1;
804
        cb = cb1;
805
        cr = cr1;
806
        for(w = width; w >= 2; w -= 2) {
807
            lum[0] = p[0];
808
            cb[0] = p[1];
809
            lum[1] = p[2];
810
            cr[0] = p[3];
811
            p += 4;
812
            lum += 2;
813
            cb++;
814
            cr++;
815
        }
816
        p1 += src->linesize[0];
817
        lum1 += dst->linesize[0];
818
        cb1 += dst->linesize[1];
819
        cr1 += dst->linesize[2];
820 de6d9b64 Fabrice Bellard
    }
821
}
822
823 da64ecc3 Drew Hess
static void yuv422p_to_yuv422(AVPicture *dst, const AVPicture *src,
824 c50c0bc8 Fabrice Bellard
                              int width, int height)
825
{
826
    uint8_t *p, *p1;
827
    const uint8_t *lum, *cr, *cb, *lum1, *cr1, *cb1;
828
    int w;
829
830
    p1 = dst->data[0];
831
    lum1 = src->data[0];
832 0a05e494 Fabrice Bellard
    cb1 = src->data[1];
833
    cr1 = src->data[2];
834
    for(;height > 0; height--) {
835 c50c0bc8 Fabrice Bellard
        p = p1;
836
        lum = lum1;
837
        cb = cb1;
838
        cr = cr1;
839
        for(w = width; w >= 2; w -= 2) {
840
            p[0] = lum[0];
841
            p[1] = cb[0];
842
            p[2] = lum[1];
843
            p[3] = cr[0];
844
            p += 4;
845
            lum += 2;
846
            cb++;
847
            cr++;
848
        }
849 0a05e494 Fabrice Bellard
        p1 += dst->linesize[0];
850
        lum1 += src->linesize[0];
851
        cb1 += src->linesize[1];
852
        cr1 += src->linesize[2];
853 c50c0bc8 Fabrice Bellard
    }
854
}
855
856 ebb177dd Todd Kirby
static void yuv422p_to_uyvy422(AVPicture *dst, const AVPicture *src,
857
                              int width, int height)
858
{
859
    uint8_t *p, *p1;
860
    const uint8_t *lum, *cr, *cb, *lum1, *cr1, *cb1;
861
    int w;
862
863
    p1 = dst->data[0];
864
    lum1 = src->data[0];
865
    cb1 = src->data[1];
866
    cr1 = src->data[2];
867
    for(;height > 0; height--) {
868
        p = p1;
869
        lum = lum1;
870
        cb = cb1;
871
        cr = cr1;
872
        for(w = width; w >= 2; w -= 2) {
873
            p[1] = lum[0];
874
            p[0] = cb[0];
875
            p[3] = lum[1];
876
            p[2] = cr[0];
877
            p += 4;
878
            lum += 2;
879
            cb++;
880
            cr++;
881
        }
882
        p1 += dst->linesize[0];
883
        lum1 += src->linesize[0];
884
        cb1 += src->linesize[1];
885
        cr1 += src->linesize[2];
886
    }
887
}
888
889 f02be79d Roman Shaposhnik
static void uyvy411_to_yuv411p(AVPicture *dst, const AVPicture *src,
890
                              int width, int height)
891
{
892
    const uint8_t *p, *p1;
893
    uint8_t *lum, *cr, *cb, *lum1, *cr1, *cb1;
894
    int w;
895
896
    p1 = src->data[0];
897
    lum1 = dst->data[0];
898
    cb1 = dst->data[1];
899
    cr1 = dst->data[2];
900
    for(;height > 0; height--) {
901
        p = p1;
902
        lum = lum1;
903
        cb = cb1;
904
        cr = cr1;
905
        for(w = width; w >= 4; w -= 4) {
906
            cb[0] = p[0];
907
            lum[0] = p[1];
908
            lum[1] = p[2];
909
            cr[0] = p[3];
910
            lum[2] = p[4];
911
            lum[3] = p[5];
912
            p += 6;
913
            lum += 4;
914
            cb++;
915
            cr++;
916
        }
917
        p1 += src->linesize[0];
918
        lum1 += dst->linesize[0];
919
        cb1 += dst->linesize[1];
920
        cr1 += dst->linesize[2];
921
    }
922
}
923 ebb177dd Todd Kirby
924
925 d7e2f57f Michael Niedermayer
static void yuv420p_to_yuv422(AVPicture *dst, const AVPicture *src,
926
                              int width, int height)
927
{
928
    int w, h;
929
    uint8_t *line1, *line2, *linesrc = dst->data[0];
930
    uint8_t *lum1, *lum2, *lumsrc = src->data[0];
931
    uint8_t *cb1, *cb2 = src->data[1];
932
    uint8_t *cr1, *cr2 = src->data[2];
933
    
934
    for(h = height / 2; h--;) {
935
        line1 = linesrc;
936
        line2 = linesrc + dst->linesize[0];
937
        
938
        lum1 = lumsrc;
939
        lum2 = lumsrc + src->linesize[0];
940
        
941
        cb1 = cb2;
942
        cr1 = cr2;
943
        
944
        for(w = width / 2; w--;) {
945
                *line1++ = *lum1++; *line2++ = *lum2++;                     
946
                *line1++ =          *line2++ = *cb1++;                      
947
                *line1++ = *lum1++; *line2++ = *lum2++;                     
948
                *line1++ =          *line2++ = *cr1++;
949
        }
950
        
951
        linesrc += dst->linesize[0] * 2;
952
        lumsrc += src->linesize[0] * 2;
953
        cb2 += src->linesize[1];
954
        cr2 += src->linesize[2];
955
    }
956
}
957
958 c50c0bc8 Fabrice Bellard
#define SCALEBITS 10
959 de6d9b64 Fabrice Bellard
#define ONE_HALF  (1 << (SCALEBITS - 1))
960 c50c0bc8 Fabrice Bellard
#define FIX(x)          ((int) ((x) * (1<<SCALEBITS) + 0.5))
961 de6d9b64 Fabrice Bellard
962 c50c0bc8 Fabrice Bellard
#define YUV_TO_RGB1_CCIR(cb1, cr1)\
963
{\
964
    cb = (cb1) - 128;\
965
    cr = (cr1) - 128;\
966
    r_add = FIX(1.40200*255.0/224.0) * cr + ONE_HALF;\
967
    g_add = - FIX(0.34414*255.0/224.0) * cb - FIX(0.71414*255.0/224.0) * cr + \
968
            ONE_HALF;\
969
    b_add = FIX(1.77200*255.0/224.0) * cb + ONE_HALF;\
970
}
971 b6147995 Fabrice Bellard
972 c50c0bc8 Fabrice Bellard
#define YUV_TO_RGB2_CCIR(r, g, b, y1)\
973
{\
974
    y = ((y1) - 16) * FIX(255.0/219.0);\
975
    r = cm[(y + r_add) >> SCALEBITS];\
976
    g = cm[(y + g_add) >> SCALEBITS];\
977
    b = cm[(y + b_add) >> SCALEBITS];\
978
}
979
980
#define YUV_TO_RGB1(cb1, cr1)\
981
{\
982
    cb = (cb1) - 128;\
983
    cr = (cr1) - 128;\
984
    r_add = FIX(1.40200) * cr + ONE_HALF;\
985
    g_add = - FIX(0.34414) * cb - FIX(0.71414) * cr + ONE_HALF;\
986
    b_add = FIX(1.77200) * cb + ONE_HALF;\
987
}
988 b6147995 Fabrice Bellard
989
#define YUV_TO_RGB2(r, g, b, y1)\
990
{\
991 c50c0bc8 Fabrice Bellard
    y = (y1) << SCALEBITS;\
992
    r = cm[(y + r_add) >> SCALEBITS];\
993
    g = cm[(y + g_add) >> SCALEBITS];\
994
    b = cm[(y + b_add) >> SCALEBITS];\
995 b6147995 Fabrice Bellard
}
996
997 c50c0bc8 Fabrice Bellard
#define Y_CCIR_TO_JPEG(y)\
998 b6147995 Fabrice Bellard
 cm[((y) * FIX(255.0/219.0) + (ONE_HALF - 16 * FIX(255.0/219.0))) >> SCALEBITS]
999
1000 c50c0bc8 Fabrice Bellard
#define Y_JPEG_TO_CCIR(y)\
1001 b6147995 Fabrice Bellard
 (((y) * FIX(219.0/255.0) + (ONE_HALF + (16 << SCALEBITS))) >> SCALEBITS)
1002
1003 c50c0bc8 Fabrice Bellard
#define C_CCIR_TO_JPEG(y)\
1004
 cm[(((y) - 128) * FIX(127.0/112.0) + (ONE_HALF + (128 << SCALEBITS))) >> SCALEBITS]
1005
1006
/* NOTE: the clamp is really necessary! */
1007 4cfbf61b Falk Hüffner
static inline int C_JPEG_TO_CCIR(int y) {
1008
    y = (((y - 128) * FIX(112.0/127.0) + (ONE_HALF + (128 << SCALEBITS))) >> SCALEBITS);
1009
    if (y < 16)
1010
        y = 16;
1011
    return y;
1012
}
1013
1014 c50c0bc8 Fabrice Bellard
1015 b6147995 Fabrice Bellard
#define RGB_TO_Y(r, g, b) \
1016
((FIX(0.29900) * (r) + FIX(0.58700) * (g) + \
1017
  FIX(0.11400) * (b) + ONE_HALF) >> SCALEBITS)
1018
1019 c50c0bc8 Fabrice Bellard
#define RGB_TO_U(r1, g1, b1, shift)\
1020 b6147995 Fabrice Bellard
(((- FIX(0.16874) * r1 - FIX(0.33126) * g1 +         \
1021 c50c0bc8 Fabrice Bellard
     FIX(0.50000) * b1 + (ONE_HALF << shift) - 1) >> (SCALEBITS + shift)) + 128)
1022 b6147995 Fabrice Bellard
1023 c50c0bc8 Fabrice Bellard
#define RGB_TO_V(r1, g1, b1, shift)\
1024 b6147995 Fabrice Bellard
(((FIX(0.50000) * r1 - FIX(0.41869) * g1 -           \
1025 c50c0bc8 Fabrice Bellard
   FIX(0.08131) * b1 + (ONE_HALF << shift) - 1) >> (SCALEBITS + shift)) + 128)
1026 b6147995 Fabrice Bellard
1027
#define RGB_TO_Y_CCIR(r, g, b) \
1028
((FIX(0.29900*219.0/255.0) * (r) + FIX(0.58700*219.0/255.0) * (g) + \
1029
  FIX(0.11400*219.0/255.0) * (b) + (ONE_HALF + (16 << SCALEBITS))) >> SCALEBITS)
1030
1031 c50c0bc8 Fabrice Bellard
#define RGB_TO_U_CCIR(r1, g1, b1, shift)\
1032 b6147995 Fabrice Bellard
(((- FIX(0.16874*224.0/255.0) * r1 - FIX(0.33126*224.0/255.0) * g1 +         \
1033 c50c0bc8 Fabrice Bellard
     FIX(0.50000*224.0/255.0) * b1 + (ONE_HALF << shift) - 1) >> (SCALEBITS + shift)) + 128)
1034 b6147995 Fabrice Bellard
1035 c50c0bc8 Fabrice Bellard
#define RGB_TO_V_CCIR(r1, g1, b1, shift)\
1036 b6147995 Fabrice Bellard
(((FIX(0.50000*224.0/255.0) * r1 - FIX(0.41869*224.0/255.0) * g1 -           \
1037 c50c0bc8 Fabrice Bellard
   FIX(0.08131*224.0/255.0) * b1 + (ONE_HALF << shift) - 1) >> (SCALEBITS + shift)) + 128)
1038 b6147995 Fabrice Bellard
1039 c50c0bc8 Fabrice Bellard
static uint8_t y_ccir_to_jpeg[256];
1040
static uint8_t y_jpeg_to_ccir[256];
1041
static uint8_t c_ccir_to_jpeg[256];
1042
static uint8_t c_jpeg_to_ccir[256];
1043
1044
/* init various conversion tables */
1045
static void img_convert_init(void)
1046 b6147995 Fabrice Bellard
{
1047 c50c0bc8 Fabrice Bellard
    int i;
1048 b6147995 Fabrice Bellard
    uint8_t *cm = cropTbl + MAX_NEG_CROP;
1049
1050 c50c0bc8 Fabrice Bellard
    for(i = 0;i < 256; i++) {
1051
        y_ccir_to_jpeg[i] = Y_CCIR_TO_JPEG(i);
1052
        y_jpeg_to_ccir[i] = Y_JPEG_TO_CCIR(i);
1053
        c_ccir_to_jpeg[i] = C_CCIR_TO_JPEG(i);
1054
        c_jpeg_to_ccir[i] = C_JPEG_TO_CCIR(i);
1055 b6147995 Fabrice Bellard
    }
1056
}
1057
1058 c50c0bc8 Fabrice Bellard
/* apply to each pixel the given table */
1059
static void img_apply_table(uint8_t *dst, int dst_wrap, 
1060
                            const uint8_t *src, int src_wrap,
1061
                            int width, int height, const uint8_t *table1)
1062 b6147995 Fabrice Bellard
{
1063
    int n;
1064
    const uint8_t *s;
1065
    uint8_t *d;
1066 c50c0bc8 Fabrice Bellard
    const uint8_t *table;
1067 b6147995 Fabrice Bellard
1068 c50c0bc8 Fabrice Bellard
    table = table1;
1069 b6147995 Fabrice Bellard
    for(;height > 0; height--) {
1070
        s = src;
1071
        d = dst;
1072
        n = width;
1073
        while (n >= 4) {
1074 c50c0bc8 Fabrice Bellard
            d[0] = table[s[0]];
1075
            d[1] = table[s[1]];
1076
            d[2] = table[s[2]];
1077
            d[3] = table[s[3]];
1078 b6147995 Fabrice Bellard
            d += 4;
1079
            s += 4;
1080
            n -= 4;
1081
        }
1082
        while (n > 0) {
1083 c50c0bc8 Fabrice Bellard
            d[0] = table[s[0]];
1084 b6147995 Fabrice Bellard
            d++;
1085
            s++;
1086
            n--;
1087
        }
1088
        dst += dst_wrap;
1089
        src += src_wrap;
1090
    }
1091
}
1092
1093 85c242d8 Fabrice Bellard
/* XXX: use generic filter ? */
1094 e352ff08 Fabrice Bellard
/* XXX: in most cases, the sampling position is incorrect */
1095
1096
/* 4x1 -> 1x1 */
1097
static void shrink41(uint8_t *dst, int dst_wrap, 
1098
                     const uint8_t *src, int src_wrap,
1099
                     int width, int height)
1100
{
1101
    int w;
1102
    const uint8_t *s;
1103
    uint8_t *d;
1104
1105
    for(;height > 0; height--) {
1106
        s = src;
1107
        d = dst;
1108
        for(w = width;w > 0; w--) {
1109
            d[0] = (s[0] + s[1] + s[2] + s[3] + 2) >> 2;
1110
            s += 4;
1111
            d++;
1112
        }
1113
        src += src_wrap;
1114
        dst += dst_wrap;
1115
    }
1116
}
1117
1118
/* 2x1 -> 1x1 */
1119
static void shrink21(uint8_t *dst, int dst_wrap, 
1120
                     const uint8_t *src, int src_wrap,
1121
                     int width, int height)
1122
{
1123
    int w;
1124
    const uint8_t *s;
1125
    uint8_t *d;
1126
1127
    for(;height > 0; height--) {
1128
        s = src;
1129
        d = dst;
1130
        for(w = width;w > 0; w--) {
1131
            d[0] = (s[0] + s[1]) >> 1;
1132
            s += 2;
1133
            d++;
1134
        }
1135
        src += src_wrap;
1136
        dst += dst_wrap;
1137
    }
1138
}
1139
1140 85c242d8 Fabrice Bellard
/* 1x2 -> 1x1 */
1141 e352ff08 Fabrice Bellard
static void shrink12(uint8_t *dst, int dst_wrap, 
1142
                     const uint8_t *src, int src_wrap,
1143
                     int width, int height)
1144 85c242d8 Fabrice Bellard
{
1145
    int w;
1146 e352ff08 Fabrice Bellard
    uint8_t *d;
1147
    const uint8_t *s1, *s2;
1148 85c242d8 Fabrice Bellard
1149
    for(;height > 0; height--) {
1150
        s1 = src;
1151
        s2 = s1 + src_wrap;
1152
        d = dst;
1153
        for(w = width;w >= 4; w-=4) {
1154
            d[0] = (s1[0] + s2[0]) >> 1;
1155
            d[1] = (s1[1] + s2[1]) >> 1;
1156
            d[2] = (s1[2] + s2[2]) >> 1;
1157
            d[3] = (s1[3] + s2[3]) >> 1;
1158
            s1 += 4;
1159
            s2 += 4;
1160
            d += 4;
1161
        }
1162
        for(;w > 0; w--) {
1163
            d[0] = (s1[0] + s2[0]) >> 1;
1164
            s1++;
1165
            s2++;
1166
            d++;
1167
        }
1168
        src += 2 * src_wrap;
1169
        dst += dst_wrap;
1170
    }
1171
}
1172
1173
/* 2x2 -> 1x1 */
1174 0c1a9eda Zdenek Kabelac
static void shrink22(uint8_t *dst, int dst_wrap, 
1175 e352ff08 Fabrice Bellard
                     const uint8_t *src, int src_wrap,
1176 85c242d8 Fabrice Bellard
                     int width, int height)
1177
{
1178
    int w;
1179 e352ff08 Fabrice Bellard
    const uint8_t *s1, *s2;
1180
    uint8_t *d;
1181 85c242d8 Fabrice Bellard
1182
    for(;height > 0; height--) {
1183
        s1 = src;
1184
        s2 = s1 + src_wrap;
1185
        d = dst;
1186
        for(w = width;w >= 4; w-=4) {
1187 0a9ad8d1 Fabrice Bellard
            d[0] = (s1[0] + s1[1] + s2[0] + s2[1] + 2) >> 2;
1188
            d[1] = (s1[2] + s1[3] + s2[2] + s2[3] + 2) >> 2;
1189
            d[2] = (s1[4] + s1[5] + s2[4] + s2[5] + 2) >> 2;
1190
            d[3] = (s1[6] + s1[7] + s2[6] + s2[7] + 2) >> 2;
1191 85c242d8 Fabrice Bellard
            s1 += 8;
1192
            s2 += 8;
1193
            d += 4;
1194
        }
1195
        for(;w > 0; w--) {
1196 0a9ad8d1 Fabrice Bellard
            d[0] = (s1[0] + s1[1] + s2[0] + s2[1] + 2) >> 2;
1197 85c242d8 Fabrice Bellard
            s1 += 2;
1198
            s2 += 2;
1199
            d++;
1200
        }
1201
        src += 2 * src_wrap;
1202
        dst += dst_wrap;
1203
    }
1204
}
1205
1206 e352ff08 Fabrice Bellard
/* 4x4 -> 1x1 */
1207
static void shrink44(uint8_t *dst, int dst_wrap, 
1208
                     const uint8_t *src, int src_wrap,
1209 6742d95d François Revol
                     int width, int height)
1210
{
1211
    int w;
1212 e352ff08 Fabrice Bellard
    const uint8_t *s1, *s2, *s3, *s4;
1213
    uint8_t *d;
1214 6742d95d François Revol
1215
    for(;height > 0; height--) {
1216
        s1 = src;
1217 e352ff08 Fabrice Bellard
        s2 = s1 + src_wrap;
1218
        s3 = s2 + src_wrap;
1219
        s4 = s3 + src_wrap;
1220 6742d95d François Revol
        d = dst;
1221 e352ff08 Fabrice Bellard
        for(w = width;w > 0; w--) {
1222
            d[0] = (s1[0] + s1[1] + s1[2] + s1[3] +
1223
                    s2[0] + s2[1] + s2[2] + s2[3] +
1224
                    s3[0] + s3[1] + s3[2] + s3[3] +
1225
                    s4[0] + s4[1] + s4[2] + s4[3] + 8) >> 4;
1226
            s1 += 4;
1227
            s2 += 4;
1228
            s3 += 4;
1229
            s4 += 4;
1230 6742d95d François Revol
            d++;
1231
        }
1232 e352ff08 Fabrice Bellard
        src += 4 * src_wrap;
1233
        dst += dst_wrap;
1234
    }
1235
}
1236
1237
static void grow21_line(uint8_t *dst, const uint8_t *src,
1238
                        int width)
1239
{
1240
    int w;
1241
    const uint8_t *s1;
1242
    uint8_t *d;
1243
1244
    s1 = src;
1245
    d = dst;
1246
    for(w = width;w >= 4; w-=4) {
1247
        d[1] = d[0] = s1[0];
1248
        d[3] = d[2] = s1[1];
1249
        s1 += 2;
1250
        d += 4;
1251
    }
1252
    for(;w >= 2; w -= 2) {
1253
        d[1] = d[0] = s1[0];
1254
        s1 ++;
1255
        d += 2;
1256
    }
1257
    /* only needed if width is not a multiple of two */
1258
    /* XXX: veryfy that */
1259
    if (w) {
1260
        d[0] = s1[0];
1261
    }
1262
}
1263
1264
static void grow41_line(uint8_t *dst, const uint8_t *src,
1265
                        int width)
1266
{
1267
    int w, v;
1268
    const uint8_t *s1;
1269
    uint8_t *d;
1270
1271
    s1 = src;
1272
    d = dst;
1273
    for(w = width;w >= 4; w-=4) {
1274
        v = s1[0];
1275
        d[0] = v;
1276
        d[1] = v;
1277
        d[2] = v;
1278
        d[3] = v;
1279
        s1 ++;
1280
        d += 4;
1281
    }
1282
}
1283
1284
/* 1x1 -> 2x1 */
1285
static void grow21(uint8_t *dst, int dst_wrap,
1286
                   const uint8_t *src, int src_wrap,
1287
                   int width, int height)
1288
{
1289
    for(;height > 0; height--) {
1290
        grow21_line(dst, src, width);
1291
        src += src_wrap;
1292
        dst += dst_wrap;
1293
    }
1294
}
1295
1296
/* 1x1 -> 2x2 */
1297
static void grow22(uint8_t *dst, int dst_wrap,
1298
                   const uint8_t *src, int src_wrap,
1299
                   int width, int height)
1300
{
1301
    for(;height > 0; height--) {
1302
        grow21_line(dst, src, width);
1303 6742d95d François Revol
        if (height%2)
1304
            src += src_wrap;
1305
        dst += dst_wrap;
1306
    }
1307
}
1308
1309 e352ff08 Fabrice Bellard
/* 1x1 -> 4x1 */
1310
static void grow41(uint8_t *dst, int dst_wrap,
1311
                   const uint8_t *src, int src_wrap,
1312
                   int width, int height)
1313
{
1314
    for(;height > 0; height--) {
1315
        grow41_line(dst, src, width);
1316
        src += src_wrap;
1317
        dst += dst_wrap;
1318
    }
1319
}
1320
1321
/* 1x1 -> 4x4 */
1322
static void grow44(uint8_t *dst, int dst_wrap,
1323
                   const uint8_t *src, int src_wrap,
1324
                   int width, int height)
1325
{
1326
    for(;height > 0; height--) {
1327
        grow41_line(dst, src, width);
1328
        if ((height & 3) == 1)
1329
            src += src_wrap;
1330
        dst += dst_wrap;
1331
    }
1332
}
1333
1334 524c6b63 Fabrice Bellard
/* 1x2 -> 2x1 */
1335 0c1a9eda Zdenek Kabelac
static void conv411(uint8_t *dst, int dst_wrap, 
1336 e352ff08 Fabrice Bellard
                    const uint8_t *src, int src_wrap,
1337 789587d5 Fabrice Bellard
                    int width, int height)
1338
{
1339
    int w, c;
1340 e352ff08 Fabrice Bellard
    const uint8_t *s1, *s2;
1341
    uint8_t *d;
1342 789587d5 Fabrice Bellard
1343 50643575 Michael Niedermayer
    width>>=1;
1344
1345 524c6b63 Fabrice Bellard
    for(;height > 0; height--) {
1346 789587d5 Fabrice Bellard
        s1 = src;
1347
        s2 = src + src_wrap;
1348
        d = dst;
1349
        for(w = width;w > 0; w--) {
1350
            c = (s1[0] + s2[0]) >> 1;
1351
            d[0] = c;
1352
            d[1] = c;
1353
            s1++;
1354
            s2++;
1355
            d += 2;
1356
        }
1357
        src += src_wrap * 2;
1358
        dst += dst_wrap;
1359
    }
1360
}
1361
1362 7e7e5940 Fabrice Bellard
/* XXX: add jpeg quantize code */
1363
1364
#define TRANSP_INDEX (6*6*6)
1365
1366
/* this is maybe slow, but allows for extensions */
1367
static inline unsigned char gif_clut_index(uint8_t r, uint8_t g, uint8_t b)
1368 85c242d8 Fabrice Bellard
{
1369 7e7e5940 Fabrice Bellard
    return ((((r)/47)%6)*6*6+(((g)/47)%6)*6+(((b)/47)%6));
1370 85c242d8 Fabrice Bellard
}
1371
1372 7e7e5940 Fabrice Bellard
static void build_rgb_palette(uint8_t *palette, int has_alpha)
1373
{
1374
    uint32_t *pal;
1375
    static const uint8_t pal_value[6] = { 0x00, 0x33, 0x66, 0x99, 0xcc, 0xff };
1376
    int i, r, g, b;
1377
1378
    pal = (uint32_t *)palette;
1379
    i = 0;
1380
    for(r = 0; r < 6; r++) {
1381
        for(g = 0; g < 6; g++) {
1382
            for(b = 0; b < 6; b++) {
1383
                pal[i++] = (0xff << 24) | (pal_value[r] << 16) | 
1384
                    (pal_value[g] << 8) | pal_value[b];
1385
            }
1386
        }
1387
    }
1388
    if (has_alpha)
1389
        pal[i++] = 0;
1390
    while (i < 256)
1391
        pal[i++] = 0xff000000;
1392 524c6b63 Fabrice Bellard
}
1393
1394
/* copy bit n to bits 0 ... n - 1 */
1395
static inline unsigned int bitcopy_n(unsigned int a, int n)
1396 b71472eb Philip Gladstone
{
1397 524c6b63 Fabrice Bellard
    int mask;
1398
    mask = (1 << n) - 1;
1399
    return (a & (0xff & ~mask)) | ((-((a >> n) & 1)) & mask);
1400
}
1401
1402
/* rgb555 handling */
1403
1404 7e7e5940 Fabrice Bellard
#define RGB_NAME rgb555
1405
1406 524c6b63 Fabrice Bellard
#define RGB_IN(r, g, b, s)\
1407
{\
1408 0c1a9eda Zdenek Kabelac
    unsigned int v = ((const uint16_t *)(s))[0];\
1409 524c6b63 Fabrice Bellard
    r = bitcopy_n(v >> (10 - 3), 3);\
1410
    g = bitcopy_n(v >> (5 - 3), 3);\
1411
    b = bitcopy_n(v << 3, 3);\
1412
}
1413
1414 7e7e5940 Fabrice Bellard
#define RGBA_IN(r, g, b, a, s)\
1415 524c6b63 Fabrice Bellard
{\
1416 7e7e5940 Fabrice Bellard
    unsigned int v = ((const uint16_t *)(s))[0];\
1417
    r = bitcopy_n(v >> (10 - 3), 3);\
1418
    g = bitcopy_n(v >> (5 - 3), 3);\
1419
    b = bitcopy_n(v << 3, 3);\
1420 b5ff5e22 Fabrice Bellard
    a = (-(v >> 15)) & 0xff;\
1421 7e7e5940 Fabrice Bellard
}
1422
1423
#define RGBA_OUT(d, r, g, b, a)\
1424
{\
1425
    ((uint16_t *)(d))[0] = ((r >> 3) << 10) | ((g >> 3) << 5) | (b >> 3) | \
1426
                           ((a << 8) & 0x8000);\
1427 524c6b63 Fabrice Bellard
}
1428
1429
#define BPP 2
1430
1431 7e7e5940 Fabrice Bellard
#include "imgconvert_template.h"
1432 524c6b63 Fabrice Bellard
1433
/* rgb565 handling */
1434
1435 7e7e5940 Fabrice Bellard
#define RGB_NAME rgb565
1436
1437 524c6b63 Fabrice Bellard
#define RGB_IN(r, g, b, s)\
1438
{\
1439 0c1a9eda Zdenek Kabelac
    unsigned int v = ((const uint16_t *)(s))[0];\
1440 524c6b63 Fabrice Bellard
    r = bitcopy_n(v >> (11 - 3), 3);\
1441
    g = bitcopy_n(v >> (5 - 2), 2);\
1442
    b = bitcopy_n(v << 3, 3);\
1443
}
1444
1445
#define RGB_OUT(d, r, g, b)\
1446
{\
1447 0c1a9eda Zdenek Kabelac
    ((uint16_t *)(d))[0] = ((r >> 3) << 11) | ((g >> 2) << 5) | (b >> 3);\
1448 524c6b63 Fabrice Bellard
}
1449
1450
#define BPP 2
1451
1452 7e7e5940 Fabrice Bellard
#include "imgconvert_template.h"
1453 524c6b63 Fabrice Bellard
1454
/* bgr24 handling */
1455
1456 7e7e5940 Fabrice Bellard
#define RGB_NAME bgr24
1457
1458 524c6b63 Fabrice Bellard
#define RGB_IN(r, g, b, s)\
1459
{\
1460
    b = (s)[0];\
1461
    g = (s)[1];\
1462
    r = (s)[2];\
1463
}
1464
1465
#define RGB_OUT(d, r, g, b)\
1466
{\
1467
    (d)[0] = b;\
1468
    (d)[1] = g;\
1469
    (d)[2] = r;\
1470
}
1471
1472
#define BPP 3
1473
1474 7e7e5940 Fabrice Bellard
#include "imgconvert_template.h"
1475 524c6b63 Fabrice Bellard
1476
#undef RGB_IN
1477
#undef RGB_OUT
1478
#undef BPP
1479
1480
/* rgb24 handling */
1481
1482 7e7e5940 Fabrice Bellard
#define RGB_NAME rgb24
1483
#define FMT_RGB24
1484
1485 524c6b63 Fabrice Bellard
#define RGB_IN(r, g, b, s)\
1486
{\
1487
    r = (s)[0];\
1488
    g = (s)[1];\
1489
    b = (s)[2];\
1490
}
1491
1492
#define RGB_OUT(d, r, g, b)\
1493
{\
1494
    (d)[0] = r;\
1495
    (d)[1] = g;\
1496
    (d)[2] = b;\
1497
}
1498
1499
#define BPP 3
1500
1501 7e7e5940 Fabrice Bellard
#include "imgconvert_template.h"
1502 524c6b63 Fabrice Bellard
1503
/* rgba32 handling */
1504
1505 7e7e5940 Fabrice Bellard
#define RGB_NAME rgba32
1506
#define FMT_RGBA32
1507
1508 524c6b63 Fabrice Bellard
#define RGB_IN(r, g, b, s)\
1509
{\
1510 0c1a9eda Zdenek Kabelac
    unsigned int v = ((const uint32_t *)(s))[0];\
1511 524c6b63 Fabrice Bellard
    r = (v >> 16) & 0xff;\
1512
    g = (v >> 8) & 0xff;\
1513
    b = v & 0xff;\
1514
}
1515
1516 7e7e5940 Fabrice Bellard
#define RGBA_IN(r, g, b, a, s)\
1517 524c6b63 Fabrice Bellard
{\
1518 7e7e5940 Fabrice Bellard
    unsigned int v = ((const uint32_t *)(s))[0];\
1519
    a = (v >> 24) & 0xff;\
1520
    r = (v >> 16) & 0xff;\
1521
    g = (v >> 8) & 0xff;\
1522
    b = v & 0xff;\
1523 524c6b63 Fabrice Bellard
}
1524
1525 7e7e5940 Fabrice Bellard
#define RGBA_OUT(d, r, g, b, a)\
1526
{\
1527
    ((uint32_t *)(d))[0] = (a << 24) | (r << 16) | (g << 8) | b;\
1528 b71472eb Philip Gladstone
}
1529
1530 7e7e5940 Fabrice Bellard
#define BPP 4
1531 524c6b63 Fabrice Bellard
1532 7e7e5940 Fabrice Bellard
#include "imgconvert_template.h"
1533 b71472eb Philip Gladstone
1534 da64ecc3 Drew Hess
static void mono_to_gray(AVPicture *dst, const AVPicture *src,
1535 2a877875 Fabrice Bellard
                         int width, int height, int xor_mask)
1536 524c6b63 Fabrice Bellard
{
1537
    const unsigned char *p;
1538
    unsigned char *q;
1539
    int v, dst_wrap, src_wrap;
1540
    int y, w;
1541
1542
    p = src->data[0];
1543
    src_wrap = src->linesize[0] - ((width + 7) >> 3);
1544
1545
    q = dst->data[0];
1546 2a877875 Fabrice Bellard
    dst_wrap = dst->linesize[0] - width;
1547 524c6b63 Fabrice Bellard
    for(y=0;y<height;y++) {
1548
        w = width; 
1549
        while (w >= 8) {
1550 2a877875 Fabrice Bellard
            v = *p++ ^ xor_mask;
1551
            q[0] = -(v >> 7);
1552
            q[1] = -((v >> 6) & 1);
1553
            q[2] = -((v >> 5) & 1);
1554
            q[3] = -((v >> 4) & 1);
1555
            q[4] = -((v >> 3) & 1);
1556
            q[5] = -((v >> 2) & 1);
1557
            q[6] = -((v >> 1) & 1);
1558
            q[7] = -((v >> 0) & 1);
1559 524c6b63 Fabrice Bellard
            w -= 8;
1560 2a877875 Fabrice Bellard
            q += 8;
1561 524c6b63 Fabrice Bellard
        }
1562
        if (w > 0) {
1563 2a877875 Fabrice Bellard
            v = *p++ ^ xor_mask;
1564 524c6b63 Fabrice Bellard
            do {
1565 2a877875 Fabrice Bellard
                q[0] = -((v >> 7) & 1);
1566
                q++;
1567 524c6b63 Fabrice Bellard
                v <<= 1;
1568
            } while (--w);
1569 85c242d8 Fabrice Bellard
        }
1570 524c6b63 Fabrice Bellard
        p += src_wrap;
1571
        q += dst_wrap;
1572 85c242d8 Fabrice Bellard
    }
1573
}
1574
1575 da64ecc3 Drew Hess
static void monowhite_to_gray(AVPicture *dst, const AVPicture *src,
1576 524c6b63 Fabrice Bellard
                               int width, int height)
1577
{
1578 2a877875 Fabrice Bellard
    mono_to_gray(dst, src, width, height, 0xff);
1579
}
1580 524c6b63 Fabrice Bellard
1581 da64ecc3 Drew Hess
static void monoblack_to_gray(AVPicture *dst, const AVPicture *src,
1582 2a877875 Fabrice Bellard
                               int width, int height)
1583
{
1584
    mono_to_gray(dst, src, width, height, 0x00);
1585
}
1586 524c6b63 Fabrice Bellard
1587 da64ecc3 Drew Hess
static void gray_to_mono(AVPicture *dst, const AVPicture *src,
1588 2a877875 Fabrice Bellard
                         int width, int height, int xor_mask)
1589
{
1590
    int n;
1591 0c1a9eda Zdenek Kabelac
    const uint8_t *s;
1592
    uint8_t *d;
1593 2a877875 Fabrice Bellard
    int j, b, v, n1, src_wrap, dst_wrap, y;
1594
1595
    s = src->data[0];
1596
    src_wrap = src->linesize[0] - width;
1597
1598
    d = dst->data[0];
1599
    dst_wrap = dst->linesize[0] - ((width + 7) >> 3);
1600 524c6b63 Fabrice Bellard
1601
    for(y=0;y<height;y++) {
1602 2a877875 Fabrice Bellard
        n = width;
1603
        while (n >= 8) {
1604
            v = 0;
1605
            for(j=0;j<8;j++) {
1606
                b = s[0];
1607
                s++;
1608
                v = (v << 1) | (b >> 7);
1609
            }
1610
            d[0] = v ^ xor_mask;
1611
            d++;
1612
            n -= 8;
1613 524c6b63 Fabrice Bellard
        }
1614 2a877875 Fabrice Bellard
        if (n > 0) {
1615
            n1 = n;
1616
            v = 0;
1617
            while (n > 0) {
1618
                b = s[0];
1619
                s++;
1620
                v = (v << 1) | (b >> 7);
1621
                n--;
1622
            }
1623
            d[0] = (v << (8 - (n1 & 7))) ^ xor_mask;
1624
            d++;
1625 524c6b63 Fabrice Bellard
        }
1626 2a877875 Fabrice Bellard
        s += src_wrap;
1627
        d += dst_wrap;
1628 524c6b63 Fabrice Bellard
    }
1629
}
1630
1631 da64ecc3 Drew Hess
static void gray_to_monowhite(AVPicture *dst, const AVPicture *src,
1632 2a877875 Fabrice Bellard
                              int width, int height)
1633
{
1634
    gray_to_mono(dst, src, width, height, 0xff);
1635
}
1636
1637 da64ecc3 Drew Hess
static void gray_to_monoblack(AVPicture *dst, const AVPicture *src,
1638 2a877875 Fabrice Bellard
                              int width, int height)
1639
{
1640
    gray_to_mono(dst, src, width, height, 0x00);
1641
}
1642
1643 524c6b63 Fabrice Bellard
typedef struct ConvertEntry {
1644 da64ecc3 Drew Hess
    void (*convert)(AVPicture *dst,
1645
                    const AVPicture *src, int width, int height);
1646 524c6b63 Fabrice Bellard
} ConvertEntry;
1647
1648 c50c0bc8 Fabrice Bellard
/* Add each new convertion function in this table. In order to be able
1649
   to convert from any format to any format, the following constraints
1650
   must be satisfied:
1651

1652
   - all FF_COLOR_RGB formats must convert to and from PIX_FMT_RGB24 
1653

1654
   - all FF_COLOR_GRAY formats must convert to and from PIX_FMT_GRAY8
1655

1656
   - all FF_COLOR_RGB formats with alpha must convert to and from PIX_FMT_RGBA32
1657

1658 e352ff08 Fabrice Bellard
   - PIX_FMT_YUV444P and PIX_FMT_YUVJ444P must convert to and from
1659 c50c0bc8 Fabrice Bellard
     PIX_FMT_RGB24.
1660

1661
   - PIX_FMT_422 must convert to and from PIX_FMT_422P.
1662 e352ff08 Fabrice Bellard

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