Statistics
| Branch: | Revision:

ffmpeg / libavcodec / imgconvert.c @ cb231c48

History | View | Annotate | Download (57.7 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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  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_YUV410P] = {
101
        .name = "yuv410p",
102
        .nb_channels = 3,
103
        .color_type = FF_COLOR_YUV,
104
        .pixel_type = FF_PIXEL_PLANAR,
105
        .depth = 8,
106
        .x_chroma_shift = 2, .y_chroma_shift = 2,
107
    },
108
    [PIX_FMT_YUV411P] = {
109
        .name = "yuv411p",
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 = 0,
115
    },
116

    
117
    /* JPEG YUV */
118
    [PIX_FMT_YUVJ420P] = {
119
        .name = "yuvj420p",
120
        .nb_channels = 3,
121
        .color_type = FF_COLOR_YUV_JPEG,
122
        .pixel_type = FF_PIXEL_PLANAR,
123
        .depth = 8,
124
        .x_chroma_shift = 1, .y_chroma_shift = 1, 
125
    },
126
    [PIX_FMT_YUVJ422P] = {
127
        .name = "yuvj422p",
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 = 0, 
133
    },
134
    [PIX_FMT_YUVJ444P] = {
135
        .name = "yuvj444p",
136
        .nb_channels = 3,
137
        .color_type = FF_COLOR_YUV_JPEG,
138
        .pixel_type = FF_PIXEL_PLANAR,
139
        .depth = 8,
140
        .x_chroma_shift = 0, .y_chroma_shift = 0, 
141
    },
142

    
143
    /* RGB formats */
144
    [PIX_FMT_RGB24] = {
145
        .name = "rgb24",
146
        .nb_channels = 3,
147
        .color_type = FF_COLOR_RGB,
148
        .pixel_type = FF_PIXEL_PACKED,
149
        .depth = 8,
150
    },
151
    [PIX_FMT_BGR24] = {
152
        .name = "bgr24",
153
        .nb_channels = 3,
154
        .color_type = FF_COLOR_RGB,
155
        .pixel_type = FF_PIXEL_PACKED,
156
        .depth = 8,
157
    },
158
    [PIX_FMT_RGBA32] = {
159
        .name = "rgba32",
160
        .nb_channels = 4, .is_alpha = 1,
161
        .color_type = FF_COLOR_RGB,
162
        .pixel_type = FF_PIXEL_PACKED,
163
        .depth = 8,
164
    },
165
    [PIX_FMT_RGB565] = {
166
        .name = "rgb565",
167
        .nb_channels = 3,
168
        .color_type = FF_COLOR_RGB,
169
        .pixel_type = FF_PIXEL_PACKED,
170
        .depth = 5,
171
    },
172
    [PIX_FMT_RGB555] = {
173
        .name = "rgb555",
174
        .nb_channels = 4, .is_alpha = 1,
175
        .color_type = FF_COLOR_RGB,
176
        .pixel_type = FF_PIXEL_PACKED,
177
        .depth = 5,
178
    },
179

    
180
    /* gray / mono formats */
181
    [PIX_FMT_GRAY8] = {
182
        .name = "gray",
183
        .nb_channels = 1,
184
        .color_type = FF_COLOR_GRAY,
185
        .pixel_type = FF_PIXEL_PLANAR,
186
        .depth = 8,
187
    },
188
    [PIX_FMT_MONOWHITE] = {
189
        .name = "monow",
190
        .nb_channels = 1,
191
        .color_type = FF_COLOR_GRAY,
192
        .pixel_type = FF_PIXEL_PLANAR,
193
        .depth = 1,
194
    },
195
    [PIX_FMT_MONOBLACK] = {
196
        .name = "monob",
197
        .nb_channels = 1,
198
        .color_type = FF_COLOR_GRAY,
199
        .pixel_type = FF_PIXEL_PLANAR,
200
        .depth = 1,
201
    },
202

    
203
    /* paletted formats */
204
    [PIX_FMT_PAL8] = {
205
        .name = "pal8",
206
        .nb_channels = 4, .is_alpha = 1,
207
        .color_type = FF_COLOR_RGB,
208
        .pixel_type = FF_PIXEL_PALETTE,
209
        .depth = 8,
210
    },
211
};
212

    
213
void avcodec_get_chroma_sub_sample(int pix_fmt, int *h_shift, int *v_shift)
214
{
215
    *h_shift = pix_fmt_info[pix_fmt].x_chroma_shift;
216
    *v_shift = pix_fmt_info[pix_fmt].y_chroma_shift;
217
}
218

    
219
const char *avcodec_get_pix_fmt_name(int pix_fmt)
220
{
221
    if (pix_fmt < 0 || pix_fmt >= PIX_FMT_NB)
222
        return "???";
223
    else
224
        return pix_fmt_info[pix_fmt].name;
225
}
226

    
227
enum PixelFormat avcodec_get_pix_fmt(const char* name)
228
{
229
    int i; 
230
    
231
    for (i=0; i < PIX_FMT_NB; i++)
232
         if (!strcmp(pix_fmt_info[i].name, name))
233
             break;
234
    return i;
235
}
236

    
237
/* Picture field are filled with 'ptr' addresses. Also return size */
238
int avpicture_fill(AVPicture *picture, uint8_t *ptr,
239
                   int pix_fmt, int width, int height)
240
{
241
    int size, w2, h2, size2;
242
    PixFmtInfo *pinfo;
243
    
244
    pinfo = &pix_fmt_info[pix_fmt];
245
    size = width * height;
246
    switch(pix_fmt) {
247
    case PIX_FMT_YUV420P:
248
    case PIX_FMT_YUV422P:
249
    case PIX_FMT_YUV444P:
250
    case PIX_FMT_YUV410P:
251
    case PIX_FMT_YUV411P:
252
    case PIX_FMT_YUVJ420P:
253
    case PIX_FMT_YUVJ422P:
254
    case PIX_FMT_YUVJ444P:
255
        w2 = (width + (1 << pinfo->x_chroma_shift) - 1) >> pinfo->x_chroma_shift;
256
        h2 = (height + (1 << pinfo->y_chroma_shift) - 1) >> pinfo->y_chroma_shift;
257
        size2 = w2 * h2;
258
        picture->data[0] = ptr;
259
        picture->data[1] = picture->data[0] + size;
260
        picture->data[2] = picture->data[1] + size2;
261
        picture->linesize[0] = width;
262
        picture->linesize[1] = w2;
263
        picture->linesize[2] = w2;
264
        return size + 2 * size2;
265
    case PIX_FMT_RGB24:
266
    case PIX_FMT_BGR24:
267
        picture->data[0] = ptr;
268
        picture->data[1] = NULL;
269
        picture->data[2] = NULL;
270
        picture->linesize[0] = width * 3;
271
        return size * 3;
272
    case PIX_FMT_RGBA32:
273
        picture->data[0] = ptr;
274
        picture->data[1] = NULL;
275
        picture->data[2] = NULL;
276
        picture->linesize[0] = width * 4;
277
        return size * 4;
278
    case PIX_FMT_RGB555:
279
    case PIX_FMT_RGB565:
280
    case PIX_FMT_YUV422:
281
        picture->data[0] = ptr;
282
        picture->data[1] = NULL;
283
        picture->data[2] = NULL;
284
        picture->linesize[0] = width * 2;
285
        return size * 2;
286
    case PIX_FMT_GRAY8:
287
        picture->data[0] = ptr;
288
        picture->data[1] = NULL;
289
        picture->data[2] = NULL;
290
        picture->linesize[0] = width;
291
        return size;
292
    case PIX_FMT_MONOWHITE:
293
    case PIX_FMT_MONOBLACK:
294
        picture->data[0] = ptr;
295
        picture->data[1] = NULL;
296
        picture->data[2] = NULL;
297
        picture->linesize[0] = (width + 7) >> 3;
298
        return picture->linesize[0] * height;
299
    case PIX_FMT_PAL8:
300
        size2 = (size + 3) & ~3;
301
        picture->data[0] = ptr;
302
        picture->data[1] = ptr + size2; /* palette is stored here as 256 32 bit words */
303
        picture->data[2] = NULL;
304
        picture->linesize[0] = width;
305
        picture->linesize[1] = 4;
306
        return size2 + 256 * 4;
307
    default:
308
        picture->data[0] = NULL;
309
        picture->data[1] = NULL;
310
        picture->data[2] = NULL;
311
        picture->data[3] = NULL;
312
        return -1;
313
    }
314
}
315

    
316
int avpicture_layout(AVPicture* src, int pix_fmt, int width, int height,
317
                     unsigned char *dest, int dest_size)
318
{
319
    PixFmtInfo* pf = &pix_fmt_info[pix_fmt];
320
    int i, j, w, h, data_planes;
321
    unsigned char* s; 
322
    int size = avpicture_get_size(pix_fmt, width, height);
323

    
324
    if (size > dest_size)
325
        return -1;
326

    
327
    if (pf->pixel_type == FF_PIXEL_PACKED || pf->pixel_type == FF_PIXEL_PALETTE) {
328
        if (pix_fmt == PIX_FMT_YUV422 || pix_fmt == PIX_FMT_RGB565 ||
329
            pix_fmt == PIX_FMT_RGB555)
330
          w = width * 2;
331
        else if (pix_fmt == PIX_FMT_PAL8)
332
          w = width;
333
        else
334
          w = width * (pf->depth * pf->nb_channels / 8);
335
          
336
        data_planes = 1;
337
        h = height;
338
    } else {
339
        data_planes = pf->nb_channels;
340
        w = width;
341
        h = height;
342
    }
343
    
344
    for (i=0; i<data_planes; i++) {
345
         if (i == 1) {
346
             w = width >> pf->x_chroma_shift;
347
             h = height >> pf->y_chroma_shift;
348
         }
349
         s = src->data[i];
350
         for(j=0; j<h; j++) {
351
             memcpy(dest, s, w);
352
             dest += w;
353
             s += src->linesize[i];
354
         }
355
    }
356
    
357
    if (pf->pixel_type == FF_PIXEL_PALETTE)
358
        memcpy((unsigned char *)(((size_t)dest + 3) & ~3), src->data[1], 256 * 4);
359
    
360
    return size;
361
}
362

    
363
int avpicture_get_size(int pix_fmt, int width, int height)
364
{
365
    AVPicture dummy_pict;
366
    return avpicture_fill(&dummy_pict, NULL, pix_fmt, width, height);
367
}
368

    
369
/**
370
 * compute the loss when converting from a pixel format to another 
371
 */
