Statistics
| Branch: | Revision:

ffmpeg / libavcodec / imgconvert.c @ 4cfbf61b

History | View | Annotate | Download (57.3 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 x;
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 >= 2; height -= 2) {
604
        p = p1;
605
        lum = lum1;
606
        cb = cb1;
607
        cr = cr1;
608
        for(x=0;x<width;x+=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
        p1 += src->linesize[0];
619
        lum1 += dst->linesize[0];
620
        p = p1;
621
        lum = lum1;
622
        for(x=0;x<width;x+=2) {
623
            lum[0] = p[0];
624
            lum[1] = p[2];
625
            p += 4;
626
            lum += 2;
627
        }
628
        p1 += src->linesize[0];
629
        lum1 += dst->linesize[0];
630
        cb1 += dst->linesize[1];
631
        cr1 += dst->linesize[2];
632
    }
633
}
634

    
635
static void yuv422_to_yuv422p(AVPicture *dst, AVPicture *src,
636
                              int width, int height)
637
{
638
    const uint8_t *p, *p1;
639
    uint8_t *lum, *cr, *cb, *lum1, *cr1, *cb1;
640
    int w;
641

    
642
    p1 = src->data[0];
643
    lum1 = dst->data[0];
644
    cb1 = dst->data[1];
645
    cr1 = dst->data[2];
646
    for(;height > 0; height--) {
647
        p = p1;
648
        lum = lum1;
649
        cb = cb1;
650
        cr = cr1;
651
        for(w = width; w >= 2; w -= 2) {
652
            lum[0] = p[0];
653
            cb[0] = p[1];
654
            lum[1] = p[2];
655
            cr[0] = p[3];
656
            p += 4;
657
            lum += 2;
658
            cb++;
659
            cr++;
660
        }
661
        p1 += src->linesize[0];
662
        lum1 += dst->linesize[0];
663
        cb1 += dst->linesize[1];
664
        cr1 += dst->linesize[2];
665
    }
666
}
667

    
668
static void yuv422p_to_yuv422(AVPicture *dst, AVPicture *src,
669
                              int width, int height)
670
{
671
    uint8_t *p, *p1;
672
    const uint8_t *lum, *cr, *cb, *lum1, *cr1, *cb1;
673
    int w;
674

    
675
    p1 = dst->data[0];
676
    lum1 = src->data[0];
677
    cb1 = src->data[1];
678
    cr1 = src->data[2];
679
    for(;height > 0; height--) {
680
        p = p1;
681
        lum = lum1;
682
        cb = cb1;
683
        cr = cr1;
684
        for(w = width; w >= 2; w -= 2) {
685
            p[0] = lum[0];
686
            p[1] = cb[0];
687
            p[2] = lum[1];
688
            p[3] = cr[0];
689
            p += 4;
690
            lum += 2;
691
            cb++;
692
            cr++;
693
        }
694
        p1 += dst->linesize[0];
695
        lum1 += src->linesize[0];
696
        cb1 += src->linesize[1];
697
        cr1 += src->linesize[2];
698
    }
699
}
700

    
701
#define SCALEBITS 10
702
#define ONE_HALF  (1 << (SCALEBITS - 1))
703
#define FIX(x)          ((int) ((x) * (1<<SCALEBITS) + 0.5))
704

    
705
#define YUV_TO_RGB1_CCIR(cb1, cr1)\
706
{\
707
    cb = (cb1) - 128;\
708
    cr = (cr1) - 128;\
709
    r_add = FIX(1.40200*255.0/224.0) * cr + ONE_HALF;\
710
    g_add = - FIX(0.34414*255.0/224.0) * cb - FIX(0.71414*255.0/224.0) * cr + \
711
            ONE_HALF;\
712
    b_add = FIX(1.77200*255.0/224.0) * cb + ONE_HALF;\
713
}
714

    
715
#define YUV_TO_RGB2_CCIR(r, g, b, y1)\
716
{\
717
    y = ((y1) - 16) * FIX(255.0/219.0);\
718
    r = cm[(y + r_add) >> SCALEBITS];\
719
    g = cm[(y + g_add) >> SCALEBITS];\
720
    b = cm[(y + b_add) >> SCALEBITS];\
721
}
722

    
723
#define YUV_TO_RGB1(cb1, cr1)\
724
{\
725
    cb = (cb1) - 128;\
726
    cr = (cr1) - 128;\
727
    r_add = FIX(1.40200) * cr + ONE_HALF;\
728
    g_add = - FIX(0.34414) * cb - FIX(0.71414) * cr + ONE_HALF;\
729
    b_add = FIX(1.77200) * cb + ONE_HALF;\
730
}
731

    
732
#define YUV_TO_RGB2(r, g, b, y1)\
733
{\
734
    y = (y1) << SCALEBITS;\
735
    r = cm[(y + r_add) >> SCALEBITS];\
736
    g = cm[(y + g_add) >> SCALEBITS];\
737
    b = cm[(y + b_add) >> SCALEBITS];\
738
}
739

    
740
#define Y_CCIR_TO_JPEG(y)\
741
 cm[((y) * FIX(255.0/219.0) + (ONE_HALF - 16 * FIX(255.0/219.0))) >> SCALEBITS]
742

    
743
#define Y_JPEG_TO_CCIR(y)\
744
 (((y) * FIX(219.0/255.0) + (ONE_HALF + (16 << SCALEBITS))) >> SCALEBITS)
745

    
746
#define C_CCIR_TO_JPEG(y)\
747
 cm[(((y) - 128) * FIX(127.0/112.0) + (ONE_HALF + (128 << SCALEBITS))) >> SCALEBITS]
748

    
749
/* NOTE: the clamp is really necessary! */
750
static inline int C_JPEG_TO_CCIR(int y) {
751
    y = (((y - 128) * FIX(112.0/127.0) + (ONE_HALF + (128 << SCALEBITS))) >> SCALEBITS);
752
    if (y < 16)
753
        y = 16;
754
    return y;
755
}
756

    
757

    
758
#define RGB_TO_Y(r, g, b) \
759
((FIX(0.29900) * (r) + FIX(0.58700) * (g) + \
760
  FIX(0.11400) * (b) + ONE_HALF) >> SCALEBITS)
