Statistics
| Branch: | Revision:

ffmpeg / libavcodec / imgconvert.c @ 5509bffa

History | View | Annotate | Download (66.1 KB)

1
/*
2
 * Misc image convertion routines
3
 * Copyright (c) 2001, 2002, 2003 Fabrice Bellard.
4
 *
5
 * 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
 *
10
 * This library is distributed in the hope that it will be useful,
11
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13
 * Lesser General Public License for more details.
14
 *
15
 * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18
 */
19

    
20
/**
21
 * @file imgconvert.c
22
 * Misc image convertion routines.
23
 */
24

    
25
/* 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

    
31
#include "avcodec.h"
32
#include "dsputil.h"
33

    
34
#ifdef USE_FASTMEMCPY
35
#include "fastmemcpy.h"
36
#endif
37

    
38
#ifdef HAVE_MMX
39
#include "i386/mmx.h"
40
#endif
41

    
42
#define xglue(x, y) x ## y
43
#define glue(x, y) xglue(x, y)
44

    
45
#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
#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
typedef struct PixFmtInfo {
55
    const char *name;
56
    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
    uint8_t is_alpha : 1;    /* true if alpha can be specified */
60
    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
} 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
        .name = "yuv420p",
70
        .nb_channels = 3,
71
        .color_type = FF_COLOR_YUV,
72
        .pixel_type = FF_PIXEL_PLANAR,
73
        .depth = 8,
74
        .x_chroma_shift = 1, .y_chroma_shift = 1,
75
    },
76
    [PIX_FMT_YUV422P] = {
77
        .name = "yuv422p",
78
        .nb_channels = 3,
79
        .color_type = FF_COLOR_YUV,
80
        .pixel_type = FF_PIXEL_PLANAR,
81
        .depth = 8,
82
        .x_chroma_shift = 1, .y_chroma_shift = 0,
83
    },
84
    [PIX_FMT_YUV444P] = {
85
        .name = "yuv444p",
86
        .nb_channels = 3,
87
        .color_type = FF_COLOR_YUV,
88
        .pixel_type = FF_PIXEL_PLANAR,
89
        .depth = 8,
90
        .x_chroma_shift = 0, .y_chroma_shift = 0,
91
    },
92
    [PIX_FMT_YUV422] = {
93
        .name = "yuv422",
94
        .nb_channels = 1,
95
        .color_type = FF_COLOR_YUV,
96
        .pixel_type = FF_PIXEL_PACKED,
97
        .depth = 8,
98
        .x_chroma_shift = 1, .y_chroma_shift = 0,
99
    },