372
int avcodec_get_pix_fmt_loss(int dst_pix_fmt, int src_pix_fmt,
373
                             int has_alpha)
374
{
375
    const PixFmtInfo *pf, *ps;
376
    int loss;
377

    
378
    ps = &pix_fmt_info[src_pix_fmt];
379
    pf = &pix_fmt_info[dst_pix_fmt];
380

    
381
    /* compute loss */
382
    loss = 0;
383
    pf = &pix_fmt_info[dst_pix_fmt];
384
    if (pf->depth < ps->depth ||
385
        (dst_pix_fmt == PIX_FMT_RGB555 && src_pix_fmt == PIX_FMT_RGB565))
386
        loss |= FF_LOSS_DEPTH;
387
    if (pf->x_chroma_shift > ps->x_chroma_shift ||
388
        pf->y_chroma_shift > ps->y_chroma_shift)
389
        loss |= FF_LOSS_RESOLUTION;
390
    switch(pf->color_type) {
391
    case FF_COLOR_RGB:
392
        if (ps->color_type != FF_COLOR_RGB &&
393
            ps->color_type != FF_COLOR_GRAY)
394
            loss |= FF_LOSS_COLORSPACE;
395
        break;
396
    case FF_COLOR_GRAY:
397
        if (ps->color_type != FF_COLOR_GRAY)
398
            loss |= FF_LOSS_COLORSPACE;
399
        break;
400
    case FF_COLOR_YUV:
401
        if (ps->color_type != FF_COLOR_YUV)
402
            loss |= FF_LOSS_COLORSPACE;
403
        break;
404
    case FF_COLOR_YUV_JPEG:
405
        if (ps->color_type != FF_COLOR_YUV_JPEG &&
406
            ps->color_type != FF_COLOR_YUV && 
407
            ps->color_type != FF_COLOR_GRAY)
408
            loss |= FF_LOSS_COLORSPACE;
409
        break;
410
    default:
411
        /* fail safe test */
412
        if (ps->color_type != pf->color_type)
413
            loss |= FF_LOSS_COLORSPACE;
414
        break;
415
    }
416
    if (pf->color_type == FF_COLOR_GRAY &&
417
        ps->color_type != FF_COLOR_GRAY)
418
        loss |= FF_LOSS_CHROMA;
419
    if (!pf->is_alpha && (ps->is_alpha && has_alpha))
420
        loss |= FF_LOSS_ALPHA;
421
    if (pf->pixel_type == FF_PIXEL_PALETTE && 
422
        (ps->pixel_type != FF_PIXEL_PALETTE && ps->color_type != FF_COLOR_GRAY))
423
        loss |= FF_LOSS_COLORQUANT;
424
    return loss;
425
}
426

    
427
static int avg_bits_per_pixel(int pix_fmt)
428
{
429
    int bits;
430
    const PixFmtInfo *pf;
431

    
432
    pf = &pix_fmt_info[pix_fmt];
433
    switch(pf->pixel_type) {
434
    case FF_PIXEL_PACKED:
435
        switch(pix_fmt) {
436
        case PIX_FMT_YUV422:
437
        case PIX_FMT_RGB565:
438
        case PIX_FMT_RGB555:
439
            bits = 16;
440
            break;
441
        default:
442
            bits = pf->depth * pf->nb_channels;
443
            break;
444
        }
445
        break;
446
    case FF_PIXEL_PLANAR:
447
        if (pf->x_chroma_shift == 0 && pf->y_chroma_shift == 0) {
448
            bits = pf->depth * pf->nb_channels;
449
        } else {
450
            bits = pf->depth + ((2 * pf->depth) >> 
451
                                (pf->x_chroma_shift + pf->y_chroma_shift));
452
        }
453
        break;
454
    case FF_PIXEL_PALETTE:
455
        bits = 8;
456
        break;
457
    default:
458
        bits = -1;
459
        break;
460
    }
461
    return bits;
462
}
463

    
464
static int avcodec_find_best_pix_fmt1(int pix_fmt_mask, 
465
                                      int src_pix_fmt,
466
                                      int has_alpha,
467
                                      int loss_mask)
468
{
469
    int dist, i, loss, min_dist, dst_pix_fmt;
470

    
471
    /* find exact color match with smallest size */
472
    dst_pix_fmt = -1;
473
    min_dist = 0x7fffffff;
474
    for(i = 0;i < PIX_FMT_NB; i++) {
475
        if (pix_fmt_mask & (1 << i)) {
476
            loss = avcodec_get_pix_fmt_loss(i, src_pix_fmt, has_alpha) & loss_mask;
477
            if (loss == 0) {
478
                dist = avg_bits_per_pixel(i);
479
                if (dist < min_dist) {
480
                    min_dist = dist;
481
                    dst_pix_fmt = i;
482
                }
483
            }
484
        }
485
    }
486
    return dst_pix_fmt;
487
}
488

    
489
/** 
490
 * find best pixel format to convert to. Return -1 if none found 
491
 */
492
int avcodec_find_best_pix_fmt(int pix_fmt_mask, int src_pix_fmt,
493
                              int has_alpha, int *loss_ptr)
494
{
495
    int dst_pix_fmt, loss_mask, i;
496
    static const int loss_mask_order[] = {
497
        ~0, /* no loss first */
498
        ~FF_LOSS_ALPHA,
499
        ~FF_LOSS_RESOLUTION,
500
        ~(FF_LOSS_COLORSPACE | FF_LOSS_RESOLUTION),
501
        ~FF_LOSS_COLORQUANT,
502
        ~FF_LOSS_DEPTH,
503
        0,
504
    };
505

    
506
    /* try with successive loss */
507
    i = 0;
508
    for(;;) {
509
        loss_mask = loss_mask_order[i++];
510
        dst_pix_fmt = avcodec_find_best_pix_fmt1(pix_fmt_mask, src_pix_fmt, 
511
                                                 has_alpha, loss_mask);
512
        if (dst_pix_fmt >= 0)
513
            goto found;
514
        if (loss_mask == 0)
515
            break;
516
    }
517
    return -1;
518
 found:
519
    if (loss_ptr)
520
        *loss_ptr = avcodec_get_pix_fmt_loss(dst_pix_fmt, src_pix_fmt, has_alpha);
521
    return dst_pix_fmt;
522
}
523

    
524
static void img_copy_plane(uint8_t *dst, int dst_wrap, 
525
                           const uint8_t *src, int src_wrap,
526
                           int width, int height)
527
{
528
    for(;height > 0; height--) {
529
        memcpy(dst, src, width);
530
        dst += dst_wrap;
531
        src += src_wrap;
532
    }
533
}
534

    
535
/**
536
 * Copy image 'src' to 'dst'.
537
 */
538
void img_copy(AVPicture *dst, AVPicture *src,
539
              int pix_fmt, int width, int height)
540
{
541
    int bwidth, bits, i;
542
    PixFmtInfo *pf = &pix_fmt_info[pix_fmt];
543
    
544
    pf = &pix_fmt_info[pix_fmt];
545
    switch(pf->pixel_type) {
546
    case FF_PIXEL_PACKED:
547
        switch(pix_fmt) {
548
        case PIX_FMT_YUV422:
549
        case PIX_FMT_RGB565:
550
        case PIX_FMT_RGB555:
551
            bits = 16;
552
            break;
553
        default:
554
            bits = pf->depth * pf->nb_channels;
555
            break;
556
        }
557
        bwidth = (width * bits + 7) >> 3;
558
        img_copy_plane(dst->data[0], dst->linesize[0],
559
                       src->data[0], src->linesize[0],
560
                       bwidth, height);
561
        break;
562
    case FF_PIXEL_PLANAR:
563
        for(i = 0; i < pf->nb_channels; i++) {
564
            int w, h;
565
            w = width;
566
            h = height;
567
            if (i == 1 || i == 2) {
568
                w >>= pf->x_chroma_shift;
569
                h >>= pf->y_chroma_shift;
570
            }
571
            bwidth = (w * pf->depth + 7) >> 3;
572
            img_copy_plane(dst->data[i], dst->linesize[i],
573
                           src->data[i], src->linesize[i],
574
                           bwidth, h);
575
        }
576
        break;
577
    case FF_PIXEL_PALETTE:
578
        img_copy_plane(dst->data[0], dst->linesize[0],
579
                       src->data[0], src->linesize[0],
580
                       width, height);
581
        /* copy the palette */
582
        img_copy_plane(dst->data[1], dst->linesize[1],
583
                       src->data[1], src->linesize[1],
584
                       4, 256);
585
        break;
586
    }
587
}
588

    
589
/* XXX: totally non optimized */
590

    
591
static void yuv422_to_yuv420p(AVPicture *dst, AVPicture *src,
592
                              int width, int height)
593
{
594
    const uint8_t *p, *p1;
595
    uint8_t *lum, *cr, *cb, *lum1, *cr1, *cb1;
596
    int w;
597
 
598
    p1 = src->data[0];
599
    lum1 = dst->data[0];
600
    cb1 = dst->data[1];
601
    cr1 = dst->data[2];
602

    
603
    for(;height >= 1; height -= 2) {
604
        p = p1;
605
        lum = lum1;
606
        cb = cb1;
607
        cr = cr1;
608
        for(w = width; w >= 2; w -= 2) {
609
            lum[0] = p[0];
610
            cb[0] = p[1];
611
            lum[1] = p[2];
612
            cr[0] = p[3];
613
            p += 4;
614
            lum += 2;
615
            cb++;
616
            cr++;
617
        }
618
        if (w) {
619
            lum[0] = p[0];
620
            cb[0] = p[1];
621
            cr[0] = p[3];
622
            cb++;
623
            cr++;
624
        }
625
        p1 += src->linesize[0];
626
        lum1 += dst->linesize[0];
627
        if (height>1) {
628
            p = p1;
629
            lum = lum1;
630
            for(w = width; w >= 2; w -= 2) {
631
                lum[0] = p[0];
632
                lum[1] = p[2];
633
                p += 4;
634
                lum += 2;
635
            }
636
            if (w) {
637
                lum[0] = p[0];
638
            }
639
            p1 += src->linesize[0];
640
            lum1 += dst->linesize[0];
641
        }
642
        cb1 += dst->linesize[1];
643
        cr1 += dst->linesize[2];
644
    }
645
}
646

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

    
654
    p1 = src->data[0];