761

    
762
#define RGB_TO_U(r1, g1, b1, shift)\
763
(((- FIX(0.16874) * r1 - FIX(0.33126) * g1 +         \
764
     FIX(0.50000) * b1 + (ONE_HALF << shift) - 1) >> (SCALEBITS + shift)) + 128)
765

    
766
#define RGB_TO_V(r1, g1, b1, shift)\
767
(((FIX(0.50000) * r1 - FIX(0.41869) * g1 -           \
768
   FIX(0.08131) * b1 + (ONE_HALF << shift) - 1) >> (SCALEBITS + shift)) + 128)
769

    
770
#define RGB_TO_Y_CCIR(r, g, b) \
771
((FIX(0.29900*219.0/255.0) * (r) + FIX(0.58700*219.0/255.0) * (g) + \
772
  FIX(0.11400*219.0/255.0) * (b) + (ONE_HALF + (16 << SCALEBITS))) >> SCALEBITS)
773

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

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

    
782
static uint8_t y_ccir_to_jpeg[256];
783
static uint8_t y_jpeg_to_ccir[256];
784
static uint8_t c_ccir_to_jpeg[256];
785
static uint8_t c_jpeg_to_ccir[256];
786

    
787
/* init various conversion tables */
788
static void img_convert_init(void)
789
{
790
    int i;
791
    uint8_t *cm = cropTbl + MAX_NEG_CROP;
792

    
793
    for(i = 0;i < 256; i++) {
794
        y_ccir_to_jpeg[i] = Y_CCIR_TO_JPEG(i);
795
        y_jpeg_to_ccir[i] = Y_JPEG_TO_CCIR(i);
796
        c_ccir_to_jpeg[i] = C_CCIR_TO_JPEG(i);
797
        c_jpeg_to_ccir[i] = C_JPEG_TO_CCIR(i);
798
    }
799
}
800

    
801
/* apply to each pixel the given table */
802
static void img_apply_table(uint8_t *dst, int dst_wrap, 
803
                            const uint8_t *src, int src_wrap,
804
                            int width, int height, const uint8_t *table1)
805
{
806
    int n;
807
    const uint8_t *s;
808
    uint8_t *d;
809
    const uint8_t *table;
810

    
811
    table = table1;
812
    for(;height > 0; height--) {
813
        s = src;
814
        d = dst;
815
        n = width;
816
        while (n >= 4) {
817
            d[0] = table[s[0]];
818
            d[1] = table[s[1]];
819
            d[2] = table[s[2]];
820
            d[3] = table[s[3]];
821
            d += 4;
822
            s += 4;
823
            n -= 4;
824
        }
825
        while (n > 0) {
826
            d[0] = table[s[0]];
827
            d++;
828
            s++;
829
            n--;
830
        }
831
        dst += dst_wrap;
832
        src += src_wrap;
833
    }
834
}
835

    
836
/* XXX: use generic filter ? */
837
/* XXX: in most cases, the sampling position is incorrect */
838

    
839
/* 4x1 -> 1x1 */
840
static void shrink41(uint8_t *dst, int dst_wrap, 
841
                     const uint8_t *src, int src_wrap,
842
                     int width, int height)
843
{
844
    int w;
845
    const uint8_t *s;
846
    uint8_t *d;
847

    
848
    for(;height > 0; height--) {
849
        s = src;
850
        d = dst;
851
        for(w = width;w > 0; w--) {
852
            d[0] = (s[0] + s[1] + s[2] + s[3] + 2) >> 2;
853
            s += 4;
854
            d++;
855
        }
856
        src += src_wrap;
857
        dst += dst_wrap;
858
    }
859
}
860

    
861
/* 2x1 -> 1x1 */
862
static void shrink21(uint8_t *dst, int dst_wrap, 
863
                     const uint8_t *src, int src_wrap,
864
                     int width, int height)
865
{
866
    int w;
867
    const uint8_t *s;
868
    uint8_t *d;
869

    
870
    for(;height > 0; height--) {
871
        s = src;
872
        d = dst;
873
        for(w = width;w > 0; w--) {
874
            d[0] = (s[0] + s[1]) >> 1;
875
            s += 2;
876
            d++;
877
        }
878
        src += src_wrap;
879
        dst += dst_wrap;
880
    }
881
}
882

    
883
/* 1x2 -> 1x1 */
884
static void shrink12(uint8_t *dst, int dst_wrap, 
885
                     const uint8_t *src, int src_wrap,
886
                     int width, int height)
887
{
888
    int w;
889
    uint8_t *d;
890
    const uint8_t *s1, *s2;
891

    
892
    for(;height > 0; height--) {
893
        s1 = src;
894
        s2 = s1 + src_wrap;
895
        d = dst;
896
        for(w = width;w >= 4; w-=4) {
897
            d[0] = (s1[0] + s2[0]) >> 1;
898
            d[1] = (s1[1] + s2[1]) >> 1;
899
            d[2] = (s1[2] + s2[2]) >> 1;
900
            d[3] = (s1[3] + s2[3]) >> 1;
901
            s1 += 4;
902
            s2 += 4;
903
            d += 4;
904
        }
905
        for(;w > 0; w--) {
906
            d[0] = (s1[0] + s2[0]) >> 1;
907
            s1++;
908
            s2++;
909
            d++;
910
        }
911
        src += 2 * src_wrap;
912
        dst += dst_wrap;
913
    }
914
}
915

    
916
/* 2x2 -> 1x1 */
917
static void shrink22(uint8_t *dst, int dst_wrap, 
918
                     const uint8_t *src, int src_wrap,
919
                     int width, int height)
