Statistics
| Branch: | Revision:

ffmpeg / libavcodec / imgconvert.c @ 20d46c03

History | View | Annotate | Download (76.1 KB)

1
/*
2
 * Misc image convertion routines
3
 * Copyright (c) 2001, 2002, 2003 Fabrice Bellard.
4
 *
5
 * This file is part of FFmpeg.
6
 *
7
 * FFmpeg is free software; you can redistribute it and/or
8
 * modify it under the terms of the GNU Lesser General Public
9
 * License as published by the Free Software Foundation; either
10
 * version 2.1 of the License, or (at your option) any later version.
11
 *
12
 * FFmpeg is distributed in the hope that it will be useful,
13
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15
 * Lesser General Public License for more details.
16
 *
17
 * You should have received a copy of the GNU Lesser General Public
18
 * License along with FFmpeg; if not, write to the Free Software
19
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20
 */
21

    
22
/**
23
 * @file imgconvert.c
24
 * Misc image convertion routines.
25
 */
26

    
27
/* TODO:
28
 * - write 'ffimg' program to test all the image related stuff
29
 * - move all api to slice based system
30
 * - integrate deinterlacing, postprocessing and scaling in the conversion process
31
 */
32

    
33
#include "avcodec.h"
34
#include "dsputil.h"
35

    
36
#ifdef USE_FASTMEMCPY
37
#include "libvo/fastmemcpy.h"
38
#endif
39

    
40
#ifdef HAVE_MMX
41
#include "i386/mmx.h"
42
#endif
43

    
44
#define xglue(x, y) x ## y
45
#define glue(x, y) xglue(x, y)
46

    
47
#define FF_COLOR_RGB      0 /* RGB color space */
48
#define FF_COLOR_GRAY     1 /* gray color space */
49
#define FF_COLOR_YUV      2 /* YUV color space. 16 <= Y <= 235, 16 <= U, V <= 240 */
50
#define FF_COLOR_YUV_JPEG 3 /* YUV color space. 0 <= Y <= 255, 0 <= U, V <= 255 */
51

    
52
#define FF_PIXEL_PLANAR   0 /* each channel has one component in AVPicture */
53
#define FF_PIXEL_PACKED   1 /* only one components containing all the channels */
54
#define FF_PIXEL_PALETTE  2  /* one components containing indexes for a palette */
55

    
56
typedef struct PixFmtInfo {
57
    const char *name;
58
    uint8_t nb_channels;     /* number of channels (including alpha) */
59
    uint8_t color_type;      /* color type (see FF_COLOR_xxx constants) */
60
    uint8_t pixel_type;      /* pixel storage type (see FF_PIXEL_xxx constants) */
61
    uint8_t is_alpha : 1;    /* true if alpha can be specified */
62
    uint8_t x_chroma_shift;  /* X chroma subsampling factor is 2 ^ shift */
63
    uint8_t y_chroma_shift;  /* Y chroma subsampling factor is 2 ^ shift */
64
    uint8_t depth;           /* bit depth of the color components */
65
} PixFmtInfo;
66

    
67
/* this table gives more information about formats */
68
static const PixFmtInfo pix_fmt_info[PIX_FMT_NB] = {
69
    /* YUV formats */
70
    [PIX_FMT_YUV420P] = {
71
        .name = "yuv420p",
72
        .nb_channels = 3,
73
        .color_type = FF_COLOR_YUV,
74
        .pixel_type = FF_PIXEL_PLANAR,
75
        .depth = 8,
76
        .x_chroma_shift = 1, .y_chroma_shift = 1,
77
    },
78
    [PIX_FMT_YUV422P] = {
79
        .name = "yuv422p",
80
        .nb_channels = 3,
81
        .color_type = FF_COLOR_YUV,
82
        .pixel_type = FF_PIXEL_PLANAR,
83
        .depth = 8,
84
        .x_chroma_shift = 1, .y_chroma_shift = 0,
85
    },
86
    [PIX_FMT_YUV444P] = {
87
        .name = "yuv444p",
88
        .nb_channels = 3,
89
        .color_type = FF_COLOR_YUV,
90
        .pixel_type = FF_PIXEL_PLANAR,
91
        .depth = 8,
92
        .x_chroma_shift = 0, .y_chroma_shift = 0,
93
    },
94
    [PIX_FMT_YUV422] = {
95
        .name = "yuv422",
96
        .nb_channels = 1,
97
        .color_type = FF_COLOR_YUV,
98
        .pixel_type = FF_PIXEL_PACKED,
99
        .depth = 8,
100
        .x_chroma_shift = 1, .y_chroma_shift = 0,
101
    },
102
    [PIX_FMT_UYVY422] = {
103
        .name = "uyvy422",
104
        .nb_channels = 1,
105
        .color_type = FF_COLOR_YUV,
106
        .pixel_type = FF_PIXEL_PACKED,
107
        .depth = 8,
108
        .x_chroma_shift = 1, .y_chroma_shift = 0,
109
    },
110
    [PIX_FMT_YUV410P] = {
111
        .name = "yuv410p",
112
        .nb_channels = 3,
113
        .color_type = FF_COLOR_YUV,
114
        .pixel_type = FF_PIXEL_PLANAR,
115
        .depth = 8,
116
        .x_chroma_shift = 2, .y_chroma_shift = 2,
117
    },
118
    [PIX_FMT_YUV411P] = {
119
        .name = "yuv411p",
120
        .nb_channels = 3,
121
        .color_type = FF_COLOR_YUV,
122
        .pixel_type = FF_PIXEL_PLANAR,
123
        .depth = 8,
124
        .x_chroma_shift = 2, .y_chroma_shift = 0,
125
    },
126

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

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

    
195
    /* gray / mono formats */
196
    [PIX_FMT_GRAY16BE] = {
197
        .name = "gray16be",
198
        .nb_channels = 1,
199
        .color_type = FF_COLOR_GRAY,
200
        .pixel_type = FF_PIXEL_PLANAR,
201
        .depth = 16,
202
    },
203
    [PIX_FMT_GRAY16LE] = {
204
        .name = "gray16le",
205
        .nb_channels = 1,
206
        .color_type = FF_COLOR_GRAY,
207
        .pixel_type = FF_PIXEL_PLANAR,
208
        .depth = 16,
209
    },
210
    [PIX_FMT_GRAY8] = {
211
        .name = "gray",
212
        .nb_channels = 1,
213
        .color_type = FF_COLOR_GRAY,
214
        .pixel_type = FF_PIXEL_PLANAR,
215
        .depth = 8,
216
    },
217
    [PIX_FMT_MONOWHITE] = {
218
        .name = "monow",
219
        .nb_channels = 1,
220
        .color_type = FF_COLOR_GRAY,
221
        .pixel_type = FF_PIXEL_PLANAR,
222
        .depth = 1,
223
    },
224
    [PIX_FMT_MONOBLACK] = {
225
        .name = "monob",
226
        .nb_channels = 1,
227
        .color_type = FF_COLOR_GRAY,
228
        .pixel_type = FF_PIXEL_PLANAR,
229
        .depth = 1,
230
    },
231

    
232
    /* paletted formats */
233
    [PIX_FMT_PAL8] = {
234
        .name = "pal8",
235
        .nb_channels = 4, .is_alpha = 1,
236
        .color_type = FF_COLOR_RGB,
237
        .pixel_type = FF_PIXEL_PALETTE,
238
        .depth = 8,
239
    },
240
    [PIX_FMT_XVMC_MPEG2_MC] = {
241
        .name = "xvmcmc",
242
    },
243
    [PIX_FMT_XVMC_MPEG2_IDCT] = {
244
        .name = "xvmcidct",
245
    },
246
    [PIX_FMT_UYVY411] = {
247
        .name = "uyvy411",
248
        .nb_channels = 1,
249
        .color_type = FF_COLOR_YUV,
250
        .pixel_type = FF_PIXEL_PACKED,
251
        .depth = 8,
252
        .x_chroma_shift = 2, .y_chroma_shift = 0,
253
    },
254
    [PIX_FMT_BGR32] = {
255
        .name = "bgr32",
256
        .nb_channels = 4, .is_alpha = 1,
257
        .color_type = FF_COLOR_RGB,
258
        .pixel_type = FF_PIXEL_PACKED,
259
        .depth = 8,
260
        .x_chroma_shift = 0, .y_chroma_shift = 0,
261
    },
262
    [PIX_FMT_BGR565] = {
263
        .name = "bgr565",
264
        .nb_channels = 3,
265
        .color_type = FF_COLOR_RGB,
266
        .pixel_type = FF_PIXEL_PACKED,
267
        .depth = 5,
268
        .x_chroma_shift = 0, .y_chroma_shift = 0,
269
    },
270
    [PIX_FMT_BGR555] = {
271
        .name = "bgr555",
272
        .nb_channels = 3,
273
        .color_type = FF_COLOR_RGB,
274
        .pixel_type = FF_PIXEL_PACKED,
275
        .depth = 5,
276
        .x_chroma_shift = 0, .y_chroma_shift = 0,
277
    },
278
    [PIX_FMT_RGB8] = {
279
        .name = "rgb8",
280
        .nb_channels = 1,
281
        .color_type = FF_COLOR_RGB,
282
        .pixel_type = FF_PIXEL_PACKED,
283
        .depth = 8,
284
        .x_chroma_shift = 0, .y_chroma_shift = 0,
285
    },
286
    [PIX_FMT_RGB4] = {
287
        .name = "rgb4",
288
        .nb_channels = 1,
289
        .color_type = FF_COLOR_RGB,
290
        .pixel_type = FF_PIXEL_PACKED,
291
        .depth = 4,
292
        .x_chroma_shift = 0, .y_chroma_shift = 0,
293
    },
294
    [PIX_FMT_RGB4_BYTE] = {
295
        .name = "rgb4_byte",
296
        .nb_channels = 1,
297
        .color_type = FF_COLOR_RGB,
298
        .pixel_type = FF_PIXEL_PACKED,
299
        .depth = 8,
300
        .x_chroma_shift = 0, .y_chroma_shift = 0,
301
    },
302
    [PIX_FMT_BGR8] = {
303
        .name = "bgr8",
304
        .nb_channels = 1,
305
        .color_type = FF_COLOR_RGB,
306
        .pixel_type = FF_PIXEL_PACKED,
307
        .depth = 8,
308
        .x_chroma_shift = 0, .y_chroma_shift = 0,
309
    },
310
    [PIX_FMT_BGR4] = {
311
        .name = "bgr4",
312
        .nb_channels = 1,
313
        .color_type = FF_COLOR_RGB,
314
        .pixel_type = FF_PIXEL_PACKED,
315
        .depth = 4,
316
        .x_chroma_shift = 0, .y_chroma_shift = 0,
317
    },
318
    [PIX_FMT_BGR4_BYTE] = {
319
        .name = "bgr4_byte",
320
        .nb_channels = 1,
321
        .color_type = FF_COLOR_RGB,
322
        .pixel_type = FF_PIXEL_PACKED,
323
        .depth = 8,
324
        .x_chroma_shift = 0, .y_chroma_shift = 0,
325
    },
326
    [PIX_FMT_NV12] = {
327
        .name = "nv12",
328
        .nb_channels = 2,
329
        .color_type = FF_COLOR_YUV,
330
        .pixel_type = FF_PIXEL_PLANAR,
331
        .depth = 8,
332
        .x_chroma_shift = 1, .y_chroma_shift = 1,
333
    },
334
    [PIX_FMT_NV21] = {
335
        .name = "nv12",
336
        .nb_channels = 2,
337
        .color_type = FF_COLOR_YUV,
338
        .pixel_type = FF_PIXEL_PLANAR,
339
        .depth = 8,
340
        .x_chroma_shift = 1, .y_chroma_shift = 1,
341
    },
342

    
343
    [PIX_FMT_BGR32_1] = {
344
        .name = "bgr32_1",
345
        .nb_channels = 4, .is_alpha = 1,
346
        .color_type = FF_COLOR_RGB,
347
        .pixel_type = FF_PIXEL_PACKED,
348
        .depth = 8,
349
        .x_chroma_shift = 0, .y_chroma_shift = 0,
350
    },
351
    [PIX_FMT_RGB32_1] = {
352
        .name = "rgb32_1",
353
        .nb_channels = 4, .is_alpha = 1,
354
        .color_type = FF_COLOR_RGB,
355
        .pixel_type = FF_PIXEL_PACKED,
356
        .depth = 8,
357
        .x_chroma_shift = 0, .y_chroma_shift = 0,
358
    },
359
};
360

    
361
void avcodec_get_chroma_sub_sample(int pix_fmt, int *h_shift, int *v_shift)
362
{
363
    *h_shift = pix_fmt_info[pix_fmt].x_chroma_shift;
364
    *v_shift = pix_fmt_info[pix_fmt].y_chroma_shift;
365
}
366

    
367
const char *avcodec_get_pix_fmt_name(int pix_fmt)
368
{
369
    if (pix_fmt < 0 || pix_fmt >= PIX_FMT_NB)
370
        return "???";
371
    else
372
        return pix_fmt_info[pix_fmt].name;
373
}
374

    
375
enum PixelFormat avcodec_get_pix_fmt(const char* name)
376
{
377
    int i;
378

    
379
    for (i=0; i < PIX_FMT_NB; i++)
380
         if (!strcmp(pix_fmt_info[i].name, name))
381
             break;
382
    return i;
383
}
384

    
385
/* Picture field are filled with 'ptr' addresses. Also return size */
386
int avpicture_fill(AVPicture *picture, uint8_t *ptr,
387
                   int pix_fmt, int width, int height)