655
    lum1 = dst->data[0];
656
    cb1 = dst->data[1];
657
    cr1 = dst->data[2];
658
    for(;height > 0; height--) {
659
        p = p1;
660
        lum = lum1;
661
        cb = cb1;
662
        cr = cr1;
663
        for(w = width; w >= 2; w -= 2) {
664
            lum[0] = p[0];
665
            cb[0] = p[1];
666
            lum[1] = p[2];
667
            cr[0] = p[3];
668
            p += 4;
669
            lum += 2;
670
            cb++;
671
            cr++;
672
        }
673
        p1 += src->linesize[0];
674
        lum1 += dst->linesize[0];
675
        cb1 += dst->linesize[1];
676
        cr1 += dst->linesize[2];
677
    }
678
}
679

    
680
static void yuv422p_to_yuv422(AVPicture *dst, AVPicture *src,
681
                              int width, int height)
682
{
683
    uint8_t *p, *p1;
684
    const uint8_t *lum, *cr, *cb, *lum1, *cr1, *cb1;
685
    int w;
686

    
687
    p1 = dst->data[0];
688
    lum1 = src->data[0];
689
    cb1 = src->data[1];
690
    cr1 = src->data[2];
691
    for(;height > 0; height--) {
692
        p = p1;
693
        lum = lum1;
694
        cb = cb1;
695
        cr = cr1;
696
        for(w = width; w >= 2; w -= 2) {
697
            p[0] = lum[0];
698
            p[1] = cb[0];
699
            p[2] = lum[1];
700
            p[3] = cr[0];
701
            p += 4;
702
            lum += 2;
703
            cb++;
704
            cr++;
705
        }
706
        p1 += dst->linesize[0];
707
        lum1 += src->linesize[0];
708
        cb1 += src->linesize[1];
709
        cr1 += src->linesize[2];
710
    }
711
}
712

    
713
#define SCALEBITS 10
714
#define ONE_HALF  (1 << (SCALEBITS - 1))
715
#define FIX(x)          ((int) ((x) * (1<<SCALEBITS) + 0.5))
716

    
717
#define YUV_TO_RGB1_CCIR(cb1, cr1)\
718
{\
719
    cb = (cb1) - 128;\
720
    cr = (cr1) - 128;\
721
    r_add = FIX(1.40200*255.0/224.0) * cr + ONE_HALF;\
722
    g_add = - FIX(0.34414*255.0/224.0) * cb - FIX(0.71414*255.0/224.0) * cr + \
723
            ONE_HALF;\
724
    b_add = FIX(1.77200*255.0/224.0) * cb + ONE_HALF;\
725
}
726

    
727
#define YUV_TO_RGB2_CCIR(r, g, b, y1)\
728
{\
729
    y = ((y1) - 16) * FIX(255.0/219.0);\
730
    r = cm[(y + r_add) >> SCALEBITS];\
731
    g = cm[(y + g_add) >> SCALEBITS];\
732
    b = cm[(y + b_add) >> SCALEBITS];\
733
}
734

    
735
#define YUV_TO_RGB1(cb1, cr1)\
736
{\
737
    cb = (cb1) - 128;\
738
    cr = (cr1) - 128;\
739
    r_add = FIX(1.40200) * cr + ONE_HALF;\
740
    g_add = - FIX(0.34414) * cb - FIX(0.71414) * cr + ONE_HALF;\
741
    b_add = FIX(1.77200) * cb + ONE_HALF;\
742
}
743

    
744
#define YUV_TO_RGB2(r, g, b, y1)\
745
{\
746
    y = (y1) << SCALEBITS;\
747
    r = cm[(y + r_add) >> SCALEBITS];\
748
    g = cm[(y + g_add) >> SCALEBITS];\
749
    b = cm[(y + b_add) >> SCALEBITS];\
750
}
751

    
752
#define Y_CCIR_TO_JPEG(y)\
753
 cm[((y) * FIX(255.0/219.0) + (ONE_HALF - 16 * FIX(255.0/219.0))) >> SCALEBITS]
754

    
755
#define Y_JPEG_TO_CCIR(y)\
756
 (((y) * FIX(219.0/255.0) + (ONE_HALF + (16 << SCALEBITS))) >> SCALEBITS)
757

    
758
#define C_CCIR_TO_JPEG(y)\
759
 cm[(((y) - 128) * FIX(127.0/112.0) + (ONE_HALF + (128 << SCALEBITS))) >> SCALEBITS]
760

    
761
/* NOTE: the clamp is really necessary! */
762
static inline int C_JPEG_TO_CCIR(int y) {
763
    y = (((y - 128) * FIX(112.0/127.0) + (ONE_HALF + (128 << SCALEBITS))) >> SCALEBITS);
764
    if (y < 16)
765
        y = 16;
766
    return y;
767
}
768

    
769

    
770
#define RGB_TO_Y(r, g, b) \
771
((FIX(0.29900) * (r) + FIX(0.58700) * (g) + \
772
  FIX(0.11400) * (b) + ONE_HALF) >> SCALEBITS)
773

    
774
#define RGB_TO_U(r1, g1, b1, shift)\
775
(((- FIX(0.16874) * r1 - FIX(0.33126) * g1 +         \
776
     FIX(0.50000) * b1 + (ONE_HALF << shift) - 1) >> (SCALEBITS + shift)) + 128)
777

    
778
#define RGB_TO_V(r1, g1, b1, shift)\
779
(((FIX(0.50000) * r1 - FIX(0.41869) * g1 -           \
780
   FIX(0.08131) * b1 + (ONE_HALF << shift) - 1) >> (SCALEBITS + shift)) + 128)
781

    
782
#define RGB_TO_Y_CCIR(r, g, b) \
783
((FIX(0.29900*219.0/255.0) * (r) + FIX(0.58700*219.0/255.0) * (g) + \
784
  FIX(0.11400*219.0/255.0) * (b) + (ONE_HALF + (16 << SCALEBITS))) >> SCALEBITS)
785

    
786
#define RGB_TO_U_CCIR(r1, g1, b1, shift)\
787
(((- FIX(0.16874*224.0/255.0) * r1 - FIX(0.33126*224.0/255.0) * g1 +         \
788
     FIX(0.50000*224.0/255.0) * b1 + (ONE_HALF << shift) - 1) >> (SCALEBITS + shift)) + 128)
789

    
790
#define RGB_TO_V_CCIR(r1, g1, b1, shift)\
791
(((FIX(0.50000*224.0/255.0) * r1 - FIX(0.41869*224.0/255.0) * g1 -           \
792
   FIX(0.08131*224.0/255.0) * b1 + (ONE_HALF << shift) - 1) >> (SCALEBITS + shift)) + 128)
793

    
794
static uint8_t y_ccir_to_jpeg[256];
795
static uint8_t y_jpeg_to_ccir[256];
796
static uint8_t c_ccir_to_jpeg[256];
797
static uint8_t c_jpeg_to_ccir[256];
798

    
799
/* init various conversion tables */
800
static void img_convert_init(void)
801
{
802
    int i;
803
    uint8_t *cm = cropTbl + MAX_NEG_CROP;
804

    
805
    for(i = 0;i < 256; i++) {
806
        y_ccir_to_jpeg[i] = Y_CCIR_TO_JPEG(i);
807
        y_jpeg_to_ccir[i] = Y_JPEG_TO_CCIR(i);
808
        c_ccir_to_jpeg[i] = C_CCIR_TO_JPEG(i);
809
        c_jpeg_to_ccir[i] = C_JPEG_TO_CCIR(i);
810
    }
811
}
812

    
813
/* apply to each pixel the given table */
814
static void img_apply_table(uint8_t *dst, int dst_wrap, 
815
                            const uint8_t *src, int src_wrap,
816
                            int width, int height, const uint8_t *table1)
817
{
818
    int n;
819
    const uint8_t *s;
820
    uint8_t *d;
821
    const uint8_t *table;
822

    
823
    table = table1;
824
    for(;height > 0; height--) {
825
        s = src;
826
        d = dst;
827
        n = width;
828
        while (n >= 4) {
829
            d[0] = table[s[0]];
830
            d[1] = table[s[1]];
831
            d[2] = table[s[2]];
832
            d[3] = table[s[3]];
833
            d += 4;
834
            s += 4;
835
            n -= 4;
836
        }
837
        while (n > 0) {
838
            d[0] = table[s[0]];
839
            d++;
840
            s++;
841
            n--;
842
        }
843
        dst += dst_wrap;
844
        src += src_wrap;
845
    }
846
}
847

    
848
/* XXX: use generic filter ? */
849
/* XXX: in most cases, the sampling position is incorrect */
850

    
851
/* 4x1 -> 1x1 */
852
static void shrink41(uint8_t *dst, int dst_wrap, 
853
                     const uint8_t *src, int src_wrap,
854
                     int width, int height)
855
{
856
    int w;
857
    const uint8_t *s;
858
    uint8_t *d;
859

    
860
    for(;height > 0; height--) {
861
        s = src;
862
        d = dst;
863
        for(w = width;w > 0; w--) {
864
            d[0] = (s[0] + s[1] + s[2] + s[3] + 2) >> 2;
865
            s += 4;
866
            d++;
867
        }
868
        src += src_wrap;
869
        dst += dst_wrap;
870
    }
871
}
872

    
873
/* 2x1 -> 1x1 */
874
static void shrink21(uint8_t *dst, int dst_wrap, 
875
                     const uint8_t *src, int src_wrap,
876
                     int width, int height)