920
{
921
    int w;
922
    const uint8_t *s1, *s2;
923
    uint8_t *d;
924

    
925
    for(;height > 0; height--) {
926
        s1 = src;
927
        s2 = s1 + src_wrap;
928
        d = dst;
929
        for(w = width;w >= 4; w-=4) {
930
            d[0] = (s1[0] + s1[1] + s2[0] + s2[1] + 2) >> 2;
931
            d[1] = (s1[2] + s1[3] + s2[2] + s2[3] + 2) >> 2;
932
            d[2] = (s1[4] + s1[5] + s2[4] + s2[5] + 2) >> 2;
933
            d[3] = (s1[6] + s1[7] + s2[6] + s2[7] + 2) >> 2;
934
            s1 += 8;
935
            s2 += 8;
936
            d += 4;
937
        }
938
        for(;w > 0; w--) {
939
            d[0] = (s1[0] + s1[1] + s2[0] + s2[1] + 2) >> 2;
940
            s1 += 2;
941
            s2 += 2;
942
            d++;
943
        }
944
        src += 2 * src_wrap;
945
        dst += dst_wrap;
946
    }
947
}
948

    
949
/* 4x4 -> 1x1 */
950
static void shrink44(uint8_t *dst, int dst_wrap, 
951
                     const uint8_t *src, int src_wrap,
952
                     int width, int height)
953
{
954
    int w;
955
    const uint8_t *s1, *s2, *s3, *s4;
956
    uint8_t *d;
957

    
958
    for(;height > 0; height--) {
959
        s1 = src;
960
        s2 = s1 + src_wrap;
961
        s3 = s2 + src_wrap;
962
        s4 = s3 + src_wrap;
963
        d = dst;
964
        for(w = width;w > 0; w--) {
965
            d[0] = (s1[0] + s1[1] + s1[2] + s1[3] +
966
                    s2[0] + s2[1] + s2[2] + s2[3] +
967
                    s3[0] + s3[1] + s3[2] + s3[3] +
968
                    s4[0] + s4[1] + s4[2] + s4[3] + 8) >> 4;
969
            s1 += 4;
970
            s2 += 4;
971
            s3 += 4;
972
            s4 += 4;
973
            d++;
974
        }
975
        src += 4 * src_wrap;
976
        dst += dst_wrap;
977
    }
978
}
979

    
980
static void grow21_line(uint8_t *dst, const uint8_t *src,
981
                        int width)
982
{
983
    int w;
984
    const uint8_t *s1;
985
    uint8_t *d;
986

    
987
    s1 = src;
988
    d = dst;
989
    for(w = width;w >= 4; w-=4) {
990
        d[1] = d[0] = s1[0];
991
        d[3] = d[2] = s1[1];
992
        s1 += 2;
993
        d += 4;
994
    }
995
    for(;w >= 2; w -= 2) {
996
        d[1] = d[0] = s1[0];
997
        s1 ++;
998
        d += 2;
999
    }
1000
    /* only needed if width is not a multiple of two */
1001
    /* XXX: veryfy that */
1002
    if (w) {
1003
        d[0] = s1[0];
1004
    }
1005
}
1006

    
1007
static void grow41_line(uint8_t *dst, const uint8_t *src,
1008
                        int width)
1009
{
1010
    int w, v;
1011
    const uint8_t *s1;
1012
    uint8_t *d;
1013

    
1014
    s1 = src;
1015
    d = dst;
1016
    for(w = width;w >= 4; w-=4) {
1017
        v = s1[0];
1018
        d[0] = v;
1019
        d[1] = v;
1020
        d[2] = v;
1021
        d[3] = v;
1022
        s1 ++;
1023
        d += 4;
1024
    }
1025
}
1026

    
1027
/* 1x1 -> 2x1 */
1028
static void grow21(uint8_t *dst, int dst_wrap,
1029
                   const uint8_t *src, int src_wrap,
1030
                   int width, int height)
1031
{
1032
    for(;height > 0; height--) {
1033
        grow21_line(dst, src, width);
1034
        src += src_wrap;
1035
        dst += dst_wrap;
1036
    }
1037
}
1038

    
1039
/* 1x1 -> 2x2 */
1040
static void grow22(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
        if (height%2)
1047
            src += src_wrap;
1048
        dst += dst_wrap;
1049
    }
1050
}
1051

    
1052
/* 1x1 -> 4x1 */
1053
static void grow41(uint8_t *dst, int dst_wrap,
1054
                   const uint8_t *src, int src_wrap,
1055
                   int width, int height)
1056
{
1057
    for(;height > 0; height--) {
1058
        grow41_line(dst, src, width);
1059
        src += src_wrap;
1060
        dst += dst_wrap;
1061
    }
1062
}
1063

    
1064
/* 1x1 -> 4x4 */
1065
static void grow44(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
        if ((height & 3) == 1)
1072
            src += src_wrap;
1073
        dst += dst_wrap;
1074
    }
1075
}
1076

    
1077
/* 1x2 -> 2x1 */
1078
static void conv411(uint8_t *dst, int dst_wrap, 
1079
                    const uint8_t *src, int src_wrap,
1080
                    int width, int height)