100
    [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
    [PIX_FMT_YUV410P] = {
109
        .name = "yuv410p",
110
        .nb_channels = 3,
111
        .color_type = FF_COLOR_YUV,
112
        .pixel_type = FF_PIXEL_PLANAR,
113
        .depth = 8,
114
        .x_chroma_shift = 2, .y_chroma_shift = 2,
115
    },
116
    [PIX_FMT_YUV411P] = {
117
        .name = "yuv411p",
118
        .nb_channels = 3,
119
        .color_type = FF_COLOR_YUV,
120
        .pixel_type = FF_PIXEL_PLANAR,
121
        .depth = 8,
122
        .x_chroma_shift = 2, .y_chroma_shift = 0,
123
    },
124

    
125
    /* JPEG YUV */
126
    [PIX_FMT_YUVJ420P] = {
127
        .name = "yuvj420p",
128
        .nb_channels = 3,
129
        .color_type = FF_COLOR_YUV_JPEG,
130
        .pixel_type = FF_PIXEL_PLANAR,
131
        .depth = 8,
132
        .x_chroma_shift = 1, .y_chroma_shift = 1,
133
    },
134
    [PIX_FMT_YUVJ422P] = {
135
        .name = "yuvj422p",
136
        .nb_channels = 3,
137
        .color_type = FF_COLOR_YUV_JPEG,
138
        .pixel_type = FF_PIXEL_PLANAR,
139
        .depth = 8,
140
        .x_chroma_shift = 1, .y_chroma_shift = 0,
141
    },
142
    [PIX_FMT_YUVJ444P] = {
143
        .name = "yuvj444p",
144
        .nb_channels = 3,
145
        .color_type = FF_COLOR_YUV_JPEG,
146
        .pixel_type = FF_PIXEL_PLANAR,
147
        .depth = 8,
148
        .x_chroma_shift = 0, .y_chroma_shift = 0,
149
    },
150

    
151
    /* RGB formats */
152
    [PIX_FMT_RGB24] = {
153
        .name = "rgb24",
154
        .nb_channels = 3,
155
        .color_type = FF_COLOR_RGB,
156
        .pixel_type = FF_PIXEL_PACKED,
157
        .depth = 8,
158
        .x_chroma_shift = 0, .y_chroma_shift = 0,
159
    },
160
    [PIX_FMT_BGR24] = {
161
        .name = "bgr24",
162
        .nb_channels = 3,
163
        .color_type = FF_COLOR_RGB,
164
        .pixel_type = FF_PIXEL_PACKED,
165
        .depth = 8,
166
        .x_chroma_shift = 0, .y_chroma_shift = 0,
167
    },
168
    [PIX_FMT_RGBA32] = {
169
        .name = "rgba32",
170
        .nb_channels = 4, .is_alpha = 1,
171
        .color_type = FF_COLOR_RGB,
172
        .pixel_type = FF_PIXEL_PACKED,
173
        .depth = 8,
174
        .x_chroma_shift = 0, .y_chroma_shift = 0,
175
    },
176
    [PIX_FMT_RGB565] = {
177
        .name = "rgb565",
178
        .nb_channels = 3,
179
        .color_type = FF_COLOR_RGB,
180
        .pixel_type = FF_PIXEL_PACKED,
181
        .depth = 5,
182
        .x_chroma_shift = 0, .y_chroma_shift = 0,
183
    },
184
    [PIX_FMT_RGB555] = {
185
        .name = "rgb555",
186
        .nb_channels = 4, .is_alpha = 1,
187
        .color_type = FF_COLOR_RGB,
188
        .pixel_type = FF_PIXEL_PACKED,
189
        .depth = 5,
190
        .x_chroma_shift = 0, .y_chroma_shift = 0,
191
    },
192

    
193
    /* gray / mono formats */
194
    [PIX_FMT_GRAY8] = {
195
        .name = "gray",
196
        .nb_channels = 1,
197
        .color_type = FF_COLOR_GRAY,
198
        .pixel_type = FF_PIXEL_PLANAR,
199
        .depth = 8,
200
    },
201
    [PIX_FMT_MONOWHITE] = {
202
        .name = "monow",
203
        .nb_channels = 1,
204
        .color_type = FF_COLOR_GRAY,
205
        .pixel_type = FF_PIXEL_PLANAR,
206
        .depth = 1,
207
    },
208
    [PIX_FMT_MONOBLACK] = {
209
        .name = "monob",
210
        .nb_channels = 1,
211
        .color_type = FF_COLOR_GRAY,
212
        .pixel_type = FF_PIXEL_PLANAR,
213
        .depth = 1,
214
    },
215

    
216
    /* paletted formats */
217
    [PIX_FMT_PAL8] = {
218
        .name = "pal8",
219
        .nb_channels = 4, .is_alpha = 1,
220
        .color_type = FF_COLOR_RGB,
221
        .pixel_type = FF_PIXEL_PALETTE,
222
        .depth = 8,
223
    },
224
    [PIX_FMT_XVMC_MPEG2_MC] = {
225
        .name = "xvmcmc",
226
    },
227
    [PIX_FMT_XVMC_MPEG2_IDCT] = {
228
        .name = "xvmcidct",
229
    },
230
    [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
};
239

    
240
void avcodec_get_chroma_sub_sample(int pix_fmt, int *h_shift, int *v_shift)
241
{
242
    *h_shift = pix_fmt_info[pix_fmt].x_chroma_shift;
243
    *v_shift = pix_fmt_info[pix_fmt].y_chroma_shift;
244
}
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
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
/* Picture field are filled with 'ptr' addresses. Also return size */
265
int avpicture_fill(AVPicture *picture, uint8_t *ptr,
266
                   int pix_fmt, int width, int height)
267
{
268
    int size, w2, h2, size2;
269
    PixFmtInfo *pinfo;
270

    
271
    if(avcodec_check_dimensions(NULL, width, height))
272
        goto fail;
273

    
274
    pinfo = &pix_fmt_info[pix_fmt];
275
    size = width * height;
276
    switch(pix_fmt) {
277
    case PIX_FMT_YUV420P:
278
    case PIX_FMT_YUV422P:
279
    case PIX_FMT_YUV444P:
280
    case PIX_FMT_YUV410P:
281
    case PIX_FMT_YUV411P:
282
    case PIX_FMT_YUVJ420P:
283
    case PIX_FMT_YUVJ422P:
284
    case PIX_FMT_YUVJ444P:
285
        w2 = (width + (1 << pinfo->x_chroma_shift) - 1) >> pinfo->x_chroma_shift;
286
        h2 = (height + (1 << pinfo->y_chroma_shift) - 1) >> pinfo->y_chroma_shift;
287
        size2 = w2 * h2;
288
        picture->data[0] = ptr;
289
        picture->data[1] = picture->data[0] + size;
290
        picture->data[2] = picture->data[1] + size2;
291
        picture->linesize[0] = width;
292
        picture->linesize[1] = w2;
293
        picture->linesize[2] = w2;
294
        return size + 2 * size2;
295
    case PIX_FMT_RGB24:
296
    case PIX_FMT_BGR24:
297
        picture->data[0] = ptr;
298
        picture->data[1] = NULL;
299
        picture->data[2] = NULL;
300
        picture->linesize[0] = width * 3;
301
        return size * 3;
302
    case PIX_FMT_RGBA32:
303
        picture->data[0] = ptr;
304
        picture->data[1] = NULL;
305
        picture->data[2] = NULL;
306
        picture->linesize[0] = width * 4;
307
        return size * 4;
308
    case PIX_FMT_RGB555:
309
    case PIX_FMT_RGB565:
310
    case PIX_FMT_YUV422:
311
        picture->data[0] = ptr;
312
        picture->data[1] = NULL;
313
        picture->data[2] = NULL;
314
        picture->linesize[0] = width * 2;
315
        return size * 2;
316
    case PIX_FMT_UYVY422:
317
        picture->data[0] = ptr;
318
        picture->data[1] = NULL;
319
        picture->data[2] = NULL;
320
        picture->linesize[0] = width * 2;
321
        return size * 2;
322
    case PIX_FMT_UYVY411:
323
        picture->data[0] = ptr;
324
        picture->data[1] = NULL;
325
        picture->data[2] = NULL;
326
        picture->linesize[0] = width + width/2;
327
        return size + size/2;
328
    case PIX_FMT_GRAY8:
329
        picture->data[0] = ptr;
330
        picture->data[1] = NULL;
331
        picture->data[2] = NULL;
332
        picture->linesize[0] = width;
333
        return size;
334
    case PIX_FMT_MONOWHITE:
335
    case PIX_FMT_MONOBLACK:
336
        picture->data[0] = ptr;
337
        picture->data[1] = NULL;
338
        picture->data[2] = NULL;
339
        picture->linesize[0] = (width + 7) >> 3;
340
        return picture->linesize[0] * height;
341
    case PIX_FMT_PAL8:
342
        size2 = (size + 3) & ~3;
343
        picture->data[0] = ptr;
344
        picture->data[1] = ptr + size2; /* palette is stored here as 256 32 bit words */
345
        picture->data[2] = NULL;
346
        picture->linesize[0] = width;
347
        picture->linesize[1] = 4;
348
        return size2 + 256 * 4;
349
    default:
350
fail:
351
        picture->data[0] = NULL;
352
        picture->data[1] = NULL;
353
        picture->data[2] = NULL;
354
        picture->data[3] = NULL;
355
        return -1;
356
    }
357
}
358

    
359
int avpicture_layout(const AVPicture* src, int pix_fmt, int width, int height,
360
                     unsigned char *dest, int dest_size)
361
{
362
    PixFmtInfo* pf = &pix_fmt_info[pix_fmt];
363
    int i, j, w, h, data_planes;
364
    const unsigned char* s;
365
    int size = avpicture_get_size(pix_fmt, width, height);
366

    
367
    if (size > dest_size || size < 0)
368
        return -1;
369

    
370
    if (pf->pixel_type == FF_PIXEL_PACKED || pf->pixel_type == FF_PIXEL_PALETTE) {
371
        if (pix_fmt == PIX_FMT_YUV422 ||
372
            pix_fmt == PIX_FMT_UYVY422 ||
373
            pix_fmt == PIX_FMT_RGB565 ||
374
            pix_fmt == PIX_FMT_RGB555)
375
            w = width * 2;
376
        else if (pix_fmt == PIX_FMT_UYVY411)
377
          w = width + width/2;
378
        else if (pix_fmt == PIX_FMT_PAL8)
379
          w = width;
380
        else
381
          w = width * (pf->depth * pf->nb_channels / 8);
382

    
383
        data_planes = 1;
384
        h = height;
385
    } else {
386
        data_planes = pf->nb_channels;
387
        w = (width*pf->depth + 7)/8;
388
        h = height;
389
    }
390

    
391
    for (i=0; i<data_planes; i++) {
392
         if (i == 1) {
393
             w = width >> pf->x_chroma_shift;
394
             h = height >> pf->y_chroma_shift;
395
         }
396
         s = src->data[i];
397
         for(j=0; j<h; j++) {
398
             memcpy(dest, s, w);
399
             dest += w;
400
             s += src->linesize[i];
401
         }
402
    }
403

    
404
    if (pf->pixel_type == FF_PIXEL_PALETTE)
405
        memcpy((unsigned char *)(((size_t)dest + 3) & ~3), src->data[1], 256 * 4);
406

    
407
    return size;
408
}
409

    
410
int avpicture_get_size(int pix_fmt, int width, int height)
411
{
412
    AVPicture dummy_pict;
413
    return avpicture_fill(&dummy_pict, NULL, pix_fmt, width, height);
414
}
415

    
416
/**
417
 * compute the loss when converting from a pixel format to another
418
 */
419
int avcodec_get_pix_fmt_loss(int dst_pix_fmt, int src_pix_fmt,
420
                             int has_alpha)
421
{
422
    const PixFmtInfo *pf, *ps;
423
    int loss;
424

    
425
    ps = &pix_fmt_info[src_pix_fmt];
426
    pf = &pix_fmt_info[dst_pix_fmt];
427

    
428
    /* compute loss */
429
    loss = 0;
430
    pf = &pix_fmt_info[dst_pix_fmt];
431
    if (pf->depth < ps->depth ||
432
        (dst_pix_fmt == PIX_FMT_RGB555 && src_pix_fmt == PIX_FMT_RGB565))
433
        loss |= FF_LOSS_DEPTH;
434
    if (pf->x_chroma_shift > ps->x_chroma_shift ||
435
        pf->y_chroma_shift > ps->y_chroma_shift)
436
        loss |= FF_LOSS_RESOLUTION;
437
    switch(pf->color_type) {
438
    case FF_COLOR_RGB:
439
        if (ps->color_type != FF_COLOR_RGB &&
440
            ps->color_type != FF_COLOR_GRAY)
441
            loss |= FF_LOSS_COLORSPACE;
442
        break;
443
    case FF_COLOR_GRAY:
444
        if (ps->color_type != FF_COLOR_GRAY)
445
            loss |= FF_LOSS_COLORSPACE;
446
        break;
447
    case FF_COLOR_YUV:
448
        if (ps->color_type != FF_COLOR_YUV)
449
            loss |= FF_LOSS_COLORSPACE;
450
        break;
451
    case FF_COLOR_YUV_JPEG:
452
        if (ps->color_type != FF_COLOR_YUV_JPEG &&
453
            ps->color_type != FF_COLOR_YUV &&
454
            ps->color_type != FF_COLOR_GRAY)
455
            loss |= FF_LOSS_COLORSPACE;
456
        break;
457
    default:
458
        /* fail safe test */
459
        if (ps->color_type != pf->color_type)
460
            loss |= FF_LOSS_COLORSPACE;
461
        break;
462
    }
463
    if (pf->color_type == FF_COLOR_GRAY &&
464
        ps->color_type != FF_COLOR_GRAY)
465
        loss |= FF_LOSS_CHROMA;
466
    if (!pf->is_alpha && (ps->is_alpha && has_alpha))
467
        loss |= FF_LOSS_ALPHA;
468
    if (pf->pixel_type == FF_PIXEL_PALETTE &&
469
        (ps->pixel_type != FF_PIXEL_PALETTE && ps->color_type != FF_COLOR_GRAY))
470
        loss |= FF_LOSS_COLORQUANT;
471
    return loss;
472
}
473

    
474
static int avg_bits_per_pixel(int pix_fmt)
475
{
476
    int bits;
477
    const PixFmtInfo *pf;
478

    
479
    pf = &pix_fmt_info[pix_fmt];
480
    switch(pf->pixel_type) {
481
    case FF_PIXEL_PACKED:
482
        switch(pix_fmt) {
483
        case PIX_FMT_YUV422:
484
        case PIX_FMT_UYVY422:
485
        case PIX_FMT_RGB565:
486
        case PIX_FMT_RGB555:
487
            bits = 16;
488
            break;
489
        case PIX_FMT_UYVY411:
490
            bits = 12;
491
            break;
492
        default:
493
            bits = pf->depth * pf->nb_channels;
494
            break;
495
        }
496
        break;
497
    case FF_PIXEL_PLANAR:
498
        if (pf->x_chroma_shift == 0 && pf->y_chroma_shift == 0) {
499
            bits = pf->depth * pf->nb_channels;
500
        } else {
501
            bits = pf->depth + ((2 * pf->depth) >>
502
                                (pf->x_chroma_shift + pf->y_chroma_shift));
503
        }
504
        break;
505
    case FF_PIXEL_PALETTE:
506
        bits = 8;
507
        break;
508
    default:
509
        bits = -1;
510
        break;
511
    }
512
    return bits;
513
}
514

    
515
static int avcodec_find_best_pix_fmt1(int pix_fmt_mask,
516
                                      int src_pix_fmt,
517
                                      int has_alpha,
518
                                      int loss_mask)
519
{
520
    int dist, i, loss, min_dist, dst_pix_fmt;
521

    
522
    /* find exact color match with smallest size */
523
    dst_pix_fmt = -1;
524
    min_dist = 0x7fffffff;
525
    for(i = 0;i < PIX_FMT_NB; i++) {
526
        if (pix_fmt_mask & (1 << i)) {
527
            loss = avcodec_get_pix_fmt_loss(i, src_pix_fmt, has_alpha) & loss_mask;
528
            if (loss == 0) {
529
                dist = avg_bits_per_pixel(i);
530
                if (dist < min_dist) {
531
                    min_dist = dist;
532
                    dst_pix_fmt = i;
533
                }
534
            }
535
        }
536
    }
537
    return dst_pix_fmt;
538
}
539

    
540
/**
541
 * find best pixel format to convert to. Return -1 if none found
542
 */
543
int avcodec_find_best_pix_fmt(int pix_fmt_mask, int src_pix_fmt,
544
                              int has_alpha, int *loss_ptr)
545
{
546
    int dst_pix_fmt, loss_mask, i;
547
    static const int loss_mask_order[] = {
548
        ~0, /* no loss first */
549
        ~FF_LOSS_ALPHA,
550
        ~FF_LOSS_RESOLUTION,
551
        ~(FF_LOSS_COLORSPACE | FF_LOSS_RESOLUTION),
552
        ~FF_LOSS_COLORQUANT,
553
        ~FF_LOSS_DEPTH,
554
        0,
555
    };
556

    
557
    /* try with successive loss */
558
    i = 0;
559
    for(;;) {
560
        loss_mask = loss_mask_order[i++];
561
        dst_pix_fmt = avcodec_find_best_pix_fmt1(pix_fmt_mask, src_pix_fmt,
562
                                                 has_alpha, loss_mask);
563
        if (dst_pix_fmt >= 0)
564
            goto found;
565
        if (loss_mask == 0)
566
            break;
567
    }
568
    return -1;
569
 found:
570
    if (loss_ptr)
571
        *loss_ptr = avcodec_get_pix_fmt_loss(dst_pix_fmt, src_pix_fmt, has_alpha);
572
    return dst_pix_fmt;
573
}
574

    
575
static void img_copy_plane(uint8_t *dst, int dst_wrap,
576
                           const uint8_t *src, int src_wrap,
577
                           int width, int height)
578
{
579
    if((!dst) || (!src))
580
        return;
581
    for(;height > 0; height--) {
582
        memcpy(dst, src, width);
583
        dst += dst_wrap;
584
        src += src_wrap;
585
    }
586
}
587

    
588
/**
589
 * Copy image 'src' to 'dst'.
590
 */
591
void img_copy(AVPicture *dst, const AVPicture *src,
592
              int pix_fmt, int width, int height)
593
{
594
    int bwidth, bits, i;
595
    PixFmtInfo *pf = &pix_fmt_info[pix_fmt];
596

    
597
    pf = &pix_fmt_info[pix_fmt];
598
    switch(pf->pixel_type) {
599
    case FF_PIXEL_PACKED:
600
        switch(pix_fmt) {
601
        case PIX_FMT_YUV422:
602
        case PIX_FMT_UYVY422:
603
        case PIX_FMT_RGB565:
604
        case PIX_FMT_RGB555:
605
            bits = 16;
606
            break;
607
        case PIX_FMT_UYVY411:
608
            bits = 12;
609
            break;
610
        default:
611
            bits = pf->depth * pf->nb_channels;
612
            break;
613
        }
614
        bwidth = (width * bits + 7) >> 3;
615
        img_copy_plane(dst->data[0], dst->linesize[0],
616
                       src->data[0], src->linesize[0],
617
                       bwidth, height);
618
        break;
619
    case FF_PIXEL_PLANAR:
620
        for(i = 0; i < pf->nb_channels; i++) {
621
            int w, h;
622
            w = width;
623
            h = height;
624
            if (i == 1 || i == 2) {
625
                w >>= pf->x_chroma_shift;
626
                h >>= pf->y_chroma_shift;
627
            }
628
            bwidth = (w * pf->depth + 7) >> 3;
629
            img_copy_plane(dst->data[i], dst->linesize[i],
630
                           src->data[i], src->linesize[i],
631
                           bwidth, h);
632
        }
633
        break;
634
    case FF_PIXEL_PALETTE:
635
        img_copy_plane(dst->data[0], dst->linesize[0],
636
                       src->data[0], src->linesize[0],
637
                       width, height);
638
        /* copy the palette */
639
        img_copy_plane(dst->data[1], dst->linesize[1],
640
                       src->data[1], src->linesize[1],
641
                       4, 256);
642
        break;
643
    }
644
}
645

    
646
/* XXX: totally non optimized */
647

    
648
static void yuv422_to_yuv420p(AVPicture *dst, const AVPicture *src,
649
                              int width, int height)
650
{
651
    const uint8_t *p, *p1;
652
    uint8_t *lum, *cr, *cb, *lum1, *cr1, *cb1;
653
    int w;
654

    
655
    p1 = src->data[0];
656
    lum1 = dst->data[0];
657
    cb1 = dst->data[1];
658
    cr1 = dst->data[2];
659

    
660
    for(;height >= 1; height -= 2) {
661
        p = p1;
662
        lum = lum1;
663
        cb = cb1;
664
        cr = cr1;
665
        for(w = width; w >= 2; w -= 2) {
666
            lum[0] = p[0];
667
            cb[0] = p[1];
668
            lum[1] = p[2];
669
            cr[0] = p[3];
670
            p += 4;
671
            lum += 2;
672
            cb++;
673
            cr++;
674
        }
675
        if (w) {
676
            lum[0] = p[0];
677
            cb[0] = p[1];
678
            cr[0] = p[3];
679
            cb++;
680
            cr++;
681
        }
682
        p1 += src->linesize[0];
683
        lum1 += dst->linesize[0];
684
        if (height>1) {
685
            p = p1;
686
            lum = lum1;
687
            for(w = width; w >= 2; w -= 2) {
688
                lum[0] = p[0];
689
                lum[1] = p[2];
690
                p += 4;
691
                lum += 2;
692
            }
693
            if (w) {
694
                lum[0] = p[0];
695
            }
696
            p1 += src->linesize[0];
697
            lum1 += dst->linesize[0];
698
        }
699
        cb1 += dst->linesize[1];
700
        cr1 += dst->linesize[2];
701
    }
702
}
703

    
704
static void uyvy422_to_yuv420p(AVPicture *dst, const AVPicture *src,
705
                              int width, int height)
706
{
707
    const uint8_t *p, *p1;
708
    uint8_t *lum, *cr, *cb, *lum1, *cr1, *cb1;
709
    int w;
710

    
711
    p1 = src->data[0];
712

    
713
    lum1 = dst->data[0];
714
    cb1 = dst->data[1];
715
    cr1 = dst->data[2];
716

    
717
    for(;height >= 1; height -= 2) {
718
        p = p1;
719
        lum = lum1;
720
        cb = cb1;
721
        cr = cr1;
722
        for(w = width; w >= 2; w -= 2) {
723
            lum[0] = p[1];
724
            cb[0] = p[0];
725
            lum[1] = p[3];
726
            cr[0] = p[2];
727
            p += 4;
728
            lum += 2;
729
            cb++;
730
            cr++;
731
        }
732
        if (w) {
733
            lum[0] = p[1];
734
            cb[0] = p[0];
735
            cr[0] = p[2];
736
            cb++;
737
            cr++;
738
        }
739
        p1 += src->linesize[0];
740
        lum1 += dst->linesize[0];
741
        if (height>1) {
742
            p = p1;
743
            lum = lum1;
744
            for(w = width; w >= 2; w -= 2) {
745
                lum[0] = p[1];
746
                lum[1] = p[3];
747
                p += 4;
748
                lum += 2;
749
            }
750
            if (w) {
751
                lum[0] = p[1];
752
            }
753
            p1 += src->linesize[0];
754
            lum1 += dst->linesize[0];
755
        }
756
        cb1 += dst->linesize[1];
757
        cr1 += dst->linesize[2];
758
    }
759
}
760

    
761

    
762
static void uyvy422_to_yuv422p(AVPicture *dst, const AVPicture *src,
763
                              int width, int height)
764
{
765
    const uint8_t *p, *p1;
766
    uint8_t *lum, *cr, *cb, *lum1, *cr1, *cb1;
767
    int w;
768

    
769
    p1 = src->data[0];
770
    lum1 = dst->data[0];
771
    cb1 = dst->data[1];
772
    cr1 = dst->data[2];
773
    for(;height > 0; height--) {
774
        p = p1;
775
        lum = lum1;
776
        cb = cb1;
777
        cr = cr1;
778
        for(w = width; w >= 2; w -= 2) {
779
            lum[0] = p[1];
780
            cb[0] = p[0];
781
            lum[1] = p[3];
782
            cr[0] = p[2];
783
            p += 4;
784
            lum += 2;
785
            cb++;
786
            cr++;
787
        }
788
        p1 += src->linesize[0];
789
        lum1 += dst->linesize[0];
790
        cb1 += dst->linesize[1];
791
        cr1 += dst->linesize[2];
792
    }
793
}
794

    
795

    
796
static void yuv422_to_yuv422p(AVPicture *dst, const AVPicture *src,
797
                              int width, int height)
798
{
799
    const uint8_t *p, *p1;
800
    uint8_t *lum, *cr, *cb, *lum1, *cr1, *cb1;
801
    int w;
802

    
803
    p1 = src->data[0];
804
    lum1 = dst->data[0];
805
    cb1 = dst->data[1];
806
    cr1 = dst->data[2];
807
    for(;height > 0; height--) {
808
        p = p1;
809
        lum = lum1;
810
        cb = cb1;
811
        cr = cr1;
812
        for(w = width; w >= 2; w -= 2) {
813
            lum[0] = p[0];
814
            cb[0] = p[1];
815
            lum[1] = p[2];
816
            cr[0] = p[3];
817
            p += 4;
818
            lum += 2;
819
            cb++;
820
            cr++;
821
        }
822
        p1 += src->linesize[0];
823
        lum1 += dst->linesize[0];
824
        cb1 += dst->linesize[1];
825
        cr1 += dst->linesize[2];
826
    }
827
}
828

    
829
static void yuv422p_to_yuv422(AVPicture *dst, const AVPicture *src,
830
                              int width, int height)
831
{
832
    uint8_t *p, *p1;
833
    const uint8_t *lum, *cr, *cb, *lum1, *cr1, *cb1;
834
    int w;
835

    
836
    p1 = dst->data[0];
837
    lum1 = src->data[0];
838
    cb1 = src->data[1];
839
    cr1 = src->data[2];
840
    for(;height > 0; height--) {
841
        p = p1;
842
        lum = lum1;
843
        cb = cb1;
844
        cr = cr1;
845
        for(w = width; w >= 2; w -= 2) {
846
            p[0] = lum[0];
847
            p[1] = cb[0];
848
            p[2] = lum[1];
849
            p[3] = cr[0];
850
            p += 4;
851
            lum += 2;
852
            cb++;
853
            cr++;
854
        }
855
        p1 += dst->linesize[0];
856
        lum1 += src->linesize[0];
857
        cb1 += src->linesize[1];
858
        cr1 += src->linesize[2];
859
    }
860
}
861

    
862
static void yuv422p_to_uyvy422(AVPicture *dst, const AVPicture *src,
863
                              int width, int height)
864
{
865
    uint8_t *p, *p1;
866
    const uint8_t *lum, *cr, *cb, *lum1, *cr1, *cb1;
867
    int w;
868

    
869
    p1 = dst->data[0];
870
    lum1 = src->data[0];
871
    cb1 = src->data[1];
872
    cr1 = src->data[2];
873
    for(;height > 0; height--) {
874
        p = p1;
875
        lum = lum1;
876
        cb = cb1;
877
        cr = cr1;
878
        for(w = width; w >= 2; w -= 2) {
879
            p[1] = lum[0];
880
            p[0] = cb[0];
881
            p[3] = lum[1];
882
            p[2] = cr[0];
883
            p += 4;
884
            lum += 2;
885
            cb++;
886
            cr++;
887
        }
888
        p1 += dst->linesize[0];
889
        lum1 += src->linesize[0];
890
        cb1 += src->linesize[1];
891
        cr1 += src->linesize[2];
892
    }
893
}
894

    
895
static void uyvy411_to_yuv411p(AVPicture *dst, const AVPicture *src,
896
                              int width, int height)
897
{
898
    const uint8_t *p, *p1;
899
    uint8_t *lum, *cr, *cb, *lum1, *cr1, *cb1;
900
    int w;
901

    
902
    p1 = src->data[0];
903
    lum1 = dst->data[0];
904
    cb1 = dst->data[1];
905
    cr1 = dst->data[2];
906
    for(;height > 0; height--) {
907
        p = p1;
908
        lum = lum1;
909
        cb = cb1;
910
        cr = cr1;
911
        for(w = width; w >= 4; w -= 4) {
912
            cb[0] = p[0];
913
            lum[0] = p[1];
914
            lum[1] = p[2];
915
            cr[0] = p[3];
916
            lum[2] = p[4];
917
            lum[3] = p[5];
918
            p += 6;
919
            lum += 4;
920
            cb++;
921
            cr++;
922
        }
923
        p1 += src->linesize[0];
924
        lum1 += dst->linesize[0];
925
        cb1 += dst->linesize[1];
926
        cr1 += dst->linesize[2];
927
    }
928
}
929

    
930

    
931
static void yuv420p_to_yuv422(AVPicture *dst, const AVPicture *src,
932
                              int width, int height)
933
{
934
    int w, h;
935
    uint8_t *line1, *line2, *linesrc = dst->data[0];
936
    uint8_t *lum1, *lum2, *lumsrc = src->data[0];
937
    uint8_t *cb1, *cb2 = src->data[1];
938
    uint8_t *cr1, *cr2 = src->data[2];
939

    
940
    for(h = height / 2; h--;) {
941
        line1 = linesrc;
942
        line2 = linesrc + dst->linesize[0];
943

    
944
        lum1 = lumsrc;
945
        lum2 = lumsrc + src->linesize[0];
946

    
947
        cb1 = cb2;
948
        cr1 = cr2;
949

    
950
        for(w = width / 2; w--;) {
951
                *line1++ = *lum1++; *line2++ = *lum2++;
952
                *line1++ =          *line2++ = *cb1++;
953
                *line1++ = *lum1++; *line2++ = *lum2++;
954
                *line1++ =          *line2++ = *cr1++;
955
        }
956

    
957
        linesrc += dst->linesize[0] * 2;
958
        lumsrc += src->linesize[0] * 2;
959
        cb2 += src->linesize[1];
960
        cr2 += src->linesize[2];
961
    }
962
}
963

    
964
static void yuv420p_to_uyvy422(AVPicture *dst, const AVPicture *src,
965
                              int width, int height)
966
{
967
    int w, h;
968
    uint8_t *line1, *line2, *linesrc = dst->data[0];
969
    uint8_t *lum1, *lum2, *lumsrc = src->data[0];
970
    uint8_t *cb1, *cb2 = src->data[1];
971
    uint8_t *cr1, *cr2 = src->data[2];
972

    
973
    for(h = height / 2; h--;) {
974
        line1 = linesrc;
975
        line2 = linesrc + dst->linesize[0];
976

    
977
        lum1 = lumsrc;
978
        lum2 = lumsrc + src->linesize[0];
979

    
980
        cb1 = cb2;
981
        cr1 = cr2;
982

    
983
        for(w = width / 2; w--;) {
984
                *line1++ =          *line2++ = *cb1++;
985
                *line1++ = *lum1++; *line2++ = *lum2++;
986
                *line1++ =          *line2++ = *cr1++;
987
                *line1++ = *lum1++; *line2++ = *lum2++;
988
        }
989

    
990
        linesrc += dst->linesize[0] * 2;
991
        lumsrc += src->linesize[0] * 2;
992
        cb2 += src->linesize[1];
993
        cr2 += src->linesize[2];
994
    }
995
}
996

    
997
#define SCALEBITS 10
998
#define ONE_HALF  (1 << (SCALEBITS - 1))
999
#define FIX(x)    ((int) ((x) * (1<<SCALEBITS) + 0.5))
1000

    
1001
#define YUV_TO_RGB1_CCIR(cb1, cr1)\
1002
{\
1003
    cb = (cb1) - 128;\
1004
    cr = (cr1) - 128;\
1005
    r_add = FIX(1.40200*255.0/224.0) * cr + ONE_HALF;\
1006
    g_add = - FIX(0.34414*255.0/224.0) * cb - FIX(0.71414*255.0/224.0) * cr + \
1007
            ONE_HALF;\
1008
    b_add = FIX(1.77200*255.0/224.0) * cb + ONE_HALF;\
1009
}
1010

    
1011
#define YUV_TO_RGB2_CCIR(r, g, b, y1)\
1012
{\
1013
    y = ((y1) - 16) * FIX(255.0/219.0);\
1014
    r = cm[(y + r_add) >> SCALEBITS];\
1015
    g = cm[(y + g_add) >> SCALEBITS];\
1016
    b = cm[(y + b_add) >> SCALEBITS];\
1017
}
1018

    
1019
#define YUV_TO_RGB1(cb1, cr1)\
1020
{\
1021
    cb = (cb1) - 128;\
1022
    cr = (cr1) - 128;\
1023
    r_add = FIX(1.40200) * cr + ONE_HALF;\
1024
    g_add = - FIX(0.34414) * cb - FIX(0.71414) * cr + ONE_HALF;\
1025
    b_add = FIX(1.77200) * cb + ONE_HALF;\
1026
}
1027

    
1028
#define YUV_TO_RGB2(r, g, b, y1)\
1029
{\
1030
    y = (y1) << SCALEBITS;\
1031
    r = cm[(y + r_add) >> SCALEBITS];\
1032
    g = cm[(y + g_add) >> SCALEBITS];\
1033
    b = cm[(y + b_add) >> SCALEBITS];\
1034
}
1035

    
1036
#define Y_CCIR_TO_JPEG(y)\
1037
 cm[((y) * FIX(255.0/219.0) + (ONE_HALF - 16 * FIX(255.0/219.0))) >> SCALEBITS]
1038

    
1039
#define Y_JPEG_TO_CCIR(y)\
1040
 (((y) * FIX(219.0/255.0) + (ONE_HALF + (16 << SCALEBITS))) >> SCALEBITS)
1041

    
1042
#define C_CCIR_TO_JPEG(y)\
1043
 cm[(((y) - 128) * FIX(127.0/112.0) + (ONE_HALF + (128 << SCALEBITS))) >> SCALEBITS]
1044

    
1045
/* NOTE: the clamp is really necessary! */
1046
static inline int C_JPEG_TO_CCIR(int y) {
1047
    y = (((y - 128) * FIX(112.0/127.0) + (ONE_HALF + (128 << SCALEBITS))) >> SCALEBITS);
1048
    if (y < 16)
1049
        y = 16;
1050
    return y;
1051
}
1052

    
1053

    
1054
#define RGB_TO_Y(r, g, b) \
1055
((FIX(0.29900) * (r) + FIX(0.58700) * (g) + \
1056
  FIX(0.11400) * (b) + ONE_HALF) >> SCALEBITS)
1057

    
1058
#define RGB_TO_U(r1, g1, b1, shift)\
1059
(((- FIX(0.16874) * r1 - FIX(0.33126) * g1 +         \
1060
     FIX(0.50000) * b1 + (ONE_HALF << shift) - 1) >> (SCALEBITS + shift)) + 128)
1061

    
1062
#define RGB_TO_V(r1, g1, b1, shift)\
1063
(((FIX(0.50000) * r1 - FIX(0.41869) * g1 -           \
1064
   FIX(0.08131) * b1 + (ONE_HALF << shift) - 1) >> (SCALEBITS + shift)) + 128)
1065

    
1066
#define RGB_TO_Y_CCIR(r, g, b) \
1067
((FIX(0.29900*219.0/255.0) * (r) + FIX(0.58700*219.0/255.0) * (g) + \
1068
  FIX(0.11400*219.0/255.0) * (b) + (ONE_HALF + (16 << SCALEBITS))) >> SCALEBITS)
1069

    
1070
#define RGB_TO_U_CCIR(r1, g1, b1, shift)\
1071
(((- FIX(0.16874*224.0/255.0) * r1 - FIX(0.33126*224.0/255.0) * g1 +         \
1072
     FIX(0.50000*224.0/255.0) * b1 + (ONE_HALF << shift) - 1) >> (SCALEBITS + shift)) + 128)
1073

    
1074
#define RGB_TO_V_CCIR(r1, g1, b1, shift)\
1075
(((FIX(0.50000*224.0/255.0) * r1 - FIX(0.41869*224.0/255.0) * g1 -           \
1076
   FIX(0.08131*224.0/255.0) * b1 + (ONE_HALF << shift) - 1) >> (SCALEBITS + shift)) + 128)
1077

    
1078
static uint8_t y_ccir_to_jpeg[256];
1079
static uint8_t y_jpeg_to_ccir[256];
1080
static uint8_t c_ccir_to_jpeg[256];
1081
static uint8_t c_jpeg_to_ccir[256];
1082

    
1083
/* init various conversion tables */
1084
static void img_convert_init(void)
1085
{
1086
    int i;
1087
    uint8_t *cm = cropTbl + MAX_NEG_CROP;
1088

    
1089
    for(i = 0;i < 256; i++) {
1090
        y_ccir_to_jpeg[i] = Y_CCIR_TO_JPEG(i);
1091
        y_jpeg_to_ccir[i] = Y_JPEG_TO_CCIR(i);
1092
        c_ccir_to_jpeg[i] = C_CCIR_TO_JPEG(i);
1093
        c_jpeg_to_ccir[i] = C_JPEG_TO_CCIR(i);
1094
    }
1095
}
1096

    
1097
/* apply to each pixel the given table */
1098
static void img_apply_table(uint8_t *dst, int dst_wrap,
1099
                            const uint8_t *src, int src_wrap,
1100
                            int width, int height, const uint8_t *table1)
1101
{
1102
    int n;
1103
    const uint8_t *s;
1104
    uint8_t *d;
1105
    const uint8_t *table;
1106

    
1107
    table = table1;
1108
    for(;height > 0; height--) {
1109
        s = src;
1110
        d = dst;
1111
        n = width;
1112
        while (n >= 4) {
1113
            d[0] = table[s[0]];
1114
            d[1] = table[s[1]];
1115
            d[2] = table[s[2]];
1116
            d[3] = table[s[3]];
1117
            d += 4;
1118
            s += 4;
1119
            n -= 4;
1120
        }
1121
        while (n > 0) {
1122
            d[0] = table[s[0]];
1123
            d++;
1124
            s++;
1125
            n--;
1126
        }
1127
        dst += dst_wrap;
1128
        src += src_wrap;
1129
    }
1130
}
1131

    
1132
/* XXX: use generic filter ? */
1133
/* XXX: in most cases, the sampling position is incorrect */
1134

    
1135
/* 4x1 -> 1x1 */
1136
static void shrink41(uint8_t *dst, int dst_wrap,
1137
                     const uint8_t *src, int src_wrap,
1138
                     int width, int height)
1139
{
1140
    int w;
1141
    const uint8_t *s;
1142
    uint8_t *d;
1143

    
1144
    for(;height > 0; height--) {
1145
        s = src;
1146
        d = dst;
1147
        for(w = width;w > 0; w--) {
1148
            d[0] = (s[0] + s[1] + s[2] + s[3] + 2) >> 2;
1149
            s += 4;
1150
            d++;
1151
        }
1152
        src += src_wrap;
1153
        dst += dst_wrap;
1154
    }
1155
}
1156

    
1157
/* 2x1 -> 1x1 */
1158
static void shrink21(uint8_t *dst, int dst_wrap,
1159
                     const uint8_t *src, int src_wrap,
1160
                     int width, int height)
1161
{
1162
    int w;
1163
    const uint8_t *s;
1164
    uint8_t *d;
1165

    
1166
    for(;height > 0; height--) {
1167
        s = src;
1168
        d = dst;
1169
        for(w = width;w > 0; w--) {
1170
            d[0] = (s[0] + s[1]) >> 1;
1171
            s += 2;
1172
            d++;
1173
        }
1174
        src += src_wrap;
1175
        dst += dst_wrap;
1176
    }
1177
}
1178

    
1179
/* 1x2 -> 1x1 */
1180
static void shrink12(uint8_t *dst, int dst_wrap,
1181
                     const uint8_t *src, int src_wrap,
1182
                     int width, int height)
1183
{
1184
    int w;
1185
    uint8_t *d;
1186
    const uint8_t *s1, *s2;
1187

    
1188
    for(;height > 0; height--) {
1189
        s1 = src;
1190
        s2 = s1 + src_wrap;
1191
        d = dst;
1192
        for(w = width;w >= 4; w-=4) {
1193
            d[0] = (s1[0] + s2[0]) >> 1;
1194
            d[1] = (s1[1] + s2[1]) >> 1;
1195
            d[2] = (s1[2] + s2[2]) >> 1;
1196
            d[3] = (s1[3] + s2[3]) >> 1;
1197
            s1 += 4;
1198
            s2 += 4;
1199
            d += 4;
1200
        }
1201
        for(;w > 0; w--) {
1202
            d[0] = (s1[0] + s2[0]) >> 1;
1203
            s1++;
1204
            s2++;
1205
            d++;
1206
        }
1207
        src += 2 * src_wrap;
1208
        dst += dst_wrap;
1209
    }
1210
}
1211

    
1212
/* 2x2 -> 1x1 */
1213
static void shrink22(uint8_t *dst, int dst_wrap,
1214
                     const uint8_t *src, int src_wrap,
1215
                     int width, int height)
1216
{
1217
    int w;
1218
    const uint8_t *s1, *s2;
1219
    uint8_t *d;
1220

    
1221
    for(;height > 0; height--) {
1222
        s1 = src;
1223
        s2 = s1 + src_wrap;
1224
        d = dst;
1225
        for(w = width;w >= 4; w-=4) {
1226
            d[0] = (s1[0] + s1[1] + s2[0] + s2[1] + 2) >> 2;
1227
            d[1] = (s1[2] + s1[3] + s2[2] + s2[3] + 2) >> 2;
1228
            d[2] = (s1[4] + s1[5] + s2[4] + s2[5] + 2) >> 2;
1229
            d[3] = (s1[6] + s1[7] + s2[6] + s2[7] + 2) >> 2;
1230
            s1 += 8;
1231
            s2 += 8;
1232
            d += 4;
1233
        }
1234
        for(;w > 0; w--) {
1235
            d[0] = (s1[0] + s1[1] + s2[0] + s2[1] + 2) >> 2;
1236
            s1 += 2;
1237
            s2 += 2;
1238
            d++;
1239
        }
1240
        src += 2 * src_wrap;
1241
        dst += dst_wrap;
1242
    }
1243
}
1244

    
1245
/* 4x4 -> 1x1 */
1246
static void shrink44(uint8_t *dst, int dst_wrap,
1247
                     const uint8_t *src, int src_wrap,
1248
                     int width, int height)
1249
{
1250
    int w;
1251
    const uint8_t *s1, *s2, *s3, *s4;
1252
    uint8_t *d;
1253

    
1254
    for(;height > 0; height--) {
1255
        s1 = src;
1256
        s2 = s1 + src_wrap;
1257
        s3 = s2 + src_wrap;
1258
        s4 = s3 + src_wrap;
1259
        d = dst;
1260
        for(w = width;w > 0; w--) {
1261
            d[0] = (s1[0] + s1[1] + s1[2] + s1[3] +
1262
                    s2[0] + s2[1] + s2[2] + s2[3] +
1263
                    s3[0] + s3[1] + s3[2] + s3[3] +
1264
                    s4[0] + s4[1] + s4[2] + s4[3] + 8) >> 4;
1265
            s1 += 4;
1266
            s2 += 4;
1267
            s3 += 4;
1268
            s4 += 4;
1269
            d++;
1270
        }
1271
        src += 4 * src_wrap;
1272
        dst += dst_wrap;
1273
    }
1274
}
1275

    
1276
static void grow21_line(uint8_t *dst, const uint8_t *src,
1277
                        int width)
1278
{
1279
    int w;
1280
    const uint8_t *s1;
1281
    uint8_t *d;
1282

    
1283
    s1 = src;
1284
    d = dst;
1285
    for(w = width;w >= 4; w-=4) {
1286
        d[1] = d[0] = s1[0];
1287
        d[3] = d[2] = s1[1];
1288
        s1 += 2;
1289
        d += 4;
1290
    }
1291
    for(;w >= 2; w -= 2) {
1292
        d[1] = d[0] = s1[0];
1293
        s1 ++;
1294
        d += 2;
1295
    }
1296
    /* only needed if width is not a multiple of two */
1297
    /* XXX: veryfy that */
1298
    if (w) {
1299
        d[0] = s1[0];
1300
    }
1301
}
1302

    
1303
static void grow41_line(uint8_t *dst, const uint8_t *src,
1304
                        int width)
1305
{
1306
    int w, v;
1307
    const uint8_t *s1;
1308
    uint8_t *d;
1309

    
1310
    s1 = src;
1311
    d = dst;
1312
    for(w = width;w >= 4; w-=4) {
1313
        v = s1[0];
1314
        d[0] = v;
1315
        d[1] = v;
1316
        d[2] = v;
1317
        d[3] = v;
1318
        s1 ++;
1319
        d += 4;
1320
    }
1321
}
1322

    
1323
/* 1x1 -> 2x1 */
1324
static void grow21(uint8_t *dst, int dst_wrap,
1325
                   const uint8_t *src, int src_wrap,
1326
                   int width, int height)
1327
{
1328
    for(;height > 0; height--) {
1329
        grow21_line(dst, src, width);
1330
        src += src_wrap;
1331
        dst += dst_wrap;
1332
    }
1333
}
1334

    
1335
/* 1x1 -> 2x2 */
1336
static void grow22(uint8_t *dst, int dst_wrap,
1337
                   const uint8_t *src, int src_wrap,
1338
                   int width, int height)
1339
{
1340
    for(;height > 0; height--) {
1341
        grow21_line(dst, src, width);
1342
        if (height%2)
1343
            src += src_wrap;
1344
        dst += dst_wrap;
1345
    }
1346
}
1347

    
1348
/* 1x1 -> 4x1 */
1349
static void grow41(uint8_t *dst, int dst_wrap,
1350
                   const uint8_t *src, int src_wrap,
1351
                   int width, int height)
1352
{
1353
    for(;height > 0; height--) {
1354
        grow41_line(dst, src, width);
1355
        src += src_wrap;
1356
        dst += dst_wrap;
1357
    }
1358
}
1359

    
1360
/* 1x1 -> 4x4 */
1361
static void grow44(uint8_t *dst, int dst_wrap,
1362
                   const uint8_t *src, int src_wrap,
1363
                   int width, int height)
1364
{
1365
    for(;height > 0; height--) {
1366
        grow41_line(dst, src, width);
1367
        if ((height & 3) == 1)
1368
            src += src_wrap;
1369
        dst += dst_wrap;
1370
    }
1371
}
1372

    
1373
/* 1x2 -> 2x1 */
1374
static void conv411(uint8_t *dst, int dst_wrap,
1375
                    const uint8_t *src, int src_wrap,
1376
                    int width, int height)
1377
{
1378
    int w, c;
1379
    const uint8_t *s1, *s2;
1380
    uint8_t *d;
1381

    
1382
    width>>=1;
1383

    
1384
    for(;height > 0; height--) {
1385
        s1 = src;
1386
        s2 = src + src_wrap;
1387
        d = dst;
1388
        for(w = width;w > 0; w--) {
1389
            c = (s1[0] + s2[0]) >> 1;
1390
            d[0] = c;
1391
            d[1] = c;
1392
            s1++;
1393
            s2++;
1394
            d += 2;
1395
        }
1396
        src += src_wrap * 2;
1397
        dst += dst_wrap;
1398
    }
1399
}
1400

    
1401
/* XXX: add jpeg quantize code */
1402

    
1403
#define TRANSP_INDEX (6*6*6)
1404

    
1405
/* this is maybe slow, but allows for extensions */
1406
static inline unsigned char gif_clut_index(uint8_t r, uint8_t g, uint8_t b)
1407
{
1408
    return ((((r)/47)%6)*6*6+(((g)/47)%6)*6+(((b)/47)%6));
1409
}
1410

    
1411
static void build_rgb_palette(uint8_t *palette, int has_alpha)
1412
{
1413
    uint32_t *pal;
1414
    static const uint8_t pal_value[6] = { 0x00, 0x33, 0x66, 0x99, 0xcc, 0xff };
1415
    int i, r, g, b;
1416

    
1417
    pal = (uint32_t *)palette;
1418
    i = 0;
1419
    for(r = 0; r < 6; r++) {
1420
        for(g = 0; g < 6; g++) {
1421
            for(b = 0; b < 6; b++) {
1422
                pal[i++] = (0xff << 24) | (pal_value[r] << 16) |
1423
                    (pal_value[g] << 8) | pal_value[b];
1424
            }
1425
        }
1426
    }
1427
    if (has_alpha)
1428
        pal[i++] = 0;
1429
    while (i < 256)
1430
        pal[i++] = 0xff000000;
1431
}
1432

    
1433
/* copy bit n to bits 0 ... n - 1 */
1434
static inline unsigned int bitcopy_n(unsigned int a, int n)
1435
{
1436
    int mask;
1437
    mask = (1 << n) - 1;
1438
    return (a & (0xff & ~mask)) | ((-((a >> n) & 1)) & mask);
1439
}
1440

    
1441
/* rgb555 handling */
1442

    
1443
#define RGB_NAME rgb555
1444

    
1445
#define RGB_IN(r, g, b, s)\
1446
{\
1447
    unsigned int v = ((const uint16_t *)(s))[0];\
1448
    r = bitcopy_n(v >> (10 - 3), 3);\
1449
    g = bitcopy_n(v >> (5 - 3), 3);\
1450
    b = bitcopy_n(v << 3, 3);\
1451
}
1452

    
1453
#define RGBA_IN(r, g, b, a, s)\
1454
{\
1455
    unsigned int v = ((const uint16_t *)(s))[0];\
1456
    r = bitcopy_n(v >> (10 - 3), 3);\
1457
    g = bitcopy_n(v >> (5 - 3), 3);\
1458
    b = bitcopy_n(v << 3, 3);\
1459
    a = (-(v >> 15)) & 0xff;\
1460
}
1461

    
1462
#define RGBA_OUT(d, r, g, b, a)\
1463
{\
1464
    ((uint16_t *)(d))[0] = ((r >> 3) << 10) | ((g >> 3) << 5) | (b >> 3) | \
1465
                           ((a << 8) & 0x8000);\
1466
}
1467

    
1468
#define BPP 2
1469

    
1470
#include "imgconvert_template.h"
1471

    
1472
/* rgb565 handling */
1473

    
1474
#define RGB_NAME rgb565
1475

    
1476
#define RGB_IN(r, g, b, s)\
1477
{\
1478
    unsigned int v = ((const uint16_t *)(s))[0];\
1479
    r = bitcopy_n(v >> (11 - 3), 3);\
1480
    g = bitcopy_n(v >> (5 - 2), 2);\
1481
    b = bitcopy_n(v << 3, 3);\
1482
}
1483

    
1484
#define RGB_OUT(d, r, g, b)\
1485
{\
1486
    ((uint16_t *)(d))[0] = ((r >> 3) << 11) | ((g >> 2) << 5) | (b >> 3);\
1487
}
1488

    
1489
#define BPP 2
1490

    
1491
#include "imgconvert_template.h"
1492

    
1493
/* bgr24 handling */
1494

    
1495
#define RGB_NAME bgr24
1496

    
1497
#define RGB_IN(r, g, b, s)\
1498
{\
1499
    b = (s)[0];\
1500
    g = (s)[1];\
1501
    r = (s)[2];\
1502
}
1503

    
1504
#define RGB_OUT(d, r, g, b)\
1505
{\
1506
    (d)[0] = b;\
1507
    (d)[1] = g;\
1508
    (d)[2] = r;\
1509
}
1510

    
1511
#define BPP 3
1512

    
1513
#include "imgconvert_template.h"
1514

    
1515
#undef RGB_IN
1516
#undef RGB_OUT
1517
#undef BPP
1518

    
1519
/* rgb24 handling */
1520

    
1521
#define RGB_NAME rgb24
1522
#define FMT_RGB24
1523

    
1524
#define RGB_IN(r, g, b, s)\
1525
{\
1526
    r = (s)[0];\
1527
    g = (s)[1];\
1528
    b = (s)[2];\
1529
}
1530

    
1531
#define RGB_OUT(d, r, g, b)\
1532
{\
1533
    (d)[0] = r;\
1534
    (d)[1] = g;\
1535
    (d)[2] = b;\
1536
}
1537

    
1538
#define BPP 3
1539

    
1540
#include "imgconvert_template.h"
1541

    
1542
/* rgba32 handling */
1543

    
1544
#define RGB_NAME rgba32
1545
#define FMT_RGBA32
1546

    
1547
#define RGB_IN(r, g, b, s)\
1548
{\
1549
    unsigned int v = ((const uint32_t *)(s))[0];\
1550
    r = (v >> 16) & 0xff;\
1551
    g = (v >> 8) & 0xff;\
1552
    b = v & 0xff;\
1553
}
1554

    
1555
#define RGBA_IN(r, g, b, a, s)\
1556
{\
1557
    unsigned int v = ((const uint32_t *)(s))[0];\
1558
    a = (v >> 24) & 0xff;\
1559
    r = (v >> 16) & 0xff;\
1560
    g = (v >> 8) & 0xff;\
1561
    b = v & 0xff;\
1562
}
1563

    
1564
#define RGBA_OUT(d, r, g, b, a)\
1565
{\
1566
    ((uint32_t *)(d))[0] = (a << 24) | (r << 16) | (g << 8) | b;\
1567
}
1568

    
1569
#define BPP 4
1570

    
1571
#include "imgconvert_template.h"
1572

    
1573
static void mono_to_gray(AVPicture *dst, const AVPicture *src,
1574
                         int width, int height, int xor_mask)
1575
{
1576
    const unsigned char *p;
1577
    unsigned char *q;
1578
    int v, dst_wrap, src_wrap;
1579
    int y, w;
1580

    
1581
    p = src->data[0];
1582
    src_wrap = src->linesize[0] - ((width + 7) >> 3);
1583

    
1584
    q = dst->data[0];
1585
    dst_wrap = dst->linesize[0] - width;
1586
    for(y=0;y<height;y++) {
1587
        w = width;
1588
        while (w >= 8) {
1589
            v = *p++ ^ xor_mask;
1590
            q[0] = -(v >> 7);
1591
            q[1] = -((v >> 6) & 1);
1592
            q[2] = -((v >> 5) & 1);
1593
            q[3] = -((v >> 4) & 1);
1594
            q[4] = -((v >> 3) & 1);
1595
            q[5] = -((v >> 2) & 1);
1596
            q[6] = -((v >> 1) & 1);
1597
            q[7] = -((v >> 0) & 1);
1598
            w -= 8;
1599
            q += 8;
1600
        }
1601
        if (w > 0) {
1602
            v = *p++ ^ xor_mask;
1603
            do {
1604
                q[0] = -((v >> 7) & 1);
1605
                q++;
1606
                v <<= 1;
1607
            } while (--w);
1608
        }
1609
        p += src_wrap;
1610
        q += dst_wrap;
1611
    }
1612
}
1613

    
1614
static void monowhite_to_gray(AVPicture *dst, const AVPicture *src,
1615
                               int width, int height)
1616
{
1617
    mono_to_gray(dst, src, width, height, 0xff);
1618
}
1619

    
1620
static void monoblack_to_gray(AVPicture *dst, const AVPicture *src,
1621
                               int width, int height)
1622
{
1623
    mono_to_gray(dst, src, width, height, 0x00);
1624
}
1625

    
1626
static void gray_to_mono(AVPicture *dst, const AVPicture *src,
1627
                         int width, int height, int xor_mask)
1628
{
1629
    int n;
1630
    const uint8_t *s;
1631
    uint8_t *d;
1632
    int j, b, v, n1, src_wrap, dst_wrap, y;
1633

    
1634
    s = src->data[0];
1635
    src_wrap = src->linesize[0] - width;
1636

    
1637
    d = dst->data[0];
1638
    dst_wrap = dst->linesize[0] - ((width + 7) >> 3);
1639

    
1640
    for(y=0;y<height;y++) {
1641
        n = width;
1642
        while (n >= 8) {
1643
            v = 0;
1644
            for(j=0;j<8;j++) {
1645
                b = s[0];
1646
                s++;
1647
                v = (v << 1) | (b >> 7);
1648
            }
1649
            d[0] = v ^ xor_mask;
1650
            d++;
1651
            n -= 8;
1652
        }
1653
        if (n > 0) {
1654
            n1 = n;
1655
            v = 0;
1656
            while (n > 0) {
1657
                b = s[0];
1658
                s++;
1659
                v = (v << 1) | (b >> 7);
1660
                n--;
1661
            }
1662
            d[0] = (v << (8 - (n1 & 7))) ^ xor_mask;
1663
            d++;
1664
        }
1665
        s += src_wrap;
1666
        d += dst_wrap;
1667
    }
1668
}
1669

    
1670
static void gray_to_monowhite(AVPicture *dst, const AVPicture *src,
1671
                              int width, int height)
1672
{
1673
    gray_to_mono(dst, src, width, height, 0xff);
1674
}
1675

    
1676
static void gray_to_monoblack(AVPicture *dst, const AVPicture *src,
1677
                              int width, int height)
1678
{
1679
    gray_to_mono(dst, src, width, height, 0x00);
1680
}
1681

    
1682
typedef struct ConvertEntry {
1683
    void (*convert)(AVPicture *dst,
1684
                    const AVPicture *src, int width, int height);
1685
} ConvertEntry;
1686

    
1687
/* Add each new convertion function in this table. In order to be able
1688
   to convert from any format to any format, the following constraints
1689
   must be satisfied:
1690

1691
   - all FF_COLOR_RGB formats must convert to and from PIX_FMT_RGB24
1692

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

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

1697
   - PIX_FMT_YUV444P and PIX_FMT_YUVJ444P must convert to and from
1698
     PIX_FMT_RGB24.
1699

1700
   - PIX_FMT_422 must convert to and from PIX_FMT_422P.
1701

1702
   The other conversion functions are just optimisations for common cases.
1703
*/
1704
static ConvertEntry convert_table[PIX_FMT_NB][PIX_FMT_NB] = {
1705
    [PIX_FMT_YUV420P] = {
1706
        [PIX_FMT_YUV422] = {
1707
            .convert = yuv420p_to_yuv422,
1708
        },
1709
        [PIX_FMT_RGB555] = {
1710
            .convert = yuv420p_to_rgb555
1711
        },
1712
        [PIX_FMT_RGB565] = {
1713
            .convert = yuv420p_to_rgb565
1714
        },
1715
        [PIX_FMT_BGR24] = {
1716
            .convert = yuv420p_to_bgr24
1717
        },
1718
        [PIX_FMT_RGB24] = {
1719
            .convert = yuv420p_to_rgb24
1720
        },
1721
        [PIX_FMT_RGBA32] = {
1722
            .convert = yuv420p_to_rgba32
1723
        },
1724
        [PIX_FMT_UYVY422] = {
1725
            .convert = yuv420p_to_uyvy422,
1726
        },
1727
    },
1728
    [PIX_FMT_YUV422P] = {
1729
        [PIX_FMT_YUV422] = {
1730
            .convert = yuv422p_to_yuv422,
1731
        },
1732
        [PIX_FMT_UYVY422] = {
1733
            .convert = yuv422p_to_uyvy422,
1734
        },
1735
    },
1736
    [PIX_FMT_YUV444P] = {
1737
        [PIX_FMT_RGB24] = {
1738
            .convert = yuv444p_to_rgb24
1739
        },
1740
    },
1741
    [PIX_FMT_YUVJ420P] = {
1742
        [PIX_FMT_RGB555] = {
1743
            .convert = yuvj420p_to_rgb555
1744
        },
1745
        [PIX_FMT_RGB565] = {
1746
            .convert = yuvj420p_to_rgb565
1747
        },
1748
        [PIX_FMT_BGR24] = {
1749
            .convert = yuvj420p_to_bgr24
1750
        },
1751
        [PIX_FMT_RGB24] = {
1752
            .convert = yuvj420p_to_rgb24
1753
        },
1754
        [PIX_FMT_RGBA32] = {
1755
            .convert = yuvj420p_to_rgba32
1756
        },
1757
    },
1758
    [PIX_FMT_YUVJ444P] = {
1759
        [PIX_FMT_RGB24] = {
1760
            .convert = yuvj444p_to_rgb24
1761
        },
1762
    },
1763
    [PIX_FMT_YUV422] = {
1764
        [PIX_FMT_YUV420P] = {
1765
            .convert = yuv422_to_yuv420p,
1766
        },
1767
        [PIX_FMT_YUV422P] = {
1768
            .convert = yuv422_to_yuv422p,
1769
        },
1770
    },
1771
    [PIX_FMT_UYVY422] = {
1772
        [PIX_FMT_YUV420P] = {
1773
            .convert = uyvy422_to_yuv420p,
1774
        },
1775
        [PIX_FMT_YUV422P] = {
1776
            .convert = uyvy422_to_yuv422p,
1777
        },
1778
    },
1779
    [PIX_FMT_RGB24] = {
1780
        [PIX_FMT_YUV420P] = {
1781
            .convert = rgb24_to_yuv420p
1782
        },
1783
        [PIX_FMT_RGB565] = {
1784
            .convert = rgb24_to_rgb565
1785
        },
1786
        [PIX_FMT_RGB555] = {
1787
            .convert = rgb24_to_rgb555
1788
        },
1789
        [PIX_FMT_RGBA32] = {
1790
            .convert = rgb24_to_rgba32
1791
        },
1792
        [PIX_FMT_BGR24] = {
1793
            .convert = rgb24_to_bgr24
1794
        },
1795
        [PIX_FMT_GRAY8] = {
1796
            .convert = rgb24_to_gray
1797
        },
1798
        [PIX_FMT_PAL8] = {
1799
            .convert = rgb24_to_pal8
1800
        },
1801
        [PIX_FMT_YUV444P] = {
1802
            .convert = rgb24_to_yuv444p
1803
        },
1804
        [PIX_FMT_YUVJ420P] = {
1805
            .convert = rgb24_to_yuvj420p
1806
        },
1807
        [PIX_FMT_YUVJ444P] = {
1808
            .convert = rgb24_to_yuvj444p
1809
        },
1810
    },
1811
    [PIX_FMT_RGBA32] = {
1812
        [PIX_FMT_RGB24] = {
1813
            .convert = rgba32_to_rgb24
1814
        },
1815
        [PIX_FMT_RGB555] = {
1816
            .convert = rgba32_to_rgb555
1817
        },
1818
        [PIX_FMT_PAL8] = {
1819
            .convert = rgba32_to_pal8
1820
        },
1821
        [PIX_FMT_YUV420P] = {
1822
            .convert = rgba32_to_yuv420p
1823
        },
1824
        [PIX_FMT_GRAY8] = {
1825
            .convert = rgba32_to_gray
1826
        },
1827
    },
1828
    [PIX_FMT_BGR24] = {
1829
        [PIX_FMT_RGB24] = {
1830
            .convert = bgr24_to_rgb24
1831
        },
1832
        [PIX_FMT_YUV420P] = {
1833
            .convert = bgr24_to_yuv420p
1834
        },
1835
        [PIX_FMT_GRAY8] = {
1836
            .convert = bgr24_to_gray
1837
        },
1838
    },
1839
    [PIX_FMT_RGB555] = {
1840
        [PIX_FMT_RGB24] = {
1841
            .convert = rgb555_to_rgb24
1842
        },
1843
        [PIX_FMT_RGBA32] = {
1844
            .convert = rgb555_to_rgba32
1845
        },
1846
        [PIX_FMT_YUV420P] = {
1847
            .convert = rgb555_to_yuv420p
1848
        },
1849
        [PIX_FMT_GRAY8] = {
1850
            .convert = rgb555_to_gray
1851
        },
1852
    },
1853
    [PIX_FMT_RGB565] = {
1854
        [PIX_FMT_RGB24] = {
1855
            .convert = rgb565_to_rgb24
1856
        },
1857
        [PIX_FMT_YUV420P] = {
1858
            .convert = rgb565_to_yuv420p
1859
        },
1860
        [PIX_FMT_GRAY8] = {
1861
            .convert = rgb565_to_gray
1862
        },
1863
    },
1864
    [PIX_FMT_GRAY8] = {
1865
        [PIX_FMT_RGB555] = {
1866
            .convert = gray_to_rgb555
1867
        },
1868
        [PIX_FMT_RGB565] = {
1869
            .convert = gray_to_rgb565
1870
        },
1871
        [PIX_FMT_RGB24] = {
1872
            .convert = gray_to_rgb24
1873
        },
1874
        [PIX_FMT_BGR24] = {
1875
            .convert = gray_to_bgr24
1876
        },
1877
        [PIX_FMT_RGBA32] = {
1878
            .convert = gray_to_rgba32
1879
        },
1880
        [PIX_FMT_MONOWHITE] = {
1881
            .convert = gray_to_monowhite
1882
        },
1883
        [PIX_FMT_MONOBLACK] = {
1884
            .convert = gray_to_monoblack
1885
        },
1886
    },
1887
    [PIX_FMT_MONOWHITE] = {
1888
        [PIX_FMT_GRAY8] = {
1889
            .convert = monowhite_to_gray
1890
        },
1891
    },
1892
    [PIX_FMT_MONOBLACK] = {
1893
        [PIX_FMT_GRAY8] = {
1894
            .convert = monoblack_to_gray
1895
        },
1896
    },
1897
    [PIX_FMT_PAL8] = {
1898
        [PIX_FMT_RGB555] = {
1899
            .convert = pal8_to_rgb555
1900
        },
1901
        [PIX_FMT_RGB565] = {
1902
            .convert = pal8_to_rgb565
1903
        },
1904
        [PIX_FMT_BGR24] = {
1905
            .convert = pal8_to_bgr24
1906
        },
1907
        [PIX_FMT_RGB24] = {
1908
            .convert = pal8_to_rgb24
1909
        },
1910
        [PIX_FMT_RGBA32] = {
1911
            .convert = pal8_to_rgba32
1912
        },
1913
    },
1914
    [PIX_FMT_UYVY411] = {
1915
        [PIX_FMT_YUV411P] = {
1916
            .convert = uyvy411_to_yuv411p,
1917
        },
1918
    },
1919

    
1920
};
1921

    
1922
int avpicture_alloc(AVPicture *picture,
1923
                           int pix_fmt, int width, int height)
1924
{
1925
    unsigned int size;
1926
    void *ptr;
1927

    
1928
    size = avpicture_get_size(pix_fmt, width, height);
1929
    if(size<0)
1930
        goto fail;
1931
    ptr = av_malloc(size);
1932
    if (!ptr)
1933
        goto fail;
1934
    avpicture_fill(picture, ptr, pix_fmt, width, height);
1935
    return 0;
1936
 fail:
1937
    memset(picture, 0, sizeof(AVPicture));
1938
    return -1;
1939
}
1940

    
1941
void avpicture_free(AVPicture *picture)
1942
{
1943
    av_free(picture->data[0]);
1944
}
1945

    
1946
/* return true if yuv planar */
1947
static inline int is_yuv_planar(PixFmtInfo *ps)
1948
{
1949
    return (ps->color_type == FF_COLOR_YUV ||
1950
            ps->color_type == FF_COLOR_YUV_JPEG) &&
1951
        ps->pixel_type == FF_PIXEL_PLANAR;
1952
}
1953

    
1954
/* XXX: always use linesize. Return -1 if not supported */
1955
int img_convert(AVPicture *dst, int dst_pix_fmt,
1956
                const AVPicture *src, int src_pix_fmt,
1957
                int src_width, int src_height)
1958
{
1959
    static int inited;
1960
    int i, ret, dst_width, dst_height, int_pix_fmt;
1961
    PixFmtInfo *src_pix, *dst_pix;
1962
    ConvertEntry *ce;
1963
    AVPicture tmp1, *tmp = &tmp1;
1964

    
1965
    if (src_pix_fmt < 0 || src_pix_fmt >= PIX_FMT_NB ||
1966
        dst_pix_fmt < 0 || dst_pix_fmt >= PIX_FMT_NB)
1967
        return -1;
1968
    if (src_width <= 0 || src_height <= 0)
1969
        return 0;
1970

    
1971
    if (!inited) {
1972
        inited = 1;
1973
        img_convert_init();
1974
    }
1975

    
1976
    dst_width = src_width;
1977
    dst_height = src_height;
1978

    
1979
    dst_pix = &pix_fmt_info[dst_pix_fmt];
1980
    src_pix = &pix_fmt_info[src_pix_fmt];
1981
    if (src_pix_fmt == dst_pix_fmt) {
1982
        /* no conversion needed: just copy */
1983
        img_copy(dst, src, dst_pix_fmt, dst_width, dst_height);
1984
        return 0;
1985
    }
1986

    
1987
    ce = &convert_table[src_pix_fmt][dst_pix_fmt];
1988
    if (ce->convert) {
1989
        /* specific conversion routine */
1990
        ce->convert(dst, src, dst_width, dst_height);
1991
        return 0;
1992
    }
1993

    
1994
    /* gray to YUV */
1995
    if (is_yuv_planar(dst_pix) &&
1996
        src_pix_fmt == PIX_FMT_GRAY8) {
1997
        int w, h, y;
1998
        uint8_t *d;
1999

    
2000
        if (dst_pix->color_type == FF_COLOR_YUV_JPEG) {
2001
            img_copy_plane(dst->data[0], dst->linesize[0],
2002
                     src->data[0], src->linesize[0],
2003
                     dst_width, dst_height);
2004
        } else {
2005
            img_apply_table(dst->data[0], dst->linesize[0],
2006
                            src->data[0], src->linesize[0],
2007
                            dst_width, dst_height,
2008
                            y_jpeg_to_ccir);
2009
        }
2010
        /* fill U and V with 128 */
2011
        w = dst_width;
2012
        h = dst_height;
2013
        w >>= dst_pix->x_chroma_shift;
2014
        h >>= dst_pix->y_chroma_shift;
2015
        for(i = 1; i <= 2; i++) {
2016
            d = dst->data[i];
2017
            for(y = 0; y< h; y++) {
2018
                memset(d, 128, w);
2019
                d += dst->linesize[i];
2020
            }
2021
        }
2022
        return 0;
2023
    }
2024

    
2025
    /* YUV to gray */
2026
    if (is_yuv_planar(src_pix) &&
2027
        dst_pix_fmt == PIX_FMT_GRAY8) {
2028
        if (src_pix->color_type == FF_COLOR_YUV_JPEG) {
2029
            img_copy_plane(dst->data[0], dst->linesize[0],
2030
                     src->data[0], src->linesize[0],
2031
                     dst_width, dst_height);
2032
        } else {
2033
            img_apply_table(dst->data[0], dst->linesize[0],
2034
                            src->data[0], src->linesize[0],
2035
                            dst_width, dst_height,
2036
                            y_ccir_to_jpeg);
2037
        }
2038
        return 0;
2039
    }
2040

    
2041
    /* YUV to YUV planar */
2042
    if (is_yuv_planar(dst_pix) && is_yuv_planar(src_pix)) {
2043
        int x_shift, y_shift, w, h, xy_shift;
2044
        void (*resize_func)(uint8_t *dst, int dst_wrap,
2045
                            const uint8_t *src, int src_wrap,
2046
                            int width, int height);
2047

    
2048
        /* compute chroma size of the smallest dimensions */
2049
        w = dst_width;
2050
        h = dst_height;
2051
        if (dst_pix->x_chroma_shift >= src_pix->x_chroma_shift)
2052
            w >>= dst_pix->x_chroma_shift;
2053
        else
2054
            w >>= src_pix->x_chroma_shift;
2055
        if (dst_pix->y_chroma_shift >= src_pix->y_chroma_shift)
2056
            h >>= dst_pix->y_chroma_shift;
2057
        else
2058
            h >>= src_pix->y_chroma_shift;
2059

    
2060
        x_shift = (dst_pix->x_chroma_shift - src_pix->x_chroma_shift);
2061
        y_shift = (dst_pix->y_chroma_shift - src_pix->y_chroma_shift);
2062
        xy_shift = ((x_shift & 0xf) << 4) | (y_shift & 0xf);
2063
        /* there must be filters for conversion at least from and to
2064
           YUV444 format */
2065
        switch(xy_shift) {
2066
        case 0x00:
2067
            resize_func = img_copy_plane;
2068
            break;
2069
        case 0x10:
2070
            resize_func = shrink21;
2071
            break;
2072
        case 0x20:
2073
            resize_func = shrink41;
2074
            break;
2075
        case 0x01:
2076
            resize_func = shrink12;
2077
            break;
2078
        case 0x11:
2079
            resize_func = shrink22;
2080
            break;
2081
        case 0x22:
2082
            resize_func = shrink44;
2083
            break;
2084
        case 0xf0:
2085
            resize_func = grow21;
2086
            break;
2087
        case 0xe0:
2088
            resize_func = grow41;
2089
            break;
2090
        case 0xff:
2091
            resize_func = grow22;
2092
            break;
2093
        case 0xee:
2094
            resize_func = grow44;
2095
            break;
2096
        case 0xf1:
2097
            resize_func = conv411;
2098
            break;
2099
        default:
2100
            /* currently not handled */
2101
            goto no_chroma_filter;
2102
        }
2103

    
2104
        img_copy_plane(dst->data[0], dst->linesize[0],
2105
                       src->data[0], src->linesize[0],
2106
                       dst_width, dst_height);
2107

    
2108
        for(i = 1;i <= 2; i++)
2109
            resize_func(dst->data[i], dst->linesize[i],
2110
                        src->data[i], src->linesize[i],
2111
                        dst_width>>dst_pix->x_chroma_shift, dst_height>>dst_pix->y_chroma_shift);
2112
        /* if yuv color space conversion is needed, we do it here on
2113
           the destination image */
2114
        if (dst_pix->color_type != src_pix->color_type) {
2115
            const uint8_t *y_table, *c_table;
2116
            if (dst_pix->color_type == FF_COLOR_YUV) {
2117
                y_table = y_jpeg_to_ccir;
2118
                c_table = c_jpeg_to_ccir;
2119
            } else {
2120
                y_table = y_ccir_to_jpeg;
2121
                c_table = c_ccir_to_jpeg;
2122
            }
2123
            img_apply_table(dst->data[0], dst->linesize[0],
2124
                            dst->data[0], dst->linesize[0],
2125
                            dst_width, dst_height,
2126
                            y_table);
2127

    
2128
            for(i = 1;i <= 2; i++)
2129
                img_apply_table(dst->data[i], dst->linesize[i],
2130
                                dst->data[i], dst->linesize[i],
2131
                                dst_width>>dst_pix->x_chroma_shift,
2132
                                dst_height>>dst_pix->y_chroma_shift,
2133
                                c_table);
2134
        }
2135
        return 0;
2136
    }
2137
 no_chroma_filter:
2138

    
2139
    /* try to use an intermediate format */
2140
    if (src_pix_fmt == PIX_FMT_YUV422 ||
2141
        dst_pix_fmt == PIX_FMT_YUV422) {
2142
        /* specific case: convert to YUV422P first */
2143
        int_pix_fmt = PIX_FMT_YUV422P;
2144
    } else if (src_pix_fmt == PIX_FMT_UYVY422 ||
2145
        dst_pix_fmt == PIX_FMT_UYVY422) {
2146
        /* specific case: convert to YUV422P first */
2147
        int_pix_fmt = PIX_FMT_YUV422P;
2148
    } else if (src_pix_fmt == PIX_FMT_UYVY411 ||
2149
        dst_pix_fmt == PIX_FMT_UYVY411) {
2150
        /* specific case: convert to YUV411P first */
2151
        int_pix_fmt = PIX_FMT_YUV411P;
2152
    } else if ((src_pix->color_type == FF_COLOR_GRAY &&
2153
                src_pix_fmt != PIX_FMT_GRAY8) ||
2154
               (dst_pix->color_type == FF_COLOR_GRAY &&
2155
                dst_pix_fmt != PIX_FMT_GRAY8)) {
2156
        /* gray8 is the normalized format */
2157
        int_pix_fmt = PIX_FMT_GRAY8;
2158
    } else if ((is_yuv_planar(src_pix) &&
2159
                src_pix_fmt != PIX_FMT_YUV444P &&
2160
                src_pix_fmt != PIX_FMT_YUVJ444P)) {
2161
        /* yuv444 is the normalized format */
2162
        if (src_pix->color_type == FF_COLOR_YUV_JPEG)
2163
            int_pix_fmt = PIX_FMT_YUVJ444P;
2164
        else
2165
            int_pix_fmt = PIX_FMT_YUV444P;
2166
    } else if ((is_yuv_planar(dst_pix) &&
2167
                dst_pix_fmt != PIX_FMT_YUV444P &&
2168
                dst_pix_fmt != PIX_FMT_YUVJ444P)) {
2169
        /* yuv444 is the normalized format */
2170
        if (dst_pix->color_type == FF_COLOR_YUV_JPEG)
2171
            int_pix_fmt = PIX_FMT_YUVJ444P;
2172
        else
2173
            int_pix_fmt = PIX_FMT_YUV444P;
2174
    } else {
2175
        /* the two formats are rgb or gray8 or yuv[j]444p */
2176
        if (src_pix->is_alpha && dst_pix->is_alpha)
2177
            int_pix_fmt = PIX_FMT_RGBA32;
2178
        else
2179
            int_pix_fmt = PIX_FMT_RGB24;
2180
    }
2181
    if (avpicture_alloc(tmp, int_pix_fmt, dst_width, dst_height) < 0)
2182
        return -1;
2183
    ret = -1;
2184
    if (img_convert(tmp, int_pix_fmt,
2185
                    src, src_pix_fmt, src_width, src_height) < 0)
2186
        goto fail1;
2187
    if (img_convert(dst, dst_pix_fmt,
2188
                    tmp, int_pix_fmt, dst_width, dst_height) < 0)
2189
        goto fail1;
2190
    ret = 0;
2191
 fail1:
2192
    avpicture_free(tmp);
2193
    return ret;
2194
}
2195

    
2196
/* NOTE: we scan all the pixels to have an exact information */
2197
static int get_alpha_info_pal8(const AVPicture *src, int width, int height)
2198
{
2199
    const unsigned char *p;
2200
    int src_wrap, ret, x, y;
2201
    unsigned int a;
2202
    uint32_t *palette = (uint32_t *)src->data[1];
2203

    
2204
    p = src->data[0];
2205
    src_wrap = src->linesize[0] - width;
2206
    ret = 0;
2207
    for(y=0;y<height;y++) {
2208
        for(x=0;x<width;x++) {
2209
            a = palette[p[0]] >> 24;
2210
            if (a == 0x00) {
2211
                ret |= FF_ALPHA_TRANSP;
2212
            } else if (a != 0xff) {
2213
                ret |= FF_ALPHA_SEMI_TRANSP;
2214
            }
2215
            p++;
2216
        }
2217
        p += src_wrap;
2218
    }
2219
    return ret;
2220
}
2221

    
2222
/**
2223
 * Tell if an image really has transparent alpha values.
2224
 * @return ored mask of FF_ALPHA_xxx constants
2225
 */
2226
int img_get_alpha_info(const AVPicture *src,
2227
                       int pix_fmt, int width, int height)
2228
{
2229
    PixFmtInfo *pf = &pix_fmt_info[pix_fmt];
2230
    int ret;
2231

    
2232
    pf = &pix_fmt_info[pix_fmt];
2233
    /* no alpha can be represented in format */
2234
    if (!pf->is_alpha)
2235
        return 0;
2236
    switch(pix_fmt) {
2237
    case PIX_FMT_RGBA32:
2238
        ret = get_alpha_info_rgba32(src, width, height);
2239
        break;
2240
    case PIX_FMT_RGB555:
2241
        ret = get_alpha_info_rgb555(src, width, height);
2242
        break;
2243
    case PIX_FMT_PAL8:
2244
        ret = get_alpha_info_pal8(src, width, height);
2245
        break;
2246
    default:
2247
        /* we do not know, so everything is indicated */
2248
        ret = FF_ALPHA_TRANSP | FF_ALPHA_SEMI_TRANSP;
2249
        break;
2250
    }
2251
    return ret;
2252
}
2253

    
2254
#ifdef HAVE_MMX
2255
#define DEINT_INPLACE_LINE_LUM \
2256
                    movd_m2r(lum_m4[0],mm0);\
2257
                    movd_m2r(lum_m3[0],mm1);\
2258
                    movd_m2r(lum_m2[0],mm2);\
2259
                    movd_m2r(lum_m1[0],mm3);\
2260
                    movd_m2r(lum[0],mm4);\
2261
                    punpcklbw_r2r(mm7,mm0);\
2262
                    movd_r2m(mm2,lum_m4[0]);\
2263
                    punpcklbw_r2r(mm7,mm1);\
2264
                    punpcklbw_r2r(mm7,mm2);\
2265
                    punpcklbw_r2r(mm7,mm3);\
2266
                    punpcklbw_r2r(mm7,mm4);\
2267
                    paddw_r2r(mm3,mm1);\
2268
                    psllw_i2r(1,mm2);\
2269
                    paddw_r2r(mm4,mm0);\
2270
                    psllw_i2r(2,mm1);\
2271
                    paddw_r2r(mm6,mm2);\
2272
                    paddw_r2r(mm2,mm1);\
2273
                    psubusw_r2r(mm0,mm1);\
2274
                    psrlw_i2r(3,mm1);\
2275
                    packuswb_r2r(mm7,mm1);\
2276
                    movd_r2m(mm1,lum_m2[0]);
2277

    
2278
#define DEINT_LINE_LUM \
2279
                    movd_m2r(lum_m4[0],mm0);\
2280
                    movd_m2r(lum_m3[0],mm1);\
2281
                    movd_m2r(lum_m2[0],mm2);\
2282
                    movd_m2r(lum_m1[0],mm3);\
2283
                    movd_m2r(lum[0],mm4);\
2284
                    punpcklbw_r2r(mm7,mm0);\
2285
                    punpcklbw_r2r(mm7,mm1);\
2286
                    punpcklbw_r2r(mm7,mm2);\
2287
                    punpcklbw_r2r(mm7,mm3);\
2288
                    punpcklbw_r2r(mm7,mm4);\
2289
                    paddw_r2r(mm3,mm1);\
2290
                    psllw_i2r(1,mm2);\
2291
                    paddw_r2r(mm4,mm0);\
2292
                    psllw_i2r(2,mm1);\
2293
                    paddw_r2r(mm6,mm2);\
2294
                    paddw_r2r(mm2,mm1);\
2295
                    psubusw_r2r(mm0,mm1);\
2296
                    psrlw_i2r(3,mm1);\
2297
                    packuswb_r2r(mm7,mm1);\
2298
                    movd_r2m(mm1,dst[0]);
2299
#endif
2300

    
2301
/* filter parameters: [-1 4 2 4 -1] // 8 */
2302
static void deinterlace_line(uint8_t *dst,
2303
                             const uint8_t *lum_m4, const uint8_t *lum_m3,
2304
                             const uint8_t *lum_m2, const uint8_t *lum_m1,
2305
                             const uint8_t *lum,
2306
                             int size)
2307
{
2308
#ifndef HAVE_MMX
2309
    uint8_t *cm = cropTbl + MAX_NEG_CROP;
2310
    int sum;
2311

    
2312
    for(;size > 0;size--) {
2313
        sum = -lum_m4[0];
2314
        sum += lum_m3[0] << 2;
2315
        sum += lum_m2[0] << 1;
2316
        sum += lum_m1[0] << 2;
2317
        sum += -lum[0];
2318
        dst[0] = cm[(sum + 4) >> 3];
2319
        lum_m4++;
2320
        lum_m3++;
2321
        lum_m2++;
2322
        lum_m1++;
2323
        lum++;
2324
        dst++;
2325
    }
2326
#else
2327

    
2328
    {
2329
        mmx_t rounder;
2330
        rounder.uw[0]=4;
2331
        rounder.uw[1]=4;
2332
        rounder.uw[2]=4;
2333
        rounder.uw[3]=4;
2334
        pxor_r2r(mm7,mm7);
2335
        movq_m2r(rounder,mm6);
2336
    }
2337
    for (;size > 3; size-=4) {
2338
        DEINT_LINE_LUM
2339
        lum_m4+=4;
2340
        lum_m3+=4;
2341
        lum_m2+=4;
2342
        lum_m1+=4;
2343
        lum+=4;
2344
        dst+=4;
2345
    }
2346
#endif
2347
}
2348
static void deinterlace_line_inplace(uint8_t *lum_m4, uint8_t *lum_m3, uint8_t *lum_m2, uint8_t *lum_m1, uint8_t *lum,
2349
                             int size)
2350
{
2351
#ifndef HAVE_MMX
2352
    uint8_t *cm = cropTbl + MAX_NEG_CROP;
2353
    int sum;
2354

    
2355
    for(;size > 0;size--) {
2356
        sum = -lum_m4[0];
2357
        sum += lum_m3[0] << 2;
2358
        sum += lum_m2[0] << 1;
2359
        lum_m4[0]=lum_m2[0];
2360
        sum += lum_m1[0] << 2;
2361
        sum += -lum[0];
2362
        lum_m2[0] = cm[(sum + 4) >> 3];
2363
        lum_m4++;
2364
        lum_m3++;
2365
        lum_m2++;
2366
        lum_m1++;
2367
        lum++;
2368
    }
2369
#else
2370

    
2371
    {
2372
        mmx_t rounder;
2373
        rounder.uw[0]=4;
2374
        rounder.uw[1]=4;
2375
        rounder.uw[2]=4;
2376
        rounder.uw[3]=4;
2377
        pxor_r2r(mm7,mm7);
2378
        movq_m2r(rounder,mm6);
2379
    }
2380
    for (;size > 3; size-=4) {
2381
        DEINT_INPLACE_LINE_LUM
2382
        lum_m4+=4;
2383
        lum_m3+=4;
2384
        lum_m2+=4;
2385
        lum_m1+=4;
2386
        lum+=4;
2387
    }
2388
#endif
2389
}
2390

    
2391
/* deinterlacing : 2 temporal taps, 3 spatial taps linear filter. The
2392
   top field is copied as is, but the bottom field is deinterlaced
2393
   against the top field. */
2394
static void deinterlace_bottom_field(uint8_t *dst, int dst_wrap,
2395
                                    const uint8_t *src1, int src_wrap,
2396
                                    int width, int height)
2397
{
2398
    const uint8_t *src_m2, *src_m1, *src_0, *src_p1, *src_p2;
2399
    int y;
2400

    
2401
    src_m2 = src1;
2402
    src_m1 = src1;
2403
    src_0=&src_m1[src_wrap];
2404
    src_p1=&src_0[src_wrap];
2405
    src_p2=&src_p1[src_wrap];
2406
    for(y=0;y<(height-2);y+=2) {
2407
        memcpy(dst,src_m1,width);
2408
        dst += dst_wrap;
2409
        deinterlace_line(dst,src_m2,src_m1,src_0,src_p1,src_p2,width);
2410
        src_m2 = src_0;
2411
        src_m1 = src_p1;
2412
        src_0 = src_p2;
2413
        src_p1 += 2*src_wrap;
2414
        src_p2 += 2*src_wrap;
2415
        dst += dst_wrap;
2416
    }
2417
    memcpy(dst,src_m1,width);
2418
    dst += dst_wrap;
2419
    /* do last line */
2420
    deinterlace_line(dst,src_m2,src_m1,src_0,src_0,src_0,width);
2421
}
2422

    
2423
static void deinterlace_bottom_field_inplace(uint8_t *src1, int src_wrap,
2424
                                             int width, int height)
2425
{
2426
    uint8_t *src_m1, *src_0, *src_p1, *src_p2;
2427
    int y;
2428
    uint8_t *buf;
2429
    buf = (uint8_t*)av_malloc(width);
2430

    
2431
    src_m1 = src1;
2432
    memcpy(buf,src_m1,width);
2433
    src_0=&src_m1[src_wrap];
2434
    src_p1=&src_0[src_wrap];
2435
    src_p2=&src_p1[src_wrap];
2436
    for(y=0;y<(height-2);y+=2) {
2437
        deinterlace_line_inplace(buf,src_m1,src_0,src_p1,src_p2,width);
2438
        src_m1 = src_p1;
2439
        src_0 = src_p2;
2440
        src_p1 += 2*src_wrap;
2441
        src_p2 += 2*src_wrap;
2442
    }
2443
    /* do last line */
2444
    deinterlace_line_inplace(buf,src_m1,src_0,src_0,src_0,width);
2445
    av_free(buf);
2446
}
2447

    
2448

    
2449
/* deinterlace - if not supported return -1 */
2450
int avpicture_deinterlace(AVPicture *dst, const AVPicture *src,
2451
                          int pix_fmt, int width, int height)
2452
{
2453
    int i;
2454

    
2455
    if (pix_fmt != PIX_FMT_YUV420P &&
2456
        pix_fmt != PIX_FMT_YUV422P &&
2457
        pix_fmt != PIX_FMT_YUV444P &&
2458
        pix_fmt != PIX_FMT_YUV411P)
2459
        return -1;
2460
    if ((width & 3) != 0 || (height & 3) != 0)
2461
        return -1;
2462

    
2463
    for(i=0;i<3;i++) {
2464
        if (i == 1) {
2465
            switch(pix_fmt) {
2466
            case PIX_FMT_YUV420P:
2467
                width >>= 1;
2468
                height >>= 1;
2469
                break;
2470
            case PIX_FMT_YUV422P:
2471
                width >>= 1;
2472
                break;
2473
            case PIX_FMT_YUV411P:
2474
                width >>= 2;
2475
                break;
2476
            default:
2477
                break;
2478
            }
2479
        }
2480
        if (src == dst) {
2481
            deinterlace_bottom_field_inplace(dst->data[i], dst->linesize[i],
2482
                                 width, height);
2483
        } else {
2484
            deinterlace_bottom_field(dst->data[i],dst->linesize[i],
2485
                                        src->data[i], src->linesize[i],
2486
                                        width, height);
2487
        }
2488
    }
2489
#ifdef HAVE_MMX
2490
    emms();
2491
#endif
2492
    return 0;
2493
}
2494

    
2495
#undef FIX