877
{
878
    int w;
879
    const uint8_t *s;
880
    uint8_t *d;
881

    
882
    for(;height > 0; height--) {
883
        s = src;
884
        d = dst;
885
        for(w = width;w > 0; w--) {
886
            d[0] = (s[0] + s[1]) >> 1;
887
            s += 2;
888
            d++;
889
        }
890
        src += src_wrap;
891
        dst += dst_wrap;
892
    }
893
}
894

    
895
/* 1x2 -> 1x1 */
896
static void shrink12(uint8_t *dst, int dst_wrap, 
897
                     const uint8_t *src, int src_wrap,
898
                     int width, int height)
899
{
900
    int w;
901
    uint8_t *d;
902
    const uint8_t *s1, *s2;
903

    
904
    for(;height > 0; height--) {
905
        s1 = src;
906
        s2 = s1 + src_wrap;
907
        d = dst;
908
        for(w = width;w >= 4; w-=4) {
909
            d[0] = (s1[0] + s2[0]) >> 1;
910
            d[1] = (s1[1] + s2[1]) >> 1;
911
            d[2] = (s1[2] + s2[2]) >> 1;
912
            d[3] = (s1[3] + s2[3]) >> 1;
913
            s1 += 4;
914
            s2 += 4;
915
            d += 4;
916
        }
917
        for(;w > 0; w--) {
918
            d[0] = (s1[0] + s2[0]) >> 1;
919
            s1++;
920
            s2++;
921
            d++;
922
        }
923
        src += 2 * src_wrap;
924
        dst += dst_wrap;
925
    }
926
}
927

    
928
/* 2x2 -> 1x1 */
929
static void shrink22(uint8_t *dst, int dst_wrap, 
930
                     const uint8_t *src, int src_wrap,
931
                     int width, int height)
932
{
933
    int w;
934
    const uint8_t *s1, *s2;
935
    uint8_t *d;
936

    
937
    for(;height > 0; height--) {
938
        s1 = src;
939
        s2 = s1 + src_wrap;
940
        d = dst;
941
        for(w = width;w >= 4; w-=4) {
942
            d[0] = (s1[0] + s1[1] + s2[0] + s2[1] + 2) >> 2;
943
            d[1] = (s1[2] + s1[3] + s2[2] + s2[3] + 2) >> 2;
944
            d[2] = (s1[4] + s1[5] + s2[4] + s2[5] + 2) >> 2;
945
            d[3] = (s1[6] + s1[7] + s2[6] + s2[7] + 2) >> 2;
946
            s1 += 8;
947
            s2 += 8;
948
            d += 4;
949
        }
950
        for(;w > 0; w--) {
951
            d[0] = (s1[0] + s1[1] + s2[0] + s2[1] + 2) >> 2;
952
            s1 += 2;
953
            s2 += 2;
954
            d++;
955
        }
956
        src += 2 * src_wrap;
957
        dst += dst_wrap;
958
    }
959
}
960

    
961
/* 4x4 -> 1x1 */
962
static void shrink44(uint8_t *dst, int dst_wrap, 
963
                     const uint8_t *src, int src_wrap,
964
                     int width, int height)
965
{
966
    int w;
967
    const uint8_t *s1, *s2, *s3, *s4;
968
    uint8_t *d;
969

    
970
    for(;height > 0; height--) {
971
        s1 = src;
972
        s2 = s1 + src_wrap;
973
        s3 = s2 + src_wrap;
974
        s4 = s3 + src_wrap;
975
        d = dst;
976
        for(w = width;w > 0; w--) {
977
            d[0] = (s1[0] + s1[1] + s1[2] + s1[3] +
978
                    s2[0] + s2[1] + s2[2] + s2[3] +
979
                    s3[0] + s3[1] + s3[2] + s3[3] +
980
                    s4[0] + s4[1] + s4[2] + s4[3] + 8) >> 4;
981
            s1 += 4;
982
            s2 += 4;
983
            s3 += 4;
984
            s4 += 4;
985
            d++;
986
        }
987
        src += 4 * src_wrap;
988
        dst += dst_wrap;
989
    }
990
}
991

    
992
static void grow21_line(uint8_t *dst, const uint8_t *src,
993
                        int width)
994
{
995
    int w;
996
    const uint8_t *s1;
997
    uint8_t *d;
998

    
999
    s1 = src;
1000
    d = dst;
1001
    for(w = width;w >= 4; w-=4) {
1002
        d[1] = d[0] = s1[0];
1003
        d[3] = d[2] = s1[1];
1004
        s1 += 2;
1005
        d += 4;
1006
    }
1007
    for(;w >= 2; w -= 2) {
1008
        d[1] = d[0] = s1[0];
1009
        s1 ++;
1010
        d += 2;
1011
    }
1012
    /* only needed if width is not a multiple of two */
1013
    /* XXX: veryfy that */
1014
    if (w) {
1015
        d[0] = s1[0];
1016
    }
1017
}
1018

    
1019
static void grow41_line(uint8_t *dst, const uint8_t *src,
1020
                        int width)
1021
{
1022
    int w, v;
1023
    const uint8_t *s1;
1024
    uint8_t *d;
1025

    
1026
    s1 = src;
1027
    d = dst;
1028
    for(w = width;w >= 4; w-=4) {
1029
        v = s1[0];
1030
        d[0] = v;
1031
        d[1] = v;
1032
        d[2] = v;
1033
        d[3] = v;
1034
        s1 ++;
1035
        d += 4;
1036
    }
1037
}
1038

    
1039
/* 1x1 -> 2x1 */
1040
static void grow21(uint8_t *dst, int dst_wrap,
1041
                   const uint8_t *src, int src_wrap,
1042
                   int width, int height)
1043
{
1044
    for(;height > 0; height--) {
1045
        grow21_line(dst, src, width);
1046
        src += src_wrap;
1047
        dst += dst_wrap;
1048
    }
1049
}
1050

    
1051
/* 1x1 -> 2x2 */
1052
static void grow22(uint8_t *dst, int dst_wrap,
1053
                   const uint8_t *src, int src_wrap,
1054
                   int width, int height)
1055
{
1056
    for(;height > 0; height--) {
1057
        grow21_line(dst, src, width);
1058
        if (height%2)
1059
            src += src_wrap;
1060
        dst += dst_wrap;
1061
    }
1062
}
1063

    
1064
/* 1x1 -> 4x1 */
1065
static void grow41(uint8_t *dst, int dst_wrap,
1066
                   const uint8_t *src, int src_wrap,
1067
                   int width, int height)
1068
{
1069
    for(;height > 0; height--) {
1070
        grow41_line(dst, src, width);
1071
        src += src_wrap;
1072
        dst += dst_wrap;
1073
    }
1074
}
1075

    
1076
/* 1x1 -> 4x4 */
1077
static void grow44(uint8_t *dst, int dst_wrap,
1078
                   const uint8_t *src, int src_wrap,
1079
                   int width, int height)
1080
{
1081
    for(;height > 0; height--) {
1082
        grow41_line(dst, src, width);
1083
        if ((height & 3) == 1)
1084
            src += src_wrap;
1085
        dst += dst_wrap;
1086
    }
1087
}
1088

    
1089
/* 1x2 -> 2x1 */
1090
static void conv411(uint8_t *dst, int dst_wrap, 
1091
                    const uint8_t *src, int src_wrap,
1092
                    int width, int height)