1081
{
1082
    int w, c;
1083
    const uint8_t *s1, *s2;
1084
    uint8_t *d;
1085

    
1086
    width>>=1;
1087

    
1088
    for(;height > 0; height--) {
1089
        s1 = src;
1090
        s2 = src + src_wrap;
1091
        d = dst;
1092
        for(w = width;w > 0; w--) {
1093
            c = (s1[0] + s2[0]) >> 1;
1094
            d[0] = c;
1095
            d[1] = c;
1096
            s1++;
1097
            s2++;
1098
            d += 2;
1099
        }
1100
        src += src_wrap * 2;
1101
        dst += dst_wrap;
1102
    }
1103
}
1104

    
1105
/* XXX: add jpeg quantize code */
1106

    
1107
#define TRANSP_INDEX (6*6*6)
1108

    
1109
/* this is maybe slow, but allows for extensions */
1110
static inline unsigned char gif_clut_index(uint8_t r, uint8_t g, uint8_t b)
1111
{
1112
    return ((((r)/47)%6)*6*6+(((g)/47)%6)*6+(((b)/47)%6));
1113
}
1114

    
1115
static void build_rgb_palette(uint8_t *palette, int has_alpha)
1116
{
1117
    uint32_t *pal;
1118
    static const uint8_t pal_value[6] = { 0x00, 0x33, 0x66, 0x99, 0xcc, 0xff };
1119
    int i, r, g, b;
1120

    
1121
    pal = (uint32_t *)palette;
1122
    i = 0;
1123
    for(r = 0; r < 6; r++) {
1124
        for(g = 0; g < 6; g++) {
1125
            for(b = 0; b < 6; b++) {
1126
                pal[i++] = (0xff << 24) | (pal_value[r] << 16) | 
1127
                    (pal_value[g] << 8) | pal_value[b];
1128
            }
1129
        }
1130
    }
1131
    if (has_alpha)
1132
        pal[i++] = 0;
1133
    while (i < 256)
1134
        pal[i++] = 0xff000000;
1135
}
1136

    
1137
/* copy bit n to bits 0 ... n - 1 */
1138
static inline unsigned int bitcopy_n(unsigned int a, int n)
1139
{
1140
    int mask;
1141
    mask = (1 << n) - 1;
1142
    return (a & (0xff & ~mask)) | ((-((a >> n) & 1)) & mask);
1143
}
1144

    
1145
/* rgb555 handling */
1146

    
1147
#define RGB_NAME rgb555
1148

    
1149
#define RGB_IN(r, g, b, s)\
1150
{\
1151
    unsigned int v = ((const uint16_t *)(s))[0];\
1152
    r = bitcopy_n(v >> (10 - 3), 3);\
1153
    g = bitcopy_n(v >> (5 - 3), 3);\
1154
    b = bitcopy_n(v << 3, 3);\
1155
}
1156

    
1157
#define RGBA_IN(r, g, b, a, s)\
1158
{\
1159
    unsigned int v = ((const uint16_t *)(s))[0];\
1160
    r = bitcopy_n(v >> (10 - 3), 3);\
1161
    g = bitcopy_n(v >> (5 - 3), 3);\
1162
    b = bitcopy_n(v << 3, 3);\
1163
    a = (-(v >> 15)) & 0xff;\
1164
}
1165

    
1166
#define RGBA_OUT(d, r, g, b, a)\
1167
{\
1168
    ((uint16_t *)(d))[0] = ((r >> 3) << 10) | ((g >> 3) << 5) | (b >> 3) | \
1169
                           ((a << 8) & 0x8000);\
1170
}
1171

    
1172
#define BPP 2
1173

    
1174
#include "imgconvert_template.h"
1175

    
1176
/* rgb565 handling */
1177

    
1178
#define RGB_NAME rgb565
1179

    
1180
#define RGB_IN(r, g, b, s)\
1181
{\
1182
    unsigned int v = ((const uint16_t *)(s))[0];\
1183
    r = bitcopy_n(v >> (11 - 3), 3);\
1184
    g = bitcopy_n(v >> (5 - 2), 2);\
1185
    b = bitcopy_n(v << 3, 3);\
1186
}
1187

    
1188
#define RGB_OUT(d, r, g, b)\
1189
{\
1190
    ((uint16_t *)(d))[0] = ((r >> 3) << 11) | ((g >> 2) << 5) | (b >> 3);\
1191
}
1192

    
1193
#define BPP 2
1194

    
1195
#include "imgconvert_template.h"
1196

    
1197
/* bgr24 handling */
1198

    
1199
#define RGB_NAME bgr24
1200

    
1201
#define RGB_IN(r, g, b, s)\
1202
{\
1203
    b = (s)[0];\
1204
    g = (s)[1];\
1205
    r = (s)[2];\
1206
}
1207

    
1208
#define RGB_OUT(d, r, g, b)\
1209
{\
1210
    (d)[0] = b;\
1211
    (d)[1] = g;\
1212
    (d)[2] = r;\
1213
}
1214

    
1215
#define BPP 3
1216

    
1217
#include "imgconvert_template.h"
1218

    
1219
#undef RGB_IN
1220
#undef RGB_OUT
1221
#undef BPP
1222

    
1223
/* rgb24 handling */
1224

    
1225
#define RGB_NAME rgb24
1226
#define FMT_RGB24
1227

    
1228
#define RGB_IN(r, g, b, s)\
1229
{\
1230
    r = (s)[0];\
1231
    g = (s)[1];\
1232
    b = (s)[2];\
1233
}
1234

    
1235
#define RGB_OUT(d, r, g, b)\
1236
{\
1237
    (d)[0] = r;\
1238
    (d)[1] = g;\
1239
    (d)[2] = b;\
1240
}
1241

    
1242
#define BPP 3
1243

    
1244
#include "imgconvert_template.h"
1245

    
1246
/* rgba32 handling */
1247

    
1248
#define RGB_NAME rgba32
1249
#define FMT_RGBA32
1250

    
1251
#define RGB_IN(r, g, b, s)\
1252
{\
1253
    unsigned int v = ((const uint32_t *)(s))[0];\
1254
    r = (v >> 16) & 0xff;\
1255
    g = (v >> 8) & 0xff;\
1256
    b = v & 0xff;\
1257
}
1258

    
1259
#define RGBA_IN(r, g, b, a, s)\
1260
{\
1261
    unsigned int v = ((const uint32_t *)(s))[0];\
1262
    a = (v >> 24) & 0xff;\
1263
    r = (v >> 16) & 0xff;\
1264
    g = (v >> 8) & 0xff;\
1265
    b = v & 0xff;\
1266
}
1267

    
1268
#define RGBA_OUT(d, r, g, b, a)\
1269
{\
1270
    ((uint32_t *)(d))[0] = (a << 24) | (r << 16) | (g << 8) | b;\
1271
}
1272

    
1273
#define BPP 4
1274

    
1275
#include "imgconvert_template.h"
1276

    
1277
static void mono_to_gray(AVPicture *dst, AVPicture *src,
1278
                         int width, int height, int xor_mask)