388
{
389
    int size, w2, h2, size2;
390
    const PixFmtInfo *pinfo;
391

    
392
    if(avcodec_check_dimensions(NULL, width, height))
393
        goto fail;
394

    
395
    pinfo = &pix_fmt_info[pix_fmt];
396
    size = width * height;
397
    switch(pix_fmt) {
398
    case PIX_FMT_YUV420P:
399
    case PIX_FMT_YUV422P:
400
    case PIX_FMT_YUV444P:
401
    case PIX_FMT_YUV410P:
402
    case PIX_FMT_YUV411P:
403
    case PIX_FMT_YUVJ420P:
404
    case PIX_FMT_YUVJ422P:
405
    case PIX_FMT_YUVJ444P:
406
        w2 = (width + (1 << pinfo->x_chroma_shift) - 1) >> pinfo->x_chroma_shift;
407
        h2 = (height + (1 << pinfo->y_chroma_shift) - 1) >> pinfo->y_chroma_shift;
408
        size2 = w2 * h2;
409
        picture->data[0] = ptr;
410
        picture->data[1] = picture->data[0] + size;
411
        picture->data[2] = picture->data[1] + size2;
412
        picture->linesize[0] = width;
413
        picture->linesize[1] = w2;
414
        picture->linesize[2] = w2;
415
        return size + 2 * size2;
416
    case PIX_FMT_NV12:
417
    case PIX_FMT_NV21:
418
        w2 = (width + (1 << pinfo->x_chroma_shift) - 1) >> pinfo->x_chroma_shift;
419
        h2 = (height + (1 << pinfo->y_chroma_shift) - 1) >> pinfo->y_chroma_shift;
420
        size2 = w2 * h2 * 2;
421
        picture->data[0] = ptr;
422
        picture->data[1] = picture->data[0] + size;
423
        picture->data[2] = NULL;
424
        picture->linesize[0] = width;
425
        picture->linesize[1] = w2;
426
        picture->linesize[2] = 0;
427
        return size + 2 * size2;
428
    case PIX_FMT_RGB24:
429
    case PIX_FMT_BGR24:
430
        picture->data[0] = ptr;
431
        picture->data[1] = NULL;
432
        picture->data[2] = NULL;
433
        picture->linesize[0] = width * 3;
434
        return size * 3;
435
    case PIX_FMT_RGBA32:
436
    case PIX_FMT_BGR32:
437
    case PIX_FMT_RGB32_1:
438
    case PIX_FMT_BGR32_1:
439
        picture->data[0] = ptr;
440
        picture->data[1] = NULL;
441
        picture->data[2] = NULL;
442
        picture->linesize[0] = width * 4;
443
        return size * 4;
444
    case PIX_FMT_GRAY16BE:
445
    case PIX_FMT_GRAY16LE:
446
    case PIX_FMT_BGR555:
447
    case PIX_FMT_BGR565:
448
    case PIX_FMT_RGB555:
449
    case PIX_FMT_RGB565:
450
    case PIX_FMT_YUV422:
451
        picture->data[0] = ptr;
452
        picture->data[1] = NULL;
453
        picture->data[2] = NULL;
454
        picture->linesize[0] = width * 2;
455
        return size * 2;
456
    case PIX_FMT_UYVY422:
457
        picture->data[0] = ptr;
458
        picture->data[1] = NULL;
459
        picture->data[2] = NULL;
460
        picture->linesize[0] = width * 2;
461
        return size * 2;
462
    case PIX_FMT_UYVY411:
463
        picture->data[0] = ptr;
464
        picture->data[1] = NULL;
465
        picture->data[2] = NULL;
466
        picture->linesize[0] = width + width/2;
467
        return size + size/2;
468
    case PIX_FMT_RGB8:
469
    case PIX_FMT_BGR8:
470
    case PIX_FMT_RGB4_BYTE:
471
    case PIX_FMT_BGR4_BYTE:
472
    case PIX_FMT_GRAY8:
473
        picture->data[0] = ptr;
474
        picture->data[1] = NULL;
475
        picture->data[2] = NULL;
476
        picture->linesize[0] = width;
477
        return size;
478
    case PIX_FMT_RGB4:
479
    case PIX_FMT_BGR4:
480
        picture->data[0] = ptr;
481
        picture->data[1] = NULL;
482
        picture->data[2] = NULL;
483
        picture->linesize[0] = width / 2;
484
        return size / 2;
485
    case PIX_FMT_MONOWHITE:
486
    case PIX_FMT_MONOBLACK:
487
        picture->data[0] = ptr;
488
        picture->data[1] = NULL;
489
        picture->data[2] = NULL;
490
        picture->linesize[0] = (width + 7) >> 3;
491
        return picture->linesize[0] * height;
492
    case PIX_FMT_PAL8:
493
        size2 = (size + 3) & ~3;
494
        picture->data[0] = ptr;
495
        picture->data[1] = ptr + size2; /* palette is stored here as 256 32 bit words */
496
        picture->data[2] = NULL;
497
        picture->linesize[0] = width;
498
        picture->linesize[1] = 4;
499
        return size2 + 256 * 4;
500
    default:
501
fail:
502
        picture->data[0] = NULL;
503
        picture->data[1] = NULL;
504
        picture->data[2] = NULL;
505
        picture->data[3] = NULL;
506
        return -1;
507
    }
508
}
509

    
510
int avpicture_layout(const AVPicture* src, int pix_fmt, int width, int height,
511
                     unsigned char *dest, int dest_size)
512
{
513
    const PixFmtInfo* pf = &pix_fmt_info[pix_fmt];
514
    int i, j, w, h, data_planes;
515
    const unsigned char* s;
516
    int size = avpicture_get_size(pix_fmt, width, height);
517

    
518
    if (size > dest_size || size < 0)
519
        return -1;
520

    
521
    if (pf->pixel_type == FF_PIXEL_PACKED || pf->pixel_type == FF_PIXEL_PALETTE) {
522
        if (pix_fmt == PIX_FMT_YUV422 ||
523
            pix_fmt == PIX_FMT_UYVY422 ||
524
            pix_fmt == PIX_FMT_BGR565 ||
525
            pix_fmt == PIX_FMT_BGR555 ||
526
            pix_fmt == PIX_FMT_RGB565 ||
527
            pix_fmt == PIX_FMT_RGB555)
528
            w = width * 2;
529
        else if (pix_fmt == PIX_FMT_UYVY411)
530
          w = width + width/2;
531
        else if (pix_fmt == PIX_FMT_PAL8)
532
          w = width;
533
        else
534
          w = width * (pf->depth * pf->nb_channels / 8);
535

    
536
        data_planes = 1;
537
        h = height;
538
    } else {
539
        data_planes = pf->nb_channels;
540
        w = (width*pf->depth + 7)/8;
541
        h = height;
542
    }
543

    
544
    for (i=0; i<data_planes; i++) {
545
         if (i == 1) {
546
             w = width >> pf->x_chroma_shift;
547
             h = height >> pf->y_chroma_shift;
548
         }
549
         s = src->data[i];
550
         for(j=0; j<h; j++) {
551
             memcpy(dest, s, w);
552
             dest += w;
553
             s += src->linesize[i];
554
         }
555
    }
556

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

    
560
    return size;
561
}
562

    
563
int avpicture_get_size(int pix_fmt, int width, int height)
564
{
565
    AVPicture dummy_pict;
566
    return avpicture_fill(&dummy_pict, NULL, pix_fmt, width, height);
567
}
568

    
569
/**
570
 * compute the loss when converting from a pixel format to another
571
 */
572
int avcodec_get_pix_fmt_loss(int dst_pix_fmt, int src_pix_fmt,
573
                             int has_alpha)
574
{
575
    const PixFmtInfo *pf, *ps;
576
    int loss;
577

    
578
    ps = &pix_fmt_info[src_pix_fmt];
579
    pf = &pix_fmt_info[dst_pix_fmt];
580

    
581
    /* compute loss */
582
    loss = 0;
583
    pf = &pix_fmt_info[dst_pix_fmt];
584
    if (pf->depth < ps->depth ||
585
        (dst_pix_fmt == PIX_FMT_RGB555 && src_pix_fmt == PIX_FMT_RGB565))
586
        loss |= FF_LOSS_DEPTH;
587
    if (pf->x_chroma_shift > ps->x_chroma_shift ||
588
        pf->y_chroma_shift > ps->y_chroma_shift)
589
        loss |= FF_LOSS_RESOLUTION;
590
    switch(pf->color_type) {
591
    case FF_COLOR_RGB:
592
        if (ps->color_type != FF_COLOR_RGB &&
593
            ps->color_type != FF_COLOR_GRAY)
594
            loss |= FF_LOSS_COLORSPACE;
595
        break;
596
    case FF_COLOR_GRAY:
597
        if (ps->color_type != FF_COLOR_GRAY)
598
            loss |= FF_LOSS_COLORSPACE;
599
        break;
600
    case FF_COLOR_YUV:
601
        if (ps->color_type != FF_COLOR_YUV)
602
            loss |= FF_LOSS_COLORSPACE;
603
        break;
604
    case FF_COLOR_YUV_JPEG:
605
        if (ps->color_type != FF_COLOR_YUV_JPEG &&
606
            ps->color_type != FF_COLOR_YUV &&
607
            ps->color_type != FF_COLOR_GRAY)
608
            loss |= FF_LOSS_COLORSPACE;
609
        break;
610
    default:
611
        /* fail safe test */
612
        if (ps->color_type != pf->color_type)
613
            loss |= FF_LOSS_COLORSPACE;
614
        break;
615
    }
616
    if (pf->color_type == FF_COLOR_GRAY &&
617
        ps->color_type != FF_COLOR_GRAY)
618
        loss |= FF_LOSS_CHROMA;
619
    if (!pf->is_alpha && (ps->is_alpha && has_alpha))
620
        loss |= FF_LOSS_ALPHA;
621
    if (pf->pixel_type == FF_PIXEL_PALETTE &&
622
        (ps->pixel_type != FF_PIXEL_PALETTE && ps->color_type != FF_COLOR_GRAY))
623
        loss |= FF_LOSS_COLORQUANT;
624
    return loss;
625
}
626

    
627
static int avg_bits_per_pixel(int pix_fmt)
628
{
629
    int bits;
630
    const PixFmtInfo *pf;
631

    
632
    pf = &pix_fmt_info[pix_fmt];
633
    switch(pf->pixel_type) {
634
    case FF_PIXEL_PACKED:
635
        switch(pix_fmt) {
636
        case PIX_FMT_YUV422:
637
        case PIX_FMT_UYVY422:
638
        case PIX_FMT_RGB565:
639
        case PIX_FMT_RGB555:
640
        case PIX_FMT_BGR565:
641
        case PIX_FMT_BGR555:
642
            bits = 16;
643
            break;
644
        case PIX_FMT_UYVY411:
645
            bits = 12;
646
            break;
647
        default:
648
            bits = pf->depth * pf->nb_channels;
649
            break;
650
        }
651
        break;
652
    case FF_PIXEL_PLANAR:
653
        if (pf->x_chroma_shift == 0 && pf->y_chroma_shift == 0) {
654
            bits = pf->depth * pf->nb_channels;
655
        } else {
656
            bits = pf->depth + ((2 * pf->depth) >>
657
                                (pf->x_chroma_shift + pf->y_chroma_shift));
658
        }
659
        break;
660
    case FF_PIXEL_PALETTE:
661
        bits = 8;
662
        break;
663
    default:
664
        bits = -1;
665
        break;
666
    }
667
    return bits;
668
}
669

    
670
static int avcodec_find_best_pix_fmt1(int pix_fmt_mask,
671
                                      int src_pix_fmt,
672
                                      int has_alpha,
673
                                      int loss_mask)
674
{
675
    int dist, i, loss, min_dist, dst_pix_fmt;
676

    
677
    /* find exact color match with smallest size */
678
    dst_pix_fmt = -1;
679
    min_dist = 0x7fffffff;
680
    for(i = 0;i < PIX_FMT_NB; i++) {
681
        if (pix_fmt_mask & (1 << i)) {
682
            loss = avcodec_get_pix_fmt_loss(i, src_pix_fmt, has_alpha) & loss_mask;
683
            if (loss == 0) {
684
                dist = avg_bits_per_pixel(i);
685
                if (dist < min_dist) {
686
                    min_dist = dist;
687
                    dst_pix_fmt = i;
688
                }
689
            }
690
        }
691
    }
692
    return dst_pix_fmt;
693
}
694

    
695
/**
696
 * find best pixel format to convert to. Return -1 if none found
697
 */
698
int avcodec_find_best_pix_fmt(int pix_fmt_mask, int src_pix_fmt,
699
                              int has_alpha, int *loss_ptr)
700
{
701
    int dst_pix_fmt, loss_mask, i;
702
    static const int loss_mask_order[] = {
703
        ~0, /* no loss first */
704
        ~FF_LOSS_ALPHA,
705
        ~FF_LOSS_RESOLUTION,
706
        ~(FF_LOSS_COLORSPACE | FF_LOSS_RESOLUTION),
707
        ~FF_LOSS_COLORQUANT,
708
        ~FF_LOSS_DEPTH,
709
        0,
710
    };
711

    
712
    /* try with successive loss */
713
    i = 0;
714
    for(;;) {
715
        loss_mask = loss_mask_order[i++];
716
        dst_pix_fmt = avcodec_find_best_pix_fmt1(pix_fmt_mask, src_pix_fmt,
717
                                                 has_alpha, loss_mask);
718
        if (dst_pix_fmt >= 0)
719
            goto found;
720
        if (loss_mask == 0)
721
            break;
722
    }
723
    return -1;
724
 found:
725
    if (loss_ptr)
726
        *loss_ptr = avcodec_get_pix_fmt_loss(dst_pix_fmt, src_pix_fmt, has_alpha);
727
    return dst_pix_fmt;
728
}
729

    
730
void ff_img_copy_plane(uint8_t *dst, int dst_wrap,
731
                           const uint8_t *src, int src_wrap,
732
                           int width, int height)