1093
{
1094
    int w, c;
1095
    const uint8_t *s1, *s2;
1096
    uint8_t *d;
1097

    
1098
    width>>=1;
1099

    
1100
    for(;height > 0; height--) {
1101
        s1 = src;
1102
        s2 = src + src_wrap;
1103
        d = dst;
1104
        for(w = width;w > 0; w--) {
1105
            c = (s1[0] + s2[0]) >> 1;
1106
            d[0] = c;
1107
            d[1] = c;
1108
            s1++;
1109
            s2++;
1110
            d += 2;
1111
        }
1112
        src += src_wrap * 2;
1113
        dst += dst_wrap;
1114
    }
1115
}
1116

    
1117
/* XXX: add jpeg quantize code */
1118

    
1119
#define TRANSP_INDEX (6*6*6)
1120

    
1121
/* this is maybe slow, but allows for extensions */
1122
static inline unsigned char gif_clut_index(uint8_t r, uint8_t g, uint8_t b)
1123
{
1124
    return ((((r)/47)%6)*6*6+(((g)/47)%6)*6+(((b)/47)%6));
1125
}
1126

    
1127
static void build_rgb_palette(uint8_t *palette, int has_alpha)
1128
{
1129
    uint32_t *pal;
1130
    static const uint8_t pal_value[6] = { 0x00, 0x33, 0x66, 0x99, 0xcc, 0xff };
1131
    int i, r, g, b;
1132

    
1133
    pal = (uint32_t *)palette;
1134
    i = 0;
1135
    for(r = 0; r < 6; r++) {
1136
        for(g = 0; g < 6; g++) {
1137
            for(b = 0; b < 6; b++) {
1138
                pal[i++] = (0xff << 24) | (pal_value[r] << 16) | 
1139
                    (pal_value[g] << 8) | pal_value[b];
1140
            }
1141
        }
1142
    }
1143
    if (has_alpha)
1144
        pal[i++] = 0;
1145
    while (i < 256)
1146
        pal[i++] = 0xff000000;
1147
}
1148

    
1149
/* copy bit n to bits 0 ... n - 1 */
1150
static inline unsigned int bitcopy_n(unsigned int a, int n)
1151
{
1152
    int mask;
1153
    mask = (1 << n) - 1;
1154
    return (a & (0xff & ~mask)) | ((-((a >> n) & 1)) & mask);
1155
}
1156

    
1157
/* rgb555 handling */
1158

    
1159
#define RGB_NAME rgb555
1160

    
1161
#define RGB_IN(r, g, b, s)\
1162
{\
1163
    unsigned int v = ((const uint16_t *)(s))[0];\
1164
    r = bitcopy_n(v >> (10 - 3), 3);\
1165
    g = bitcopy_n(v >> (5 - 3), 3);\
1166
    b = bitcopy_n(v << 3, 3);\
1167
}
1168

    
1169
#define RGBA_IN(r, g, b, a, s)\
1170
{\
1171
    unsigned int v = ((const uint16_t *)(s))[0];\
1172
    r = bitcopy_n(v >> (10 - 3), 3);\
1173
    g = bitcopy_n(v >> (5 - 3), 3);\
1174
    b = bitcopy_n(v << 3, 3);\
1175
    a = (-(v >> 15)) & 0xff;\
1176
}
1177

    
1178
#define RGBA_OUT(d, r, g, b, a)\
1179
{\
1180
    ((uint16_t *)(d))[0] = ((r >> 3) << 10) | ((g >> 3) << 5) | (b >> 3) | \
1181
                           ((a << 8) & 0x8000);\
1182
}
1183

    
1184
#define BPP 2
1185

    
1186
#include "imgconvert_template.h"
1187

    
1188
/* rgb565 handling */
1189

    
1190
#define RGB_NAME rgb565
1191

    
1192
#define RGB_IN(r, g, b, s)\
1193
{\
1194
    unsigned int v = ((const uint16_t *)(s))[0];\
1195
    r = bitcopy_n(v >> (11 - 3), 3);\
1196
    g = bitcopy_n(v >> (5 - 2), 2);\
1197
    b = bitcopy_n(v << 3, 3);\
1198
}
1199

    
1200
#define RGB_OUT(d, r, g, b)\
1201
{\
1202
    ((uint16_t *)(d))[0] = ((r >> 3) << 11) | ((g >> 2) << 5) | (b >> 3);\
1203
}
1204

    
1205
#define BPP 2
1206

    
1207
#include "imgconvert_template.h"
1208

    
1209
/* bgr24 handling */
1210

    
1211
#define RGB_NAME bgr24
1212

    
1213
#define RGB_IN(r, g, b, s)\
1214
{\
1215
    b = (s)[0];\
1216
    g = (s)[1];\
1217
    r = (s)[2];\
1218
}
1219

    
1220
#define RGB_OUT(d, r, g, b)\
1221
{\
1222
    (d)[0] = b;\
1223
    (d)[1] = g;\
1224
    (d)[2] = r;\
1225
}
1226

    
1227
#define BPP 3
1228

    
1229
#include "imgconvert_template.h"
1230

    
1231
#undef RGB_IN
1232
#undef RGB_OUT
1233
#undef BPP
1234

    
1235
/* rgb24 handling */
1236

    
1237
#define RGB_NAME rgb24
1238
#define FMT_RGB24
1239

    
1240
#define RGB_IN(r, g, b, s)\
1241
{\
1242
    r = (s)[0];\
1243
    g = (s)[1];\
1244
    b = (s)[2];\
1245
}
1246

    
1247
#define RGB_OUT(d, r, g, b)\
1248
{\
1249
    (d)[0] = r;\
1250
    (d)[1] = g;\
1251
    (d)[2] = b;\
1252
}
1253

    
1254
#define BPP 3
1255

    
1256
#include "imgconvert_template.h"
1257

    
1258
/* rgba32 handling */
1259

    
1260
#define RGB_NAME rgba32
1261
#define FMT_RGBA32
1262

    
1263
#define RGB_IN(r, g, b, s)\
1264
{\
1265
    unsigned int v = ((const uint32_t *)(s))[0];\
1266
    r = (v >> 16) & 0xff;\
1267
    g = (v >> 8) & 0xff;\
1268
    b = v & 0xff;\
1269
}
1270

    
1271
#define RGBA_IN(r, g, b, a, s)\
1272
{\
1273
    unsigned int v = ((const uint32_t *)(s))[0];\
1274
    a = (v >> 24) & 0xff;\
1275
    r = (v >> 16) & 0xff;\
1276
    g = (v >> 8) & 0xff;\
1277
    b = v & 0xff;\
1278
}
1279

    
1280
#define RGBA_OUT(d, r, g, b, a)\
1281
{\
1282
    ((uint32_t *)(d))[0] = (a << 24) | (r << 16) | (g << 8) | b;\
1283
}
1284

    
1285
#define BPP 4
1286

    
1287
#include "imgconvert_template.h"
1288

    
1289
static void mono_to_gray(AVPicture *dst, AVPicture *src,
1290
                         int width, int height, int xor_mask)
1291
{
1292
    const unsigned char *p;
1293
    unsigned char *q;
1294
    int v, dst_wrap, src_wrap;
1295
    int y, w;
1296

    
1297
    p = src->data[0];
1298
    src_wrap = src->linesize[0] - ((width + 7) >> 3);
1299

    
1300
    q = dst->data[0];
1301
    dst_wrap = dst->linesize[0] - width;
1302
    for(y=0;y<height;y++) {
1303
        w = width; 
1304
        while (w >= 8) {
1305
            v = *p++ ^ xor_mask;
1306
            q[0] = -(v >> 7);
1307
            q[1] = -((v >> 6) & 1);
1308
            q[2] = -((v >> 5) & 1);
1309
            q[3] = -((v >> 4) & 1);
1310
            q[4] = -((v >> 3) & 1);
1311
            q[5] = -((v >> 2) & 1);
1312
            q[6] = -((v >> 1) & 1);
1313
            q[7] = -((v >> 0) & 1);
1314
            w -= 8;
1315
            q += 8;
1316
        }
1317
        if (w > 0) {
1318
            v = *p++ ^ xor_mask;
1319
            do {
1320
                q[0] = -((v >> 7) & 1);
1321
                q++;
1322
                v <<= 1;
1323
            } while (--w);
1324
        }
1325
        p += src_wrap;
1326
        q += dst_wrap;
1327
    }
1328
}
1329

    
1330
static void monowhite_to_gray(AVPicture *dst, AVPicture *src,
1331
                               int width, int height)
1332
{
1333
    mono_to_gray(dst, src, width, height, 0xff);
1334
}
1335

    
1336
static void monoblack_to_gray(AVPicture *dst, AVPicture *src,
1337
                               int width, int height)
1338
{
1339
    mono_to_gray(dst, src, width, height, 0x00);
1340
}
1341

    
1342
static void gray_to_mono(AVPicture *dst, AVPicture *src,
1343
                         int width, int height, int xor_mask)
1344
{
1345
    int n;
1346
    const uint8_t *s;
1347
    uint8_t *d;
1348
    int j, b, v, n1, src_wrap, dst_wrap, y;
1349

    
1350
    s = src->data[0];
1351
    src_wrap = src->linesize[0] - width;
1352

    
1353
    d = dst->data[0];
1354
    dst_wrap = dst->linesize[0] - ((width + 7) >> 3);
1355

    
1356
    for(y=0;y<height;y++) {
1357
        n = width;
1358
        while (n >= 8) {
1359
            v = 0;
1360
            for(j=0;j<8;j++) {
1361
                b = s[0];
1362
                s++;
1363
                v = (v << 1) | (b >> 7);
1364
            }
1365
            d[0] = v ^ xor_mask;
1366
            d++;
1367
            n -= 8;
1368
        }
1369
        if (n > 0) {
1370
            n1 = n;
1371
            v = 0;
1372
            while (n > 0) {
1373
                b = s[0];
1374
                s++;
1375
                v = (v << 1) | (b >> 7);
1376
                n--;
1377
            }
1378
            d[0] = (v << (8 - (n1 & 7))) ^ xor_mask;
1379
            d++;
1380
        }
1381
        s += src_wrap;
1382
        d += dst_wrap;
1383
    }
1384
}
1385

    
1386
static void gray_to_monowhite(AVPicture *dst, AVPicture *src,
1387
                              int width, int height)
1388
{
1389
    gray_to_mono(dst, src, width, height, 0xff);
1390
}
1391

    
1392
static void gray_to_monoblack(AVPicture *dst, AVPicture *src,
1393
                              int width, int height)
