Statistics
| Branch: | Revision:

ffmpeg / libavcodec / imgconvert.c @ 8dbcc9f2

History | View | Annotate | Download (58 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
    [PIX_FMT_YUV410P] = {
101 ef9f7306 Måns Rullgård
        .name = "yuv410p",
102 7e7e5940 Fabrice Bellard
        .nb_channels = 3,
103 b6147995 Fabrice Bellard
        .color_type = FF_COLOR_YUV,
104 7e7e5940 Fabrice Bellard
        .pixel_type = FF_PIXEL_PLANAR,
105 b6147995 Fabrice Bellard
        .depth = 8,
106 ef9f7306 Måns Rullgård
        .x_chroma_shift = 2, .y_chroma_shift = 2,
107 524c6b63 Fabrice Bellard
    },
108
    [PIX_FMT_YUV411P] = {
109 ef9f7306 Måns Rullgård
        .name = "yuv411p",
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 = 0,
115 524c6b63 Fabrice Bellard
    },
116
117 b6147995 Fabrice Bellard
    /* JPEG YUV */
118
    [PIX_FMT_YUVJ420P] = {
119
        .name = "yuvj420p",
120 7e7e5940 Fabrice Bellard
        .nb_channels = 3,
121 b6147995 Fabrice Bellard
        .color_type = FF_COLOR_YUV_JPEG,
122 7e7e5940 Fabrice Bellard
        .pixel_type = FF_PIXEL_PLANAR,
123 b6147995 Fabrice Bellard
        .depth = 8,
124
        .x_chroma_shift = 1, .y_chroma_shift = 1, 
125
    },
126
    [PIX_FMT_YUVJ422P] = {
127
        .name = "yuvj422p",
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 = 0, 
133
    },
134
    [PIX_FMT_YUVJ444P] = {
135
        .name = "yuvj444p",
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 = 0, .y_chroma_shift = 0, 
141
    },
142
143 524c6b63 Fabrice Bellard
    /* RGB formats */
144
    [PIX_FMT_RGB24] = {
145 ef9f7306 Måns Rullgård
        .name = "rgb24",
146 7e7e5940 Fabrice Bellard
        .nb_channels = 3,
147 b6147995 Fabrice Bellard
        .color_type = FF_COLOR_RGB,
148 7e7e5940 Fabrice Bellard
        .pixel_type = FF_PIXEL_PACKED,
149 b6147995 Fabrice Bellard
        .depth = 8,
150 2cbb7820 Michael Niedermayer
        .x_chroma_shift = 0, .y_chroma_shift = 0,
151 524c6b63 Fabrice Bellard
    },
152
    [PIX_FMT_BGR24] = {
153 ef9f7306 Måns Rullgård
        .name = "bgr24",
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_RGBA32] = {
161 ef9f7306 Måns Rullgård
        .name = "rgba32",
162 7e7e5940 Fabrice Bellard
        .nb_channels = 4, .is_alpha = 1,
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_RGB565] = {
169 ef9f7306 Måns Rullgård
        .name = "rgb565",
170 7e7e5940 Fabrice Bellard
        .nb_channels = 3,
171 b6147995 Fabrice Bellard
        .color_type = FF_COLOR_RGB,
172 7e7e5940 Fabrice Bellard
        .pixel_type = FF_PIXEL_PACKED,
173 b6147995 Fabrice Bellard
        .depth = 5,
174 2cbb7820 Michael Niedermayer
        .x_chroma_shift = 0, .y_chroma_shift = 0,
175 524c6b63 Fabrice Bellard
    },
176
    [PIX_FMT_RGB555] = {
177 ef9f7306 Måns Rullgård
        .name = "rgb555",
178 7e7e5940 Fabrice Bellard
        .nb_channels = 4, .is_alpha = 1,
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
185
    /* gray / mono formats */
186
    [PIX_FMT_GRAY8] = {
187 ef9f7306 Måns Rullgård
        .name = "gray",
188 7e7e5940 Fabrice Bellard
        .nb_channels = 1,
189 b6147995 Fabrice Bellard
        .color_type = FF_COLOR_GRAY,
190 7e7e5940 Fabrice Bellard
        .pixel_type = FF_PIXEL_PLANAR,
191 b6147995 Fabrice Bellard
        .depth = 8,
192 524c6b63 Fabrice Bellard
    },
193
    [PIX_FMT_MONOWHITE] = {
194 ef9f7306 Måns Rullgård
        .name = "monow",
195 7e7e5940 Fabrice Bellard
        .nb_channels = 1,
196 b6147995 Fabrice Bellard
        .color_type = FF_COLOR_GRAY,
197 7e7e5940 Fabrice Bellard
        .pixel_type = FF_PIXEL_PLANAR,
198 b6147995 Fabrice Bellard
        .depth = 1,
199 524c6b63 Fabrice Bellard
    },
200
    [PIX_FMT_MONOBLACK] = {
201 ef9f7306 Måns Rullgård
        .name = "monob",
202 7e7e5940 Fabrice Bellard
        .nb_channels = 1,
203 b6147995 Fabrice Bellard
        .color_type = FF_COLOR_GRAY,
204 7e7e5940 Fabrice Bellard
        .pixel_type = FF_PIXEL_PLANAR,
205 b6147995 Fabrice Bellard
        .depth = 1,
206 524c6b63 Fabrice Bellard
    },
207 7e6d70d0 Fabrice Bellard
208
    /* paletted formats */
209
    [PIX_FMT_PAL8] = {
210
        .name = "pal8",
211 7e7e5940 Fabrice Bellard
        .nb_channels = 4, .is_alpha = 1,
212 b6147995 Fabrice Bellard
        .color_type = FF_COLOR_RGB,
213 7e7e5940 Fabrice Bellard
        .pixel_type = FF_PIXEL_PALETTE,
214 b6147995 Fabrice Bellard
        .depth = 8,
215 7e6d70d0 Fabrice Bellard
    },
216 524c6b63 Fabrice Bellard
};
217
218
void avcodec_get_chroma_sub_sample(int pix_fmt, int *h_shift, int *v_shift)
219
{
220 b6147995 Fabrice Bellard
    *h_shift = pix_fmt_info[pix_fmt].x_chroma_shift;
221
    *v_shift = pix_fmt_info[pix_fmt].y_chroma_shift;
222 524c6b63 Fabrice Bellard
}
223
224
const char *avcodec_get_pix_fmt_name(int pix_fmt)
225
{
226
    if (pix_fmt < 0 || pix_fmt >= PIX_FMT_NB)
227
        return "???";
228
    else
229
        return pix_fmt_info[pix_fmt].name;
230
}
231
232 63167088 Roman Shaposhnik
enum PixelFormat avcodec_get_pix_fmt(const char* name)
233
{
234
    int i; 
235
    
236
    for (i=0; i < PIX_FMT_NB; i++)
237
         if (!strcmp(pix_fmt_info[i].name, name))
238
             break;
239
    return i;
240
}
241
242 2a877875 Fabrice Bellard
/* Picture field are filled with 'ptr' addresses. Also return size */
243 0c1a9eda Zdenek Kabelac
int avpicture_fill(AVPicture *picture, uint8_t *ptr,
244 da64ecc3 Drew Hess
                   int pix_fmt, int width, int height)
245 2a877875 Fabrice Bellard
{
246 4c7e8619 Fabrice Bellard
    int size, w2, h2, size2;
247
    PixFmtInfo *pinfo;
248
    
249
    pinfo = &pix_fmt_info[pix_fmt];
250 2a877875 Fabrice Bellard
    size = width * height;
251
    switch(pix_fmt) {
252
    case PIX_FMT_YUV420P:
253 4c7e8619 Fabrice Bellard
    case PIX_FMT_YUV422P:
254
    case PIX_FMT_YUV444P:
255
    case PIX_FMT_YUV410P:
256
    case PIX_FMT_YUV411P:
257 c50c0bc8 Fabrice Bellard
    case PIX_FMT_YUVJ420P:
258
    case PIX_FMT_YUVJ422P:
259
    case PIX_FMT_YUVJ444P:
260 4c7e8619 Fabrice Bellard
        w2 = (width + (1 << pinfo->x_chroma_shift) - 1) >> pinfo->x_chroma_shift;
261
        h2 = (height + (1 << pinfo->y_chroma_shift) - 1) >> pinfo->y_chroma_shift;
262
        size2 = w2 * h2;
263 2a877875 Fabrice Bellard
        picture->data[0] = ptr;
264
        picture->data[1] = picture->data[0] + size;
265 4c7e8619 Fabrice Bellard
        picture->data[2] = picture->data[1] + size2;
266 2a877875 Fabrice Bellard
        picture->linesize[0] = width;
267 4c7e8619 Fabrice Bellard
        picture->linesize[1] = w2;
268
        picture->linesize[2] = w2;
269
        return size + 2 * size2;
270 2a877875 Fabrice Bellard
    case PIX_FMT_RGB24:
271
    case PIX_FMT_BGR24:
272
        picture->data[0] = ptr;
273
        picture->data[1] = NULL;
274
        picture->data[2] = NULL;
275
        picture->linesize[0] = width * 3;
276
        return size * 3;
277
    case PIX_FMT_RGBA32:
278
        picture->data[0] = ptr;
279
        picture->data[1] = NULL;
280
        picture->data[2] = NULL;
281
        picture->linesize[0] = width * 4;
282
        return size * 4;
283
    case PIX_FMT_RGB555:
284
    case PIX_FMT_RGB565:
285
    case PIX_FMT_YUV422:
286
        picture->data[0] = ptr;
287
        picture->data[1] = NULL;
288
        picture->data[2] = NULL;
289
        picture->linesize[0] = width * 2;
290
        return size * 2;
291
    case PIX_FMT_GRAY8:
292
        picture->data[0] = ptr;
293
        picture->data[1] = NULL;
294
        picture->data[2] = NULL;
295
        picture->linesize[0] = width;
296
        return size;
297
    case PIX_FMT_MONOWHITE:
298
    case PIX_FMT_MONOBLACK:
299
        picture->data[0] = ptr;
300
        picture->data[1] = NULL;
301
        picture->data[2] = NULL;
302
        picture->linesize[0] = (width + 7) >> 3;
303
        return picture->linesize[0] * height;
304 7e6d70d0 Fabrice Bellard
    case PIX_FMT_PAL8:
305
        size2 = (size + 3) & ~3;
306
        picture->data[0] = ptr;
307
        picture->data[1] = ptr + size2; /* palette is stored here as 256 32 bit words */
308
        picture->data[2] = NULL;
309
        picture->linesize[0] = width;
310
        picture->linesize[1] = 4;
311
        return size2 + 256 * 4;
312 2a877875 Fabrice Bellard
    default:
313
        picture->data[0] = NULL;
314
        picture->data[1] = NULL;
315
        picture->data[2] = NULL;
316 7e6d70d0 Fabrice Bellard
        picture->data[3] = NULL;
317 2a877875 Fabrice Bellard
        return -1;
318
    }
319
}
320
321 da64ecc3 Drew Hess
int avpicture_layout(const AVPicture* src, int pix_fmt, int width, int height,
322 63167088 Roman Shaposhnik
                     unsigned char *dest, int dest_size)
323
{
324
    PixFmtInfo* pf = &pix_fmt_info[pix_fmt];
325
    int i, j, w, h, data_planes;
326 da64ecc3 Drew Hess
    const unsigned char* s; 
327 63167088 Roman Shaposhnik
    int size = avpicture_get_size(pix_fmt, width, height);
328
329
    if (size > dest_size)
330
        return -1;
331
332 affd55a1 Roman Shaposhnik
    if (pf->pixel_type == FF_PIXEL_PACKED || pf->pixel_type == FF_PIXEL_PALETTE) {
333 63167088 Roman Shaposhnik
        if (pix_fmt == PIX_FMT_YUV422 || pix_fmt == PIX_FMT_RGB565 ||
334
            pix_fmt == PIX_FMT_RGB555)
335
          w = width * 2;
336 affd55a1 Roman Shaposhnik
        else if (pix_fmt == PIX_FMT_PAL8)
337
          w = width;
338 63167088 Roman Shaposhnik
        else
339
          w = width * (pf->depth * pf->nb_channels / 8);
340 affd55a1 Roman Shaposhnik
          
341 63167088 Roman Shaposhnik
        data_planes = 1;
342
        h = height;
343
    } else {
344
        data_planes = pf->nb_channels;
345
        w = width;
346
        h = height;
347
    }
348
    
349
    for (i=0; i<data_planes; i++) {
350
         if (i == 1) {
351
             w = width >> pf->x_chroma_shift;
352
             h = height >> pf->y_chroma_shift;
353
         }
354
         s = src->data[i];
355
         for(j=0; j<h; j++) {
356
             memcpy(dest, s, w);
357
             dest += w;
358
             s += src->linesize[i];
359
         }
360
    }
361 affd55a1 Roman Shaposhnik
    
362
    if (pf->pixel_type == FF_PIXEL_PALETTE)
363
        memcpy((unsigned char *)(((size_t)dest + 3) & ~3), src->data[1], 256 * 4);
364
    
365 63167088 Roman Shaposhnik
    return size;
366
}
367
368 2a877875 Fabrice Bellard
int avpicture_get_size(int pix_fmt, int width, int height)
369
{
370
    AVPicture dummy_pict;
371
    return avpicture_fill(&dummy_pict, NULL, pix_fmt, width, height);
372
}
373
374 b6147995 Fabrice Bellard
/**
375
 * compute the loss when converting from a pixel format to another 
376
 */
377
int avcodec_get_pix_fmt_loss(int dst_pix_fmt, int src_pix_fmt,
378
                             int has_alpha)
379
{
380
    const PixFmtInfo *pf, *ps;
381
    int loss;
382
383
    ps = &pix_fmt_info[src_pix_fmt];
384
    pf = &pix_fmt_info[dst_pix_fmt];
385
386
    /* compute loss */
387
    loss = 0;
388
    pf = &pix_fmt_info[dst_pix_fmt];
389 0a9ad8d1 Fabrice Bellard
    if (pf->depth < ps->depth ||
390
        (dst_pix_fmt == PIX_FMT_RGB555 && src_pix_fmt == PIX_FMT_RGB565))
391 b6147995 Fabrice Bellard
        loss |= FF_LOSS_DEPTH;
392 0a9ad8d1 Fabrice Bellard
    if (pf->x_chroma_shift > ps->x_chroma_shift ||
393
        pf->y_chroma_shift > ps->y_chroma_shift)
394 b6147995 Fabrice Bellard
        loss |= FF_LOSS_RESOLUTION;
395
    switch(pf->color_type) {
396
    case FF_COLOR_RGB:
397
        if (ps->color_type != FF_COLOR_RGB &&
398
            ps->color_type != FF_COLOR_GRAY)
399
            loss |= FF_LOSS_COLORSPACE;
400
        break;
401
    case FF_COLOR_GRAY:
402
        if (ps->color_type != FF_COLOR_GRAY)
403
            loss |= FF_LOSS_COLORSPACE;
404
        break;
405
    case FF_COLOR_YUV:
406
        if (ps->color_type != FF_COLOR_YUV)
407
            loss |= FF_LOSS_COLORSPACE;
408
        break;
409
    case FF_COLOR_YUV_JPEG:
410
        if (ps->color_type != FF_COLOR_YUV_JPEG &&
411 0a9ad8d1 Fabrice Bellard
            ps->color_type != FF_COLOR_YUV && 
412
            ps->color_type != FF_COLOR_GRAY)
413 b6147995 Fabrice Bellard
            loss |= FF_LOSS_COLORSPACE;
414
        break;
415
    default:
416
        /* fail safe test */
417
        if (ps->color_type != pf->color_type)
418
            loss |= FF_LOSS_COLORSPACE;
419
        break;
420
    }
421
    if (pf->color_type == FF_COLOR_GRAY &&
422
        ps->color_type != FF_COLOR_GRAY)
423
        loss |= FF_LOSS_CHROMA;
424
    if (!pf->is_alpha && (ps->is_alpha && has_alpha))
425
        loss |= FF_LOSS_ALPHA;
426 7e7e5940 Fabrice Bellard
    if (pf->pixel_type == FF_PIXEL_PALETTE && 
427
        (ps->pixel_type != FF_PIXEL_PALETTE && ps->color_type != FF_COLOR_GRAY))
428 b6147995 Fabrice Bellard
        loss |= FF_LOSS_COLORQUANT;
429
    return loss;
430
}
431
432
static int avg_bits_per_pixel(int pix_fmt)
433
{
434
    int bits;
435
    const PixFmtInfo *pf;
436
437
    pf = &pix_fmt_info[pix_fmt];
438 7e7e5940 Fabrice Bellard
    switch(pf->pixel_type) {
439
    case FF_PIXEL_PACKED:
440 b6147995 Fabrice Bellard
        switch(pix_fmt) {
441 7e7e5940 Fabrice Bellard
        case PIX_FMT_YUV422:
442 b6147995 Fabrice Bellard
        case PIX_FMT_RGB565:
443
        case PIX_FMT_RGB555:
444
            bits = 16;
445
            break;
446
        default:
447 7e7e5940 Fabrice Bellard
            bits = pf->depth * pf->nb_channels;
448 b6147995 Fabrice Bellard
            break;
449
        }
450 7e7e5940 Fabrice Bellard
        break;
451
    case FF_PIXEL_PLANAR:
452
        if (pf->x_chroma_shift == 0 && pf->y_chroma_shift == 0) {
453
            bits = pf->depth * pf->nb_channels;
454
        } else {
455
            bits = pf->depth + ((2 * pf->depth) >> 
456
                                (pf->x_chroma_shift + pf->y_chroma_shift));
457
        }
458
        break;
459
    case FF_PIXEL_PALETTE:
460
        bits = 8;
461
        break;
462
    default:
463
        bits = -1;
464
        break;
465 b6147995 Fabrice Bellard
    }
466
    return bits;
467
}
468
469
static int avcodec_find_best_pix_fmt1(int pix_fmt_mask, 
470
                                      int src_pix_fmt,
471
                                      int has_alpha,
472
                                      int loss_mask)
473
{
474
    int dist, i, loss, min_dist, dst_pix_fmt;
475
476
    /* find exact color match with smallest size */
477
    dst_pix_fmt = -1;
478
    min_dist = 0x7fffffff;
479
    for(i = 0;i < PIX_FMT_NB; i++) {
480
        if (pix_fmt_mask & (1 << i)) {
481
            loss = avcodec_get_pix_fmt_loss(i, src_pix_fmt, has_alpha) & loss_mask;
482
            if (loss == 0) {
483
                dist = avg_bits_per_pixel(i);
484
                if (dist < min_dist) {
485
                    min_dist = dist;
486
                    dst_pix_fmt = i;
487
                }
488
            }
489
        }
490
    }
491
    return dst_pix_fmt;
492
}
493
494
/** 
495
 * find best pixel format to convert to. Return -1 if none found 
496
 */
497
int avcodec_find_best_pix_fmt(int pix_fmt_mask, int src_pix_fmt,
498
                              int has_alpha, int *loss_ptr)
499
{
500
    int dst_pix_fmt, loss_mask, i;
501
    static const int loss_mask_order[] = {
502
        ~0, /* no loss first */
503
        ~FF_LOSS_ALPHA,
504
        ~FF_LOSS_RESOLUTION,
505
        ~(FF_LOSS_COLORSPACE | FF_LOSS_RESOLUTION),
506
        ~FF_LOSS_COLORQUANT,
507
        ~FF_LOSS_DEPTH,
508
        0,
509
    };
510
511
    /* try with successive loss */
512
    i = 0;
513
    for(;;) {
514
        loss_mask = loss_mask_order[i++];
515
        dst_pix_fmt = avcodec_find_best_pix_fmt1(pix_fmt_mask, src_pix_fmt, 
516
                                                 has_alpha, loss_mask);
517
        if (dst_pix_fmt >= 0)
518
            goto found;
519
        if (loss_mask == 0)
520
            break;
521
    }
522
    return -1;
523
 found:
524
    if (loss_ptr)
525
        *loss_ptr = avcodec_get_pix_fmt_loss(dst_pix_fmt, src_pix_fmt, has_alpha);
526
    return dst_pix_fmt;
527
}
528
529 7e7e5940 Fabrice Bellard
static void img_copy_plane(uint8_t *dst, int dst_wrap, 
530 e352ff08 Fabrice Bellard
                           const uint8_t *src, int src_wrap,
531
                           int width, int height)
532 7e7e5940 Fabrice Bellard
{
533
    for(;height > 0; height--) {
534
        memcpy(dst, src, width);
535
        dst += dst_wrap;
536
        src += src_wrap;
537
    }
538
}
539
540 0469baf1 Fabrice Bellard
/**
541
 * Copy image 'src' to 'dst'.
542
 */
543 da64ecc3 Drew Hess
void img_copy(AVPicture *dst, const AVPicture *src,
544 7e7e5940 Fabrice Bellard
              int pix_fmt, int width, int height)
545
{
546
    int bwidth, bits, i;
547
    PixFmtInfo *pf = &pix_fmt_info[pix_fmt];
548
    
549
    pf = &pix_fmt_info[pix_fmt];
550
    switch(pf->pixel_type) {
551
    case FF_PIXEL_PACKED:
552
        switch(pix_fmt) {
553
        case PIX_FMT_YUV422:
554
        case PIX_FMT_RGB565:
555
        case PIX_FMT_RGB555:
556
            bits = 16;
557
            break;
558
        default:
559
            bits = pf->depth * pf->nb_channels;
560
            break;
561
        }
562
        bwidth = (width * bits + 7) >> 3;
563
        img_copy_plane(dst->data[0], dst->linesize[0],
564
                       src->data[0], src->linesize[0],
565
                       bwidth, height);
566
        break;
567
    case FF_PIXEL_PLANAR:
568
        for(i = 0; i < pf->nb_channels; i++) {
569
            int w, h;
570
            w = width;
571
            h = height;
572
            if (i == 1 || i == 2) {
573
                w >>= pf->x_chroma_shift;
574
                h >>= pf->y_chroma_shift;
575
            }
576
            bwidth = (w * pf->depth + 7) >> 3;
577
            img_copy_plane(dst->data[i], dst->linesize[i],
578
                           src->data[i], src->linesize[i],
579
                           bwidth, h);
580
        }
581
        break;
582
    case FF_PIXEL_PALETTE:
583
        img_copy_plane(dst->data[0], dst->linesize[0],
584
                       src->data[0], src->linesize[0],
585
                       width, height);
586
        /* copy the palette */
587
        img_copy_plane(dst->data[1], dst->linesize[1],
588
                       src->data[1], src->linesize[1],
589
                       4, 256);
590
        break;
591
    }
592
}
593 2a877875 Fabrice Bellard
594 de6d9b64 Fabrice Bellard
/* XXX: totally non optimized */
595
596 da64ecc3 Drew Hess
static void yuv422_to_yuv420p(AVPicture *dst, const AVPicture *src,
597 524c6b63 Fabrice Bellard
                              int width, int height)
598 de6d9b64 Fabrice Bellard
{
599 c50c0bc8 Fabrice Bellard
    const uint8_t *p, *p1;
600
    uint8_t *lum, *cr, *cb, *lum1, *cr1, *cb1;
601 d4f5d74a Garrick Meeker
    int w;
602 524c6b63 Fabrice Bellard
 
603 c50c0bc8 Fabrice Bellard
    p1 = src->data[0];
604
    lum1 = dst->data[0];
605 0a05e494 Fabrice Bellard
    cb1 = dst->data[1];
606
    cr1 = dst->data[2];
607 c50c0bc8 Fabrice Bellard
608 d4f5d74a Garrick Meeker
    for(;height >= 1; height -= 2) {
609 c50c0bc8 Fabrice Bellard
        p = p1;
610
        lum = lum1;
611
        cb = cb1;
612
        cr = cr1;
613 d4f5d74a Garrick Meeker
        for(w = width; w >= 2; w -= 2) {
614 e78df699 Michael Niedermayer
            lum[0] = p[0];
615
            cb[0] = p[1];
616
            lum[1] = p[2];
617
            cr[0] = p[3];
618 de6d9b64 Fabrice Bellard
            p += 4;
619
            lum += 2;
620
            cb++;
621
            cr++;
622
        }
623 d4f5d74a Garrick Meeker
        if (w) {
624 e78df699 Michael Niedermayer
            lum[0] = p[0];
625 d4f5d74a Garrick Meeker
            cb[0] = p[1];
626
            cr[0] = p[3];
627
            cb++;
628
            cr++;
629 de6d9b64 Fabrice Bellard
        }
630 c50c0bc8 Fabrice Bellard
        p1 += src->linesize[0];
631
        lum1 += dst->linesize[0];
632 d4f5d74a Garrick Meeker
        if (height>1) {
633
            p = p1;
634
            lum = lum1;
635
            for(w = width; w >= 2; w -= 2) {
636
                lum[0] = p[0];
637
                lum[1] = p[2];
638
                p += 4;
639
                lum += 2;
640
            }
641
            if (w) {
642
                lum[0] = p[0];
643
            }
644
            p1 += src->linesize[0];
645
            lum1 += dst->linesize[0];
646
        }
647 c50c0bc8 Fabrice Bellard
        cb1 += dst->linesize[1];
648
        cr1 += dst->linesize[2];
649
    }
650
}
651
652 da64ecc3 Drew Hess
static void yuv422_to_yuv422p(AVPicture *dst, const AVPicture *src,
653 c50c0bc8 Fabrice Bellard
                              int width, int height)
654
{
655
    const uint8_t *p, *p1;
656
    uint8_t *lum, *cr, *cb, *lum1, *cr1, *cb1;
657
    int w;
658
659
    p1 = src->data[0];
660
    lum1 = dst->data[0];
661 0a05e494 Fabrice Bellard
    cb1 = dst->data[1];
662
    cr1 = dst->data[2];
663
    for(;height > 0; height--) {
664 c50c0bc8 Fabrice Bellard
        p = p1;
665
        lum = lum1;
666
        cb = cb1;
667
        cr = cr1;
668
        for(w = width; w >= 2; w -= 2) {
669
            lum[0] = p[0];
670
            cb[0] = p[1];
671
            lum[1] = p[2];
672
            cr[0] = p[3];
673
            p += 4;
674
            lum += 2;
675
            cb++;
676
            cr++;
677
        }
678
        p1 += src->linesize[0];
679
        lum1 += dst->linesize[0];
680
        cb1 += dst->linesize[1];
681
        cr1 += dst->linesize[2];
682 de6d9b64 Fabrice Bellard
    }
683
}
684
685 da64ecc3 Drew Hess
static void yuv422p_to_yuv422(AVPicture *dst, const AVPicture *src,
686 c50c0bc8 Fabrice Bellard
                              int width, int height)
687
{
688
    uint8_t *p, *p1;
689
    const uint8_t *lum, *cr, *cb, *lum1, *cr1, *cb1;
690
    int w;
691
692
    p1 = dst->data[0];
693
    lum1 = src->data[0];
694 0a05e494 Fabrice Bellard
    cb1 = src->data[1];
695
    cr1 = src->data[2];
696
    for(;height > 0; height--) {
697 c50c0bc8 Fabrice Bellard
        p = p1;
698
        lum = lum1;
699
        cb = cb1;
700
        cr = cr1;
701
        for(w = width; w >= 2; w -= 2) {
702
            p[0] = lum[0];
703
            p[1] = cb[0];
704
            p[2] = lum[1];
705
            p[3] = cr[0];
706
            p += 4;
707
            lum += 2;
708
            cb++;
709
            cr++;
710
        }
711 0a05e494 Fabrice Bellard
        p1 += dst->linesize[0];
712
        lum1 += src->linesize[0];
713
        cb1 += src->linesize[1];
714
        cr1 += src->linesize[2];
715 c50c0bc8 Fabrice Bellard
    }
716
}
717
718
#define SCALEBITS 10
719 de6d9b64 Fabrice Bellard
#define ONE_HALF  (1 << (SCALEBITS - 1))
720 c50c0bc8 Fabrice Bellard
#define FIX(x)          ((int) ((x) * (1<<SCALEBITS) + 0.5))
721 de6d9b64 Fabrice Bellard
722 c50c0bc8 Fabrice Bellard
#define YUV_TO_RGB1_CCIR(cb1, cr1)\
723
{\
724
    cb = (cb1) - 128;\
725
    cr = (cr1) - 128;\
726
    r_add = FIX(1.40200*255.0/224.0) * cr + ONE_HALF;\
727
    g_add = - FIX(0.34414*255.0/224.0) * cb - FIX(0.71414*255.0/224.0) * cr + \
728
            ONE_HALF;\
729
    b_add = FIX(1.77200*255.0/224.0) * cb + ONE_HALF;\
730
}
731 b6147995 Fabrice Bellard
732 c50c0bc8 Fabrice Bellard
#define YUV_TO_RGB2_CCIR(r, g, b, y1)\
733
{\
734
    y = ((y1) - 16) * FIX(255.0/219.0);\
735
    r = cm[(y + r_add) >> SCALEBITS];\
736
    g = cm[(y + g_add) >> SCALEBITS];\
737
    b = cm[(y + b_add) >> SCALEBITS];\
738
}
739
740
#define YUV_TO_RGB1(cb1, cr1)\
741
{\
742
    cb = (cb1) - 128;\
743
    cr = (cr1) - 128;\
744
    r_add = FIX(1.40200) * cr + ONE_HALF;\
745
    g_add = - FIX(0.34414) * cb - FIX(0.71414) * cr + ONE_HALF;\
746
    b_add = FIX(1.77200) * cb + ONE_HALF;\
747
}
748 b6147995 Fabrice Bellard
749
#define YUV_TO_RGB2(r, g, b, y1)\
750
{\
751 c50c0bc8 Fabrice Bellard
    y = (y1) << SCALEBITS;\
752
    r = cm[(y + r_add) >> SCALEBITS];\
753
    g = cm[(y + g_add) >> SCALEBITS];\
754
    b = cm[(y + b_add) >> SCALEBITS];\
755 b6147995 Fabrice Bellard
}
756
757 c50c0bc8 Fabrice Bellard
#define Y_CCIR_TO_JPEG(y)\
758 b6147995 Fabrice Bellard
 cm[((y) * FIX(255.0/219.0) + (ONE_HALF - 16 * FIX(255.0/219.0))) >> SCALEBITS]
759
760 c50c0bc8 Fabrice Bellard
#define Y_JPEG_TO_CCIR(y)\
761 b6147995 Fabrice Bellard
 (((y) * FIX(219.0/255.0) + (ONE_HALF + (16 << SCALEBITS))) >> SCALEBITS)
762
763 c50c0bc8 Fabrice Bellard
#define C_CCIR_TO_JPEG(y)\
764
 cm[(((y) - 128) * FIX(127.0/112.0) + (ONE_HALF + (128 << SCALEBITS))) >> SCALEBITS]
765
766
/* NOTE: the clamp is really necessary! */
767 4cfbf61b Falk Hüffner
static inline int C_JPEG_TO_CCIR(int y) {
768
    y = (((y - 128) * FIX(112.0/127.0) + (ONE_HALF + (128 << SCALEBITS))) >> SCALEBITS);
769
    if (y < 16)
770
        y = 16;
771
    return y;
772
}
773
774 c50c0bc8 Fabrice Bellard
775 b6147995 Fabrice Bellard
#define RGB_TO_Y(r, g, b) \
776
((FIX(0.29900) * (r) + FIX(0.58700) * (g) + \
777
  FIX(0.11400) * (b) + ONE_HALF) >> SCALEBITS)
778
779 c50c0bc8 Fabrice Bellard
#define RGB_TO_U(r1, g1, b1, shift)\
780 b6147995 Fabrice Bellard
(((- FIX(0.16874) * r1 - FIX(0.33126) * g1 +         \
781 c50c0bc8 Fabrice Bellard
     FIX(0.50000) * b1 + (ONE_HALF << shift) - 1) >> (SCALEBITS + shift)) + 128)
782 b6147995 Fabrice Bellard
783 c50c0bc8 Fabrice Bellard
#define RGB_TO_V(r1, g1, b1, shift)\
784 b6147995 Fabrice Bellard
(((FIX(0.50000) * r1 - FIX(0.41869) * g1 -           \
785 c50c0bc8 Fabrice Bellard
   FIX(0.08131) * b1 + (ONE_HALF << shift) - 1) >> (SCALEBITS + shift)) + 128)
786 b6147995 Fabrice Bellard
787
#define RGB_TO_Y_CCIR(r, g, b) \
788
((FIX(0.29900*219.0/255.0) * (r) + FIX(0.58700*219.0/255.0) * (g) + \
789
  FIX(0.11400*219.0/255.0) * (b) + (ONE_HALF + (16 << SCALEBITS))) >> SCALEBITS)
790
791 c50c0bc8 Fabrice Bellard
#define RGB_TO_U_CCIR(r1, g1, b1, shift)\
792 b6147995 Fabrice Bellard
(((- FIX(0.16874*224.0/255.0) * r1 - FIX(0.33126*224.0/255.0) * g1 +         \
793 c50c0bc8 Fabrice Bellard
     FIX(0.50000*224.0/255.0) * b1 + (ONE_HALF << shift) - 1) >> (SCALEBITS + shift)) + 128)
794 b6147995 Fabrice Bellard
795 c50c0bc8 Fabrice Bellard
#define RGB_TO_V_CCIR(r1, g1, b1, shift)\
796 b6147995 Fabrice Bellard
(((FIX(0.50000*224.0/255.0) * r1 - FIX(0.41869*224.0/255.0) * g1 -           \
797 c50c0bc8 Fabrice Bellard
   FIX(0.08131*224.0/255.0) * b1 + (ONE_HALF << shift) - 1) >> (SCALEBITS + shift)) + 128)
798 b6147995 Fabrice Bellard
799 c50c0bc8 Fabrice Bellard
static uint8_t y_ccir_to_jpeg[256];
800
static uint8_t y_jpeg_to_ccir[256];
801
static uint8_t c_ccir_to_jpeg[256];
802
static uint8_t c_jpeg_to_ccir[256];
803
804
/* init various conversion tables */
805
static void img_convert_init(void)
806 b6147995 Fabrice Bellard
{
807 c50c0bc8 Fabrice Bellard
    int i;
808 b6147995 Fabrice Bellard
    uint8_t *cm = cropTbl + MAX_NEG_CROP;
809
810 c50c0bc8 Fabrice Bellard
    for(i = 0;i < 256; i++) {
811
        y_ccir_to_jpeg[i] = Y_CCIR_TO_JPEG(i);
812
        y_jpeg_to_ccir[i] = Y_JPEG_TO_CCIR(i);
813
        c_ccir_to_jpeg[i] = C_CCIR_TO_JPEG(i);
814
        c_jpeg_to_ccir[i] = C_JPEG_TO_CCIR(i);
815 b6147995 Fabrice Bellard
    }
816
}
817
818 c50c0bc8 Fabrice Bellard
/* apply to each pixel the given table */
819
static void img_apply_table(uint8_t *dst, int dst_wrap, 
820
                            const uint8_t *src, int src_wrap,
821
                            int width, int height, const uint8_t *table1)
822 b6147995 Fabrice Bellard
{
823
    int n;
824
    const uint8_t *s;
825
    uint8_t *d;
826 c50c0bc8 Fabrice Bellard
    const uint8_t *table;
827 b6147995 Fabrice Bellard
828 c50c0bc8 Fabrice Bellard
    table = table1;
829 b6147995 Fabrice Bellard
    for(;height > 0; height--) {
830
        s = src;
831
        d = dst;
832
        n = width;
833
        while (n >= 4) {
834 c50c0bc8 Fabrice Bellard
            d[0] = table[s[0]];
835
            d[1] = table[s[1]];
836
            d[2] = table[s[2]];
837
            d[3] = table[s[3]];
838 b6147995 Fabrice Bellard
            d += 4;
839
            s += 4;
840
            n -= 4;
841
        }
842
        while (n > 0) {
843 c50c0bc8 Fabrice Bellard
            d[0] = table[s[0]];
844 b6147995 Fabrice Bellard
            d++;
845
            s++;
846
            n--;
847
        }
848
        dst += dst_wrap;
849
        src += src_wrap;
850
    }
851
}
852
853 85c242d8 Fabrice Bellard
/* XXX: use generic filter ? */
854 e352ff08 Fabrice Bellard
/* XXX: in most cases, the sampling position is incorrect */
855
856
/* 4x1 -> 1x1 */
857
static void shrink41(uint8_t *dst, int dst_wrap, 
858
                     const uint8_t *src, int src_wrap,
859
                     int width, int height)
860
{
861
    int w;
862
    const uint8_t *s;
863
    uint8_t *d;
864
865
    for(;height > 0; height--) {
866
        s = src;
867
        d = dst;
868
        for(w = width;w > 0; w--) {
869
            d[0] = (s[0] + s[1] + s[2] + s[3] + 2) >> 2;
870
            s += 4;
871
            d++;
872
        }
873
        src += src_wrap;
874
        dst += dst_wrap;
875
    }
876
}
877
878
/* 2x1 -> 1x1 */
879
static void shrink21(uint8_t *dst, int dst_wrap, 
880
                     const uint8_t *src, int src_wrap,
881
                     int width, int height)
882
{
883
    int w;
884
    const uint8_t *s;
885
    uint8_t *d;
886
887
    for(;height > 0; height--) {
888
        s = src;
889
        d = dst;
890
        for(w = width;w > 0; w--) {
891
            d[0] = (s[0] + s[1]) >> 1;
892
            s += 2;
893
            d++;
894
        }
895
        src += src_wrap;
896
        dst += dst_wrap;
897
    }
898
}
899
900 85c242d8 Fabrice Bellard
/* 1x2 -> 1x1 */
901 e352ff08 Fabrice Bellard
static void shrink12(uint8_t *dst, int dst_wrap, 
902
                     const uint8_t *src, int src_wrap,
903
                     int width, int height)
904 85c242d8 Fabrice Bellard
{
905
    int w;
906 e352ff08 Fabrice Bellard
    uint8_t *d;
907
    const uint8_t *s1, *s2;
908 85c242d8 Fabrice Bellard
909
    for(;height > 0; height--) {
910
        s1 = src;
911
        s2 = s1 + src_wrap;
912
        d = dst;
913
        for(w = width;w >= 4; w-=4) {
914
            d[0] = (s1[0] + s2[0]) >> 1;
915
            d[1] = (s1[1] + s2[1]) >> 1;
916
            d[2] = (s1[2] + s2[2]) >> 1;
917
            d[3] = (s1[3] + s2[3]) >> 1;
918
            s1 += 4;
919
            s2 += 4;
920
            d += 4;
921
        }
922
        for(;w > 0; w--) {
923
            d[0] = (s1[0] + s2[0]) >> 1;
924
            s1++;
925
            s2++;
926
            d++;
927
        }
928
        src += 2 * src_wrap;
929
        dst += dst_wrap;
930
    }
931
}
932
933
/* 2x2 -> 1x1 */
934 0c1a9eda Zdenek Kabelac
static void shrink22(uint8_t *dst, int dst_wrap, 
935 e352ff08 Fabrice Bellard
                     const uint8_t *src, int src_wrap,
936 85c242d8 Fabrice Bellard
                     int width, int height)
937
{
938
    int w;
939 e352ff08 Fabrice Bellard
    const uint8_t *s1, *s2;
940
    uint8_t *d;
941 85c242d8 Fabrice Bellard
942
    for(;height > 0; height--) {
943
        s1 = src;
944
        s2 = s1 + src_wrap;
945
        d = dst;
946
        for(w = width;w >= 4; w-=4) {
947 0a9ad8d1 Fabrice Bellard
            d[0] = (s1[0] + s1[1] + s2[0] + s2[1] + 2) >> 2;
948
            d[1] = (s1[2] + s1[3] + s2[2] + s2[3] + 2) >> 2;
949
            d[2] = (s1[4] + s1[5] + s2[4] + s2[5] + 2) >> 2;
950
            d[3] = (s1[6] + s1[7] + s2[6] + s2[7] + 2) >> 2;
951 85c242d8 Fabrice Bellard
            s1 += 8;
952
            s2 += 8;
953
            d += 4;
954
        }
955
        for(;w > 0; w--) {
956 0a9ad8d1 Fabrice Bellard
            d[0] = (s1[0] + s1[1] + s2[0] + s2[1] + 2) >> 2;
957 85c242d8 Fabrice Bellard
            s1 += 2;
958
            s2 += 2;
959
            d++;
960
        }
961
        src += 2 * src_wrap;
962
        dst += dst_wrap;
963
    }
964
}
965
966 e352ff08 Fabrice Bellard
/* 4x4 -> 1x1 */
967
static void shrink44(uint8_t *dst, int dst_wrap, 
968
                     const uint8_t *src, int src_wrap,
969 6742d95d François Revol
                     int width, int height)
970
{
971
    int w;
972 e352ff08 Fabrice Bellard
    const uint8_t *s1, *s2, *s3, *s4;
973
    uint8_t *d;
974 6742d95d François Revol
975
    for(;height > 0; height--) {
976
        s1 = src;
977 e352ff08 Fabrice Bellard
        s2 = s1 + src_wrap;
978
        s3 = s2 + src_wrap;
979
        s4 = s3 + src_wrap;
980 6742d95d François Revol
        d = dst;
981 e352ff08 Fabrice Bellard
        for(w = width;w > 0; w--) {
982
            d[0] = (s1[0] + s1[1] + s1[2] + s1[3] +
983
                    s2[0] + s2[1] + s2[2] + s2[3] +
984
                    s3[0] + s3[1] + s3[2] + s3[3] +
985
                    s4[0] + s4[1] + s4[2] + s4[3] + 8) >> 4;
986
            s1 += 4;
987
            s2 += 4;
988
            s3 += 4;
989
            s4 += 4;
990 6742d95d François Revol
            d++;
991
        }
992 e352ff08 Fabrice Bellard
        src += 4 * src_wrap;
993
        dst += dst_wrap;
994
    }
995
}
996
997
static void grow21_line(uint8_t *dst, const uint8_t *src,
998
                        int width)
999
{
1000
    int w;
1001
    const uint8_t *s1;
1002
    uint8_t *d;
1003
1004
    s1 = src;
1005
    d = dst;
1006
    for(w = width;w >= 4; w-=4) {
1007
        d[1] = d[0] = s1[0];
1008
        d[3] = d[2] = s1[1];
1009
        s1 += 2;
1010
        d += 4;
1011
    }
1012
    for(;w >= 2; w -= 2) {
1013
        d[1] = d[0] = s1[0];
1014
        s1 ++;
1015
        d += 2;
1016
    }
1017
    /* only needed if width is not a multiple of two */
1018
    /* XXX: veryfy that */
1019
    if (w) {
1020
        d[0] = s1[0];
1021
    }
1022
}
1023
1024
static void grow41_line(uint8_t *dst, const uint8_t *src,
1025
                        int width)
1026
{
1027
    int w, v;
1028
    const uint8_t *s1;
1029
    uint8_t *d;
1030
1031
    s1 = src;
1032
    d = dst;
1033
    for(w = width;w >= 4; w-=4) {
1034
        v = s1[0];
1035
        d[0] = v;
1036
        d[1] = v;
1037
        d[2] = v;
1038
        d[3] = v;
1039
        s1 ++;
1040
        d += 4;
1041
    }
1042
}
1043
1044
/* 1x1 -> 2x1 */
1045
static void grow21(uint8_t *dst, int dst_wrap,
1046
                   const uint8_t *src, int src_wrap,
1047
                   int width, int height)
1048
{
1049
    for(;height > 0; height--) {
1050
        grow21_line(dst, src, width);
1051
        src += src_wrap;
1052
        dst += dst_wrap;
1053
    }
1054
}
1055
1056
/* 1x1 -> 2x2 */
1057
static void grow22(uint8_t *dst, int dst_wrap,
1058
                   const uint8_t *src, int src_wrap,
1059
                   int width, int height)
1060
{
1061
    for(;height > 0; height--) {
1062
        grow21_line(dst, src, width);
1063 6742d95d François Revol
        if (height%2)
1064
            src += src_wrap;
1065
        dst += dst_wrap;
1066
    }
1067
}
1068
1069 e352ff08 Fabrice Bellard
/* 1x1 -> 4x1 */
1070
static void grow41(uint8_t *dst, int dst_wrap,
1071
                   const uint8_t *src, int src_wrap,
1072
                   int width, int height)
1073
{
1074
    for(;height > 0; height--) {
1075
        grow41_line(dst, src, width);
1076
        src += src_wrap;
1077
        dst += dst_wrap;
1078
    }
1079
}
1080
1081
/* 1x1 -> 4x4 */
1082
static void grow44(uint8_t *dst, int dst_wrap,
1083
                   const uint8_t *src, int src_wrap,
1084
                   int width, int height)
1085
{
1086
    for(;height > 0; height--) {
1087
        grow41_line(dst, src, width);
1088
        if ((height & 3) == 1)
1089
            src += src_wrap;
1090
        dst += dst_wrap;
1091
    }
1092
}
1093
1094 524c6b63 Fabrice Bellard
/* 1x2 -> 2x1 */
1095 0c1a9eda Zdenek Kabelac
static void conv411(uint8_t *dst, int dst_wrap, 
1096 e352ff08 Fabrice Bellard
                    const uint8_t *src, int src_wrap,
1097 789587d5 Fabrice Bellard
                    int width, int height)
1098
{
1099
    int w, c;
1100 e352ff08 Fabrice Bellard
    const uint8_t *s1, *s2;
1101
    uint8_t *d;
1102 789587d5 Fabrice Bellard
1103 50643575 Michael Niedermayer
    width>>=1;
1104
1105 524c6b63 Fabrice Bellard
    for(;height > 0; height--) {
1106 789587d5 Fabrice Bellard
        s1 = src;
1107
        s2 = src + src_wrap;
1108
        d = dst;
1109
        for(w = width;w > 0; w--) {
1110
            c = (s1[0] + s2[0]) >> 1;
1111
            d[0] = c;
1112
            d[1] = c;
1113
            s1++;
1114
            s2++;
1115
            d += 2;
1116
        }
1117
        src += src_wrap * 2;
1118
        dst += dst_wrap;
1119
    }
1120
}
1121
1122 7e7e5940 Fabrice Bellard
/* XXX: add jpeg quantize code */
1123
1124
#define TRANSP_INDEX (6*6*6)
1125
1126
/* this is maybe slow, but allows for extensions */
1127
static inline unsigned char gif_clut_index(uint8_t r, uint8_t g, uint8_t b)
1128 85c242d8 Fabrice Bellard
{
1129 7e7e5940 Fabrice Bellard
    return ((((r)/47)%6)*6*6+(((g)/47)%6)*6+(((b)/47)%6));
1130 85c242d8 Fabrice Bellard
}
1131
1132 7e7e5940 Fabrice Bellard
static void build_rgb_palette(uint8_t *palette, int has_alpha)
1133
{
1134
    uint32_t *pal;
1135
    static const uint8_t pal_value[6] = { 0x00, 0x33, 0x66, 0x99, 0xcc, 0xff };
1136
    int i, r, g, b;
1137
1138
    pal = (uint32_t *)palette;
1139
    i = 0;
1140
    for(r = 0; r < 6; r++) {
1141
        for(g = 0; g < 6; g++) {
1142
            for(b = 0; b < 6; b++) {
1143
                pal[i++] = (0xff << 24) | (pal_value[r] << 16) | 
1144
                    (pal_value[g] << 8) | pal_value[b];
1145
            }
1146
        }
1147
    }
1148
    if (has_alpha)
1149
        pal[i++] = 0;
1150
    while (i < 256)
1151
        pal[i++] = 0xff000000;
1152 524c6b63 Fabrice Bellard
}
1153
1154
/* copy bit n to bits 0 ... n - 1 */
1155
static inline unsigned int bitcopy_n(unsigned int a, int n)
1156 b71472eb Philip Gladstone
{
1157 524c6b63 Fabrice Bellard
    int mask;
1158
    mask = (1 << n) - 1;
1159
    return (a & (0xff & ~mask)) | ((-((a >> n) & 1)) & mask);
1160
}
1161
1162
/* rgb555 handling */
1163
1164 7e7e5940 Fabrice Bellard
#define RGB_NAME rgb555
1165
1166 524c6b63 Fabrice Bellard
#define RGB_IN(r, g, b, s)\
1167
{\
1168 0c1a9eda Zdenek Kabelac
    unsigned int v = ((const uint16_t *)(s))[0];\
1169 524c6b63 Fabrice Bellard
    r = bitcopy_n(v >> (10 - 3), 3);\
1170
    g = bitcopy_n(v >> (5 - 3), 3);\
1171
    b = bitcopy_n(v << 3, 3);\
1172
}
1173
1174 7e7e5940 Fabrice Bellard
#define RGBA_IN(r, g, b, a, s)\
1175 524c6b63 Fabrice Bellard
{\
1176 7e7e5940 Fabrice Bellard
    unsigned int v = ((const uint16_t *)(s))[0];\
1177
    r = bitcopy_n(v >> (10 - 3), 3);\
1178
    g = bitcopy_n(v >> (5 - 3), 3);\
1179
    b = bitcopy_n(v << 3, 3);\
1180 b5ff5e22 Fabrice Bellard
    a = (-(v >> 15)) & 0xff;\
1181 7e7e5940 Fabrice Bellard
}
1182
1183
#define RGBA_OUT(d, r, g, b, a)\
1184
{\
1185
    ((uint16_t *)(d))[0] = ((r >> 3) << 10) | ((g >> 3) << 5) | (b >> 3) | \
1186
                           ((a << 8) & 0x8000);\
1187 524c6b63 Fabrice Bellard
}
1188
1189
#define BPP 2
1190
1191 7e7e5940 Fabrice Bellard
#include "imgconvert_template.h"
1192 524c6b63 Fabrice Bellard
1193
/* rgb565 handling */
1194
1195 7e7e5940 Fabrice Bellard
#define RGB_NAME rgb565
1196
1197 524c6b63 Fabrice Bellard
#define RGB_IN(r, g, b, s)\
1198
{\
1199 0c1a9eda Zdenek Kabelac
    unsigned int v = ((const uint16_t *)(s))[0];\
1200 524c6b63 Fabrice Bellard
    r = bitcopy_n(v >> (11 - 3), 3);\
1201
    g = bitcopy_n(v >> (5 - 2), 2);\
1202
    b = bitcopy_n(v << 3, 3);\
1203
}
1204
1205
#define RGB_OUT(d, r, g, b)\
1206
{\
1207 0c1a9eda Zdenek Kabelac
    ((uint16_t *)(d))[0] = ((r >> 3) << 11) | ((g >> 2) << 5) | (b >> 3);\
1208 524c6b63 Fabrice Bellard
}
1209
1210
#define BPP 2
1211
1212 7e7e5940 Fabrice Bellard
#include "imgconvert_template.h"
1213 524c6b63 Fabrice Bellard
1214
/* bgr24 handling */
1215
1216 7e7e5940 Fabrice Bellard
#define RGB_NAME bgr24
1217
1218 524c6b63 Fabrice Bellard
#define RGB_IN(r, g, b, s)\
1219
{\
1220
    b = (s)[0];\
1221
    g = (s)[1];\
1222
    r = (s)[2];\
1223
}
1224
1225
#define RGB_OUT(d, r, g, b)\
1226
{\
1227
    (d)[0] = b;\
1228
    (d)[1] = g;\
1229
    (d)[2] = r;\
1230
}
1231
1232
#define BPP 3
1233
1234 7e7e5940 Fabrice Bellard
#include "imgconvert_template.h"
1235 524c6b63 Fabrice Bellard
1236
#undef RGB_IN
1237
#undef RGB_OUT
1238
#undef BPP
1239
1240
/* rgb24 handling */
1241
1242 7e7e5940 Fabrice Bellard
#define RGB_NAME rgb24
1243
#define FMT_RGB24
1244
1245 524c6b63 Fabrice Bellard
#define RGB_IN(r, g, b, s)\
1246
{\
1247
    r = (s)[0];\
1248
    g = (s)[1];\
1249
    b = (s)[2];\
1250
}
1251
1252
#define RGB_OUT(d, r, g, b)\
1253
{\
1254
    (d)[0] = r;\
1255
    (d)[1] = g;\
1256
    (d)[2] = b;\
1257
}
1258
1259
#define BPP 3
1260
1261 7e7e5940 Fabrice Bellard
#include "imgconvert_template.h"
1262 524c6b63 Fabrice Bellard
1263
/* rgba32 handling */
1264
1265 7e7e5940 Fabrice Bellard
#define RGB_NAME rgba32
1266
#define FMT_RGBA32
1267
1268 524c6b63 Fabrice Bellard
#define RGB_IN(r, g, b, s)\
1269
{\
1270 0c1a9eda Zdenek Kabelac
    unsigned int v = ((const uint32_t *)(s))[0];\
1271 524c6b63 Fabrice Bellard
    r = (v >> 16) & 0xff;\
1272
    g = (v >> 8) & 0xff;\
1273
    b = v & 0xff;\
1274
}
1275
1276 7e7e5940 Fabrice Bellard
#define RGBA_IN(r, g, b, a, s)\
1277 524c6b63 Fabrice Bellard
{\
1278 7e7e5940 Fabrice Bellard
    unsigned int v = ((const uint32_t *)(s))[0];\
1279
    a = (v >> 24) & 0xff;\
1280
    r = (v >> 16) & 0xff;\
1281
    g = (v >> 8) & 0xff;\
1282
    b = v & 0xff;\
1283 524c6b63 Fabrice Bellard
}
1284
1285 7e7e5940 Fabrice Bellard
#define RGBA_OUT(d, r, g, b, a)\
1286
{\
1287
    ((uint32_t *)(d))[0] = (a << 24) | (r << 16) | (g << 8) | b;\
1288 b71472eb Philip Gladstone
}
1289
1290 7e7e5940 Fabrice Bellard
#define BPP 4
1291 524c6b63 Fabrice Bellard
1292 7e7e5940 Fabrice Bellard
#include "imgconvert_template.h"
1293 b71472eb Philip Gladstone
1294 da64ecc3 Drew Hess
static void mono_to_gray(AVPicture *dst, const AVPicture *src,
1295 2a877875 Fabrice Bellard
                         int width, int height, int xor_mask)
1296 524c6b63 Fabrice Bellard
{
1297
    const unsigned char *p;
1298
    unsigned char *q;
1299
    int v, dst_wrap, src_wrap;
1300
    int y, w;
1301
1302
    p = src->data[0];
1303
    src_wrap = src->linesize[0] - ((width + 7) >> 3);
1304
1305
    q = dst->data[0];
1306 2a877875 Fabrice Bellard
    dst_wrap = dst->linesize[0] - width;
1307 524c6b63 Fabrice Bellard
    for(y=0;y<height;y++) {
1308
        w = width; 
1309
        while (w >= 8) {
1310 2a877875 Fabrice Bellard
            v = *p++ ^ xor_mask;
1311
            q[0] = -(v >> 7);
1312
            q[1] = -((v >> 6) & 1);
1313
            q[2] = -((v >> 5) & 1);
1314
            q[3] = -((v >> 4) & 1);
1315
            q[4] = -((v >> 3) & 1);
1316
            q[5] = -((v >> 2) & 1);
1317
            q[6] = -((v >> 1) & 1);
1318
            q[7] = -((v >> 0) & 1);
1319 524c6b63 Fabrice Bellard
            w -= 8;
1320 2a877875 Fabrice Bellard
            q += 8;
1321 524c6b63 Fabrice Bellard
        }
1322
        if (w > 0) {
1323 2a877875 Fabrice Bellard
            v = *p++ ^ xor_mask;
1324 524c6b63 Fabrice Bellard
            do {
1325 2a877875 Fabrice Bellard
                q[0] = -((v >> 7) & 1);
1326
                q++;
1327 524c6b63 Fabrice Bellard
                v <<= 1;
1328
            } while (--w);
1329 85c242d8 Fabrice Bellard
        }
1330 524c6b63 Fabrice Bellard
        p += src_wrap;
1331
        q += dst_wrap;
1332 85c242d8 Fabrice Bellard
    }
1333
}
1334
1335 da64ecc3 Drew Hess
static void monowhite_to_gray(AVPicture *dst, const AVPicture *src,
1336 524c6b63 Fabrice Bellard
                               int width, int height)
1337
{
1338 2a877875 Fabrice Bellard
    mono_to_gray(dst, src, width, height, 0xff);
1339
}
1340 524c6b63 Fabrice Bellard
1341 da64ecc3 Drew Hess
static void monoblack_to_gray(AVPicture *dst, const AVPicture *src,
1342 2a877875 Fabrice Bellard
                               int width, int height)
1343
{
1344
    mono_to_gray(dst, src, width, height, 0x00);
1345
}
1346 524c6b63 Fabrice Bellard
1347 da64ecc3 Drew Hess
static void gray_to_mono(AVPicture *dst, const AVPicture *src,
1348 2a877875 Fabrice Bellard
                         int width, int height, int xor_mask)
1349
{
1350
    int n;
1351 0c1a9eda Zdenek Kabelac
    const uint8_t *s;
1352
    uint8_t *d;
1353 2a877875 Fabrice Bellard
    int j, b, v, n1, src_wrap, dst_wrap, y;
1354
1355
    s = src->data[0];
1356
    src_wrap = src->linesize[0] - width;
1357
1358
    d = dst->data[0];
1359
    dst_wrap = dst->linesize[0] - ((width + 7) >> 3);
1360 524c6b63 Fabrice Bellard
1361
    for(y=0;y<height;y++) {
1362 2a877875 Fabrice Bellard
        n = width;
1363
        while (n >= 8) {
1364
            v = 0;
1365
            for(j=0;j<8;j++) {
1366
                b = s[0];
1367
                s++;
1368
                v = (v << 1) | (b >> 7);
1369
            }
1370
            d[0] = v ^ xor_mask;
1371
            d++;
1372
            n -= 8;
1373 524c6b63 Fabrice Bellard
        }
1374 2a877875 Fabrice Bellard
        if (n > 0) {
1375
            n1 = n;
1376
            v = 0;
1377
            while (n > 0) {
1378
                b = s[0];
1379
                s++;
1380
                v = (v << 1) | (b >> 7);
1381
                n--;
1382
            }
1383
            d[0] = (v << (8 - (n1 & 7))) ^ xor_mask;
1384
            d++;
1385 524c6b63 Fabrice Bellard
        }
1386 2a877875 Fabrice Bellard
        s += src_wrap;
1387
        d += dst_wrap;
1388 524c6b63 Fabrice Bellard
    }
1389
}
1390
1391 da64ecc3 Drew Hess
static void gray_to_monowhite(AVPicture *dst, const AVPicture *src,
1392 2a877875 Fabrice Bellard
                              int width, int height)
1393
{
1394
    gray_to_mono(dst, src, width, height, 0xff);
1395
}
1396
1397 da64ecc3 Drew Hess
static void gray_to_monoblack(AVPicture *dst, const AVPicture *src,
1398 2a877875 Fabrice Bellard
                              int width, int height)
1399
{
1400
    gray_to_mono(dst, src, width, height, 0x00);
1401
}
1402
1403 524c6b63 Fabrice Bellard
typedef struct ConvertEntry {
1404 da64ecc3 Drew Hess
    void (*convert)(AVPicture *dst,
1405
                    const AVPicture *src, int width, int height);
1406 524c6b63 Fabrice Bellard
} ConvertEntry;
1407
1408 c50c0bc8 Fabrice Bellard
/* Add each new convertion function in this table. In order to be able
1409
   to convert from any format to any format, the following constraints
1410
   must be satisfied:
1411

1412
   - all FF_COLOR_RGB formats must convert to and from PIX_FMT_RGB24 
1413

1414
   - all FF_COLOR_GRAY formats must convert to and from PIX_FMT_GRAY8
1415

1416
   - all FF_COLOR_RGB formats with alpha must convert to and from PIX_FMT_RGBA32
1417

1418 e352ff08 Fabrice Bellard
   - PIX_FMT_YUV444P and PIX_FMT_YUVJ444P must convert to and from
1419 c50c0bc8 Fabrice Bellard
     PIX_FMT_RGB24.
1420

1421
   - PIX_FMT_422 must convert to and from PIX_FMT_422P.
1422 e352ff08 Fabrice Bellard

1423
   The other conversion functions are just optimisations for common cases.
1424 524c6b63 Fabrice Bellard
*/
1425
static ConvertEntry convert_table[PIX_FMT_NB][PIX_FMT_NB] = {
1426
    [PIX_FMT_YUV420P] = {
1427
        [PIX_FMT_RGB555] = { 
1428 ef9f7306 Måns Rullgård
            .convert = yuv420p_to_rgb555
1429 524c6b63 Fabrice Bellard
        },
1430
        [PIX_FMT_RGB565] = { 
1431 ef9f7306 Måns Rullgård
            .convert = yuv420p_to_rgb565
1432 524c6b63 Fabrice Bellard
        },
1433
        [PIX_FMT_BGR24] = { 
1434 ef9f7306 Måns Rullgård
            .convert = yuv420p_to_bgr24
1435 524c6b63 Fabrice Bellard
        },
1436
        [PIX_FMT_RGB24] = { 
1437 ef9f7306 Måns Rullgård
            .convert = yuv420p_to_rgb24
1438 524c6b63 Fabrice Bellard
        },
1439
        [PIX_FMT_RGBA32] = { 
1440 ef9f7306 Måns Rullgård
            .convert = yuv420p_to_rgba32
1441 524c6b63 Fabrice Bellard
        },
1442
    },
1443 c50c0bc8 Fabrice Bellard
    [PIX_FMT_YUV422P] = { 
1444
        [PIX_FMT_YUV422] = { 
1445
            .convert = yuv422p_to_yuv422,
1446
        },
1447
    },
1448
    [PIX_FMT_YUV444P] = { 
1449
        [PIX_FMT_RGB24] = { 
1450
            .convert = yuv444p_to_rgb24
1451
        },
1452
    },
1453
    [PIX_FMT_YUVJ420P] = {
1454 524c6b63 Fabrice Bellard
        [PIX_FMT_RGB555] = { 
1455 c50c0bc8 Fabrice Bellard
            .convert = yuvj420p_to_rgb555
1456 524c6b63 Fabrice Bellard
        },
1457
        [PIX_FMT_RGB565] = { 
1458 c50c0bc8 Fabrice Bellard
            .convert = yuvj420p_to_rgb565
1459 524c6b63 Fabrice Bellard
        },
1460
        [PIX_FMT_BGR24] = { 
1461 c50c0bc8 Fabrice Bellard
            .convert = yuvj420p_to_bgr24
1462 524c6b63 Fabrice Bellard
        },
1463
        [PIX_FMT_RGB24] = { 
1464 c50c0bc8 Fabrice Bellard
            .convert = yuvj420p_to_rgb24
1465 524c6b63 Fabrice Bellard
        },
1466
        [PIX_FMT_RGBA32] = { 
1467 c50c0bc8 Fabrice Bellard
            .convert = yuvj420p_to_rgba32
1468
        },
1469
    },
1470
    [PIX_FMT_YUVJ444P] = { 
1471
        [PIX_FMT_RGB24] = { 
1472
            .convert = yuvj444p_to_rgb24
1473 524c6b63 Fabrice Bellard
        },
1474
    },
1475
    [PIX_FMT_YUV422] = { 
1476
        [PIX_FMT_YUV420P] = { 
1477 ef9f7306 Måns Rullgård
            .convert = yuv422_to_yuv420p,
1478 524c6b63 Fabrice Bellard
        },
1479 c50c0bc8 Fabrice Bellard
        [PIX_FMT_YUV422P] = { 
1480
            .convert = yuv422_to_yuv422p,
1481
        },
1482 524c6b63 Fabrice Bellard
    },
1483
1484
    [PIX_FMT_RGB24] = {
1485
        [PIX_FMT_YUV420P] = { 
1486 ef9f7306 Måns Rullgård
            .convert = rgb24_to_yuv420p
1487 524c6b63 Fabrice Bellard
        },
1488
        [PIX_FMT_RGB565] = { 
1489 ef9f7306 Måns Rullgård
            .convert = rgb24_to_rgb565
1490 524c6b63 Fabrice Bellard
        },
1491
        [PIX_FMT_RGB555] = { 
1492 ef9f7306 Måns Rullgård
            .convert = rgb24_to_rgb555
1493 524c6b63 Fabrice Bellard
        },
1494 7e7e5940 Fabrice Bellard
        [PIX_FMT_RGBA32] = { 
1495
            .convert = rgb24_to_rgba32
1496
        },
1497
        [PIX_FMT_BGR24] = { 
1498
            .convert = rgb24_to_bgr24
1499
        },
1500 524c6b63 Fabrice Bellard
        [PIX_FMT_GRAY8] = { 
1501 ef9f7306 Måns Rullgård
            .convert = rgb24_to_gray
1502 524c6b63 Fabrice Bellard
        },
1503 7e7e5940 Fabrice Bellard
        [PIX_FMT_PAL8] = {
1504 7e6d70d0 Fabrice Bellard
            .convert = rgb24_to_pal8
1505
        },
1506 c50c0bc8 Fabrice Bellard
        [PIX_FMT_YUV444P] = { 
1507
            .convert = rgb24_to_yuv444p
1508
        },
1509
        [PIX_FMT_YUVJ420P] = { 
1510
            .convert = rgb24_to_yuvj420p
1511
        },
1512
        [PIX_FMT_YUVJ444P] = { 
1513
            .convert = rgb24_to_yuvj444p
1514
        },
1515 524c6b63 Fabrice Bellard
    },
1516
    [PIX_FMT_RGBA32] = {
1517 7e7e5940 Fabrice Bellard
        [PIX_FMT_RGB24] = { 
1518
            .convert = rgba32_to_rgb24
1519
        },
1520
        [PIX_FMT_RGB555] = { 
1521
            .convert = rgba32_to_rgb555
1522
        },
1523
        [PIX_FMT_PAL8] = { 
1524
            .convert = rgba32_to_pal8
1525
        },
1526 524c6b63 Fabrice Bellard
        [PIX_FMT_YUV420P] = { 
1527 ef9f7306 Måns Rullgård
            .convert = rgba32_to_yuv420p
1528 524c6b63 Fabrice Bellard
        },
1529 69572401 Fabrice Bellard
        [PIX_FMT_GRAY8] = { 
1530
            .convert = rgba32_to_gray
1531
        },
1532 524c6b63 Fabrice Bellard
    },
1533
    [PIX_FMT_BGR24] = {
1534 7e7e5940 Fabrice Bellard
        [PIX_FMT_RGB24] = { 
1535
            .convert = bgr24_to_rgb24
1536
        },
1537 524c6b63 Fabrice Bellard
        [PIX_FMT_YUV420P] = { 
1538 ef9f7306 Måns Rullgård
            .convert = bgr24_to_yuv420p
1539 524c6b63 Fabrice Bellard
        },
1540 69572401 Fabrice Bellard
        [PIX_FMT_GRAY8] = { 
1541
            .convert = bgr24_to_gray
1542
        },
1543 524c6b63 Fabrice Bellard
    },
1544
    [PIX_FMT_RGB555] = {
1545 7e7e5940 Fabrice Bellard
        [PIX_FMT_RGB24] = { 
1546
            .convert = rgb555_to_rgb24
1547
        },
1548
        [PIX_FMT_RGBA32] = { 
1549
            .convert = rgb555_to_rgba32
1550
        },
1551 524c6b63 Fabrice Bellard
        [PIX_FMT_YUV420P] = { 
1552 ef9f7306 Måns Rullgård
            .convert = rgb555_to_yuv420p
1553 524c6b63 Fabrice Bellard
        },
1554 69572401 Fabrice Bellard
        [PIX_FMT_GRAY8] = { 
1555
            .convert = rgb555_to_gray
1556
        },
1557 524c6b63 Fabrice Bellard
    },
1558
    [PIX_FMT_RGB565] = {
1559 7e7e5940 Fabrice Bellard
        [PIX_FMT_RGB24] = { 
1560
            .convert = rgb565_to_rgb24
1561
        },
1562 524c6b63 Fabrice Bellard
        [PIX_FMT_YUV420P] = { 
1563 ef9f7306 Måns Rullgård
            .convert = rgb565_to_yuv420p
1564 524c6b63 Fabrice Bellard
        },
1565 69572401 Fabrice Bellard
        [PIX_FMT_GRAY8] = { 
1566
            .convert = rgb565_to_gray
1567
        },
1568 524c6b63 Fabrice Bellard
    },
1569
    [PIX_FMT_GRAY8] = {
1570 69572401 Fabrice Bellard
        [PIX_FMT_RGB555] = { 
1571
            .convert = gray_to_rgb555
1572
        },
1573
        [PIX_FMT_RGB565] = { 
1574
            .convert = gray_to_rgb565
1575
        },
1576 524c6b63 Fabrice Bellard
        [PIX_FMT_RGB24] = { 
1577 ef9f7306 Måns Rullgård
            .convert = gray_to_rgb24
1578 524c6b63 Fabrice Bellard
        },
1579 69572401 Fabrice Bellard
        [PIX_FMT_BGR24] = { 
1580
            .convert = gray_to_bgr24
1581
        },
1582
        [PIX_FMT_RGBA32] = { 
1583
            .convert = gray_to_rgba32
1584
        },
1585 2a877875 Fabrice Bellard
        [PIX_FMT_MONOWHITE] = { 
1586 ef9f7306 Måns Rullgård
            .convert = gray_to_monowhite
1587 2a877875 Fabrice Bellard
        },
1588
        [PIX_FMT_MONOBLACK] = { 
1589 ef9f7306 Måns Rullgård
            .convert = gray_to_monoblack
1590 2a877875 Fabrice Bellard
        },
1591 524c6b63 Fabrice Bellard
    },
1592
    [PIX_FMT_MONOWHITE] = {
1593 2a877875 Fabrice Bellard
        [PIX_FMT_GRAY8] = { 
1594 ef9f7306 Måns Rullgård
            .convert = monowhite_to_gray
1595 524c6b63 Fabrice Bellard
        },
1596
    },
1597
    [PIX_FMT_MONOBLACK] = {
1598 2a877875 Fabrice Bellard
        [PIX_FMT_GRAY8] = { 
1599 ef9f7306 Måns Rullgård
            .convert = monoblack_to_gray
1600 524c6b63 Fabrice Bellard
        },
1601
    },
1602 7e6d70d0 Fabrice Bellard
    [PIX_FMT_PAL8] = {
1603
        [PIX_FMT_RGB555] = { 
1604
            .convert = pal8_to_rgb555
1605
        },
1606
        [PIX_FMT_RGB565] = { 
1607
            .convert = pal8_to_rgb565
1608
        },
1609
        [PIX_FMT_BGR24] = { 
1610
            .convert = pal8_to_bgr24
1611
        },
1612
        [PIX_FMT_RGB24] = { 
1613
            .convert = pal8_to_rgb24
1614
        },
1615
        [PIX_FMT_RGBA32] = { 
1616
            .convert = pal8_to_rgba32
1617
        },
1618
    },
1619 524c6b63 Fabrice Bellard
};
1620
1621 75917b88 Drew Hess
int avpicture_alloc(AVPicture *picture,
1622 524c6b63 Fabrice Bellard
                           int pix_fmt, int width, int height)
1623
{
1624 5c91a675 Zdenek Kabelac
    unsigned int size;
1625 524c6b63 Fabrice Bellard
    void *ptr;
1626
1627
    size = avpicture_get_size(pix_fmt, width, height);
1628
    ptr = av_malloc(size);
1629
    if (!ptr)
1630
        goto fail;
1631
    avpicture_fill(picture, ptr, pix_fmt, width, height);
1632
    return 0;
1633
 fail:
1634
    memset(picture, 0, sizeof(AVPicture));
1635
    return -1;
1636
}
1637
1638 75917b88 Drew Hess
void avpicture_free(AVPicture *picture)
1639 524c6b63 Fabrice Bellard
{
1640 8e1e6f31 Fabrice Bellard
    av_free(picture->data[0]);
1641 524c6b63 Fabrice Bellard
}
1642
1643 c50c0bc8 Fabrice Bellard
/* return true if yuv planar */
1644
static inline int is_yuv_planar(PixFmtInfo *ps)
1645
{
1646
    return (ps->color_type == FF_COLOR_YUV ||
1647 7e7e5940 Fabrice Bellard
            ps->color_type == FF_COLOR_YUV_JPEG) && 
1648
        ps->pixel_type == FF_PIXEL_PLANAR;
1649 c50c0bc8 Fabrice Bellard
}
1650
1651 85c242d8 Fabrice Bellard
/* XXX: always use linesize. Return -1 if not supported */
1652
int img_convert(AVPicture *dst, int dst_pix_fmt,
1653 da64ecc3 Drew Hess
                const AVPicture *src, int src_pix_fmt, 
1654 524c6b63 Fabrice Bellard
                int src_width, int src_height)
1655 85c242d8 Fabrice Bellard
{
1656 c50c0bc8 Fabrice Bellard
    static int inited;
1657 2a877875 Fabrice Bellard
    int i, ret, dst_width, dst_height, int_pix_fmt;
1658 524c6b63 Fabrice Bellard
    PixFmtInfo *src_pix, *dst_pix;
1659
    ConvertEntry *ce;
1660
    AVPicture tmp1, *tmp = &tmp1;
1661
1662
    if (src_pix_fmt < 0 || src_pix_fmt >= PIX_FMT_NB ||
1663
        dst_pix_fmt < 0 || dst_pix_fmt >= PIX_FMT_NB)
1664
        return -1;
1665
    if (src_width <= 0 || src_height <= 0)
1666
        return 0;
1667 69572401 Fabrice Bellard
1668 c50c0bc8 Fabrice Bellard
    if (!inited) {
1669
        inited = 1;
1670
        img_convert_init();
1671
    }
1672
1673 524c6b63 Fabrice Bellard
    dst_width = src_width;
1674
    dst_height = src_height;
1675 69572401 Fabrice Bellard
1676 524c6b63 Fabrice Bellard
    dst_pix = &pix_fmt_info[dst_pix_fmt];
1677
    src_pix = &pix_fmt_info[src_pix_fmt];
1678
    if (src_pix_fmt == dst_pix_fmt) {
1679 7e7e5940 Fabrice Bellard
        /* no conversion needed: just copy */
1680
        img_copy(dst, src, dst_pix_fmt, dst_width, dst_height);
1681 524c6b63 Fabrice Bellard
        return 0;
1682
    }
1683
1684
    ce = &convert_table[src_pix_fmt][dst_pix_fmt];
1685
    if (ce->convert) {
1686
        /* specific convertion routine */
1687
        ce->convert(dst, src, dst_width, dst_height);
1688
        return 0;
1689
    }
1690
1691
    /* gray to YUV */
1692 c50c0bc8 Fabrice Bellard
    if (is_yuv_planar(dst_pix) &&
1693 b6147995 Fabrice Bellard
        src_pix_fmt == PIX_FMT_GRAY8) {
1694 524c6b63 Fabrice Bellard
        int w, h, y;
1695
        uint8_t *d;
1696
1697 b6147995 Fabrice Bellard
        if (dst_pix->color_type == FF_COLOR_YUV_JPEG) {
1698 7e7e5940 Fabrice Bellard
            img_copy_plane(dst->data[0], dst->linesize[0],
1699 b6147995 Fabrice Bellard
                     src->data[0], src->linesize[0],
1700
                     dst_width, dst_height);
1701
        } else {
1702 c50c0bc8 Fabrice Bellard
            img_apply_table(dst->data[0], dst->linesize[0],
1703
                            src->data[0], src->linesize[0],
1704
                            dst_width, dst_height,
1705
                            y_jpeg_to_ccir);
1706 b6147995 Fabrice Bellard
        }
1707 524c6b63 Fabrice Bellard
        /* fill U and V with 128 */
1708
        w = dst_width;
1709
        h = dst_height;
1710
        w >>= dst_pix->x_chroma_shift;
1711
        h >>= dst_pix->y_chroma_shift;
1712
        for(i = 1; i <= 2; i++) {
1713
            d = dst->data[i];
1714 2a877875 Fabrice Bellard
            for(y = 0; y< h; y++) {
1715
                memset(d, 128, w);
1716 524c6b63 Fabrice Bellard
                d += dst->linesize[i];
1717
            }
1718 b71472eb Philip Gladstone
        }
1719 524c6b63 Fabrice Bellard
        return 0;
1720
    }
1721
1722
    /* YUV to gray */
1723 c50c0bc8 Fabrice Bellard
    if (is_yuv_planar(src_pix) && 
1724 b6147995 Fabrice Bellard
        dst_pix_fmt == PIX_FMT_GRAY8) {
1725
        if (src_pix->color_type == FF_COLOR_YUV_JPEG) {
1726 7e7e5940 Fabrice Bellard
            img_copy_plane(dst->data[0], dst->linesize[0],
1727 b6147995 Fabrice Bellard
                     src->data[0], src->linesize[0],
1728
                     dst_width, dst_height);
1729
        } else {
1730 c50c0bc8 Fabrice Bellard
            img_apply_table(dst->data[0], dst->linesize[0],
1731
                            src->data[0], src->linesize[0],
1732
                            dst_width, dst_height,
1733
                            y_ccir_to_jpeg);
1734 b6147995 Fabrice Bellard
        }
1735 524c6b63 Fabrice Bellard
        return 0;
1736
    }
1737
1738 c50c0bc8 Fabrice Bellard
    /* YUV to YUV planar */
1739
    if (is_yuv_planar(dst_pix) && is_yuv_planar(src_pix)) {
1740 e352ff08 Fabrice Bellard
        int x_shift, y_shift, w, h, xy_shift;
1741 0c1a9eda Zdenek Kabelac
        void (*resize_func)(uint8_t *dst, int dst_wrap, 
1742 e352ff08 Fabrice Bellard
                            const uint8_t *src, int src_wrap,
1743 524c6b63 Fabrice Bellard
                            int width, int height);
1744
1745
        /* compute chroma size of the smallest dimensions */
1746
        w = dst_width;
1747
        h = dst_height;
1748
        if (dst_pix->x_chroma_shift >= src_pix->x_chroma_shift)
1749
            w >>= dst_pix->x_chroma_shift;
1750
        else
1751
            w >>= src_pix->x_chroma_shift;
1752
        if (dst_pix->y_chroma_shift >= src_pix->y_chroma_shift)
1753
            h >>= dst_pix->y_chroma_shift;
1754
        else
1755
            h >>= src_pix->y_chroma_shift;
1756
1757
        x_shift = (dst_pix->x_chroma_shift - src_pix->x_chroma_shift);
1758
        y_shift = (dst_pix->y_chroma_shift - src_pix->y_chroma_shift);
1759 e352ff08 Fabrice Bellard
        xy_shift = ((x_shift & 0xf) << 4) | (y_shift & 0xf);
1760
        /* there must be filters for conversion at least from and to
1761
           YUV444 format */
1762
        switch(xy_shift) {
1763
        case 0x00:
1764 7e7e5940 Fabrice Bellard
            resize_func = img_copy_plane;
1765 e352ff08 Fabrice Bellard
            break;
1766
        case 0x10:
1767
            resize_func = shrink21;
1768
            break;
1769
        case 0x20:
1770
            resize_func = shrink41;
1771
            break;
1772
        case 0x01:
1773
            resize_func = shrink12;
1774
            break;
1775
        case 0x11:
1776 524c6b63 Fabrice Bellard
            resize_func = shrink22;
1777 e352ff08 Fabrice Bellard
            break;
1778
        case 0x22:
1779
            resize_func = shrink44;
1780
            break;
1781
        case 0xf0:
1782
            resize_func = grow21;
1783
            break;
1784
        case 0xe0:
1785
            resize_func = grow41;
1786
            break;
1787
        case 0xff:
1788 524c6b63 Fabrice Bellard
            resize_func = grow22;
1789 e352ff08 Fabrice Bellard
            break;
1790
        case 0xee:
1791
            resize_func = grow44;
1792
            break;
1793
        case 0xf1:
1794 524c6b63 Fabrice Bellard
            resize_func = conv411;
1795 e352ff08 Fabrice Bellard
            break;
1796
        default:
1797 524c6b63 Fabrice Bellard
            /* currently not handled */
1798 e352ff08 Fabrice Bellard
            goto no_chroma_filter;
1799 85c242d8 Fabrice Bellard
        }
1800 524c6b63 Fabrice Bellard
1801 7e7e5940 Fabrice Bellard
        img_copy_plane(dst->data[0], dst->linesize[0],
1802
                       src->data[0], src->linesize[0],
1803
                       dst_width, dst_height);
1804 566986ee Max Krasnyansky
1805 524c6b63 Fabrice Bellard
        for(i = 1;i <= 2; i++)
1806 566986ee Max Krasnyansky
            resize_func(dst->data[i], dst->linesize[i],
1807
                        src->data[i], src->linesize[i],
1808 185fdc54 Michael Niedermayer
                        dst_width>>dst_pix->x_chroma_shift, dst_height>>dst_pix->y_chroma_shift);
1809 c50c0bc8 Fabrice Bellard
        /* if yuv color space conversion is needed, we do it here on
1810
           the destination image */
1811
        if (dst_pix->color_type != src_pix->color_type) {
1812
            const uint8_t *y_table, *c_table;
1813
            if (dst_pix->color_type == FF_COLOR_YUV) {
1814
                y_table = y_jpeg_to_ccir;
1815
                c_table = c_jpeg_to_ccir;
1816
            } else {
1817
                y_table = y_ccir_to_jpeg;
1818
                c_table = c_ccir_to_jpeg;
1819
            }
1820
            img_apply_table(dst->data[0], dst->linesize[0],
1821
                            dst->data[0], dst->linesize[0],
1822
                            dst_width, dst_height,
1823
                            y_table);
1824
1825
            for(i = 1;i <= 2; i++)
1826
                img_apply_table(dst->data[i], dst->linesize[i],
1827
                                dst->data[i], dst->linesize[i],
1828
                                dst_width>>dst_pix->x_chroma_shift, 
1829
                                dst_height>>dst_pix->y_chroma_shift,
1830
                                c_table);
1831
        }
1832
        return 0;
1833 85c242d8 Fabrice Bellard
    }
1834 e352ff08 Fabrice Bellard
 no_chroma_filter:
1835 524c6b63 Fabrice Bellard
1836 2a877875 Fabrice Bellard
    /* try to use an intermediate format */
1837 c50c0bc8 Fabrice Bellard
    if (src_pix_fmt == PIX_FMT_YUV422 ||
1838
        dst_pix_fmt == PIX_FMT_YUV422) {
1839
        /* specific case: convert to YUV422P first */
1840
        int_pix_fmt = PIX_FMT_YUV422P;
1841
    } else if ((src_pix->color_type == FF_COLOR_GRAY &&
1842
                src_pix_fmt != PIX_FMT_GRAY8) || 
1843
               (dst_pix->color_type == FF_COLOR_GRAY &&
1844
                dst_pix_fmt != PIX_FMT_GRAY8)) {
1845
        /* gray8 is the normalized format */
1846 2a877875 Fabrice Bellard
        int_pix_fmt = PIX_FMT_GRAY8;
1847 c50c0bc8 Fabrice Bellard
    } else if ((is_yuv_planar(src_pix) && 
1848
                src_pix_fmt != PIX_FMT_YUV444P &&
1849
                src_pix_fmt != PIX_FMT_YUVJ444P)) {
1850
        /* yuv444 is the normalized format */
1851
        if (src_pix->color_type == FF_COLOR_YUV_JPEG)
1852
            int_pix_fmt = PIX_FMT_YUVJ444P;
1853
        else
1854
            int_pix_fmt = PIX_FMT_YUV444P;
1855
    } else if ((is_yuv_planar(dst_pix) && 
1856
                dst_pix_fmt != PIX_FMT_YUV444P &&
1857
                dst_pix_fmt != PIX_FMT_YUVJ444P)) {
1858
        /* yuv444 is the normalized format */
1859
        if (dst_pix->color_type == FF_COLOR_YUV_JPEG)
1860
            int_pix_fmt = PIX_FMT_YUVJ444P;
1861
        else
1862
            int_pix_fmt = PIX_FMT_YUV444P;
1863 2a877875 Fabrice Bellard
    } else {
1864 c50c0bc8 Fabrice Bellard
        /* the two formats are rgb or gray8 or yuv[j]444p */
1865
        if (src_pix->is_alpha && dst_pix->is_alpha)
1866
            int_pix_fmt = PIX_FMT_RGBA32;
1867
        else
1868
            int_pix_fmt = PIX_FMT_RGB24;
1869 2a877875 Fabrice Bellard
    }
1870
    if (avpicture_alloc(tmp, int_pix_fmt, dst_width, dst_height) < 0)
1871
        return -1;
1872
    ret = -1;
1873
    if (img_convert(tmp, int_pix_fmt,
1874
                    src, src_pix_fmt, src_width, src_height) < 0)
1875
        goto fail1;
1876
    if (img_convert(dst, dst_pix_fmt,
1877
                    tmp, int_pix_fmt, dst_width, dst_height) < 0)
1878
        goto fail1;
1879
    ret = 0;
1880
 fail1:
1881
    avpicture_free(tmp);
1882
    return ret;
1883 85c242d8 Fabrice Bellard
}
1884
1885 0469baf1 Fabrice Bellard
/* NOTE: we scan all the pixels to have an exact information */
1886 da64ecc3 Drew Hess
static int get_alpha_info_pal8(const AVPicture *src, int width, int height)
1887 0469baf1 Fabrice Bellard
{
1888
    const unsigned char *p;
1889
    int src_wrap, ret, x, y;
1890
    unsigned int a;
1891
    uint32_t *palette = (uint32_t *)src->data[1];
1892
    
1893
    p = src->data[0];
1894
    src_wrap = src->linesize[0] - width;
1895
    ret = 0;
1896
    for(y=0;y<height;y++) {
1897
        for(x=0;x<width;x++) {
1898
            a = palette[p[0]] >> 24;
1899
            if (a == 0x00) {
1900
                ret |= FF_ALPHA_TRANSP;
1901
            } else if (a != 0xff) {
1902
                ret |= FF_ALPHA_SEMI_TRANSP;
1903
            }
1904
            p++;
1905
        }
1906
        p += src_wrap;
1907
    }
1908
    return ret;
1909
}
1910
1911
/**
1912
 * Tell if an image really has transparent alpha values.
1913
 * @return ored mask of FF_ALPHA_xxx constants
1914
 */
1915 da64ecc3 Drew Hess
int img_get_alpha_info(const AVPicture *src,
1916
                       int pix_fmt, int width, int height)
1917 0469baf1 Fabrice Bellard
{
1918
    PixFmtInfo *pf = &pix_fmt_info[pix_fmt];
1919
    int ret;
1920
1921
    pf = &pix_fmt_info[pix_fmt];
1922
    /* no alpha can be represented in format */
1923
    if (!pf->is_alpha)
1924
        return 0;
1925
    switch(pix_fmt) {
1926
    case PIX_FMT_RGBA32:
1927
        ret = get_alpha_info_rgba32(src, width, height);
1928
        break;
1929
    case PIX_FMT_RGB555:
1930
        ret = get_alpha_info_rgb555(src, width, height);
1931
        break;
1932
    case PIX_FMT_PAL8:
1933
        ret = get_alpha_info_pal8(src, width, height);
1934
        break;
1935
    default:
1936
        /* we do not know, so everything is indicated */
1937
        ret = FF_ALPHA_TRANSP | FF_ALPHA_SEMI_TRANSP;
1938
        break;
1939
    }
1940
    return ret;
1941
}
1942 5981f4e6 Fred
1943
#ifdef HAVE_MMX
1944
#define DEINT_INPLACE_LINE_LUM \
1945
                    movd_m2r(lum_m4[0],mm0);\
1946
                    movd_m2r(lum_m3[0],mm1);\
1947
                    movd_m2r(lum_m2[0],mm2);\
1948
                    movd_m2r(lum_m1[0],mm3);\
1949
                    movd_m2r(lum[0],mm4);\
1950
                    punpcklbw_r2r(mm7,mm0);\
1951
                    movd_r2m(mm2,lum_m4[0]);\
1952
                    punpcklbw_r2r(mm7,mm1);\
1953
                    punpcklbw_r2r(mm7,mm2);\
1954
                    punpcklbw_r2r(mm7,mm3);\
1955
                    punpcklbw_r2r(mm7,mm4);\
1956
                    paddw_r2r(mm3,mm1);\
1957
                    psllw_i2r(1,mm2);\
1958
                    paddw_r2r(mm4,mm0);\
1959
                    psllw_i2r(2,mm1);\
1960
                    paddw_r2r(mm6,mm2);\
1961
                    paddw_r2r(mm2,mm1);\
1962
                    psubusw_r2r(mm0,mm1);\
1963
                    psrlw_i2r(3,mm1);\
1964
                    packuswb_r2r(mm7,mm1);\
1965
                    movd_r2m(mm1,lum_m2[0]);
1966
1967
#define DEINT_LINE_LUM \
1968
                    movd_m2r(lum_m4[0],mm0);\
1969
                    movd_m2r(lum_m3[0],mm1);\
1970
                    movd_m2r(lum_m2[0],mm2);\
1971
                    movd_m2r(lum_m1[0],mm3);\
1972
                    movd_m2r(lum[0],mm4);\
1973
                    punpcklbw_r2r(mm7,mm0);\
1974
                    punpcklbw_r2r(mm7,mm1);\
1975
                    punpcklbw_r2r(mm7,mm2);\
1976
                    punpcklbw_r2r(mm7,mm3);\
1977
                    punpcklbw_r2r(mm7,mm4);\
1978
                    paddw_r2r(mm3,mm1);\
1979
                    psllw_i2r(1,mm2);\
1980
                    paddw_r2r(mm4,mm0);\
1981
                    psllw_i2r(2,mm1);\
1982
                    paddw_r2r(mm6,mm2);\
1983
                    paddw_r2r(mm2,mm1);\
1984
                    psubusw_r2r(mm0,mm1);\
1985
                    psrlw_i2r(3,mm1);\
1986
                    packuswb_r2r(mm7,mm1);\
1987
                    movd_r2m(mm1,dst[0]);
1988
#endif
1989
1990 85c242d8 Fabrice Bellard
/* filter parameters: [-1 4 2 4 -1] // 8 */
1991 da64ecc3 Drew Hess
static void deinterlace_line(uint8_t *dst, 
1992
                             const uint8_t *lum_m4, const uint8_t *lum_m3, 
1993
                             const uint8_t *lum_m2, const uint8_t *lum_m1, 
1994
                             const uint8_t *lum,
1995
                             int size)
1996 85c242d8 Fabrice Bellard
{
1997 5981f4e6 Fred
#ifndef HAVE_MMX
1998 0c1a9eda Zdenek Kabelac
    uint8_t *cm = cropTbl + MAX_NEG_CROP;
1999 85c242d8 Fabrice Bellard
    int sum;
2000
2001
    for(;size > 0;size--) {
2002 5981f4e6 Fred
        sum = -lum_m4[0];
2003
        sum += lum_m3[0] << 2;
2004
        sum += lum_m2[0] << 1;
2005
        sum += lum_m1[0] << 2;
2006
        sum += -lum[0];
2007 85c242d8 Fabrice Bellard
        dst[0] = cm[(sum + 4) >> 3];
2008 5981f4e6 Fred
        lum_m4++;
2009
        lum_m3++;
2010
        lum_m2++;
2011
        lum_m1++;
2012
        lum++;
2013 85c242d8 Fabrice Bellard
        dst++;
2014
    }
2015 5981f4e6 Fred
#else
2016
2017 782c5984 Michael Niedermayer
    {
2018
        mmx_t rounder;
2019
        rounder.uw[0]=4;
2020
        rounder.uw[1]=4;
2021
        rounder.uw[2]=4;
2022
        rounder.uw[3]=4;
2023
        pxor_r2r(mm7,mm7);
2024
        movq_m2r(rounder,mm6);
2025
    }
2026 5981f4e6 Fred
    for (;size > 3; size-=4) {
2027
        DEINT_LINE_LUM
2028
        lum_m4+=4;
2029
        lum_m3+=4;
2030
        lum_m2+=4;
2031
        lum_m1+=4;
2032
        lum+=4;
2033
        dst+=4;
2034
    }
2035
#endif
2036
}
2037 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,
2038 5981f4e6 Fred
                             int size)