733
{
734
    if((!dst) || (!src))
735
        return;
736
    for(;height > 0; height--) {
737
        memcpy(dst, src, width);
738
        dst += dst_wrap;
739
        src += src_wrap;
740
    }
741
}
742

    
743
/**
744
 * Copy image 'src' to 'dst'.
745
 */
746
void img_copy(AVPicture *dst, const AVPicture *src,
747
              int pix_fmt, int width, int height)
748
{
749
    int bwidth, bits, i;
750
    const PixFmtInfo *pf = &pix_fmt_info[pix_fmt];
751

    
752
    pf = &pix_fmt_info[pix_fmt];
753
    switch(pf->pixel_type) {
754
    case FF_PIXEL_PACKED:
755
        switch(pix_fmt) {
756
        case PIX_FMT_YUV422:
757
        case PIX_FMT_UYVY422:
758
        case PIX_FMT_RGB565:
759
        case PIX_FMT_RGB555:
760
        case PIX_FMT_BGR565:
761
        case PIX_FMT_BGR555:
762
            bits = 16;
763
            break;
764
        case PIX_FMT_UYVY411:
765
            bits = 12;
766
            break;
767
        default:
768
            bits = pf->depth * pf->nb_channels;
769
            break;
770
        }
771
        bwidth = (width * bits + 7) >> 3;
772
        ff_img_copy_plane(dst->data[0], dst->linesize[0],
773
                       src->data[0], src->linesize[0],
774
                       bwidth, height);
775
        break;
776
    case FF_PIXEL_PLANAR:
777
        for(i = 0; i < pf->nb_channels; i++) {
778
            int w, h;
779
            w = width;
780
            h = height;
781
            if (i == 1 || i == 2) {
782
                w >>= pf->x_chroma_shift;
783
                h >>= pf->y_chroma_shift;
784
            }
785
            bwidth = (w * pf->depth + 7) >> 3;
786
            ff_img_copy_plane(dst->data[i], dst->linesize[i],
787
                           src->data[i], src->linesize[i],
788
                           bwidth, h);
789
        }
790
        break;
791
    case FF_PIXEL_PALETTE:
792
        ff_img_copy_plane(dst->data[0], dst->linesize[0],
793
                       src->data[0], src->linesize[0],
794
                       width, height);
795
        /* copy the palette */
796
        ff_img_copy_plane(dst->data[1], dst->linesize[1],
797
                       src->data[1], src->linesize[1],
798
                       4, 256);
799
        break;
800
    }
801
}
802

    
803
/* XXX: totally non optimized */
804

    
805
static void yuv422_to_yuv420p(AVPicture *dst, const AVPicture *src,
806
                              int width, int height)
807
{
808
    const uint8_t *p, *p1;
809
    uint8_t *lum, *cr, *cb, *lum1, *cr1, *cb1;
810
    int w;
811

    
812
    p1 = src->data[0];
813
    lum1 = dst->data[0];
814
    cb1 = dst->data[1];
815
    cr1 = dst->data[2];
816

    
817
    for(;height >= 1; height -= 2) {
818
        p = p1;
819
        lum = lum1;
820
        cb = cb1;
821
        cr = cr1;
822
        for(w = width; w >= 2; w -= 2) {
823
            lum[0] = p[0];
824
            cb[0] = p[1];
825
            lum[1] = p[2];
826
            cr[0] = p[3];
827
            p += 4;
828
            lum += 2;
829
            cb++;
830
            cr++;
831
        }
832
        if (w) {
833
            lum[0] = p[0];
834
            cb[0] = p[1];
835
            cr[0] = p[3];
836
            cb++;
837
            cr++;
838
        }
839
        p1 += src->linesize[0];
840
        lum1 += dst->linesize[0];
841
        if (height>1) {
842
            p = p1;
843
            lum = lum1;
844
            for(w = width; w >= 2; w -= 2) {
845
                lum[0] = p[0];
846
                lum[1] = p[2];
847
                p += 4;
848
                lum += 2;
849
            }
850
            if (w) {
851
                lum[0] = p[0];
852
            }
853
            p1 += src->linesize[0];
854
            lum1 += dst->linesize[0];
855
        }
856
        cb1 += dst->linesize[1];
857
        cr1 += dst->linesize[2];
858
    }
859
}
860

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

    
868
    p1 = src->data[0];
869

    
870
    lum1 = dst->data[0];
871
    cb1 = dst->data[1];
872
    cr1 = dst->data[2];
873

    
874
    for(;height >= 1; height -= 2) {
875
        p = p1;
876
        lum = lum1;
877
        cb = cb1;
878
        cr = cr1;
879
        for(w = width; w >= 2; w -= 2) {
880
            lum[0] = p[1];
881
            cb[0] = p[0];
882
            lum[1] = p[3];
883
            cr[0] = p[2];
884
            p += 4;
885
            lum += 2;
886
            cb++;
887
            cr++;
888
        }
889
        if (w) {
890
            lum[0] = p[1];
891
            cb[0] = p[0];
892
            cr[0] = p[2];
893
            cb++;
894
            cr++;
895
        }
896
        p1 += src->linesize[0];
897
        lum1 += dst->linesize[0];
898
        if (height>1) {
899
            p = p1;
900
            lum = lum1;
901
            for(w = width; w >= 2; w -= 2) {
902
                lum[0] = p[1];
903
                lum[1] = p[3];
904
                p += 4;
905
                lum += 2;
906
            }
907
            if (w) {
908
                lum[0] = p[1];
909
            }
910
            p1 += src->linesize[0];
911
            lum1 += dst->linesize[0];
912
        }
913
        cb1 += dst->linesize[1];
914
        cr1 += dst->linesize[2];
915
    }
916
}
917

    
918

    
919
static void uyvy422_to_yuv422p(AVPicture *dst, const AVPicture *src,
920
                              int width, int height)
921
{
922
    const uint8_t *p, *p1;
923
    uint8_t *lum, *cr, *cb, *lum1, *cr1, *cb1;
924
    int w;
925

    
926
    p1 = src->data[0];
927
    lum1 = dst->data[0];
928
    cb1 = dst->data[1];
929
    cr1 = dst->data[2];
930
    for(;height > 0; height--) {
931
        p = p1;
932
        lum = lum1;
933
        cb = cb1;
934
        cr = cr1;
935
        for(w = width; w >= 2; w -= 2) {
936
            lum[0] = p[1];
937
            cb[0] = p[0];
938
            lum[1] = p[3];
939
            cr[0] = p[2];
940
            p += 4;
941
            lum += 2;
942
            cb++;
943
            cr++;
944
        }
945
        p1 += src->linesize[0];
946
        lum1 += dst->linesize[0];
947
        cb1 += dst->linesize[1];
948
        cr1 += dst->linesize[2];
949
    }
950
}
951

    
952

    
953
static void yuv422_to_yuv422p(AVPicture *dst, const AVPicture *src,
954
                              int width, int height)
955
{
956
    const uint8_t *p, *p1;
957
    uint8_t *lum, *cr, *cb, *lum1, *cr1, *cb1;
958
    int w;
959

    
960
    p1 = src->data[0];
961
    lum1 = dst->data[0];
962
    cb1 = dst->data[1];
963
    cr1 = dst->data[2];
964
    for(;height > 0; height--) {
965
        p = p1;
966
        lum = lum1;
967
        cb = cb1;
968
        cr = cr1;
969
        for(w = width; w >= 2; w -= 2) {
970
            lum[0] = p[0];
971
            cb[0] = p[1];
972
            lum[1] = p[2];
973
            cr[0] = p[3];
974
            p += 4;
975
            lum += 2;
976
            cb++;
977
            cr++;
978
        }
979
        p1 += src->linesize[0];
980
        lum1 += dst->linesize[0];
981
        cb1 += dst->linesize[1];
982
        cr1 += dst->linesize[2];
983
    }
984
}
985

    
986
static void yuv422p_to_yuv422(AVPicture *dst, const AVPicture *src,
987
                              int width, int height)
988
{
989
    uint8_t *p, *p1;
990
    const uint8_t *lum, *cr, *cb, *lum1, *cr1, *cb1;
991
    int w;
992

    
993
    p1 = dst->data[0];
994
    lum1 = src->data[0];
995
    cb1 = src->data[1];
996
    cr1 = src->data[2];
997
    for(;height > 0; height--) {
998
        p = p1;
999
        lum = lum1;
1000
        cb = cb1;
1001
        cr = cr1;
1002
        for(w = width; w >= 2; w -= 2) {
1003
            p[0] = lum[0];
1004
            p[1] = cb[0];
1005
            p[2] = lum[1];
1006
            p[3] = cr[0];
1007
            p += 4;
1008
            lum += 2;
1009
            cb++;
1010
            cr++;
1011
        }
1012
        p1 += dst->linesize[0];
1013
        lum1 += src->linesize[0];
1014
        cb1 += src->linesize[1];
1015
        cr1 += src->linesize[2];
1016
    }
1017
}
1018

    
1019
static void yuv422p_to_uyvy422(AVPicture *dst, const AVPicture *src,
1020
                              int width, int height)
1021
{
1022
    uint8_t *p, *p1;
1023
    const uint8_t *lum, *cr, *cb, *lum1, *cr1, *cb1;
1024
    int w;
1025

    
1026
    p1 = dst->data[0];
1027
    lum1 = src->data[0];
1028
    cb1 = src->data[1];
1029
    cr1 = src->data[2];
1030
    for(;height > 0; height--) {
1031
        p = p1;
1032
        lum = lum1;
1033
        cb = cb1;
1034
        cr = cr1;
1035
        for(w = width; w >= 2; w -= 2) {
1036
            p[1] = lum[0];
1037
            p[0] = cb[0];
1038
            p[3] = lum[1];
1039
            p[2] = cr[0];
1040
            p += 4;
1041
            lum += 2;
1042
            cb++;
1043
            cr++;
1044
        }
1045
        p1 += dst->linesize[0];
1046
        lum1 += src->linesize[0];
1047
        cb1 += src->linesize[1];
1048
        cr1 += src->linesize[2];
1049
    }
1050
}
1051

    
1052
static void uyvy411_to_yuv411p(AVPicture *dst, const AVPicture *src,
1053
                              int width, int height)
1054
{
1055
    const uint8_t *p, *p1;
1056
    uint8_t *lum, *cr, *cb, *lum1, *cr1, *cb1;
1057
    int w;
1058

    
1059
    p1 = src->data[0];
1060
    lum1 = dst->data[0];
1061
    cb1 = dst->data[1];
1062
    cr1 = dst->data[2];
1063
    for(;height > 0; height--) {
1064
        p = p1;
1065
        lum = lum1;
1066
        cb = cb1;
1067
        cr = cr1;
1068
        for(w = width; w >= 4; w -= 4) {
1069
            cb[0] = p[0];
1070
            lum[0] = p[1];
1071
            lum[1] = p[2];
1072
            cr[0] = p[3];
1073
            lum[2] = p[4];
1074
            lum[3] = p[5];
1075
            p += 6;
1076
            lum += 4;
1077
            cb++;
1078
            cr++;
1079
        }
1080
        p1 += src->linesize[0];
1081
        lum1 += dst->linesize[0];
1082
        cb1 += dst->linesize[1];
1083
        cr1 += dst->linesize[2];
1084
    }
1085
}
1086

    
1087

    
1088
static void yuv420p_to_yuv422(AVPicture *dst, const AVPicture *src,
1089
                              int width, int height)
1090
{
1091
    int w, h;
1092
    uint8_t *line1, *line2, *linesrc = dst->data[0];
1093
    uint8_t *lum1, *lum2, *lumsrc = src->data[0];
1094
    uint8_t *cb1, *cb2 = src->data[1];
1095
    uint8_t *cr1, *cr2 = src->data[2];
1096

    
1097
    for(h = height / 2; h--;) {
1098
        line1 = linesrc;
1099
        line2 = linesrc + dst->linesize[0];
1100

    
1101
        lum1 = lumsrc;
1102
        lum2 = lumsrc + src->linesize[0];
1103

    
1104
        cb1 = cb2;
1105
        cr1 = cr2;
1106

    
1107
        for(w = width / 2; w--;) {
1108
                *line1++ = *lum1++; *line2++ = *lum2++;
1109
                *line1++ =          *line2++ = *cb1++;
1110
                *line1++ = *lum1++; *line2++ = *lum2++;
1111
                *line1++ =          *line2++ = *cr1++;
1112
        }
1113

    
1114
        linesrc += dst->linesize[0] * 2;
1115
        lumsrc += src->linesize[0] * 2;
1116
        cb2 += src->linesize[1];
1117
        cr2 += src->linesize[2];
1118
    }
1119
}
1120

    
1121
static void yuv420p_to_uyvy422(AVPicture *dst, const AVPicture *src,
1122
                              int width, int height)