1279
{
1280
    const unsigned char *p;
1281
    unsigned char *q;
1282
    int v, dst_wrap, src_wrap;
1283
    int y, w;
1284

    
1285
    p = src->data[0];
1286
    src_wrap = src->linesize[0] - ((width + 7) >> 3);
1287

    
1288
    q = dst->data[0];
1289
    dst_wrap = dst->linesize[0] - width;
1290
    for(y=0;y<height;y++) {
1291
        w = width; 
1292
        while (w >= 8) {
1293
            v = *p++ ^ xor_mask;
1294
            q[0] = -(v >> 7);
1295
            q[1] = -((v >> 6) & 1);
1296
            q[2] = -((v >> 5) & 1);
1297
            q[3] = -((v >> 4) & 1);
1298
            q[4] = -((v >> 3) & 1);
1299
            q[5] = -((v >> 2) & 1);
1300
            q[6] = -((v >> 1) & 1);
1301
            q[7] = -((v >> 0) & 1);
1302
            w -= 8;
1303
            q += 8;
1304
        }
1305
        if (w > 0) {
1306
            v = *p++ ^ xor_mask;
1307
            do {
1308
                q[0] = -((v >> 7) & 1);
1309
                q++;
1310
                v <<= 1;
1311
            } while (--w);
1312
        }
1313
        p += src_wrap;
1314
        q += dst_wrap;
1315
    }
1316
}
1317

    
1318
static void monowhite_to_gray(AVPicture *dst, AVPicture *src,
1319
                               int width, int height)
1320
{
1321
    mono_to_gray(dst, src, width, height, 0xff);
1322
}
1323

    
1324
static void monoblack_to_gray(AVPicture *dst, AVPicture *src,
1325
                               int width, int height)
1326
{
1327
    mono_to_gray(dst, src, width, height, 0x00);
1328
}
1329

    
1330
static void gray_to_mono(AVPicture *dst, AVPicture *src,
1331
                         int width, int height, int xor_mask)
1332
{
1333
    int n;
1334
    const uint8_t *s;
1335
    uint8_t *d;
1336
    int j, b, v, n1, src_wrap, dst_wrap, y;
1337

    
1338
    s = src->data[0];
1339
    src_wrap = src->linesize[0] - width;
1340

    
1341
    d = dst->data[0];
1342
    dst_wrap = dst->linesize[0] - ((width + 7) >> 3);
1343

    
1344
    for(y=0;y<height;y++) {
1345
        n = width;
1346
        while (n >= 8) {
1347
            v = 0;
1348
            for(j=0;j<8;j++) {
1349
                b = s[0];
1350
                s++;
1351
                v = (v << 1) | (b >> 7);
1352
            }
1353
            d[0] = v ^ xor_mask;
1354
            d++;
1355
            n -= 8;
1356
        }
1357
        if (n > 0) {
1358
            n1 = n;
1359
            v = 0;
1360
            while (n > 0) {
1361
                b = s[0];
1362
                s++;
1363
                v = (v << 1) | (b >> 7);
1364
                n--;
1365
            }
1366
            d[0] = (v << (8 - (n1 & 7))) ^ xor_mask;
1367
            d++;
1368
        }
1369
        s += src_wrap;
1370
        d += dst_wrap;
1371
    }
1372
}
1373

    
1374
static void gray_to_monowhite(AVPicture *dst, AVPicture *src,
1375
                              int width, int height)
1376
{
1377
    gray_to_mono(dst, src, width, height, 0xff);
1378
}
1379

    
1380
static void gray_to_monoblack(AVPicture *dst, AVPicture *src,
1381
                              int width, int height)
1382
{
1383
    gray_to_mono(dst, src, width, height, 0x00);
1384
}
1385

    
1386
typedef struct ConvertEntry {
1387
    void (*convert)(AVPicture *dst, AVPicture *src, int width, int height);
1388
} ConvertEntry;
1389

    
1390
/* Add each new convertion function in this table. In order to be able
1391
   to convert from any format to any format, the following constraints
1392
   must be satisfied:
1393

1394
   - all FF_COLOR_RGB formats must convert to and from PIX_FMT_RGB24 
1395

1396
   - all FF_COLOR_GRAY formats must convert to and from PIX_FMT_GRAY8
1397

1398
   - all FF_COLOR_RGB formats with alpha must convert to and from PIX_FMT_RGBA32
1399

1400
   - PIX_FMT_YUV444P and PIX_FMT_YUVJ444P must convert to and from
1401
     PIX_FMT_RGB24.
1402

1403
   - PIX_FMT_422 must convert to and from PIX_FMT_422P.
1404

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

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

    
1603
static int avpicture_alloc(AVPicture *picture,
1604
                           int pix_fmt, int width, int height)
1605
{
1606
    unsigned int size;
1607
    void *ptr;
1608

    
1609
    size = avpicture_get_size(pix_fmt, width, height);
1610
    ptr = av_malloc(size);
1611
    if (!ptr)
1612
        goto fail;
1613
    avpicture_fill(picture, ptr, pix_fmt, width, height);
1614
    return 0;
1615
 fail:
1616
    memset(picture, 0, sizeof(AVPicture));
1617
    return -1;
1618
}
1619

    
1620
static void avpicture_free(AVPicture *picture)
1621
{
1622
    av_free(picture->data[0]);
1623
}
1624

    
1625
/* return true if yuv planar */
1626
static inline int is_yuv_planar(PixFmtInfo *ps)
1627
{
1628
    return (ps->color_type == FF_COLOR_YUV ||
1629
            ps->color_type == FF_COLOR_YUV_JPEG) && 
1630
        ps->pixel_type == FF_PIXEL_PLANAR;
1631
}
1632

    
1633
/* XXX: always use linesize. Return -1 if not supported */
1634
int img_convert(AVPicture *dst, int dst_pix_fmt,
1635
                AVPicture *src, int src_pix_fmt, 
1636
                int src_width, int src_height)