1394
{
1395
    gray_to_mono(dst, src, width, height, 0x00);
1396
}
1397

    
1398
typedef struct ConvertEntry {
1399
    void (*convert)(AVPicture *dst, AVPicture *src, int width, int height);
1400
} ConvertEntry;
1401

    
1402
/* Add each new convertion function in this table. In order to be able
1403
   to convert from any format to any format, the following constraints
1404
   must be satisfied:
1405

1406
   - all FF_COLOR_RGB formats must convert to and from PIX_FMT_RGB24 
1407

1408
   - all FF_COLOR_GRAY formats must convert to and from PIX_FMT_GRAY8
1409

1410
   - all FF_COLOR_RGB formats with alpha must convert to and from PIX_FMT_RGBA32
1411

1412
   - PIX_FMT_YUV444P and PIX_FMT_YUVJ444P must convert to and from
1413
     PIX_FMT_RGB24.
1414

1415
   - PIX_FMT_422 must convert to and from PIX_FMT_422P.
1416

1417
   The other conversion functions are just optimisations for common cases.
1418
*/
1419
static ConvertEntry convert_table[PIX_FMT_NB][PIX_FMT_NB] = {
1420
    [PIX_FMT_YUV420P] = {
1421
        [PIX_FMT_RGB555] = { 
1422
            .convert = yuv420p_to_rgb555
1423
        },
1424
        [PIX_FMT_RGB565] = { 
1425
            .convert = yuv420p_to_rgb565
1426
        },
1427
        [PIX_FMT_BGR24] = { 
1428
            .convert = yuv420p_to_bgr24
1429
        },
1430
        [PIX_FMT_RGB24] = { 
1431
            .convert = yuv420p_to_rgb24
1432
        },
1433
        [PIX_FMT_RGBA32] = { 
1434
            .convert = yuv420p_to_rgba32
1435
        },
1436
    },
1437
    [PIX_FMT_YUV422P] = { 
1438
        [PIX_FMT_YUV422] = { 
1439
            .convert = yuv422p_to_yuv422,
1440
        },
1441
    },
1442
    [PIX_FMT_YUV444P] = { 
1443
        [PIX_FMT_RGB24] = { 
1444
            .convert = yuv444p_to_rgb24
1445
        },
1446
    },
1447
    [PIX_FMT_YUVJ420P] = {
1448
        [PIX_FMT_RGB555] = { 
1449
            .convert = yuvj420p_to_rgb555
1450
        },
1451
        [PIX_FMT_RGB565] = { 
1452
            .convert = yuvj420p_to_rgb565
1453
        },
1454
        [PIX_FMT_BGR24] = { 
1455
            .convert = yuvj420p_to_bgr24
1456
        },
1457
        [PIX_FMT_RGB24] = { 
1458
            .convert = yuvj420p_to_rgb24
1459
        },
1460
        [PIX_FMT_RGBA32] = { 
1461
            .convert = yuvj420p_to_rgba32
1462
        },
1463
    },
1464
    [PIX_FMT_YUVJ444P] = { 
1465
        [PIX_FMT_RGB24] = { 
1466
            .convert = yuvj444p_to_rgb24
1467
        },
1468
    },
1469
    [PIX_FMT_YUV422] = { 
1470
        [PIX_FMT_YUV420P] = { 
1471
            .convert = yuv422_to_yuv420p,
1472
        },
1473
        [PIX_FMT_YUV422P] = { 
1474
            .convert = yuv422_to_yuv422p,
1475
        },
1476
    },
1477

    
1478
    [PIX_FMT_RGB24] = {
1479
        [PIX_FMT_YUV420P] = { 
1480
            .convert = rgb24_to_yuv420p
1481
        },
1482
        [PIX_FMT_RGB565] = { 
1483
            .convert = rgb24_to_rgb565
1484
        },
1485
        [PIX_FMT_RGB555] = { 
1486
            .convert = rgb24_to_rgb555
1487
        },
1488
        [PIX_FMT_RGBA32] = { 
1489
            .convert = rgb24_to_rgba32
1490
        },
1491
        [PIX_FMT_BGR24] = { 
1492
            .convert = rgb24_to_bgr24
1493
        },
1494
        [PIX_FMT_GRAY8] = { 
1495
            .convert = rgb24_to_gray
1496
        },
1497
        [PIX_FMT_PAL8] = {
1498
            .convert = rgb24_to_pal8
1499
        },
1500
        [PIX_FMT_YUV444P] = { 
1501
            .convert = rgb24_to_yuv444p
1502
        },
1503
        [PIX_FMT_YUVJ420P] = { 
1504
            .convert = rgb24_to_yuvj420p
1505
        },
1506
        [PIX_FMT_YUVJ444P] = { 
1507
            .convert = rgb24_to_yuvj444p
1508
        },
1509
    },
1510
    [PIX_FMT_RGBA32] = {
1511
        [PIX_FMT_RGB24] = { 
1512
            .convert = rgba32_to_rgb24
1513
        },
1514
        [PIX_FMT_RGB555] = { 
1515
            .convert = rgba32_to_rgb555
1516
        },
1517
        [PIX_FMT_PAL8] = { 
1518
            .convert = rgba32_to_pal8
1519
        },
1520
        [PIX_FMT_YUV420P] = { 
1521
            .convert = rgba32_to_yuv420p
1522
        },
1523
        [PIX_FMT_GRAY8] = { 
1524
            .convert = rgba32_to_gray
1525
        },
1526
    },
1527
    [PIX_FMT_BGR24] = {
1528
        [PIX_FMT_RGB24] = { 
1529
            .convert = bgr24_to_rgb24
1530
        },
1531
        [PIX_FMT_YUV420P] = { 
1532
            .convert = bgr24_to_yuv420p
1533
        },
1534
        [PIX_FMT_GRAY8] = { 
1535
            .convert = bgr24_to_gray
1536
        },
1537
    },
1538
    [PIX_FMT_RGB555] = {
1539
        [PIX_FMT_RGB24] = { 
1540
            .convert = rgb555_to_rgb24
1541
        },
1542
        [PIX_FMT_RGBA32] = { 
1543
            .convert = rgb555_to_rgba32
1544
        },
1545
        [PIX_FMT_YUV420P] = { 
1546
            .convert = rgb555_to_yuv420p
1547
        },
1548
        [PIX_FMT_GRAY8] = { 
1549
            .convert = rgb555_to_gray
1550
        },
1551
    },
1552
    [PIX_FMT_RGB565] = {
1553
        [PIX_FMT_RGB24] = { 
1554
            .convert = rgb565_to_rgb24
1555
        },
1556
        [PIX_FMT_YUV420P] = { 
1557
            .convert = rgb565_to_yuv420p
1558
        },
1559
        [PIX_FMT_GRAY8] = { 
1560
            .convert = rgb565_to_gray
1561
        },
1562
    },
1563
    [PIX_FMT_GRAY8] = {
1564
        [PIX_FMT_RGB555] = { 
1565
            .convert = gray_to_rgb555
1566
        },
1567
        [PIX_FMT_RGB565] = { 
1568
            .convert = gray_to_rgb565
1569
        },
1570
        [PIX_FMT_RGB24] = { 
1571
            .convert = gray_to_rgb24
1572
        },
1573
        [PIX_FMT_BGR24] = { 
1574
            .convert = gray_to_bgr24
1575
        },
1576
        [PIX_FMT_RGBA32] = { 
1577
            .convert = gray_to_rgba32
1578
        },
1579
        [PIX_FMT_MONOWHITE] = { 
1580
            .convert = gray_to_monowhite
1581
        },
1582
        [PIX_FMT_MONOBLACK] = { 
1583
            .convert = gray_to_monoblack
1584
        },
1585
    },
1586
    [PIX_FMT_MONOWHITE] = {
1587
        [PIX_FMT_GRAY8] = { 
1588
            .convert = monowhite_to_gray
1589
        },
1590
    },
1591
    [PIX_FMT_MONOBLACK] = {
1592
        [PIX_FMT_GRAY8] = { 
1593
            .convert = monoblack_to_gray
1594
        },
1595
    },
1596
    [PIX_FMT_PAL8] = {
1597
        [PIX_FMT_RGB555] = { 
1598
            .convert = pal8_to_rgb555
1599
        },
1600
        [PIX_FMT_RGB565] = { 
1601
            .convert = pal8_to_rgb565
1602
        },
1603
        [PIX_FMT_BGR24] = { 
1604
            .convert = pal8_to_bgr24
1605
        },
1606
        [PIX_FMT_RGB24] = { 
1607
            .convert = pal8_to_rgb24
1608
        },
1609
        [PIX_FMT_RGBA32] = { 
1610
            .convert = pal8_to_rgba32
1611
        },
1612
    },
1613
};
1614

    
1615
static int avpicture_alloc(AVPicture *picture,
1616
                           int pix_fmt, int width, int height)
1617
{
1618
    unsigned int size;
1619
    void *ptr;
1620

    
1621
    size = avpicture_get_size(pix_fmt, width, height);
1622
    ptr = av_malloc(size);
1623
    if (!ptr)
1624
        goto fail;
1625
    avpicture_fill(picture, ptr, pix_fmt, width, height);
1626
    return 0;
1627
 fail:
1628
    memset(picture, 0, sizeof(AVPicture));
1629
    return -1;
1630
}
1631

    
1632
static void avpicture_free(AVPicture *picture)
1633
{
1634
    av_free(picture->data[0]);
1635
}
1636

    
1637
/* return true if yuv planar */
1638
static inline int is_yuv_planar(PixFmtInfo *ps)
1639
{
1640
    return (ps->color_type == FF_COLOR_YUV ||
1641
            ps->color_type == FF_COLOR_YUV_JPEG) && 
1642
        ps->pixel_type == FF_PIXEL_PLANAR;
1643
}
1644

    
1645
/* XXX: always use linesize. Return -1 if not supported */
1646
int img_convert(AVPicture *dst, int dst_pix_fmt,
1647
                AVPicture *src, int src_pix_fmt, 
1648
                int src_width, int src_height)