1123
{
1124
    int w, h;
1125
    uint8_t *line1, *line2, *linesrc = dst->data[0];
1126
    uint8_t *lum1, *lum2, *lumsrc = src->data[0];
1127
    uint8_t *cb1, *cb2 = src->data[1];
1128
    uint8_t *cr1, *cr2 = src->data[2];
1129

    
1130
    for(h = height / 2; h--;) {
1131
        line1 = linesrc;
1132
        line2 = linesrc + dst->linesize[0];
1133

    
1134
        lum1 = lumsrc;
1135
        lum2 = lumsrc + src->linesize[0];
1136

    
1137
        cb1 = cb2;
1138
        cr1 = cr2;
1139

    
1140
        for(w = width / 2; w--;) {
1141
                *line1++ =          *line2++ = *cb1++;
1142
                *line1++ = *lum1++; *line2++ = *lum2++;
1143
                *line1++ =          *line2++ = *cr1++;
1144
                *line1++ = *lum1++; *line2++ = *lum2++;
1145
        }
1146

    
1147
        linesrc += dst->linesize[0] * 2;
1148
        lumsrc += src->linesize[0] * 2;
1149
        cb2 += src->linesize[1];
1150
        cr2 += src->linesize[2];
1151
    }
1152
}
1153

    
1154
#define SCALEBITS 10
1155
#define ONE_HALF  (1 << (SCALEBITS - 1))
1156
#define FIX(x)    ((int) ((x) * (1<<SCALEBITS) + 0.5))
1157

    
1158
#define YUV_TO_RGB1_CCIR(cb1, cr1)\
1159
{\
1160
    cb = (cb1) - 128;\
1161
    cr = (cr1) - 128;\
1162
    r_add = FIX(1.40200*255.0/224.0) * cr + ONE_HALF;\
1163
    g_add = - FIX(0.34414*255.0/224.0) * cb - FIX(0.71414*255.0/224.0) * cr + \
1164
            ONE_HALF;\
1165
    b_add = FIX(1.77200*255.0/224.0) * cb + ONE_HALF;\
1166
}
1167

    
1168
#define YUV_TO_RGB2_CCIR(r, g, b, y1)\
1169
{\
1170
    y = ((y1) - 16) * FIX(255.0/219.0);\
1171
    r = cm[(y + r_add) >> SCALEBITS];\
1172
    g = cm[(y + g_add) >> SCALEBITS];\
1173
    b = cm[(y + b_add) >> SCALEBITS];\
1174
}
1175

    
1176
#define YUV_TO_RGB1(cb1, cr1)\
1177
{\
1178
    cb = (cb1) - 128;\
1179
    cr = (cr1) - 128;\
1180
    r_add = FIX(1.40200) * cr + ONE_HALF;\
1181
    g_add = - FIX(0.34414) * cb - FIX(0.71414) * cr + ONE_HALF;\
1182
    b_add = FIX(1.77200) * cb + ONE_HALF;\
1183
}
1184

    
1185
#define YUV_TO_RGB2(r, g, b, y1)\
1186
{\
1187
    y = (y1) << SCALEBITS;\
1188
    r = cm[(y + r_add) >> SCALEBITS];\
1189
    g = cm[(y + g_add) >> SCALEBITS];\
1190
    b = cm[(y + b_add) >> SCALEBITS];\
1191
}
1192

    
1193
#define Y_CCIR_TO_JPEG(y)\
1194
 cm[((y) * FIX(255.0/219.0) + (ONE_HALF - 16 * FIX(255.0/219.0))) >> SCALEBITS]
1195

    
1196
#define Y_JPEG_TO_CCIR(y)\
1197
 (((y) * FIX(219.0/255.0) + (ONE_HALF + (16 << SCALEBITS))) >> SCALEBITS)
1198

    
1199
#define C_CCIR_TO_JPEG(y)\
1200
 cm[(((y) - 128) * FIX(127.0/112.0) + (ONE_HALF + (128 << SCALEBITS))) >> SCALEBITS]
1201

    
1202
/* NOTE: the clamp is really necessary! */
1203
static inline int C_JPEG_TO_CCIR(int y) {
1204
    y = (((y - 128) * FIX(112.0/127.0) + (ONE_HALF + (128 << SCALEBITS))) >> SCALEBITS);
1205
    if (y < 16)
1206
        y = 16;
1207
    return y;
1208
}
1209

    
1210

    
1211
#define RGB_TO_Y(r, g, b) \
1212
((FIX(0.29900) * (r) + FIX(0.58700) * (g) + \
1213
  FIX(0.11400) * (b) + ONE_HALF) >> SCALEBITS)
1214

    
1215
#define RGB_TO_U(r1, g1, b1, shift)\
1216
(((- FIX(0.16874) * r1 - FIX(0.33126) * g1 +         \
1217
     FIX(0.50000) * b1 + (ONE_HALF << shift) - 1) >> (SCALEBITS + shift)) + 128)
1218

    
1219
#define RGB_TO_V(r1, g1, b1, shift)\
1220
(((FIX(0.50000) * r1 - FIX(0.41869) * g1 -           \
1221
   FIX(0.08131) * b1 + (ONE_HALF << shift) - 1) >> (SCALEBITS + shift)) + 128)
1222

    
1223
#define RGB_TO_Y_CCIR(r, g, b) \
1224
((FIX(0.29900*219.0/255.0) * (r) + FIX(0.58700*219.0/255.0) * (g) + \
1225
  FIX(0.11400*219.0/255.0) * (b) + (ONE_HALF + (16 << SCALEBITS))) >> SCALEBITS)
1226

    
1227
#define RGB_TO_U_CCIR(r1, g1, b1, shift)\
1228
(((- FIX(0.16874*224.0/255.0) * r1 - FIX(0.33126*224.0/255.0) * g1 +         \
1229
     FIX(0.50000*224.0/255.0) * b1 + (ONE_HALF << shift) - 1) >> (SCALEBITS + shift)) + 128)
1230

    
1231
#define RGB_TO_V_CCIR(r1, g1, b1, shift)\
1232
(((FIX(0.50000*224.0/255.0) * r1 - FIX(0.41869*224.0/255.0) * g1 -           \
1233
   FIX(0.08131*224.0/255.0) * b1 + (ONE_HALF << shift) - 1) >> (SCALEBITS + shift)) + 128)
1234

    
1235
static uint8_t y_ccir_to_jpeg[256];
1236
static uint8_t y_jpeg_to_ccir[256];
1237
static uint8_t c_ccir_to_jpeg[256];
1238
static uint8_t c_jpeg_to_ccir[256];
1239

    
1240
/* init various conversion tables */
1241
static void img_convert_init(void)
1242
{
1243
    int i;
1244
    uint8_t *cm = ff_cropTbl + MAX_NEG_CROP;
1245

    
1246
    for(i = 0;i < 256; i++) {
1247
        y_ccir_to_jpeg[i] = Y_CCIR_TO_JPEG(i);
1248
        y_jpeg_to_ccir[i] = Y_JPEG_TO_CCIR(i);
1249
        c_ccir_to_jpeg[i] = C_CCIR_TO_JPEG(i);
1250
        c_jpeg_to_ccir[i] = C_JPEG_TO_CCIR(i);
1251
    }
1252
}
1253

    
1254
/* apply to each pixel the given table */
1255
static void img_apply_table(uint8_t *dst, int dst_wrap,
1256
                            const uint8_t *src, int src_wrap,
1257
                            int width, int height, const uint8_t *table1)
1258
{
1259
    int n;
1260
    const uint8_t *s;
1261
    uint8_t *d;
1262
    const uint8_t *table;
1263

    
1264
    table = table1;
1265
    for(;height > 0; height--) {
1266
        s = src;
1267
        d = dst;
1268
        n = width;
1269
        while (n >= 4) {
1270
            d[0] = table[s[0]];
1271
            d[1] = table[s[1]];
1272
            d[2] = table[s[2]];
1273
            d[3] = table[s[3]];
1274
            d += 4;
1275
            s += 4;
1276
            n -= 4;
1277
        }
1278
        while (n > 0) {
1279
            d[0] = table[s[0]];
1280
            d++;
1281
            s++;
1282
            n--;
1283
        }
1284
        dst += dst_wrap;
1285
        src += src_wrap;
1286
    }
1287
}
1288

    
1289
/* XXX: use generic filter ? */
1290
/* XXX: in most cases, the sampling position is incorrect */
1291

    
1292
/* 4x1 -> 1x1 */
1293
static void shrink41(uint8_t *dst, int dst_wrap,
1294
                     const uint8_t *src, int src_wrap,
1295
                     int width, int height)
1296
{
1297
    int w;
1298
    const uint8_t *s;
1299
    uint8_t *d;
1300

    
1301
    for(;height > 0; height--) {
1302
        s = src;
1303
        d = dst;
1304
        for(w = width;w > 0; w--) {
1305
            d[0] = (s[0] + s[1] + s[2] + s[3] + 2) >> 2;
1306
            s += 4;
1307
            d++;
1308
        }
1309
        src += src_wrap;
1310
        dst += dst_wrap;
1311
    }
1312
}
1313

    
1314
/* 2x1 -> 1x1 */
1315
static void shrink21(uint8_t *dst, int dst_wrap,
1316
                     const uint8_t *src, int src_wrap,
1317
                     int width, int height)
1318
{
1319
    int w;
1320
    const uint8_t *s;
1321
    uint8_t *d;
1322

    
1323
    for(;height > 0; height--) {
1324
        s = src;
1325
        d = dst;
1326
        for(w = width;w > 0; w--) {
1327
            d[0] = (s[0] + s[1]) >> 1;
1328
            s += 2;
1329
            d++;
1330
        }
1331
        src += src_wrap;
1332
        dst += dst_wrap;
1333
    }
1334
}
1335

    
1336
/* 1x2 -> 1x1 */
1337
static void shrink12(uint8_t *dst, int dst_wrap,
1338
                     const uint8_t *src, int src_wrap,
1339
                     int width, int height)
1340
{
1341
    int w;
1342
    uint8_t *d;
1343
    const uint8_t *s1, *s2;
1344

    
1345
    for(;height > 0; height--) {
1346
        s1 = src;
1347
        s2 = s1 + src_wrap;
1348
        d = dst;
1349
        for(w = width;w >= 4; w-=4) {
1350
            d[0] = (s1[0] + s2[0]) >> 1;
1351
            d[1] = (s1[1] + s2[1]) >> 1;
1352
            d[2] = (s1[2] + s2[2]) >> 1;
1353
            d[3] = (s1[3] + s2[3]) >> 1;
1354
            s1 += 4;
1355
            s2 += 4;
1356
            d += 4;
1357
        }
1358
        for(;w > 0; w--) {
1359
            d[0] = (s1[0] + s2[0]) >> 1;
1360
            s1++;
1361
            s2++;
1362
            d++;
1363
        }
1364
        src += 2 * src_wrap;
1365
        dst += dst_wrap;
1366
    }
1367
}
1368

    
1369
/* 2x2 -> 1x1 */
1370
void ff_shrink22(uint8_t *dst, int dst_wrap,
1371
                     const uint8_t *src, int src_wrap,
1372
                     int width, int height)
1373
{
1374
    int w;
1375
    const uint8_t *s1, *s2;
1376
    uint8_t *d;
1377

    
1378
    for(;height > 0; height--) {
1379
        s1 = src;
1380
        s2 = s1 + src_wrap;
1381
        d = dst;
1382
        for(w = width;w >= 4; w-=4) {
1383
            d[0] = (s1[0] + s1[1] + s2[0] + s2[1] + 2) >> 2;
1384
            d[1] = (s1[2] + s1[3] + s2[2] + s2[3] + 2) >> 2;
1385
            d[2] = (s1[4] + s1[5] + s2[4] + s2[5] + 2) >> 2;
1386
            d[3] = (s1[6] + s1[7] + s2[6] + s2[7] + 2) >> 2;
1387
            s1 += 8;
1388
            s2 += 8;
1389
            d += 4;
1390
        }
1391
        for(;w > 0; w--) {
1392
            d[0] = (s1[0] + s1[1] + s2[0] + s2[1] + 2) >> 2;
1393
            s1 += 2;
1394
            s2 += 2;
1395
            d++;
1396
        }
1397
        src += 2 * src_wrap;
1398
        dst += dst_wrap;
1399
    }
1400
}
1401

    
1402
/* 4x4 -> 1x1 */
1403
void ff_shrink44(uint8_t *dst, int dst_wrap,
1404
                     const uint8_t *src, int src_wrap,
1405
                     int width, int height)
1406
{
1407
    int w;
1408
    const uint8_t *s1, *s2, *s3, *s4;
1409
    uint8_t *d;
1410

    
1411
    for(;height > 0; height--) {
1412
        s1 = src;
1413
        s2 = s1 + src_wrap;
1414
        s3 = s2 + src_wrap;
1415
        s4 = s3 + src_wrap;
1416
        d = dst;
1417
        for(w = width;w > 0; w--) {
1418
            d[0] = (s1[0] + s1[1] + s1[2] + s1[3] +
1419
                    s2[0] + s2[1] + s2[2] + s2[3] +
1420
                    s3[0] + s3[1] + s3[2] + s3[3] +
1421
                    s4[0] + s4[1] + s4[2] + s4[3] + 8) >> 4;
1422
            s1 += 4;
1423
            s2 += 4;
1424
            s3 += 4;
1425
            s4 += 4;
1426
            d++;
1427
        }
1428
        src += 4 * src_wrap;
1429
        dst += dst_wrap;
1430
    }
1431
}
1432

    
1433
/* 8x8 -> 1x1 */
1434
void ff_shrink88(uint8_t *dst, int dst_wrap,
1435
                     const uint8_t *src, int src_wrap,
1436
                     int width, int height)
1437
{
1438
    int w, i;
1439

    
1440
    for(;height > 0; height--) {
1441
        for(w = width;w > 0; w--) {
1442
            int tmp=0;
1443
            for(i=0; i<8; i++){
1444
                tmp += src[0] + src[1] + src[2] + src[3] + src[4] + src[5] + src[6] + src[7];
1445
                src += src_wrap;
1446
            }
1447
            *(dst++) = (tmp + 32)>>6;
1448
            src += 8 - 8*src_wrap;
1449
        }
1450
        src += 8*src_wrap - 8*width;
1451
        dst += dst_wrap - width;
1452
    }
1453
}
1454

    
1455
static void grow21_line(uint8_t *dst, const uint8_t *src,
1456
                        int width)