2039
{
2040
#ifndef HAVE_MMX
2041 0c1a9eda Zdenek Kabelac
    uint8_t *cm = cropTbl + MAX_NEG_CROP;
2042 5981f4e6 Fred
    int sum;
2043
2044
    for(;size > 0;size--) {
2045
        sum = -lum_m4[0];
2046
        sum += lum_m3[0] << 2;
2047
        sum += lum_m2[0] << 1;
2048
        lum_m4[0]=lum_m2[0];
2049
        sum += lum_m1[0] << 2;
2050
        sum += -lum[0];
2051
        lum_m2[0] = cm[(sum + 4) >> 3];
2052
        lum_m4++;
2053
        lum_m3++;
2054
        lum_m2++;
2055
        lum_m1++;
2056
        lum++;
2057
    }
2058
#else
2059
2060 782c5984 Michael Niedermayer
    {
2061
        mmx_t rounder;
2062
        rounder.uw[0]=4;
2063
        rounder.uw[1]=4;
2064
        rounder.uw[2]=4;
2065
        rounder.uw[3]=4;
2066
        pxor_r2r(mm7,mm7);
2067
        movq_m2r(rounder,mm6);
2068
    }
2069 5981f4e6 Fred
    for (;size > 3; size-=4) {
2070
        DEINT_INPLACE_LINE_LUM
2071
        lum_m4+=4;
2072
        lum_m3+=4;
2073
        lum_m2+=4;
2074
        lum_m1+=4;
2075
        lum+=4;
2076
    }
2077
#endif
2078 85c242d8 Fabrice Bellard
}
2079
2080
/* deinterlacing : 2 temporal taps, 3 spatial taps linear filter. The
2081
   top field is copied as is, but the bottom field is deinterlaced
2082
   against the top field. */