1649
{
1650
    static int inited;
1651
    int i, ret, dst_width, dst_height, int_pix_fmt;
1652
    PixFmtInfo *src_pix, *dst_pix;
1653
    ConvertEntry *ce;
1654
    AVPicture tmp1, *tmp = &tmp1;
1655

    
1656
    if (src_pix_fmt < 0 || src_pix_fmt >= PIX_FMT_NB ||
1657
        dst_pix_fmt < 0 || dst_pix_fmt >= PIX_FMT_NB)
1658
        return -1;
1659
    if (src_width <= 0 || src_height <= 0)
1660
        return 0;
1661

    
1662
    if (!inited) {
1663
        inited = 1;
1664
        img_convert_init();
1665
    }
1666

    
1667
    dst_width = src_width;
1668
    dst_height = src_height;
1669

    
1670
    dst_pix = &pix_fmt_info[dst_pix_fmt];
1671
    src_pix = &pix_fmt_info[src_pix_fmt];
1672
    if (src_pix_fmt == dst_pix_fmt) {
1673
        /* no conversion needed: just copy */
1674
        img_copy(dst, src, dst_pix_fmt, dst_width, dst_height);
1675
        return 0;
1676
    }
1677

    
1678
    ce = &convert_table[src_pix_fmt][dst_pix_fmt];
1679
    if (ce->convert) {
1680
        /* specific convertion routine */
1681
        ce->convert(dst, src, dst_width, dst_height);
1682
        return 0;
1683
    }
1684

    
1685
    /* gray to YUV */
1686
    if (is_yuv_planar(dst_pix) &&
1687
        src_pix_fmt == PIX_FMT_GRAY8) {
1688
        int w, h, y;
1689
        uint8_t *d;
1690

    
1691
        if (dst_pix->color_type == FF_COLOR_YUV_JPEG) {
1692
            img_copy_plane(dst->data[0], dst->linesize[0],
1693
                     src->data[0], src->linesize[0],
1694
                     dst_width, dst_height);
1695
        } else {
1696
            img_apply_table(dst->data[0], dst->linesize[0],
1697
                            src->data[0], src->linesize[0],
1698
                            dst_width, dst_height,
1699
                            y_jpeg_to_ccir);
1700
        }
1701
        /* fill U and V with 128 */
1702
        w = dst_width;
1703
        h = dst_height;
1704
        w >>= dst_pix->x_chroma_shift;
1705
        h >>= dst_pix->y_chroma_shift;
1706
        for(i = 1; i <= 2; i++) {
1707
            d = dst->data[i];
1708
            for(y = 0; y< h; y++) {
1709
                memset(d, 128, w);
1710
                d += dst->linesize[i];
1711
            }
1712
        }
1713
        return 0;
1714
    }
1715

    
1716
    /* YUV to gray */
1717
    if (is_yuv_planar(src_pix) && 
1718
        dst_pix_fmt == PIX_FMT_GRAY8) {
1719
        if (src_pix->color_type == FF_COLOR_YUV_JPEG) {
1720
            img_copy_plane(dst->data[0], dst->linesize[0],
1721
                     src->data[0], src->linesize[0],
1722
                     dst_width, dst_height);
1723
        } else {
1724
            img_apply_table(dst->data[0], dst->linesize[0],
1725
                            src->data[0], src->linesize[0],
1726
                            dst_width, dst_height,
1727
                            y_ccir_to_jpeg);
1728
        }
1729
        return 0;
1730
    }
1731

    
1732
    /* YUV to YUV planar */
1733
    if (is_yuv_planar(dst_pix) && is_yuv_planar(src_pix)) {
1734
        int x_shift, y_shift, w, h, xy_shift;
1735
        void (*resize_func)(uint8_t *dst, int dst_wrap, 
1736
                            const uint8_t *src, int src_wrap,
1737
                            int width, int height);
1738

    
1739
        /* compute chroma size of the smallest dimensions */
1740
        w = dst_width;
1741
        h = dst_height;
1742
        if (dst_pix->x_chroma_shift >= src_pix->x_chroma_shift)
1743
            w >>= dst_pix->x_chroma_shift;
1744
        else
1745
            w >>= src_pix->x_chroma_shift;
1746
        if (dst_pix->y_chroma_shift >= src_pix->y_chroma_shift)
1747
            h >>= dst_pix->y_chroma_shift;
1748
        else
1749
            h >>= src_pix->y_chroma_shift;
1750

    
1751
        x_shift = (dst_pix->x_chroma_shift - src_pix->x_chroma_shift);
1752
        y_shift = (dst_pix->y_chroma_shift - src_pix->y_chroma_shift);
1753
        xy_shift = ((x_shift & 0xf) << 4) | (y_shift & 0xf);
1754
        /* there must be filters for conversion at least from and to
1755
           YUV444 format */
1756
        switch(xy_shift) {
1757
        case 0x00:
1758
            resize_func = img_copy_plane;
1759
            break;
1760
        case 0x10:
1761
            resize_func = shrink21;
1762
            break;
1763
        case 0x20:
1764
            resize_func = shrink41;
1765
            break;
1766
        case 0x01:
1767
            resize_func = shrink12;
1768
            break;
1769
        case 0x11:
1770
            resize_func = shrink22;
1771
            break;
1772
        case 0x22:
1773
            resize_func = shrink44;
1774
            break;
1775
        case 0xf0:
1776
            resize_func = grow21;
1777
            break;
1778
        case 0xe0:
1779
            resize_func = grow41;
1780
            break;
1781
        case 0xff:
1782
            resize_func = grow22;
1783
            break;
1784
        case 0xee:
1785
            resize_func = grow44;
1786
            break;
1787
        case 0xf1:
1788
            resize_func = conv411;
1789
            break;
1790
        default:
1791
            /* currently not handled */
1792
            goto no_chroma_filter;
1793
        }
1794

    
1795
        img_copy_plane(dst->data[0], dst->linesize[0],
1796
                       src->data[0], src->linesize[0],
1797
                       dst_width, dst_height);
1798

    
1799
        for(i = 1;i <= 2; i++)
1800
            resize_func(dst->data[i], dst->linesize[i],
1801
                        src->data[i], src->linesize[i],
1802
                        dst_width>>dst_pix->x_chroma_shift, dst_height>>dst_pix->y_chroma_shift);
1803
        /* if yuv color space conversion is needed, we do it here on
1804
           the destination image */
1805
        if (dst_pix->color_type != src_pix->color_type) {
1806
            const uint8_t *y_table, *c_table;
1807
            if (dst_pix->color_type == FF_COLOR_YUV) {
1808
                y_table = y_jpeg_to_ccir;
1809
                c_table = c_jpeg_to_ccir;
1810
            } else {
1811
                y_table = y_ccir_to_jpeg;
1812
                c_table = c_ccir_to_jpeg;
1813
            }
1814
            img_apply_table(dst->data[0], dst->linesize[0],
1815
                            dst->data[0], dst->linesize[0],
1816
                            dst_width, dst_height,
1817
                            y_table);
1818

    
1819
            for(i = 1;i <= 2; i++)
1820
                img_apply_table(dst->data[i], dst->linesize[i],
1821
                                dst->data[i], dst->linesize[i],
1822
                                dst_width>>dst_pix->x_chroma_shift, 
1823
                                dst_height>>dst_pix->y_chroma_shift,
1824
                                c_table);
1825
        }
1826
        return 0;
1827
    }
1828
 no_chroma_filter:
1829

    
1830
    /* try to use an intermediate format */
1831
    if (src_pix_fmt == PIX_FMT_YUV422 ||
1832
        dst_pix_fmt == PIX_FMT_YUV422) {
1833
        /* specific case: convert to YUV422P first */
1834
        int_pix_fmt = PIX_FMT_YUV422P;
1835
    } else if ((src_pix->color_type == FF_COLOR_GRAY &&
1836
                src_pix_fmt != PIX_FMT_GRAY8) || 
1837
               (dst_pix->color_type == FF_COLOR_GRAY &&
1838
                dst_pix_fmt != PIX_FMT_GRAY8)) {
1839
        /* gray8 is the normalized format */
1840
        int_pix_fmt = PIX_FMT_GRAY8;
1841
    } else if ((is_yuv_planar(src_pix) && 
1842
                src_pix_fmt != PIX_FMT_YUV444P &&
1843
                src_pix_fmt != PIX_FMT_YUVJ444P)) {
1844
        /* yuv444 is the normalized format */
1845
        if (src_pix->color_type == FF_COLOR_YUV_JPEG)
1846
            int_pix_fmt = PIX_FMT_YUVJ444P;
1847
        else
1848
            int_pix_fmt = PIX_FMT_YUV444P;
1849
    } else if ((is_yuv_planar(dst_pix) && 
1850
                dst_pix_fmt != PIX_FMT_YUV444P &&
1851
                dst_pix_fmt != PIX_FMT_YUVJ444P)) {
1852
        /* yuv444 is the normalized format */
1853
        if (dst_pix->color_type == FF_COLOR_YUV_JPEG)
1854
            int_pix_fmt = PIX_FMT_YUVJ444P;
1855
        else
1856
            int_pix_fmt = PIX_FMT_YUV444P;
1857
    } else {
1858
        /* the two formats are rgb or gray8 or yuv[j]444p */
1859
        if (src_pix->is_alpha && dst_pix->is_alpha)
1860
            int_pix_fmt = PIX_FMT_RGBA32;
1861
        else
1862
            int_pix_fmt = PIX_FMT_RGB24;
1863
    }
1864
    if (avpicture_alloc(tmp, int_pix_fmt, dst_width, dst_height) < 0)
1865
        return -1;
1866
    ret = -1;
1867
    if (img_convert(tmp, int_pix_fmt,
1868
                    src, src_pix_fmt, src_width, src_height) < 0)
1869
        goto fail1;
1870
    if (img_convert(dst, dst_pix_fmt,
1871
                    tmp, int_pix_fmt, dst_width, dst_height) < 0)
1872
        goto fail1;
1873
    ret = 0;
1874
 fail1:
1875
    avpicture_free(tmp);
1876
    return ret;
1877
}
1878

    
1879
/* NOTE: we scan all the pixels to have an exact information */
1880
static int get_alpha_info_pal8(AVPicture *src, int width, int height)
1881
{
1882
    const unsigned char *p;
1883
    int src_wrap, ret, x, y;
1884
    unsigned int a;
1885
    uint32_t *palette = (uint32_t *)src->data[1];
1886
    
1887
    p = src->data[0];
1888
    src_wrap = src->linesize[0] - width;
1889
    ret = 0;
1890
    for(y=0;y<height;y++) {
1891
        for(x=0;x<width;x++) {
1892
            a = palette[p[0]] >> 24;
1893
            if (a == 0x00) {
1894
                ret |= FF_ALPHA_TRANSP;
1895
            } else if (a != 0xff) {
1896
                ret |= FF_ALPHA_SEMI_TRANSP;
1897
            }
1898
            p++;
1899
        }
1900
        p += src_wrap;
1901
    }
1902
    return ret;
1903
}
1904

    
1905
/**
1906
 * Tell if an image really has transparent alpha values.
1907
 * @return ored mask of FF_ALPHA_xxx constants
1908
 */
1909
int img_get_alpha_info(AVPicture *src, int pix_fmt, int width, int height)
1910
{
1911
    PixFmtInfo *pf = &pix_fmt_info[pix_fmt];
1912
    int ret;
1913

    
1914
    pf = &pix_fmt_info[pix_fmt];
1915
    /* no alpha can be represented in format */
1916
    if (!pf->is_alpha)
1917
        return 0;
1918
    switch(pix_fmt) {
1919
    case PIX_FMT_RGBA32:
1920
        ret = get_alpha_info_rgba32(src, width, height);
1921
        break;
1922
    case PIX_FMT_RGB555:
1923
        ret = get_alpha_info_rgb555(src, width, height);
1924
        break;
1925
    case PIX_FMT_PAL8:
1926
        ret = get_alpha_info_pal8(src, width, height);
1927
        break;
1928
    default:
1929
        /* we do not know, so everything is indicated */
1930
        ret = FF_ALPHA_TRANSP | FF_ALPHA_SEMI_TRANSP;
1931
        break;
1932
    }
1933
    return ret;
1934
}
1935

    
1936
#ifdef HAVE_MMX
1937
#define DEINT_INPLACE_LINE_LUM \
1938
                    movd_m2r(lum_m4[0],mm0);\