1457
{
1458
    int w;
1459
    const uint8_t *s1;
1460
    uint8_t *d;
1461

    
1462
    s1 = src;
1463
    d = dst;
1464
    for(w = width;w >= 4; w-=4) {
1465
        d[1] = d[0] = s1[0];
1466
        d[3] = d[2] = s1[1];
1467
        s1 += 2;
1468
        d += 4;
1469
    }
1470
    for(;w >= 2; w -= 2) {
1471
        d[1] = d[0] = s1[0];
1472
        s1 ++;
1473
        d += 2;
1474
    }
1475
    /* only needed if width is not a multiple of two */
1476
    /* XXX: veryfy that */
1477
    if (w) {
1478
        d[0] = s1[0];
1479
    }
1480
}
1481

    
1482
static void grow41_line(uint8_t *dst, const uint8_t *src,
1483
                        int width)
1484
{
1485
    int w, v;
1486
    const uint8_t *s1;
1487
    uint8_t *d;
1488

    
1489
    s1 = src;
1490
    d = dst;
1491
    for(w = width;w >= 4; w-=4) {
1492
        v = s1[0];
1493
        d[0] = v;
1494
        d[1] = v;
1495
        d[2] = v;
1496
        d[3] = v;
1497
        s1 ++;
1498
        d += 4;
1499
    }
1500
}
1501

    
1502
/* 1x1 -> 2x1 */
1503
static void grow21(uint8_t *dst, int dst_wrap,
1504
                   const uint8_t *src, int src_wrap,
1505
                   int width, int height)
1506
{
1507
    for(;height > 0; height--) {
1508
        grow21_line(dst, src, width);
1509
        src += src_wrap;
1510
        dst += dst_wrap;
1511
    }
1512
}
1513

    
1514
/* 1x1 -> 2x2 */
1515
static void grow22(uint8_t *dst, int dst_wrap,
1516
                   const uint8_t *src, int src_wrap,
1517
                   int width, int height)
1518
{
1519
    for(;height > 0; height--) {
1520
        grow21_line(dst, src, width);
1521
        if (height%2)
1522
            src += src_wrap;
1523
        dst += dst_wrap;
1524
    }
1525
}
1526

    
1527
/* 1x1 -> 4x1 */
1528
static void grow41(uint8_t *dst, int dst_wrap,
1529
                   const uint8_t *src, int src_wrap,
1530
                   int width, int height)
1531
{
1532
    for(;height > 0; height--) {
1533
        grow41_line(dst, src, width);
1534
        src += src_wrap;
1535
        dst += dst_wrap;
1536
    }
1537
}
1538

    
1539
/* 1x1 -> 4x4 */
1540
static void grow44(uint8_t *dst, int dst_wrap,
1541
                   const uint8_t *src, int src_wrap,
1542
                   int width, int height)
1543
{
1544
    for(;height > 0; height--) {
1545
        grow41_line(dst, src, width);
1546
        if ((height & 3) == 1)
1547
            src += src_wrap;
1548
        dst += dst_wrap;
1549
    }
1550
}
1551

    
1552
/* 1x2 -> 2x1 */
1553
static void conv411(uint8_t *dst, int dst_wrap,
1554
                    const uint8_t *src, int src_wrap,
1555
                    int width, int height)
1556
{
1557
    int w, c;
1558
    const uint8_t *s1, *s2;
1559
    uint8_t *d;
1560

    
1561
    width>>=1;
1562

    
1563
    for(;height > 0; height--) {
1564
        s1 = src;
1565
        s2 = src + src_wrap;
1566
        d = dst;
1567
        for(w = width;w > 0; w--) {
1568
            c = (s1[0] + s2[0]) >> 1;
1569
            d[0] = c;
1570
            d[1] = c;
1571
            s1++;
1572
            s2++;
1573
            d += 2;
1574
        }
1575
        src += src_wrap * 2;
1576
        dst += dst_wrap;
1577
    }
1578
}
1579

    
1580
/* XXX: add jpeg quantize code */
1581

    
1582
#define TRANSP_INDEX (6*6*6)
1583

    
1584
/* this is maybe slow, but allows for extensions */
1585
static inline unsigned char gif_clut_index(uint8_t r, uint8_t g, uint8_t b)
1586
{
1587
    return ((((r)/47)%6)*6*6+(((g)/47)%6)*6+(((b)/47)%6));
1588
}
1589

    
1590
static void build_rgb_palette(uint8_t *palette, int has_alpha)
1591
{
1592
    uint32_t *pal;
1593
    static const uint8_t pal_value[6] = { 0x00, 0x33, 0x66, 0x99, 0xcc, 0xff };
1594
    int i, r, g, b;
1595

    
1596
    pal = (uint32_t *)palette;
1597
    i = 0;
1598
    for(r = 0; r < 6; r++) {
1599
        for(g = 0; g < 6; g++) {
1600
            for(b = 0; b < 6; b++) {
1601
                pal[i++] = (0xff << 24) | (pal_value[r] << 16) |
1602
                    (pal_value[g] << 8) | pal_value[b];
1603
            }
1604
        }
1605
    }
1606
    if (has_alpha)
1607
        pal[i++] = 0;
1608
    while (i < 256)
1609
        pal[i++] = 0xff000000;
1610
}
1611

    
1612
/* copy bit n to bits 0 ... n - 1 */
1613
static inline unsigned int bitcopy_n(unsigned int a, int n)
1614
{
1615
    int mask;
1616
    mask = (1 << n) - 1;
1617
    return (a & (0xff & ~mask)) | ((-((a >> n) & 1)) & mask);
1618
}
1619

    
1620
/* rgb555 handling */
1621

    
1622
#define RGB_NAME rgb555
1623

    
1624
#define RGB_IN(r, g, b, s)\
1625
{\
1626
    unsigned int v = ((const uint16_t *)(s))[0];\
1627
    r = bitcopy_n(v >> (10 - 3), 3);\
1628
    g = bitcopy_n(v >> (5 - 3), 3);\
1629
    b = bitcopy_n(v << 3, 3);\
1630
}
1631

    
1632

    
1633
#define RGB_OUT(d, r, g, b)\
1634
{\
1635
    ((uint16_t *)(d))[0] = ((r >> 3) << 10) | ((g >> 3) << 5) | (b >> 3);\
1636
}
1637

    
1638
#define BPP 2
1639

    
1640
#include "imgconvert_template.h"
1641

    
1642
/* rgb565 handling */
1643

    
1644
#define RGB_NAME rgb565
1645

    
1646
#define RGB_IN(r, g, b, s)\
1647
{\
1648
    unsigned int v = ((const uint16_t *)(s))[0];\
1649
    r = bitcopy_n(v >> (11 - 3), 3);\
1650
    g = bitcopy_n(v >> (5 - 2), 2);\
1651
    b = bitcopy_n(v << 3, 3);\
1652
}
1653

    
1654
#define RGB_OUT(d, r, g, b)\
1655
{\
1656
    ((uint16_t *)(d))[0] = ((r >> 3) << 11) | ((g >> 2) << 5) | (b >> 3);\
1657
}
1658

    
1659
#define BPP 2
1660

    
1661
#include "imgconvert_template.h"
1662

    
1663
/* bgr24 handling */
1664

    
1665
#define RGB_NAME bgr24
1666

    
1667
#define RGB_IN(r, g, b, s)\
1668
{\
1669
    b = (s)[0];\
1670
    g = (s)[1];\
1671
    r = (s)[2];\
1672
}
1673

    
1674
#define RGB_OUT(d, r, g, b)\
1675
{\
1676
    (d)[0] = b;\
1677
    (d)[1] = g;\
1678
    (d)[2] = r;\
1679
}
1680

    
1681
#define BPP 3
1682

    
1683
#include "imgconvert_template.h"
1684

    
1685
#undef RGB_IN
1686
#undef RGB_OUT
1687
#undef BPP
1688

    
1689
/* rgb24 handling */
1690

    
1691
#define RGB_NAME rgb24
1692
#define FMT_RGB24
1693

    
1694
#define RGB_IN(r, g, b, s)\
1695
{\
1696
    r = (s)[0];\
1697
    g = (s)[1];\
1698
    b = (s)[2];\
1699
}
1700

    
1701
#define RGB_OUT(d, r, g, b)\
1702
{\
1703
    (d)[0] = r;\
1704
    (d)[1] = g;\
1705
    (d)[2] = b;\
1706
}
1707

    
1708
#define BPP 3
1709

    
1710
#include "imgconvert_template.h"
1711

    
1712
/* rgba32 handling */
1713

    
1714
#define RGB_NAME rgba32
1715
#define FMT_RGBA32
1716

    
1717
#define RGB_IN(r, g, b, s)\
1718
{\
1719
    unsigned int v = ((const uint32_t *)(s))[0];\
1720
    r = (v >> 16) & 0xff;\
1721
    g = (v >> 8) & 0xff;\
1722
    b = v & 0xff;\
1723
}
1724

    
1725
#define RGBA_IN(r, g, b, a, s)\
1726
{\
1727
    unsigned int v = ((const uint32_t *)(s))[0];\
1728
    a = (v >> 24) & 0xff;\
1729
    r = (v >> 16) & 0xff;\
1730
    g = (v >> 8) & 0xff;\
1731
    b = v & 0xff;\
1732
}
1733

    
1734
#define RGBA_OUT(d, r, g, b, a)\
1735
{\
1736
    ((uint32_t *)(d))[0] = (a << 24) | (r << 16) | (g << 8) | b;\
1737
}
1738

    
1739
#define BPP 4
1740

    
1741
#include "imgconvert_template.h"
1742

    
1743
static void mono_to_gray(AVPicture *dst, const AVPicture *src,
1744
                         int width, int height, int xor_mask)
1745
{
1746
    const unsigned char *p;
1747
    unsigned char *q;
1748
    int v, dst_wrap, src_wrap;
1749
    int y, w;
1750

    
1751
    p = src->data[0];
1752
    src_wrap = src->linesize[0] - ((width + 7) >> 3);
1753

    
1754
    q = dst->data[0];
1755
    dst_wrap = dst->linesize[0] - width;
1756
    for(y=0;y<height;y++) {
1757
        w = width;
1758
        while (w >= 8) {
1759
            v = *p++ ^ xor_mask;
1760
            q[0] = -(v >> 7);
1761
            q[1] = -((v >> 6) & 1);
1762
            q[2] = -((v >> 5) & 1);
1763
            q[3] = -((v >> 4) & 1);
1764
            q[4] = -((v >> 3) & 1);
1765
            q[5] = -((v >> 2) & 1);
1766
            q[6] = -((v >> 1) & 1);
1767
            q[7] = -((v >> 0) & 1);
1768
            w -= 8;
1769
            q += 8;
1770
        }
1771
        if (w > 0) {
1772
            v = *p++ ^ xor_mask;
1773
            do {
1774
                q[0] = -((v >> 7) & 1);
1775
                q++;
1776
                v <<= 1;
1777
            } while (--w);
1778
        }
1779
        p += src_wrap;
1780
        q += dst_wrap;
1781
    }
1782
}
1783

    
1784
static void monowhite_to_gray(AVPicture *dst, const AVPicture *src,
1785
                               int width, int height)
1786
{
1787
    mono_to_gray(dst, src, width, height, 0xff);
1788
}
1789

    
1790
static void monoblack_to_gray(AVPicture *dst, const AVPicture *src,
1791
                               int width, int height)
1792
{
1793
    mono_to_gray(dst, src, width, height, 0x00);
1794
}
1795

    
1796
static void gray_to_mono(AVPicture *dst, const AVPicture *src,
1797
                         int width, int height, int xor_mask)
1798
{
1799
    int n;
1800
    const uint8_t *s;
1801
    uint8_t *d;
1802
    int j, b, v, n1, src_wrap, dst_wrap, y;
1803

    
1804
    s = src->data[0];
1805
    src_wrap = src->linesize[0] - width;
1806

    
1807
    d = dst->data[0];
1808
    dst_wrap = dst->linesize[0] - ((width + 7) >> 3);
1809

    
1810
    for(y=0;y<height;y++) {
1811
        n = width;
1812
        while (n >= 8) {
1813
            v = 0;
1814
            for(j=0;j<8;j++) {
1815
                b = s[0];
1816
                s++;
1817
                v = (v << 1) | (b >> 7);
1818
            }
1819
            d[0] = v ^ xor_mask;
1820
            d++;
1821
            n -= 8;
1822
        }
1823
        if (n > 0) {
1824
            n1 = n;
1825
            v = 0;
1826
            while (n > 0) {
1827
                b = s[0];
1828
                s++;
1829
                v = (v << 1) | (b >> 7);
1830
                n--;
1831
            }
1832
            d[0] = (v << (8 - (n1 & 7))) ^ xor_mask;
1833
            d++;
1834
        }
1835
        s += src_wrap;
1836
        d += dst_wrap;
1837
    }
1838
}
1839

    
1840
static void gray_to_monowhite(AVPicture *dst, const AVPicture *src,
1841
                              int width, int height)
1842
{
1843
    gray_to_mono(dst, src, width, height, 0xff);
1844
}
1845

    
1846
static void gray_to_monoblack(AVPicture *dst, const AVPicture *src,
1847
                              int width, int height)
1848
{
1849
    gray_to_mono(dst, src, width, height, 0x00);
1850
}
1851

    
1852
static void gray_to_gray16(AVPicture *dst, const AVPicture *src,
1853
                              int width, int height)