2083 0c1a9eda Zdenek Kabelac
static void deinterlace_bottom_field(uint8_t *dst, int dst_wrap,
2084 da64ecc3 Drew Hess
                                    const uint8_t *src1, int src_wrap,
2085 5981f4e6 Fred
                                    int width, int height)
2086 85c242d8 Fabrice Bellard
{
2087 da64ecc3 Drew Hess
    const uint8_t *src_m2, *src_m1, *src_0, *src_p1, *src_p2;
2088 5981f4e6 Fred
    int y;
2089
2090
    src_m2 = src1;
2091
    src_m1 = src1;
2092
    src_0=&src_m1[src_wrap];
2093
    src_p1=&src_0[src_wrap];
2094
    src_p2=&src_p1[src_wrap];
2095
    for(y=0;y<(height-2);y+=2) {
2096
        memcpy(dst,src_m1,width);
2097 85c242d8 Fabrice Bellard
        dst += dst_wrap;
2098 5981f4e6 Fred
        deinterlace_line(dst,src_m2,src_m1,src_0,src_p1,src_p2,width);
2099
        src_m2 = src_0;
2100
        src_m1 = src_p1;
2101
        src_0 = src_p2;
2102
        src_p1 += 2*src_wrap;
2103
        src_p2 += 2*src_wrap;
2104 85c242d8 Fabrice Bellard
        dst += dst_wrap;
2105
    }
2106 5981f4e6 Fred
    memcpy(dst,src_m1,width);
2107
    dst += dst_wrap;
2108
    /* do last line */
2109
    deinterlace_line(dst,src_m2,src_m1,src_0,src_0,src_0,width);
2110
}
2111
2112 0c1a9eda Zdenek Kabelac
static void deinterlace_bottom_field_inplace(uint8_t *src1, int src_wrap,
2113 da64ecc3 Drew Hess
                                             int width, int height)