1939
                    movd_m2r(lum_m3[0],mm1);\
1940
                    movd_m2r(lum_m2[0],mm2);\
1941
                    movd_m2r(lum_m1[0],mm3);\
1942
                    movd_m2r(lum[0],mm4);\
1943
                    punpcklbw_r2r(mm7,mm0);\
1944
                    movd_r2m(mm2,lum_m4[0]);\
1945
                    punpcklbw_r2r(mm7,mm1);\
1946
                    punpcklbw_r2r(mm7,mm2);\
1947
                    punpcklbw_r2r(mm7,mm3);\
1948
                    punpcklbw_r2r(mm7,mm4);\
1949
                    paddw_r2r(mm3,mm1);\
1950
                    psllw_i2r(1,mm2);\
1951
                    paddw_r2r(mm4,mm0);\
1952
                    psllw_i2r(2,mm1);\
1953
                    paddw_r2r(mm6,mm2);\
1954
                    paddw_r2r(mm2,mm1);\
1955
                    psubusw_r2r(mm0,mm1);\
1956
                    psrlw_i2r(3,mm1);\
1957
                    packuswb_r2r(mm7,mm1);\
1958
                    movd_r2m(mm1,lum_m2[0]);
1959

    
1960
#define DEINT_LINE_LUM \
1961
                    movd_m2r(lum_m4[0],mm0);\
1962
                    movd_m2r(lum_m3[0],mm1);\
1963
                    movd_m2r(lum_m2[0],mm2);\
1964
                    movd_m2r(lum_m1[0],mm3);\
1965
                    movd_m2r(lum[0],mm4);\
1966
                    punpcklbw_r2r(mm7,mm0);\
1967
                    punpcklbw_r2r(mm7,mm1);\
1968
                    punpcklbw_r2r(mm7,mm2);\
1969
                    punpcklbw_r2r(mm7,mm3);\
1970
                    punpcklbw_r2r(mm7,mm4);\
1971
                    paddw_r2r(mm3,mm1);\
1972
                    psllw_i2r(1,mm2);\
1973
                    paddw_r2r(mm4,mm0);\
1974
                    psllw_i2r(2,mm1);\
1975
                    paddw_r2r(mm6,mm2);\
1976
                    paddw_r2r(mm2,mm1);\
1977
                    psubusw_r2r(mm0,mm1);\
1978
                    psrlw_i2r(3,mm1);\
1979
                    packuswb_r2r(mm7,mm1);\
1980
                    movd_r2m(mm1,dst[0]);
1981
#endif
1982

    
1983
/* filter parameters: [-1 4 2 4 -1] // 8 */
1984
static void deinterlace_line(uint8_t *dst, uint8_t *lum_m4, uint8_t *lum_m3, uint8_t *lum_m2, uint8_t *lum_m1, uint8_t *lum,
1985
                                int size)
1986
{
1987
#ifndef HAVE_MMX
1988
    uint8_t *cm = cropTbl + MAX_NEG_CROP;
1989
    int sum;
1990

    
1991
    for(;size > 0;size--) {
1992
        sum = -lum_m4[0];
1993
        sum += lum_m3[0] << 2;
1994
        sum += lum_m2[0] << 1;
1995
        sum += lum_m1[0] << 2;
1996
        sum += -lum[0];
1997
        dst[0] = cm[(sum + 4) >> 3];
1998
        lum_m4++;
1999
        lum_m3++;
2000
        lum_m2++;
2001
        lum_m1++;
2002
        lum++;
2003
        dst++;
2004
    }
2005
#else
2006

    
2007
    {
2008
        mmx_t rounder;
2009
        rounder.uw[0]=4;
2010
        rounder.uw[1]=4;
2011
        rounder.uw[2]=4;
2012
        rounder.uw[3]=4;
2013
        pxor_r2r(mm7,mm7);
2014
        movq_m2r(rounder,mm6);
2015
    }
2016
    for (;size > 3; size-=4) {
2017
        DEINT_LINE_LUM
2018
        lum_m4+=4;
2019
        lum_m3+=4;
2020
        lum_m2+=4;
2021
        lum_m1+=4;
2022
        lum+=4;
2023
        dst+=4;
2024
    }
2025
#endif
2026
}
2027
static void deinterlace_line_inplace(uint8_t *lum_m4, uint8_t *lum_m3, uint8_t *lum_m2, uint8_t *lum_m1, uint8_t *lum,
2028
                             int size)
2029
{
2030
#ifndef HAVE_MMX
2031
    uint8_t *cm = cropTbl + MAX_NEG_CROP;
2032
    int sum;
2033

    
2034
    for(;size > 0;size--) {
2035
        sum = -lum_m4[0];
2036
        sum += lum_m3[0] << 2;
2037
        sum += lum_m2[0] << 1;
2038
        lum_m4[0]=lum_m2[0];
2039
        sum += lum_m1[0] << 2;
2040
        sum += -lum[0];
2041
        lum_m2[0] = cm[(sum + 4) >> 3];
2042
        lum_m4++;
2043
        lum_m3++;
2044
        lum_m2++;
2045
        lum_m1++;
2046
        lum++;
2047
    }
2048
#else
2049

    
2050
    {
2051
        mmx_t rounder;
2052
        rounder.uw[0]=4;
2053
        rounder.uw[1]=4;
2054
        rounder.uw[2]=4;
2055
        rounder.uw[3]=4;
2056
        pxor_r2r(mm7,mm7);
2057
        movq_m2r(rounder,mm6);
2058
    }
2059
    for (;size > 3; size-=4) {
2060
        DEINT_INPLACE_LINE_LUM
2061
        lum_m4+=4;
2062
        lum_m3+=4;
2063
        lum_m2+=4;
2064
        lum_m1+=4;
2065
        lum+=4;
2066
    }
2067
#endif
2068
}
2069

    
2070
/* deinterlacing : 2 temporal taps, 3 spatial taps linear filter. The
2071
   top field is copied as is, but the bottom field is deinterlaced
2072
   against the top field. */
2073
static void deinterlace_bottom_field(uint8_t *dst, int dst_wrap,
2074
                                    uint8_t *src1, int src_wrap,
2075
                                    int width, int height)
2076
{
2077
    uint8_t *src_m2, *src_m1, *src_0, *src_p1, *src_p2;
2078
    int y;
2079

    
2080
    src_m2 = src1;
2081
    src_m1 = src1;
2082
    src_0=&src_m1[src_wrap];
2083
    src_p1=&src_0[src_wrap];
2084
    src_p2=&src_p1[src_wrap];
2085
    for(y=0;y<(height-2);y+=2) {
2086
        memcpy(dst,src_m1,width);
2087
        dst += dst_wrap;
2088
        deinterlace_line(dst,src_m2,src_m1,src_0,src_p1,src_p2,width);
2089
        src_m2 = src_0;
2090
        src_m1 = src_p1;
2091
        src_0 = src_p2;
2092
        src_p1 += 2*src_wrap;
2093
        src_p2 += 2*src_wrap;
2094
        dst += dst_wrap;
2095
    }
2096
    memcpy(dst,src_m1,width);
2097
    dst += dst_wrap;
2098
    /* do last line */
2099
    deinterlace_line(dst,src_m2,src_m1,src_0,src_0,src_0,width);
2100
}
2101

    
2102
static void deinterlace_bottom_field_inplace(uint8_t *src1, int src_wrap,
2103
                                     int width, int height)
2104
{
2105
    uint8_t *src_m1, *src_0, *src_p1, *src_p2;
2106
    int y;
2107
    uint8_t *buf;
2108
    buf = (uint8_t*)av_malloc(width);
2109

    
2110
    src_m1 = src1;
2111
    memcpy(buf,src_m1,width);
2112
    src_0=&src_m1[src_wrap];
2113
    src_p1=&src_0[src_wrap];
2114
    src_p2=&src_p1[src_wrap];
2115
    for(y=0;y<(height-2);y+=2) {
2116
        deinterlace_line_inplace(buf,src_m1,src_0,src_p1,src_p2,width);
2117
        src_m1 = src_p1;
2118
        src_0 = src_p2;
2119
        src_p1 += 2*src_wrap;
2120
        src_p2 += 2*src_wrap;
2121
    }
2122
    /* do last line */
2123
    deinterlace_line_inplace(buf,src_m1,src_0,src_0,src_0,width);
2124
    av_free(buf);
2125
}
2126

    
2127

    
2128
/* deinterlace - if not supported return -1 */
2129
int avpicture_deinterlace(AVPicture *dst, AVPicture *src,
2130
                          int pix_fmt, int width, int height)
2131
{
2132
    int i;
2133

    
2134
    if (pix_fmt != PIX_FMT_YUV420P &&
2135
        pix_fmt != PIX_FMT_YUV422P &&
2136
        pix_fmt != PIX_FMT_YUV444P &&
2137
        pix_fmt != PIX_FMT_YUV411P)
2138
        return -1;
2139
    if ((width & 3) != 0 || (height & 3) != 0)
2140
        return -1;
2141

    
2142
    for(i=0;i<3;i++) {
2143
        if (i == 1) {
2144
            switch(pix_fmt) {
2145
            case PIX_FMT_YUV420P:
2146
                width >>= 1;
2147
                height >>= 1;
2148
                break;
2149
            case PIX_FMT_YUV422P:
2150
                width >>= 1;
2151
                break;
2152
            case PIX_FMT_YUV411P:
2153
                width >>= 2;
2154
                break;
2155
            default:
2156
                break;
2157
            }
2158
        }
2159
        if (src == dst) {
2160
            deinterlace_bottom_field_inplace(src->data[i], src->linesize[i],
2161
                                 width, height);
2162
        } else {
2163
            deinterlace_bottom_field(dst->data[i],dst->linesize[i],
2164
                                        src->data[i], src->linesize[i],
2165
                                        width, height);
2166
        }
2167
    }
2168
#ifdef HAVE_MMX
2169
    emms();
2170
#endif
2171
    return 0;
2172
}
2173

    
2174
#undef FIX