1854
{
1855
    int x, y, src_wrap, dst_wrap;
1856
    uint8_t *s, *d;
1857
    s = src->data[0];
1858
    src_wrap = src->linesize[0] - width;
1859
    d = dst->data[0];
1860
    dst_wrap = dst->linesize[0] - width * 2;
1861
    for(y=0; y<height; y++){
1862
        for(x=0; x<width; x++){
1863
            *d++ = *s;
1864
            *d++ = *s++;
1865
        }
1866
        s += src_wrap;
1867
        d += dst_wrap;
1868
    }
1869
}
1870

    
1871
static void gray16_to_gray(AVPicture *dst, const AVPicture *src,
1872
                              int width, int height)
1873
{
1874
    int x, y, src_wrap, dst_wrap;
1875
    uint8_t *s, *d;
1876
    s = src->data[0];
1877
    src_wrap = src->linesize[0] - width * 2;
1878
    d = dst->data[0];
1879
    dst_wrap = dst->linesize[0] - width;
1880
    for(y=0; y<height; y++){
1881
        for(x=0; x<width; x++){
1882
            *d++ = *s;
1883
            s += 2;
1884
        }
1885
        s += src_wrap;
1886
        d += dst_wrap;
1887
    }
1888
}
1889

    
1890
static void gray16be_to_gray(AVPicture *dst, const AVPicture *src,
1891
                              int width, int height)
1892
{
1893
    gray16_to_gray(dst, src, width, height);
1894
}
1895

    
1896
static void gray16le_to_gray(AVPicture *dst, const AVPicture *src,
1897
                              int width, int height)
1898
{
1899
    gray16_to_gray(dst, src + 1, width, height);
1900
}
1901

    
1902
static void gray16_to_gray16(AVPicture *dst, const AVPicture *src,
1903
                              int width, int height)
1904
{
1905
    int x, y, src_wrap, dst_wrap;
1906
    uint16_t *s, *d;
1907
    s = src->data[0];
1908
    src_wrap = (src->linesize[0] - width * 2)/2;
1909
    d = dst->data[0];
1910
    dst_wrap = (dst->linesize[0] - width * 2)/2;
1911
    for(y=0; y<height; y++){
1912
        for(x=0; x<width; x++){
1913
            *d++ = bswap_16(*s++);
1914
        }
1915
        s += src_wrap;
1916
        d += dst_wrap;
1917
    }
1918
}
1919

    
1920

    
1921
typedef struct ConvertEntry {
1922
    void (*convert)(AVPicture *dst,
1923
                    const AVPicture *src, int width, int height);
1924
} ConvertEntry;
1925

    
1926
/* Add each new convertion function in this table. In order to be able
1927
   to convert from any format to any format, the following constraints
1928
   must be satisfied:
1929

1930
   - all FF_COLOR_RGB formats must convert to and from PIX_FMT_RGB24
1931

1932
   - all FF_COLOR_GRAY formats must convert to and from PIX_FMT_GRAY8
1933

1934
   - all FF_COLOR_RGB formats with alpha must convert to and from PIX_FMT_RGBA32
1935

1936
   - PIX_FMT_YUV444P and PIX_FMT_YUVJ444P must convert to and from
1937
     PIX_FMT_RGB24.
1938

1939
   - PIX_FMT_422 must convert to and from PIX_FMT_422P.
1940

1941
   The other conversion functions are just optimisations for common cases.
1942
*/
1943
static const ConvertEntry convert_table[PIX_FMT_NB][PIX_FMT_NB] = {
1944
    [PIX_FMT_YUV420P] = {
1945
        [PIX_FMT_YUV422] = {
1946
            .convert = yuv420p_to_yuv422,
1947
        },
1948
        [PIX_FMT_RGB555] = {
1949
            .convert = yuv420p_to_rgb555
1950
        },
1951
        [PIX_FMT_RGB565] = {
1952
            .convert = yuv420p_to_rgb565
1953
        },
1954
        [PIX_FMT_BGR24] = {
1955
            .convert = yuv420p_to_bgr24
1956
        },
1957
        [PIX_FMT_RGB24] = {
1958
            .convert = yuv420p_to_rgb24
1959
        },
1960
        [PIX_FMT_RGBA32] = {
1961
            .convert = yuv420p_to_rgba32
1962
        },
1963
        [PIX_FMT_UYVY422] = {
1964
            .convert = yuv420p_to_uyvy422,
1965
        },
1966
    },
1967
    [PIX_FMT_YUV422P] = {
1968
        [PIX_FMT_YUV422] = {
1969
            .convert = yuv422p_to_yuv422,
1970
        },
1971
        [PIX_FMT_UYVY422] = {
1972
            .convert = yuv422p_to_uyvy422,
1973
        },
1974
    },
1975
    [PIX_FMT_YUV444P] = {
1976
        [PIX_FMT_RGB24] = {
1977
            .convert = yuv444p_to_rgb24
1978
        },
1979
    },
1980
    [PIX_FMT_YUVJ420P] = {
1981
        [PIX_FMT_RGB555] = {
1982
            .convert = yuvj420p_to_rgb555
1983
        },
1984
        [PIX_FMT_RGB565] = {
1985
            .convert = yuvj420p_to_rgb565
1986
        },
1987
        [PIX_FMT_BGR24] = {
1988
            .convert = yuvj420p_to_bgr24
1989
        },
1990
        [PIX_FMT_RGB24] = {
1991
            .convert = yuvj420p_to_rgb24
1992
        },
1993
        [PIX_FMT_RGBA32] = {
1994
            .convert = yuvj420p_to_rgba32
1995
        },
1996
    },
1997
    [PIX_FMT_YUVJ444P] = {
1998
        [PIX_FMT_RGB24] = {
1999
            .convert = yuvj444p_to_rgb24
2000
        },
2001
    },
2002
    [PIX_FMT_YUV422] = {
2003
        [PIX_FMT_YUV420P] = {
2004
            .convert = yuv422_to_yuv420p,
2005
        },
2006
        [PIX_FMT_YUV422P] = {
2007
            .convert = yuv422_to_yuv422p,
2008
        },
2009
    },
2010
    [PIX_FMT_UYVY422] = {
2011
        [PIX_FMT_YUV420P] = {
2012
            .convert = uyvy422_to_yuv420p,
2013
        },
2014
        [PIX_FMT_YUV422P] = {
2015
            .convert = uyvy422_to_yuv422p,
2016
        },
2017
    },
2018
    [PIX_FMT_RGB24] = {
2019
        [PIX_FMT_YUV420P] = {
2020
            .convert = rgb24_to_yuv420p
2021
        },
2022
        [PIX_FMT_RGB565] = {
2023
            .convert = rgb24_to_rgb565
2024
        },
2025
        [PIX_FMT_RGB555] = {
2026
            .convert = rgb24_to_rgb555
2027
        },
2028
        [PIX_FMT_RGBA32] = {
2029
            .convert = rgb24_to_rgba32
2030
        },
2031
        [PIX_FMT_BGR24] = {
2032
            .convert = rgb24_to_bgr24
2033
        },
2034
        [PIX_FMT_GRAY8] = {
2035
            .convert = rgb24_to_gray
2036
        },
2037
        [PIX_FMT_PAL8] = {
2038
            .convert = rgb24_to_pal8
2039
        },
2040
        [PIX_FMT_YUV444P] = {
2041
            .convert = rgb24_to_yuv444p
2042
        },
2043
        [PIX_FMT_YUVJ420P] = {
2044
            .convert = rgb24_to_yuvj420p
2045
        },
2046
        [PIX_FMT_YUVJ444P] = {
2047
            .convert = rgb24_to_yuvj444p
2048
        },
2049
    },
2050
    [PIX_FMT_RGBA32] = {
2051
        [PIX_FMT_RGB24] = {
2052
            .convert = rgba32_to_rgb24
2053
        },
2054
        [PIX_FMT_BGR24] = {
2055
            .convert = rgba32_to_bgr24
2056
        },
2057
        [PIX_FMT_RGB565] = {
2058
            .convert = rgba32_to_rgb565
2059
        },
2060
        [PIX_FMT_RGB555] = {
2061
            .convert = rgba32_to_rgb555
2062
        },
2063
        [PIX_FMT_PAL8] = {
2064
            .convert = rgba32_to_pal8
2065
        },
2066
        [PIX_FMT_YUV420P] = {
2067
            .convert = rgba32_to_yuv420p
2068
        },
2069
        [PIX_FMT_GRAY8] = {
2070
            .convert = rgba32_to_gray
2071
        },
2072
    },
2073
    [PIX_FMT_BGR24] = {
2074
        [PIX_FMT_RGBA32] = {
2075
            .convert = bgr24_to_rgba32
2076
        },
2077
        [PIX_FMT_RGB24] = {
2078
            .convert = bgr24_to_rgb24
2079
        },
2080
        [PIX_FMT_YUV420P] = {
2081
            .convert = bgr24_to_yuv420p
2082
        },
2083
        [PIX_FMT_GRAY8] = {
2084
            .convert = bgr24_to_gray
2085
        },
2086
    },
2087
    [PIX_FMT_RGB555] = {
2088
        [PIX_FMT_RGB24] = {
2089
            .convert = rgb555_to_rgb24
2090
        },
2091
        [PIX_FMT_RGBA32] = {
2092
            .convert = rgb555_to_rgba32
2093
        },
2094
        [PIX_FMT_YUV420P] = {
2095
            .convert = rgb555_to_yuv420p
2096
        },
2097
        [PIX_FMT_GRAY8] = {
2098
            .convert = rgb555_to_gray
2099
        },
2100
    },
2101
    [PIX_FMT_RGB565] = {
2102
        [PIX_FMT_RGBA32] = {
2103
            .convert = rgb565_to_rgba32
2104
        },
2105
        [PIX_FMT_RGB24] = {
2106
            .convert = rgb565_to_rgb24
2107
        },
2108
        [PIX_FMT_YUV420P] = {
2109
            .convert = rgb565_to_yuv420p
2110
        },
2111
        [PIX_FMT_GRAY8] = {
2112
            .convert = rgb565_to_gray
2113
        },
2114
    },
2115
    [PIX_FMT_GRAY16BE] = {
2116
        [PIX_FMT_GRAY8] = {
2117
            .convert = gray16be_to_gray
2118
        },
2119
        [PIX_FMT_GRAY16LE] = {
2120
            .convert = gray16_to_gray16
2121
        },
2122
    },
2123
    [PIX_FMT_GRAY16LE] = {
2124
        [PIX_FMT_GRAY8] = {
2125
            .convert = gray16le_to_gray
2126
        },
2127
        [PIX_FMT_GRAY16BE] = {
2128
            .convert = gray16_to_gray16
2129
        },
2130
    },
2131
    [PIX_FMT_GRAY8] = {
2132
        [PIX_FMT_RGB555] = {
2133
            .convert = gray_to_rgb555
2134
        },
2135
        [PIX_FMT_RGB565] = {
2136
            .convert = gray_to_rgb565
2137
        },
2138
        [PIX_FMT_RGB24] = {
2139
            .convert = gray_to_rgb24
2140
        },
2141
        [PIX_FMT_BGR24] = {
2142
            .convert = gray_to_bgr24
2143
        },
2144
        [PIX_FMT_RGBA32] = {
2145
            .convert = gray_to_rgba32
2146
        },
2147
        [PIX_FMT_MONOWHITE] = {
2148
            .convert = gray_to_monowhite
2149
        },
2150
        [PIX_FMT_MONOBLACK] = {
2151
            .convert = gray_to_monoblack
2152
        },
2153
        [PIX_FMT_GRAY16LE] = {
2154
            .convert = gray_to_gray16
2155
        },
2156
        [PIX_FMT_GRAY16BE] = {
2157
            .convert = gray_to_gray16
2158
        },
2159
    },
2160
    [PIX_FMT_MONOWHITE] = {
2161
        [PIX_FMT_GRAY8] = {
2162
            .convert = monowhite_to_gray
2163
        },
2164
    },
2165
    [PIX_FMT_MONOBLACK] = {
2166
        [PIX_FMT_GRAY8] = {
2167
            .convert = monoblack_to_gray
2168
        },
2169
    },
2170
    [PIX_FMT_PAL8] = {
2171
        [PIX_FMT_RGB555] = {
2172
            .convert = pal8_to_rgb555
2173
        },
2174
        [PIX_FMT_RGB565] = {
2175
            .convert = pal8_to_rgb565
2176
        },
2177
        [PIX_FMT_BGR24] = {
2178
            .convert = pal8_to_bgr24
2179
        },
2180
        [PIX_FMT_RGB24] = {
2181
            .convert = pal8_to_rgb24
2182
        },
2183
        [PIX_FMT_RGBA32] = {
2184
            .convert = pal8_to_rgba32
2185
        },
2186
    },
2187
    [PIX_FMT_UYVY411] = {
2188
        [PIX_FMT_YUV411P] = {
2189
            .convert = uyvy411_to_yuv411p,
2190
        },
2191
    },
2192

    
2193
};
2194

    
2195
int avpicture_alloc(AVPicture *picture,
2196
                           int pix_fmt, int width, int height)