1637
{
1638
    static int inited;
1639
    int i, ret, dst_width, dst_height, int_pix_fmt;
1640
    PixFmtInfo *src_pix, *dst_pix;
1641
    ConvertEntry *ce;
1642
    AVPicture tmp1, *tmp = &tmp1;
1643

    
1644
    if (src_pix_fmt < 0 || src_pix_fmt >= PIX_FMT_NB ||
1645
        dst_pix_fmt < 0 || dst_pix_fmt >= PIX_FMT_NB)
1646
        return -1;
1647
    if (src_width <= 0 || src_height <= 0)
1648
        return 0;
1649

    
1650
    if (!inited) {
1651
        inited = 1;
1652
        img_convert_init();
1653
    }
1654

    
1655
    dst_width = src_width;
1656
    dst_height = src_height;
1657

    
1658
    dst_pix = &pix_fmt_info[dst_pix_fmt];
1659
    src_pix = &pix_fmt_info[src_pix_fmt];
1660
    if (src_pix_fmt == dst_pix_fmt) {
1661
        /* no conversion needed: just copy */
1662
        img_copy(dst, src, dst_pix_fmt, dst_width, dst_height);
1663
        return 0;
1664
    }
1665

    
1666
    ce = &convert_table[src_pix_fmt][dst_pix_fmt];
1667
    if (ce->convert) {
1668
        /* specific convertion routine */
1669
        ce->convert(dst, src, dst_width, dst_height);
1670
        return 0;
1671
    }
1672

    
1673
    /* gray to YUV */
1674
    if (is_yuv_planar(dst_pix) &&
1675
        src_pix_fmt == PIX_FMT_GRAY8) {
1676
        int w, h, y;
1677
        uint8_t *d;
1678

    
1679
        if (dst_pix->color_type == FF_COLOR_YUV_JPEG) {
1680
            img_copy_plane(dst->data[0], dst->linesize[0],
1681
                     src->data[0], src->linesize[0],
1682
                     dst_width, dst_height);
1683
        } else {
1684
            img_apply_table(dst->data[0], dst->linesize[0],
1685
                            src->data[0], src->linesize[0],
1686
                            dst_width, dst_height,
1687
                            y_jpeg_to_ccir);
1688
        }
1689
        /* fill U and V with 128 */
1690
        w = dst_width;
1691
        h = dst_height;
1692
        w >>= dst_pix->x_chroma_shift;
1693
        h >>= dst_pix->y_chroma_shift;
1694
        for(i = 1; i <= 2; i++) {
1695
            d = dst->data[i];
1696
            for(y = 0; y< h; y++) {
1697
                memset(d, 128, w);
1698
                d += dst->linesize[i];
1699
            }
1700
        }
1701
        return 0;
1702
    }
1703

    
1704
    /* YUV to gray */
1705
    if (is_yuv_planar(src_pix) && 
1706
        dst_pix_fmt == PIX_FMT_GRAY8) {
1707
        if (src_pix->color_type == FF_COLOR_YUV_JPEG) {
1708
            img_copy_plane(dst->data[0], dst->linesize[0],
1709
                     src->data[0], src->linesize[0],
1710
                     dst_width, dst_height);
1711
        } else {
1712
            img_apply_table(dst->data[0], dst->linesize[0],
1713
                            src->data[0], src->linesize[0],
1714
                            dst_width, dst_height,
1715
                            y_ccir_to_jpeg);
1716
        }
1717
        return 0;
1718
    }
1719

    
1720
    /* YUV to YUV planar */
1721
    if (is_yuv_planar(dst_pix) && is_yuv_planar(src_pix)) {
1722
        int x_shift, y_shift, w, h, xy_shift;
1723
        void (*resize_func)(uint8_t *dst, int dst_wrap, 
1724
                            const uint8_t *src, int src_wrap,
1725
                            int width, int height);
1726

    
1727
        /* compute chroma size of the smallest dimensions */
1728
        w = dst_width;
1729
        h = dst_height;
1730
        if (dst_pix->x_chroma_shift >= src_pix->x_chroma_shift)
1731
            w >>= dst_pix->x_chroma_shift;
1732
        else
1733
            w >>= src_pix->x_chroma_shift;
1734
        if (dst_pix->y_chroma_shift >= src_pix->y_chroma_shift)
1735
            h >>= dst_pix->y_chroma_shift;
1736
        else
1737
            h >>= src_pix->y_chroma_shift;
1738

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

    
1783
        img_copy_plane(dst->data[0], dst->linesize[0],
1784
                       src->data[0], src->linesize[0],
1785
                       dst_width, dst_height);
1786

    
1787
        for(i = 1;i <= 2; i++)
1788
            resize_func(dst->data[i], dst->linesize[i],
1789
                        src->data[i], src->linesize[i],
1790
                        dst_width>>dst_pix->x_chroma_shift, dst_height>>dst_pix->y_chroma_shift);
1791
        /* if yuv color space conversion is needed, we do it here on
1792
           the destination image */
1793
        if (dst_pix->color_type != src_pix->color_type) {
1794
            const uint8_t *y_table, *c_table;
1795
            if (dst_pix->color_type == FF_COLOR_YUV) {
1796
                y_table = y_jpeg_to_ccir;
1797
                c_table = c_jpeg_to_ccir;
1798
            } else {
1799
                y_table = y_ccir_to_jpeg;
1800
                c_table = c_ccir_to_jpeg;
1801
            }
1802
            img_apply_table(dst->data[0], dst->linesize[0],
1803
                            dst->data[0], dst->linesize[0],
1804
                            dst_width, dst_height,
1805
                            y_table);
1806

    
1807
            for(i = 1;i <= 2; i++)
1808
                img_apply_table(dst->data[i], dst->linesize[i],
1809
                                dst->data[i], dst->linesize[i],
1810
                                dst_width>>dst_pix->x_chroma_shift, 
1811
                                dst_height>>dst_pix->y_chroma_shift,
1812
                                c_table);
1813
        }
1814
        return 0;
1815
    }
1816
 no_chroma_filter:
1817

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

    
1867
/* NOTE: we scan all the pixels to have an exact information */
1868
static int get_alpha_info_pal8(AVPicture *src, int width, int height)
1869
{
1870
    const unsigned char *p;
1871
    int src_wrap, ret, x, y;
1872
    unsigned int a;
1873
    uint32_t *palette = (uint32_t *)src->data[1];
1874
    
1875
    p = src->data[0];
1876
    src_wrap = src->linesize[0] - width;
1877
    ret = 0;
1878
    for(y=0;y<height;y++) {
1879
        for(x=0;x<width;x++) {
1880
            a = palette[p[0]] >> 24;
1881
            if (a == 0x00) {
1882
                ret |= FF_ALPHA_TRANSP;
1883
            } else if (a != 0xff) {
1884
                ret |= FF_ALPHA_SEMI_TRANSP;
1885
            }
1886
            p++;
1887
        }
1888
        p += src_wrap;
1889
    }
1890
    return ret;
1891
}
1892

    
1893
/**
1894
 * Tell if an image really has transparent alpha values.
1895
 * @return ored mask of FF_ALPHA_xxx constants
1896
 */
1897
int img_get_alpha_info(AVPicture *src, int pix_fmt, int width, int height)
1898
{
1899
    PixFmtInfo *pf = &pix_fmt_info[pix_fmt];
1900
    int ret;
1901

    
1902
    pf = &pix_fmt_info[pix_fmt];
1903
    /* no alpha can be represented in format */
1904
    if (!pf->is_alpha)
1905
        return 0;
1906
    switch(pix_fmt) {
1907
    case PIX_FMT_RGBA32:
1908
        ret = get_alpha_info_rgba32(src, width, height);
1909
        break;
1910
    case PIX_FMT_RGB555:
1911
        ret = get_alpha_info_rgb555(src, width, height);
1912
        break;
1913
    case PIX_FMT_PAL8:
1914
        ret = get_alpha_info_pal8(src, width, height);
1915
        break;
1916
    default:
1917
        /* we do not know, so everything is indicated */
1918
        ret = FF_ALPHA_TRANSP | FF_ALPHA_SEMI_TRANSP;
1919
        break;
1920
    }
1921
    return ret;
1922
}
1923

    
1924
#ifdef HAVE_MMX
1925
#define DEINT_INPLACE_LINE_LUM \
1926
                    movd_m2r(lum_m4[0],mm0);\
1927
                    movd_m2r(lum_m3[0],mm1);\
1928
                    movd_m2r(lum_m2[0],mm2);\
1929
                    movd_m2r(lum_m1[0],mm3);\
1930
                    movd_m2r(lum[0],mm4);\
1931
                    punpcklbw_r2r(mm7,mm0);\
1932
                    movd_r2m(mm2,lum_m4[0]);\
1933
                    punpcklbw_r2r(mm7,mm1);\
1934
                    punpcklbw_r2r(mm7,mm2);\
1935
                    punpcklbw_r2r(mm7,mm3);\
1936
                    punpcklbw_r2r(mm7,mm4);\
1937
                    paddw_r2r(mm3,mm1);\
1938
                    psllw_i2r(1,mm2);\
1939
                    paddw_r2r(mm4,mm0);\
1940
                    psllw_i2r(2,mm1);\
1941
                    paddw_r2r(mm6,mm2);\
1942
                    paddw_r2r(mm2,mm1);\
1943
                    psubusw_r2r(mm0,mm1);\
1944
                    psrlw_i2r(3,mm1);\
1945
                    packuswb_r2r(mm7,mm1);\
1946
                    movd_r2m(mm1,lum_m2[0]);
1947

    
1948
#define DEINT_LINE_LUM \
1949
                    movd_m2r(lum_m4[0],mm0);\
1950
                    movd_m2r(lum_m3[0],mm1);\
1951
                    movd_m2r(lum_m2[0],mm2);\
1952
                    movd_m2r(lum_m1[0],mm3);\
1953
                    movd_m2r(lum[0],mm4);\
1954
                    punpcklbw_r2r(mm7,mm0);\
1955
                    punpcklbw_r2r(mm7,mm1);\
1956
                    punpcklbw_r2r(mm7,mm2);\
1957
                    punpcklbw_r2r(mm7,mm3);\
1958
                    punpcklbw_r2r(mm7,mm4);\
1959
                    paddw_r2r(mm3,mm1);\
1960
                    psllw_i2r(1,mm2);\
1961
                    paddw_r2r(mm4,mm0);\
1962
                    psllw_i2r(2,mm1);\
1963
                    paddw_r2r(mm6,mm2);\
1964
                    paddw_r2r(mm2,mm1);\
1965
                    psubusw_r2r(mm0,mm1);\
1966
                    psrlw_i2r(3,mm1);\
1967
                    packuswb_r2r(mm7,mm1);\
1968
                    movd_r2m(mm1,dst[0]);
1969
#endif
1970

    
1971
/* filter parameters: [-1 4 2 4 -1] // 8 */
1972
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,
1973
                                int size)