2114 5981f4e6 Fred
{
2115 0c1a9eda Zdenek Kabelac
    uint8_t *src_m1, *src_0, *src_p1, *src_p2;
2116 5981f4e6 Fred
    int y;
2117 0c1a9eda Zdenek Kabelac
    uint8_t *buf;
2118
    buf = (uint8_t*)av_malloc(width);
2119 5981f4e6 Fred
2120
    src_m1 = src1;
2121
    memcpy(buf,src_m1,width);
2122
    src_0=&src_m1[src_wrap];
2123
    src_p1=&src_0[src_wrap];
2124
    src_p2=&src_p1[src_wrap];
2125
    for(y=0;y<(height-2);y+=2) {
2126
        deinterlace_line_inplace(buf,src_m1,src_0,src_p1,src_p2,width);
2127
        src_m1 = src_p1;
2128
        src_0 = src_p2;
2129
        src_p1 += 2*src_wrap;
2130
        src_p2 += 2*src_wrap;
2131
    }
2132
    /* do last line */
2133
    deinterlace_line_inplace(buf,src_m1,src_0,src_0,src_0,width);
2134 6000abfa Fabrice Bellard
    av_free(buf);
2135 85c242d8 Fabrice Bellard
}
2136
2137
2138 5981f4e6 Fred
/* deinterlace - if not supported return -1 */
2139 da64ecc3 Drew Hess
int avpicture_deinterlace(AVPicture *dst, const AVPicture *src,
2140 de6d9b64 Fabrice Bellard
                          int pix_fmt, int width, int height)