2197
{
2198
    int size;
2199
    void *ptr;
2200

    
2201
    size = avpicture_get_size(pix_fmt, width, height);
2202
    if(size<0)
2203
        goto fail;
2204
    ptr = av_malloc(size);
2205
    if (!ptr)
2206
        goto fail;
2207
    avpicture_fill(picture, ptr, pix_fmt, width, height);
2208
    return 0;
2209
 fail:
2210
    memset(picture, 0, sizeof(AVPicture));
2211
    return -1;
2212
}
2213

    
2214
void avpicture_free(AVPicture *picture)
2215
{
2216
    av_free(picture->data[0]);
2217
}
2218

    
2219
/* return true if yuv planar */
2220
static inline int is_yuv_planar(const PixFmtInfo *ps)
2221
{
2222
    return (ps->color_type == FF_COLOR_YUV ||
2223
            ps->color_type == FF_COLOR_YUV_JPEG) &&
2224
        ps->pixel_type == FF_PIXEL_PLANAR;
2225
}
2226

    
2227
/**
2228
 * Crop image top and left side
2229
 */
2230
int img_crop(AVPicture *dst, const AVPicture *src,
2231
              int pix_fmt, int top_band, int left_band)
2232
{
2233
    int y_shift;
2234
    int x_shift;
2235

    
2236
    if (pix_fmt < 0 || pix_fmt >= PIX_FMT_NB || !is_yuv_planar(&pix_fmt_info[pix_fmt]))
2237
        return -1;
2238

    
2239
    y_shift = pix_fmt_info[pix_fmt].y_chroma_shift;
2240
    x_shift = pix_fmt_info[pix_fmt].x_chroma_shift;
2241

    
2242
    dst->data[0] = src->data[0] + (top_band * src->linesize[0]) + left_band;
2243
    dst->data[1] = src->data[1] + ((top_band >> y_shift) * src->linesize[1]) + (left_band >> x_shift);
2244
    dst->data[2] = src->data[2] + ((top_band >> y_shift) * src->linesize[2]) + (left_band >> x_shift);
2245

    
2246
    dst->linesize[0] = src->linesize[0];
2247
    dst->linesize[1] = src->linesize[1];
2248
    dst->linesize[2] = src->linesize[2];
2249
    return 0;
2250
}
2251

    
2252
/**
2253
 * Pad image
2254
 */
2255
int img_pad(AVPicture *dst, const AVPicture *src, int height, int width, int pix_fmt,
2256
            int padtop, int padbottom, int padleft, int padright, int *color)
2257
{
2258
    uint8_t *optr, *iptr;
2259
    int y_shift;
2260
    int x_shift;
2261
    int yheight;
2262
    int i, y;
2263

    
2264
    if (pix_fmt < 0 || pix_fmt >= PIX_FMT_NB || !is_yuv_planar(&pix_fmt_info[pix_fmt]))
2265
        return -1;
2266

    
2267
    for (i = 0; i < 3; i++) {
2268
        x_shift = i ? pix_fmt_info[pix_fmt].x_chroma_shift : 0;
2269
        y_shift = i ? pix_fmt_info[pix_fmt].y_chroma_shift : 0;
2270

    
2271
        if (padtop || padleft) {
2272
            memset(dst->data[i], color[i], dst->linesize[i] * (padtop >> y_shift) + (padleft >> x_shift));
2273
        }
2274

    
2275
        if (padleft || padright || src) {
2276
            if (src) { /* first line */
2277
                iptr = src->data[i];
2278
                optr = dst->data[i] + dst->linesize[i] * (padtop >> y_shift) + (padleft >> x_shift);
2279
                memcpy(optr, iptr, src->linesize[i]);
2280
                iptr += src->linesize[i];
2281
            }
2282
            optr = dst->data[i] + dst->linesize[i] * (padtop >> y_shift) + (dst->linesize[i] - (padright >> x_shift));
2283
            yheight = (height - 1 - (padtop + padbottom)) >> y_shift;
2284
            for (y = 0; y < yheight; y++) {
2285
                memset(optr, color[i], (padleft + padright) >> x_shift);
2286
                if (src) {
2287
                    memcpy(optr + ((padleft + padright) >> x_shift), iptr, src->linesize[i]);
2288
                    iptr += src->linesize[i];
2289
                }
2290
                optr += dst->linesize[i];
2291
            }
2292
        }
2293

    
2294
        if (padbottom || padright) {
2295
            optr = dst->data[i] + dst->linesize[i] * ((height - padbottom) >> y_shift) - (padright >> x_shift);
2296
            memset(optr, color[i], dst->linesize[i] * (padbottom >> y_shift) + (padright >> x_shift));
2297
        }
2298
    }
2299
    return 0;
2300
}
2301

    
2302
#ifndef CONFIG_SWSCALER
2303
/* XXX: always use linesize. Return -1 if not supported */
2304
int img_convert(AVPicture *dst, int dst_pix_fmt,
2305
                const AVPicture *src, int src_pix_fmt,
2306
                int src_width, int src_height)
2307
{
2308
    static int inited;
2309
    int i, ret, dst_width, dst_height, int_pix_fmt;
2310
    const PixFmtInfo *src_pix, *dst_pix;
2311
    const ConvertEntry *ce;
2312
    AVPicture tmp1, *tmp = &tmp1;
2313

    
2314
    if (src_pix_fmt < 0 || src_pix_fmt >= PIX_FMT_NB ||
2315
        dst_pix_fmt < 0 || dst_pix_fmt >= PIX_FMT_NB)
2316
        return -1;
2317
    if (src_width <= 0 || src_height <= 0)
2318
        return 0;
2319

    
2320
    if (!inited) {
2321
        inited = 1;
2322
        img_convert_init();
2323
    }
2324

    
2325
    dst_width = src_width;
2326
    dst_height = src_height;
2327

    
2328
    dst_pix = &pix_fmt_info[dst_pix_fmt];
2329
    src_pix = &pix_fmt_info[src_pix_fmt];
2330
    if (src_pix_fmt == dst_pix_fmt) {
2331
        /* no conversion needed: just copy */
2332
        img_copy(dst, src, dst_pix_fmt, dst_width, dst_height);
2333
        return 0;
2334
    }
2335

    
2336
    ce = &convert_table[src_pix_fmt][dst_pix_fmt];
2337
    if (ce->convert) {
2338
        /* specific conversion routine */
2339
        ce->convert(dst, src, dst_width, dst_height);
2340
        return 0;
2341
    }
2342

    
2343
    /* gray to YUV */
2344
    if (is_yuv_planar(dst_pix) &&
2345
        src_pix_fmt == PIX_FMT_GRAY8) {
2346
        int w, h, y;
2347
        uint8_t *d;
2348

    
2349
        if (dst_pix->color_type == FF_COLOR_YUV_JPEG) {
2350
            ff_img_copy_plane(dst->data[0], dst->linesize[0],
2351
                     src->data[0], src->linesize[0],
2352
                     dst_width, dst_height);
2353
        } else {
2354
            img_apply_table(dst->data[0], dst->linesize[0],
2355
                            src->data[0], src->linesize[0],
2356
                            dst_width, dst_height,
2357
                            y_jpeg_to_ccir);
2358
        }
2359
        /* fill U and V with 128 */
2360
        w = dst_width;
2361
        h = dst_height;
2362
        w >>= dst_pix->x_chroma_shift;
2363
        h >>= dst_pix->y_chroma_shift;
2364
        for(i = 1; i <= 2; i++) {
2365
            d = dst->data[i];
2366
            for(y = 0; y< h; y++) {
2367
                memset(d, 128, w);
2368
                d += dst->linesize[i];
2369
            }
2370
        }
2371
        return 0;
2372
    }
2373

    
2374
    /* YUV to gray */
2375
    if (is_yuv_planar(src_pix) &&
2376
        dst_pix_fmt == PIX_FMT_GRAY8) {
2377
        if (src_pix->color_type == FF_COLOR_YUV_JPEG) {
2378
            ff_img_copy_plane(dst->data[0], dst->linesize[0],
2379
                     src->data[0], src->linesize[0],
2380
                     dst_width, dst_height);
2381
        } else {
2382
            img_apply_table(dst->data[0], dst->linesize[0],
2383
                            src->data[0], src->linesize[0],
2384
                            dst_width, dst_height,
2385
                            y_ccir_to_jpeg);
2386
        }
2387
        return 0;
2388
    }
2389

    
2390
    /* YUV to YUV planar */
2391
    if (is_yuv_planar(dst_pix) && is_yuv_planar(src_pix)) {
2392
        int x_shift, y_shift, w, h, xy_shift;
2393
        void (*resize_func)(uint8_t *dst, int dst_wrap,
2394
                            const uint8_t *src, int src_wrap,
2395
                            int width, int height);
2396

    
2397
        /* compute chroma size of the smallest dimensions */
2398
        w = dst_width;
2399
        h = dst_height;
2400
        if (dst_pix->x_chroma_shift >= src_pix->x_chroma_shift)
2401
            w >>= dst_pix->x_chroma_shift;
2402
        else
2403
            w >>= src_pix->x_chroma_shift;
2404
        if (dst_pix->y_chroma_shift >= src_pix->y_chroma_shift)
2405
            h >>= dst_pix->y_chroma_shift;
2406
        else
2407
            h >>= src_pix->y_chroma_shift;
2408

    
2409
        x_shift = (dst_pix->x_chroma_shift - src_pix->x_chroma_shift);
2410
        y_shift = (dst_pix->y_chroma_shift - src_pix->y_chroma_shift);
2411
        xy_shift = ((x_shift & 0xf) << 4) | (y_shift & 0xf);
2412
        /* there must be filters for conversion at least from and to
2413
           YUV444 format */
2414
        switch(xy_shift) {
2415
        case 0x00:
2416
            resize_func = ff_img_copy_plane;
2417
            break;
2418
        case 0x10:
2419
            resize_func = shrink21;
2420
            break;
2421
        case 0x20:
2422
            resize_func = shrink41;
2423
            break;
2424
        case 0x01:
2425
            resize_func = shrink12;
2426
            break;
2427
        case 0x11:
2428
            resize_func = ff_shrink22;
2429
            break;
2430
        case 0x22:
2431
            resize_func = ff_shrink44;
2432
            break;
2433
        case 0xf0:
2434
            resize_func = grow21;
2435
            break;
2436
        case 0xe0:
2437
            resize_func = grow41;
2438
            break;
2439
        case 0xff:
2440
            resize_func = grow22;
2441
            break;
2442
        case 0xee:
2443
            resize_func = grow44;
2444
            break;
2445
        case 0xf1:
2446
            resize_func = conv411;
2447
            break;
2448
        default:
2449
            /* currently not handled */
2450
            goto no_chroma_filter;
2451
        }
2452

    
2453
        ff_img_copy_plane(dst->data[0], dst->linesize[0],
2454
                       src->data[0], src->linesize[0],
2455
                       dst_width, dst_height);
2456

    
2457
        for(i = 1;i <= 2; i++)
2458
            resize_func(dst->data[i], dst->linesize[i],
2459
                        src->data[i], src->linesize[i],
2460
                        dst_width>>dst_pix->x_chroma_shift, dst_height>>dst_pix->y_chroma_shift);
2461
        /* if yuv color space conversion is needed, we do it here on
2462
           the destination image */
2463
        if (dst_pix->color_type != src_pix->color_type) {
2464
            const uint8_t *y_table, *c_table;
2465
            if (dst_pix->color_type == FF_COLOR_YUV) {
2466
                y_table = y_jpeg_to_ccir;
2467
                c_table = c_jpeg_to_ccir;
2468
            } else {
2469
                y_table = y_ccir_to_jpeg;
2470
                c_table = c_ccir_to_jpeg;
2471
            }
2472
            img_apply_table(dst->data[0], dst->linesize[0],
2473
                            dst->data[0], dst->linesize[0],
2474
                            dst_width, dst_height,
2475
                            y_table);
2476

    
2477
            for(i = 1;i <= 2; i++)
2478
                img_apply_table(dst->data[i], dst->linesize[i],
2479
                                dst->data[i], dst->linesize[i],
2480
                                dst_width>>dst_pix->x_chroma_shift,
2481
                                dst_height>>dst_pix->y_chroma_shift,
2482
                                c_table);
2483
        }
2484
        return 0;
2485
    }
2486
 no_chroma_filter:
2487

    
2488
    /* try to use an intermediate format */
2489
    if (src_pix_fmt == PIX_FMT_YUV422 ||
2490
        dst_pix_fmt == PIX_FMT_YUV422) {
2491
        /* specific case: convert to YUV422P first */
2492
        int_pix_fmt = PIX_FMT_YUV422P;
2493
    } else if (src_pix_fmt == PIX_FMT_UYVY422 ||
2494
        dst_pix_fmt == PIX_FMT_UYVY422) {
2495
        /* specific case: convert to YUV422P first */
2496
        int_pix_fmt = PIX_FMT_YUV422P;
2497
    } else if (src_pix_fmt == PIX_FMT_UYVY411 ||
2498
        dst_pix_fmt == PIX_FMT_UYVY411) {
2499
        /* specific case: convert to YUV411P first */
2500
        int_pix_fmt = PIX_FMT_YUV411P;
2501
    } else if ((src_pix->color_type == FF_COLOR_GRAY &&
2502
                src_pix_fmt != PIX_FMT_GRAY8) ||
2503
               (dst_pix->color_type == FF_COLOR_GRAY &&
2504
                dst_pix_fmt != PIX_FMT_GRAY8)) {
2505
        /* gray8 is the normalized format */
2506
        int_pix_fmt = PIX_FMT_GRAY8;
2507
    } else if ((is_yuv_planar(src_pix) &&
2508
                src_pix_fmt != PIX_FMT_YUV444P &&
2509
                src_pix_fmt != PIX_FMT_YUVJ444P)) {
2510
        /* yuv444 is the normalized format */
2511
        if (src_pix->color_type == FF_COLOR_YUV_JPEG)
2512
            int_pix_fmt = PIX_FMT_YUVJ444P;
2513
        else
2514
            int_pix_fmt = PIX_FMT_YUV444P;
2515
    } else if ((is_yuv_planar(dst_pix) &&
2516
                dst_pix_fmt != PIX_FMT_YUV444P &&
2517
                dst_pix_fmt != PIX_FMT_YUVJ444P)) {
2518
        /* yuv444 is the normalized format */
2519
        if (dst_pix->color_type == FF_COLOR_YUV_JPEG)
2520
            int_pix_fmt = PIX_FMT_YUVJ444P;
2521
        else
2522
            int_pix_fmt = PIX_FMT_YUV444P;
2523
    } else {
2524
        /* the two formats are rgb or gray8 or yuv[j]444p */
2525
        if (src_pix->is_alpha && dst_pix->is_alpha)
2526
            int_pix_fmt = PIX_FMT_RGBA32;
2527
        else
2528
            int_pix_fmt = PIX_FMT_RGB24;
2529
    }
2530
    if (avpicture_alloc(tmp, int_pix_fmt, dst_width, dst_height) < 0)
2531
        return -1;
2532
    ret = -1;
2533
    if (img_convert(tmp, int_pix_fmt,
2534
                    src, src_pix_fmt, src_width, src_height) < 0)
2535
        goto fail1;
2536
    if (img_convert(dst, dst_pix_fmt,
2537
                    tmp, int_pix_fmt, dst_width, dst_height) < 0)
2538
        goto fail1;
2539
    ret = 0;
2540
 fail1:
2541
    avpicture_free(tmp);
2542
    return ret;
2543
}
2544
#endif
2545

    
2546
/* NOTE: we scan all the pixels to have an exact information */
2547
static int get_alpha_info_pal8(const AVPicture *src, int width, int height)
2548
{
2549
    const unsigned char *p;
2550
    int src_wrap, ret, x, y;
2551
    unsigned int a;
2552
    uint32_t *palette = (uint32_t *)src->data[1];
2553

    
2554
    p = src->data[0];
2555
    src_wrap = src->linesize[0] - width;
2556
    ret = 0;
2557
    for(y=0;y<height;y++) {
2558
        for(x=0;x<width;x++) {
2559
            a = palette[p[0]] >> 24;
2560
            if (a == 0x00) {
2561
                ret |= FF_ALPHA_TRANSP;
2562
            } else if (a != 0xff) {
2563
                ret |= FF_ALPHA_SEMI_TRANSP;
2564
            }
2565
            p++;
2566
        }
2567
        p += src_wrap;
2568
    }
2569
    return ret;
2570
}
2571

    
2572
/**
2573
 * Tell if an image really has transparent alpha values.
2574
 * @return ored mask of FF_ALPHA_xxx constants
2575
 */