1974
{
1975
#ifndef HAVE_MMX
1976
    uint8_t *cm = cropTbl + MAX_NEG_CROP;
1977
    int sum;
1978

    
1979
    for(;size > 0;size--) {
1980
        sum = -lum_m4[0];
1981
        sum += lum_m3[0] << 2;
1982
        sum += lum_m2[0] << 1;
1983
        sum += lum_m1[0] << 2;
1984
        sum += -lum[0];
1985
        dst[0] = cm[(sum + 4) >> 3];
1986
        lum_m4++;
1987
        lum_m3++;
1988
        lum_m2++;
1989
        lum_m1++;
1990
        lum++;
1991
        dst++;
1992
    }
1993
#else
1994

    
1995
    {
1996
        mmx_t rounder;
1997
        rounder.uw[0]=4;
1998
        rounder.uw[1]=4;
1999
        rounder.uw[2]=4;
2000
        rounder.uw[3]=4;
2001
        pxor_r2r(mm7,mm7);
2002
        movq_m2r(rounder,mm6);
2003
    }
2004
    for (;size > 3; size-=4) {
2005
        DEINT_LINE_LUM
2006
        lum_m4+=4;
2007
        lum_m3+=4;
2008
        lum_m2+=4;
2009
        lum_m1+=4;
2010
        lum+=4;
2011
        dst+=4;
2012
    }
2013
#endif
2014
}
2015
static void deinterlace_line_inplace(uint8_t *lum_m4, uint8_t *lum_m3, uint8_t *lum_m2, uint8_t *lum_m1, uint8_t *lum,
2016
                             int size)