2141
{
2142 85c242d8 Fabrice Bellard
    int i;
2143
2144
    if (pix_fmt != PIX_FMT_YUV420P &&
2145
        pix_fmt != PIX_FMT_YUV422P &&
2146 47017dd8 Roman Shaposhnik
        pix_fmt != PIX_FMT_YUV444P &&
2147
        pix_fmt != PIX_FMT_YUV411P)
2148 85c242d8 Fabrice Bellard
        return -1;
2149 5981f4e6 Fred
    if ((width & 3) != 0 || (height & 3) != 0)
2150 85c242d8 Fabrice Bellard
        return -1;
2151 5981f4e6 Fred
2152 85c242d8 Fabrice Bellard
    for(i=0;i<3;i++) {
2153
        if (i == 1) {
2154
            switch(pix_fmt) {
2155
            case PIX_FMT_YUV420P:
2156
                width >>= 1;
2157
                height >>= 1;
2158
                break;
2159
            case PIX_FMT_YUV422P:
2160
                width >>= 1;
2161
                break;
2162 47017dd8 Roman Shaposhnik
            case PIX_FMT_YUV411P:
2163
                width >>= 2;
2164
                break;
2165 85c242d8 Fabrice Bellard
            default:
2166
                break;
2167
            }
2168
        }
2169 5981f4e6 Fred
        if (src == dst) {
2170 da64ecc3 Drew Hess
            deinterlace_bottom_field_inplace(dst->data[i], dst->linesize[i],
2171 85c242d8 Fabrice Bellard
                                 width, height);
2172 5981f4e6 Fred
        } else {
2173
            deinterlace_bottom_field(dst->data[i],dst->linesize[i],
2174
                                        src->data[i], src->linesize[i],
2175
                                        width, height);
2176
        }
2177 de6d9b64 Fabrice Bellard
    }
2178 5981f4e6 Fred
#ifdef HAVE_MMX
2179
    emms();
2180
#endif
2181 85c242d8 Fabrice Bellard
    return 0;
2182 de6d9b64 Fabrice Bellard
}
2183 cd4af68a Zdenek Kabelac
2184
#undef FIX