2576
int img_get_alpha_info(const AVPicture *src,
2577
                       int pix_fmt, int width, int height)
2578
{
2579
    const PixFmtInfo *pf = &pix_fmt_info[pix_fmt];
2580
    int ret;
2581

    
2582
    pf = &pix_fmt_info[pix_fmt];
2583
    /* no alpha can be represented in format */
2584
    if (!pf->is_alpha)
2585
        return 0;
2586
    switch(pix_fmt) {
2587
    case PIX_FMT_RGBA32:
2588
        ret = get_alpha_info_rgba32(src, width, height);
2589
        break;
2590
    case PIX_FMT_PAL8:
2591
        ret = get_alpha_info_pal8(src, width, height);
2592
        break;
2593
    default:
2594
        /* we do not know, so everything is indicated */
2595
        ret = FF_ALPHA_TRANSP | FF_ALPHA_SEMI_TRANSP;
2596
        break;
2597
    }
2598
    return ret;
2599
}
2600

    
2601
#ifdef HAVE_MMX
2602
#define DEINT_INPLACE_LINE_LUM \
2603
                    movd_m2r(lum_m4[0],mm0);\
2604
                    movd_m2r(lum_m3[0],mm1);\
2605
                    movd_m2r(lum_m2[0],mm2);\
2606
                    movd_m2r(lum_m1[0],mm3);\
2607
                    movd_m2r(lum[0],mm4);\
2608
                    punpcklbw_r2r(mm7,mm0);\
2609
                    movd_r2m(mm2,lum_m4[0]);\
2610
                    punpcklbw_r2r(mm7,mm1);\
2611
                    punpcklbw_r2r(mm7,mm2);\
2612
                    punpcklbw_r2r(mm7,mm3);\
2613
                    punpcklbw_r2r(mm7,mm4);\
2614
                    paddw_r2r(mm3,mm1);\
2615
                    psllw_i2r(1,mm2);\
2616
                    paddw_r2r(mm4,mm0);\
2617
                    psllw_i2r(2,mm1);\
2618
                    paddw_r2r(mm6,mm2);\
2619
                    paddw_r2r(mm2,mm1);\
2620
                    psubusw_r2r(mm0,mm1);\
2621
                    psrlw_i2r(3,mm1);\
2622
                    packuswb_r2r(mm7,mm1);\
2623
                    movd_r2m(mm1,lum_m2[0]);
2624

    
2625
#define DEINT_LINE_LUM \
2626
                    movd_m2r(lum_m4[0],mm0);\
2627
                    movd_m2r(lum_m3[0],mm1);\
2628
                    movd_m2r(lum_m2[0],mm2);\
2629
                    movd_m2r(lum_m1[0],mm3);\
2630
                    movd_m2r(lum[0],mm4);\
2631
                    punpcklbw_r2r(mm7,mm0);\
2632
                    punpcklbw_r2r(mm7,mm1);\
2633
                    punpcklbw_r2r(mm7,mm2);\
2634
                    punpcklbw_r2r(mm7,mm3);\
2635
                    punpcklbw_r2r(mm7,mm4);\
2636
                    paddw_r2r(mm3,mm1);\
2637
                    psllw_i2r(1,mm2);\
2638
                    paddw_r2r(mm4,mm0);\
2639
                    psllw_i2r(2,mm1);\
2640
                    paddw_r2r(mm6,mm2);\
2641
                    paddw_r2r(mm2,mm1);\
2642
                    psubusw_r2r(mm0,mm1);\
2643
                    psrlw_i2r(3,mm1);\
2644
                    packuswb_r2r(mm7,mm1);\
2645
                    movd_r2m(mm1,dst[0]);
2646
#endif
2647

    
2648
/* filter parameters: [-1 4 2 4 -1] // 8 */
2649
static void deinterlace_line(uint8_t *dst,
2650
                             const uint8_t *lum_m4, const uint8_t *lum_m3,
2651
                             const uint8_t *lum_m2, const uint8_t *lum_m1,
2652
                             const uint8_t *lum,
2653
                             int size)
2654
{
2655
#ifndef HAVE_MMX
2656
    uint8_t *cm = ff_cropTbl + MAX_NEG_CROP;
2657
    int sum;
2658

    
2659
    for(;size > 0;size--) {
2660
        sum = -lum_m4[0];
2661
        sum += lum_m3[0] << 2;
2662
        sum += lum_m2[0] << 1;
2663
        sum += lum_m1[0] << 2;
2664
        sum += -lum[0];
2665
        dst[0] = cm[(sum + 4) >> 3];
2666
        lum_m4++;
2667
        lum_m3++;
2668
        lum_m2++;
2669
        lum_m1++;
2670
        lum++;
2671
        dst++;
2672
    }
2673
#else
2674

    
2675
    {
2676
        mmx_t rounder;
2677
        rounder.uw[0]=4;
2678
        rounder.uw[1]=4;
2679
        rounder.uw[2]=4;
2680
        rounder.uw[3]=4;
2681
        pxor_r2r(mm7,mm7);
2682
        movq_m2r(rounder,mm6);
2683
    }
2684
    for (;size > 3; size-=4) {
2685
        DEINT_LINE_LUM
2686
        lum_m4+=4;
2687
        lum_m3+=4;
2688
        lum_m2+=4;
2689
        lum_m1+=4;
2690
        lum+=4;
2691
        dst+=4;
2692
    }
2693
#endif
2694
}
2695
static void deinterlace_line_inplace(uint8_t *lum_m4, uint8_t *lum_m3, uint8_t *lum_m2, uint8_t *lum_m1, uint8_t *lum,
2696
                             int size)
2697
{
2698
#ifndef HAVE_MMX
2699
    uint8_t *cm = ff_cropTbl + MAX_NEG_CROP;
2700
    int sum;
2701

    
2702
    for(;size > 0;size--) {
2703
        sum = -lum_m4[0];
2704
        sum += lum_m3[0] << 2;
2705
        sum += lum_m2[0] << 1;
2706
        lum_m4[0]=lum_m2[0];
2707
        sum += lum_m1[0] << 2;
2708
        sum += -lum[0];
2709
        lum_m2[0] = cm[(sum + 4) >> 3];
2710
        lum_m4++;
2711
        lum_m3++;
2712
        lum_m2++;
2713
        lum_m1++;
2714
        lum++;
2715
    }
2716
#else
2717

    
2718
    {
2719
        mmx_t rounder;
2720
        rounder.uw[0]=4;
2721
        rounder.uw[1]=4;
2722
        rounder.uw[2]=4;
2723
        rounder.uw[3]=4;
2724
        pxor_r2r(mm7,mm7);
2725
        movq_m2r(rounder,mm6);
2726
    }
2727
    for (;size > 3; size-=4) {
2728
        DEINT_INPLACE_LINE_LUM
2729
        lum_m4+=4;
2730
        lum_m3+=4;
2731
        lum_m2+=4;
2732
        lum_m1+=4;
2733
        lum+=4;
2734
    }
2735
#endif
2736
}
2737

    
2738
/* deinterlacing : 2 temporal taps, 3 spatial taps linear filter. The
2739
   top field is copied as is, but the bottom field is deinterlaced
2740
   against the top field. */
2741
static void deinterlace_bottom_field(uint8_t *dst, int dst_wrap,
2742
                                    const uint8_t *src1, int src_wrap,
2743
                                    int width, int height)
2744
{
2745
    const uint8_t *src_m2, *src_m1, *src_0, *src_p1, *src_p2;
2746
    int y;
2747

    
2748
    src_m2 = src1;
2749
    src_m1 = src1;
2750
    src_0=&src_m1[src_wrap];
2751
    src_p1=&src_0[src_wrap];
2752
    src_p2=&src_p1[src_wrap];
2753
    for(y=0;y<(height-2);y+=2) {
2754
        memcpy(dst,src_m1,width);
2755
        dst += dst_wrap;
2756
        deinterlace_line(dst,src_m2,src_m1,src_0,src_p1,src_p2,width);
2757
        src_m2 = src_0;
2758
        src_m1 = src_p1;
2759
        src_0 = src_p2;
2760
        src_p1 += 2*src_wrap;
2761
        src_p2 += 2*src_wrap;
2762
        dst += dst_wrap;
2763
    }
2764
    memcpy(dst,src_m1,width);
2765
    dst += dst_wrap;
2766
    /* do last line */
2767
    deinterlace_line(dst,src_m2,src_m1,src_0,src_0,src_0,width);
2768
}
2769

    
2770
static void deinterlace_bottom_field_inplace(uint8_t *src1, int src_wrap,
2771
                                             int width, int height)
2772
{
2773
    uint8_t *src_m1, *src_0, *src_p1, *src_p2;
2774
    int y;
2775
    uint8_t *buf;
2776
    buf = (uint8_t*)av_malloc(width);
2777

    
2778
    src_m1 = src1;
2779
    memcpy(buf,src_m1,width);
2780
    src_0=&src_m1[src_wrap];
2781
    src_p1=&src_0[src_wrap];
2782
    src_p2=&src_p1[src_wrap];
2783
    for(y=0;y<(height-2);y+=2) {
2784
        deinterlace_line_inplace(buf,src_m1,src_0,src_p1,src_p2,width);
2785
        src_m1 = src_p1;
2786
        src_0 = src_p2;
2787
        src_p1 += 2*src_wrap;
2788
        src_p2 += 2*src_wrap;
2789
    }
2790
    /* do last line */
2791
    deinterlace_line_inplace(buf,src_m1,src_0,src_0,src_0,width);
2792
    av_free(buf);
2793
}
2794

    
2795

    
2796
/* deinterlace - if not supported return -1 */
2797
int avpicture_deinterlace(AVPicture *dst, const AVPicture *src,
2798
                          int pix_fmt, int width, int height)
2799
{
2800
    int i;
2801

    
2802
    if (pix_fmt != PIX_FMT_YUV420P &&
2803
        pix_fmt != PIX_FMT_YUV422P &&
2804
        pix_fmt != PIX_FMT_YUV444P &&
2805
        pix_fmt != PIX_FMT_YUV411P)
2806
        return -1;
2807
    if ((width & 3) != 0 || (height & 3) != 0)
2808
        return -1;
2809

    
2810
    for(i=0;i<3;i++) {
2811
        if (i == 1) {
2812
            switch(pix_fmt) {
2813
            case PIX_FMT_YUV420P:
2814
                width >>= 1;
2815
                height >>= 1;
2816
                break;
2817
            case PIX_FMT_YUV422P:
2818
                width >>= 1;
2819
                break;
2820
            case PIX_FMT_YUV411P:
2821
                width >>= 2;
2822
                break;
2823
            default:
2824
                break;
2825
            }
2826
        }
2827
        if (src == dst) {
2828
            deinterlace_bottom_field_inplace(dst->data[i], dst->linesize[i],
2829
                                 width, height);
2830
        } else {
2831
            deinterlace_bottom_field(dst->data[i],dst->linesize[i],
2832
                                        src->data[i], src->linesize[i],
2833
                                        width, height);
2834
        }
2835
    }
2836
#ifdef HAVE_MMX
2837
    emms();
2838
#endif
2839
    return 0;
2840
}
2841

    
2842
#undef FIX