2017
{
2018
#ifndef HAVE_MMX
2019
    uint8_t *cm = cropTbl + MAX_NEG_CROP;
2020
    int sum;
2021

    
2022
    for(;size > 0;size--) {
2023
        sum = -lum_m4[0];
2024
        sum += lum_m3[0] << 2;
2025
        sum += lum_m2[0] << 1;
2026
        lum_m4[0]=lum_m2[0];
2027
        sum += lum_m1[0] << 2;
2028
        sum += -lum[0];
2029
        lum_m2[0] = cm[(sum + 4) >> 3];
2030
        lum_m4++;
2031
        lum_m3++;
2032
        lum_m2++;
2033
        lum_m1++;
2034
        lum++;
2035
    }
2036
#else
2037

    
2038
    {
2039
        mmx_t rounder;
2040
        rounder.uw[0]=4;
2041
        rounder.uw[1]=4;
2042
        rounder.uw[2]=4;
2043
        rounder.uw[3]=4;
2044
        pxor_r2r(mm7,mm7);
2045
        movq_m2r(rounder,mm6);
2046
    }
2047
    for (;size > 3; size-=4) {
2048
        DEINT_INPLACE_LINE_LUM
2049
        lum_m4+=4;
2050
        lum_m3+=4;
2051
        lum_m2+=4;
2052
        lum_m1+=4;
2053
        lum+=4;
2054
    }
2055
#endif
2056
}
2057

    
2058
/* deinterlacing : 2 temporal taps, 3 spatial taps linear filter. The
2059
   top field is copied as is, but the bottom field is deinterlaced
2060
   against the top field. */
2061
static void deinterlace_bottom_field(uint8_t *dst, int dst_wrap,
2062
                                    uint8_t *src1, int src_wrap,
2063
                                    int width, int height)
2064
{
2065
    uint8_t *src_m2, *src_m1, *src_0, *src_p1, *src_p2;
2066
    int y;
2067

    
2068
    src_m2 = src1;
2069
    src_m1 = src1;
2070
    src_0=&src_m1[src_wrap];
2071
    src_p1=&src_0[src_wrap];
2072
    src_p2=&src_p1[src_wrap];
2073
    for(y=0;y<(height-2);y+=2) {
2074
        memcpy(dst,src_m1,width);
2075
        dst += dst_wrap;
2076
        deinterlace_line(dst,src_m2,src_m1,src_0,src_p1,src_p2,width);
2077
        src_m2 = src_0;
2078
        src_m1 = src_p1;
2079
        src_0 = src_p2;
2080
        src_p1 += 2*src_wrap;
2081
        src_p2 += 2*src_wrap;
2082
        dst += dst_wrap;
2083
    }
2084
    memcpy(dst,src_m1,width);
2085
    dst += dst_wrap;
2086
    /* do last line */
2087
    deinterlace_line(dst,src_m2,src_m1,src_0,src_0,src_0,width);
2088
}
2089

    
2090
static void deinterlace_bottom_field_inplace(uint8_t *src1, int src_wrap,
2091
                                     int width, int height)
2092
{
2093
    uint8_t *src_m1, *src_0, *src_p1, *src_p2;
2094
    int y;
2095
    uint8_t *buf;
2096
    buf = (uint8_t*)av_malloc(width);
2097

    
2098
    src_m1 = src1;
2099
    memcpy(buf,src_m1,width);
2100
    src_0=&src_m1[src_wrap];
2101
    src_p1=&src_0[src_wrap];
2102
    src_p2=&src_p1[src_wrap];
2103
    for(y=0;y<(height-2);y+=2) {
2104
        deinterlace_line_inplace(buf,src_m1,src_0,src_p1,src_p2,width);
2105
        src_m1 = src_p1;
2106
        src_0 = src_p2;
2107
        src_p1 += 2*src_wrap;
2108
        src_p2 += 2*src_wrap;
2109
    }
2110
    /* do last line */
2111
    deinterlace_line_inplace(buf,src_m1,src_0,src_0,src_0,width);
2112
    av_free(buf);
2113
}
2114

    
2115

    
2116
/* deinterlace - if not supported return -1 */
2117
int avpicture_deinterlace(AVPicture *dst, AVPicture *src,
2118
                          int pix_fmt, int width, int height)
2119
{
2120
    int i;
2121

    
2122
    if (pix_fmt != PIX_FMT_YUV420P &&
2123
        pix_fmt != PIX_FMT_YUV422P &&
2124
        pix_fmt != PIX_FMT_YUV444P)
2125
        return -1;
2126
    if ((width & 3) != 0 || (height & 3) != 0)
2127
        return -1;
2128

    
2129
    for(i=0;i<3;i++) {
2130
        if (i == 1) {
2131
            switch(pix_fmt) {
2132
            case PIX_FMT_YUV420P:
2133
                width >>= 1;
2134
                height >>= 1;
2135
                break;
2136
            case PIX_FMT_YUV422P:
2137
                width >>= 1;
2138
                break;
2139
            default:
2140
                break;
2141
            }
2142
        }
2143
        if (src == dst) {
2144
            deinterlace_bottom_field_inplace(src->data[i], src->linesize[i],
2145
                                 width, height);
2146
        } else {
2147
            deinterlace_bottom_field(dst->data[i],dst->linesize[i],
2148
                                        src->data[i], src->linesize[i],
2149
                                        width, height);
2150
        }
2151
    }
2152
#ifdef HAVE_MMX
2153
    emms();
2154
#endif
2155
    return 0;
2156
}
2157

    
2158
#undef FIX