Statistics
| Branch: | Revision:

ffmpeg / libavcodec / imgconvert.c @ 55ffe9df

History | View | Annotate | Download (76.9 KB)

1
/*
2
 * Misc image conversion 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 conversion 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
#include "colorspace.h"
36

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

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

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

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

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

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

    
132
    /* YUV formats with alpha plane */
133
    [PIX_FMT_YUVA420P] = {
134
        .name = "yuva420p",
135
        .nb_channels = 4,
136
        .color_type = FF_COLOR_YUV,
137
        .pixel_type = FF_PIXEL_PLANAR,
138
        .depth = 8,
139
        .x_chroma_shift = 1, .y_chroma_shift = 1,
140
    },
141

    
142
    /* JPEG YUV */
143
    [PIX_FMT_YUVJ420P] = {
144
        .name = "yuvj420p",
145
        .nb_channels = 3,
146
        .color_type = FF_COLOR_YUV_JPEG,
147
        .pixel_type = FF_PIXEL_PLANAR,
148
        .depth = 8,
149
        .x_chroma_shift = 1, .y_chroma_shift = 1,
150
    },
151
    [PIX_FMT_YUVJ422P] = {
152
        .name = "yuvj422p",
153
        .nb_channels = 3,
154
        .color_type = FF_COLOR_YUV_JPEG,
155
        .pixel_type = FF_PIXEL_PLANAR,
156
        .depth = 8,
157
        .x_chroma_shift = 1, .y_chroma_shift = 0,
158
    },
159
    [PIX_FMT_YUVJ444P] = {
160
        .name = "yuvj444p",
161
        .nb_channels = 3,
162
        .color_type = FF_COLOR_YUV_JPEG,
163
        .pixel_type = FF_PIXEL_PLANAR,
164
        .depth = 8,
165
        .x_chroma_shift = 0, .y_chroma_shift = 0,
166
    },
167
    [PIX_FMT_YUVJ440P] = {
168
        .name = "yuvj440p",
169
        .nb_channels = 3,
170
        .color_type = FF_COLOR_YUV_JPEG,
171
        .pixel_type = FF_PIXEL_PLANAR,
172
        .depth = 8,
173
        .x_chroma_shift = 0, .y_chroma_shift = 1,
174
    },
175

    
176
    /* RGB formats */
177
    [PIX_FMT_RGB24] = {
178
        .name = "rgb24",
179
        .nb_channels = 3,
180
        .color_type = FF_COLOR_RGB,
181
        .pixel_type = FF_PIXEL_PACKED,
182
        .depth = 8,
183
        .x_chroma_shift = 0, .y_chroma_shift = 0,
184
    },
185
    [PIX_FMT_BGR24] = {
186
        .name = "bgr24",
187
        .nb_channels = 3,
188
        .color_type = FF_COLOR_RGB,
189
        .pixel_type = FF_PIXEL_PACKED,
190
        .depth = 8,
191
        .x_chroma_shift = 0, .y_chroma_shift = 0,
192
    },
193
    [PIX_FMT_RGB32] = {
194
        .name = "rgb32",
195
        .nb_channels = 4, .is_alpha = 1,
196
        .color_type = FF_COLOR_RGB,
197
        .pixel_type = FF_PIXEL_PACKED,
198
        .depth = 8,
199
        .x_chroma_shift = 0, .y_chroma_shift = 0,
200
    },
201
    [PIX_FMT_RGB565] = {
202
        .name = "rgb565",
203
        .nb_channels = 3,
204
        .color_type = FF_COLOR_RGB,
205
        .pixel_type = FF_PIXEL_PACKED,
206
        .depth = 5,
207
        .x_chroma_shift = 0, .y_chroma_shift = 0,
208
    },
209
    [PIX_FMT_RGB555] = {
210
        .name = "rgb555",
211
        .nb_channels = 3,
212
        .color_type = FF_COLOR_RGB,
213
        .pixel_type = FF_PIXEL_PACKED,
214
        .depth = 5,
215
        .x_chroma_shift = 0, .y_chroma_shift = 0,
216
    },
217

    
218
    /* gray / mono formats */
219
    [PIX_FMT_GRAY16BE] = {
220
        .name = "gray16be",
221
        .nb_channels = 1,
222
        .color_type = FF_COLOR_GRAY,
223
        .pixel_type = FF_PIXEL_PLANAR,
224
        .depth = 16,
225
    },
226
    [PIX_FMT_GRAY16LE] = {
227
        .name = "gray16le",
228
        .nb_channels = 1,
229
        .color_type = FF_COLOR_GRAY,
230
        .pixel_type = FF_PIXEL_PLANAR,
231
        .depth = 16,
232
    },
233
    [PIX_FMT_GRAY8] = {
234
        .name = "gray",
235
        .nb_channels = 1,
236
        .color_type = FF_COLOR_GRAY,
237
        .pixel_type = FF_PIXEL_PLANAR,
238
        .depth = 8,
239
    },
240
    [PIX_FMT_MONOWHITE] = {
241
        .name = "monow",
242
        .nb_channels = 1,
243
        .color_type = FF_COLOR_GRAY,
244
        .pixel_type = FF_PIXEL_PLANAR,
245
        .depth = 1,
246
    },
247
    [PIX_FMT_MONOBLACK] = {
248
        .name = "monob",
249
        .nb_channels = 1,
250
        .color_type = FF_COLOR_GRAY,
251
        .pixel_type = FF_PIXEL_PLANAR,
252
        .depth = 1,
253
    },
254

    
255
    /* paletted formats */
256
    [PIX_FMT_PAL8] = {
257
        .name = "pal8",
258
        .nb_channels = 4, .is_alpha = 1,
259
        .color_type = FF_COLOR_RGB,
260
        .pixel_type = FF_PIXEL_PALETTE,
261
        .depth = 8,
262
    },
263
    [PIX_FMT_XVMC_MPEG2_MC] = {
264
        .name = "xvmcmc",
265
    },
266
    [PIX_FMT_XVMC_MPEG2_IDCT] = {
267
        .name = "xvmcidct",
268
    },
269
    [PIX_FMT_UYYVYY411] = {
270
        .name = "uyyvyy411",
271
        .nb_channels = 1,
272
        .color_type = FF_COLOR_YUV,
273
        .pixel_type = FF_PIXEL_PACKED,
274
        .depth = 8,
275
        .x_chroma_shift = 2, .y_chroma_shift = 0,
276
    },
277
    [PIX_FMT_BGR32] = {
278
        .name = "bgr32",
279
        .nb_channels = 4, .is_alpha = 1,
280
        .color_type = FF_COLOR_RGB,
281
        .pixel_type = FF_PIXEL_PACKED,
282
        .depth = 8,
283
        .x_chroma_shift = 0, .y_chroma_shift = 0,
284
    },
285
    [PIX_FMT_BGR565] = {
286
        .name = "bgr565",
287
        .nb_channels = 3,
288
        .color_type = FF_COLOR_RGB,
289
        .pixel_type = FF_PIXEL_PACKED,
290
        .depth = 5,
291
        .x_chroma_shift = 0, .y_chroma_shift = 0,
292
    },
293
    [PIX_FMT_BGR555] = {
294
        .name = "bgr555",
295
        .nb_channels = 3,
296
        .color_type = FF_COLOR_RGB,
297
        .pixel_type = FF_PIXEL_PACKED,
298
        .depth = 5,
299
        .x_chroma_shift = 0, .y_chroma_shift = 0,
300
    },
301
    [PIX_FMT_RGB8] = {
302
        .name = "rgb8",
303
        .nb_channels = 1,
304
        .color_type = FF_COLOR_RGB,
305
        .pixel_type = FF_PIXEL_PACKED,
306
        .depth = 8,
307
        .x_chroma_shift = 0, .y_chroma_shift = 0,
308
    },
309
    [PIX_FMT_RGB4] = {
310
        .name = "rgb4",
311
        .nb_channels = 1,
312
        .color_type = FF_COLOR_RGB,
313
        .pixel_type = FF_PIXEL_PACKED,
314
        .depth = 4,
315
        .x_chroma_shift = 0, .y_chroma_shift = 0,
316
    },
317
    [PIX_FMT_RGB4_BYTE] = {
318
        .name = "rgb4_byte",
319
        .nb_channels = 1,
320
        .color_type = FF_COLOR_RGB,
321
        .pixel_type = FF_PIXEL_PACKED,
322
        .depth = 8,
323
        .x_chroma_shift = 0, .y_chroma_shift = 0,
324
    },
325
    [PIX_FMT_BGR8] = {
326
        .name = "bgr8",
327
        .nb_channels = 1,
328
        .color_type = FF_COLOR_RGB,
329
        .pixel_type = FF_PIXEL_PACKED,
330
        .depth = 8,
331
        .x_chroma_shift = 0, .y_chroma_shift = 0,
332
    },
333
    [PIX_FMT_BGR4] = {
334
        .name = "bgr4",
335
        .nb_channels = 1,
336
        .color_type = FF_COLOR_RGB,
337
        .pixel_type = FF_PIXEL_PACKED,
338
        .depth = 4,
339
        .x_chroma_shift = 0, .y_chroma_shift = 0,
340
    },
341
    [PIX_FMT_BGR4_BYTE] = {
342
        .name = "bgr4_byte",
343
        .nb_channels = 1,
344
        .color_type = FF_COLOR_RGB,
345
        .pixel_type = FF_PIXEL_PACKED,
346
        .depth = 8,
347
        .x_chroma_shift = 0, .y_chroma_shift = 0,
348
    },
349
    [PIX_FMT_NV12] = {
350
        .name = "nv12",
351
        .nb_channels = 2,
352
        .color_type = FF_COLOR_YUV,
353
        .pixel_type = FF_PIXEL_PLANAR,
354
        .depth = 8,
355
        .x_chroma_shift = 1, .y_chroma_shift = 1,
356
    },
357
    [PIX_FMT_NV21] = {
358
        .name = "nv12",
359
        .nb_channels = 2,
360
        .color_type = FF_COLOR_YUV,
361
        .pixel_type = FF_PIXEL_PLANAR,
362
        .depth = 8,
363
        .x_chroma_shift = 1, .y_chroma_shift = 1,
364
    },
365

    
366
    [PIX_FMT_BGR32_1] = {
367
        .name = "bgr32_1",
368
        .nb_channels = 4, .is_alpha = 1,
369
        .color_type = FF_COLOR_RGB,
370
        .pixel_type = FF_PIXEL_PACKED,
371
        .depth = 8,
372
        .x_chroma_shift = 0, .y_chroma_shift = 0,
373
    },
374
    [PIX_FMT_RGB32_1] = {
375
        .name = "rgb32_1",
376
        .nb_channels = 4, .is_alpha = 1,
377
        .color_type = FF_COLOR_RGB,
378
        .pixel_type = FF_PIXEL_PACKED,
379
        .depth = 8,
380
        .x_chroma_shift = 0, .y_chroma_shift = 0,
381
    },
382
};
383

    
384
void avcodec_get_chroma_sub_sample(int pix_fmt, int *h_shift, int *v_shift)
385
{
386
    *h_shift = pix_fmt_info[pix_fmt].x_chroma_shift;
387
    *v_shift = pix_fmt_info[pix_fmt].y_chroma_shift;
388
}
389

    
390
const char *avcodec_get_pix_fmt_name(int pix_fmt)
391
{
392
    if (pix_fmt < 0 || pix_fmt >= PIX_FMT_NB)
393
        return "???";
394
    else
395
        return pix_fmt_info[pix_fmt].name;
396
}
397

    
398
enum PixelFormat avcodec_get_pix_fmt(const char* name)
399
{
400
    int i;
401

    
402
    for (i=0; i < PIX_FMT_NB; i++)
403
         if (!strcmp(pix_fmt_info[i].name, name))
404
             break;
405
    return i;
406
}
407

    
408
void avcodec_pix_fmt_string (char *buf, int buf_size, int pix_fmt)
409
{
410
    PixFmtInfo info= pix_fmt_info[pix_fmt];
411

    
412
    char is_alpha_char= info.is_alpha ? 'y' : 'n';
413

    
414
    /* print header */
415
    if (pix_fmt < 0)
416
        snprintf (buf, buf_size,
417
                  "name      " " nb_channels" " depth" " is_alpha"
418
            );
419
    else
420
        snprintf (buf, buf_size,
421
                  "%-10s" "      %1d     " "   %2d " "     %c   ",
422
                  info.name,
423
                  info.nb_channels,
424
                  info.depth,
425
                  is_alpha_char
426
            );
427
}
428

    
429
int avpicture_fill(AVPicture *picture, uint8_t *ptr,
430
                   int pix_fmt, int width, int height)
431
{
432
    int size, w2, h2, size2;
433
    const PixFmtInfo *pinfo;
434

    
435
    if(avcodec_check_dimensions(NULL, width, height))
436
        goto fail;
437

    
438
    pinfo = &pix_fmt_info[pix_fmt];
439
    size = width * height;
440
    switch(pix_fmt) {
441
    case PIX_FMT_YUV420P:
442
    case PIX_FMT_YUV422P:
443
    case PIX_FMT_YUV444P:
444
    case PIX_FMT_YUV410P:
445
    case PIX_FMT_YUV411P:
446
    case PIX_FMT_YUV440P:
447
    case PIX_FMT_YUVJ420P:
448
    case PIX_FMT_YUVJ422P:
449
    case PIX_FMT_YUVJ444P:
450
    case PIX_FMT_YUVJ440P:
451
        w2 = (width + (1 << pinfo->x_chroma_shift) - 1) >> pinfo->x_chroma_shift;
452
        h2 = (height + (1 << pinfo->y_chroma_shift) - 1) >> pinfo->y_chroma_shift;
453
        size2 = w2 * h2;
454
        picture->data[0] = ptr;
455
        picture->data[1] = picture->data[0] + size;
456
        picture->data[2] = picture->data[1] + size2;
457
        picture->data[3] = NULL;
458
        picture->linesize[0] = width;
459
        picture->linesize[1] = w2;
460
        picture->linesize[2] = w2;
461
        picture->linesize[3] = 0;
462
        return size + 2 * size2;
463
    case PIX_FMT_YUVA420P:
464
        w2 = (width + (1 << pinfo->x_chroma_shift) - 1) >> pinfo->x_chroma_shift;
465
        h2 = (height + (1 << pinfo->y_chroma_shift) - 1) >> pinfo->y_chroma_shift;
466
        size2 = w2 * h2;
467
        picture->data[0] = ptr;
468
        picture->data[1] = picture->data[0] + size;
469
        picture->data[2] = picture->data[1] + size2;
470
        picture->data[3] = picture->data[1] + size2 + size2;
471
        picture->linesize[0] = width;
472
        picture->linesize[1] = w2;
473
        picture->linesize[2] = w2;
474
        picture->linesize[3] = width;
475
        return 2 * size + 2 * size2;
476
    case PIX_FMT_NV12:
477
    case PIX_FMT_NV21:
478
        w2 = (width + (1 << pinfo->x_chroma_shift) - 1) >> pinfo->x_chroma_shift;
479
        h2 = (height + (1 << pinfo->y_chroma_shift) - 1) >> pinfo->y_chroma_shift;
480
        size2 = w2 * h2 * 2;
481
        picture->data[0] = ptr;
482
        picture->data[1] = picture->data[0] + size;
483
        picture->data[2] = NULL;
484
        picture->data[3] = NULL;
485
        picture->linesize[0] = width;
486
        picture->linesize[1] = w2;
487
        picture->linesize[2] = 0;
488
        picture->linesize[3] = 0;
489
        return size + 2 * size2;
490
    case PIX_FMT_RGB24:
491
    case PIX_FMT_BGR24:
492
        picture->data[0] = ptr;
493
        picture->data[1] = NULL;
494
        picture->data[2] = NULL;
495
        picture->data[3] = NULL;
496
        picture->linesize[0] = width * 3;
497
        return size * 3;
498
    case PIX_FMT_RGB32:
499
    case PIX_FMT_BGR32:
500
    case PIX_FMT_RGB32_1:
501
    case PIX_FMT_BGR32_1:
502
        picture->data[0] = ptr;
503
        picture->data[1] = NULL;
504
        picture->data[2] = NULL;
505
        picture->data[3] = NULL;
506
        picture->linesize[0] = width * 4;
507
        return size * 4;
508
    case PIX_FMT_GRAY16BE:
509
    case PIX_FMT_GRAY16LE:
510
    case PIX_FMT_BGR555:
511
    case PIX_FMT_BGR565:
512
    case PIX_FMT_RGB555:
513
    case PIX_FMT_RGB565:
514
    case PIX_FMT_YUYV422:
515
        picture->data[0] = ptr;
516
        picture->data[1] = NULL;
517
        picture->data[2] = NULL;
518
        picture->data[3] = NULL;
519
        picture->linesize[0] = width * 2;
520
        return size * 2;
521
    case PIX_FMT_UYVY422:
522
        picture->data[0] = ptr;
523
        picture->data[1] = NULL;
524
        picture->data[2] = NULL;
525
        picture->data[3] = NULL;
526
        picture->linesize[0] = width * 2;
527
        return size * 2;
528
    case PIX_FMT_UYYVYY411:
529
        picture->data[0] = ptr;
530
        picture->data[1] = NULL;
531
        picture->data[2] = NULL;
532
        picture->data[3] = NULL;
533
        picture->linesize[0] = width + width/2;
534
        return size + size/2;
535
    case PIX_FMT_RGB8:
536
    case PIX_FMT_BGR8:
537
    case PIX_FMT_RGB4_BYTE:
538
    case PIX_FMT_BGR4_BYTE:
539
    case PIX_FMT_GRAY8:
540
        picture->data[0] = ptr;
541
        picture->data[1] = NULL;
542
        picture->data[2] = NULL;
543
        picture->data[3] = NULL;
544
        picture->linesize[0] = width;
545
        return size;
546
    case PIX_FMT_RGB4:
547
    case PIX_FMT_BGR4:
548
        picture->data[0] = ptr;
549
        picture->data[1] = NULL;
550
        picture->data[2] = NULL;
551
        picture->data[3] = NULL;
552
        picture->linesize[0] = width / 2;
553
        return size / 2;
554
    case PIX_FMT_MONOWHITE:
555
    case PIX_FMT_MONOBLACK:
556
        picture->data[0] = ptr;
557
        picture->data[1] = NULL;
558
        picture->data[2] = NULL;
559
        picture->data[3] = NULL;
560
        picture->linesize[0] = (width + 7) >> 3;
561
        return picture->linesize[0] * height;
562
    case PIX_FMT_PAL8:
563
        size2 = (size + 3) & ~3;
564
        picture->data[0] = ptr;
565
        picture->data[1] = ptr + size2; /* palette is stored here as 256 32 bit words */
566
        picture->data[2] = NULL;
567
        picture->data[3] = NULL;
568
        picture->linesize[0] = width;
569
        picture->linesize[1] = 4;
570
        return size2 + 256 * 4;
571
    default:
572
fail:
573
        picture->data[0] = NULL;
574
        picture->data[1] = NULL;
575
        picture->data[2] = NULL;
576
        picture->data[3] = NULL;
577
        return -1;
578
    }
579
}
580

    
581
int avpicture_layout(const AVPicture* src, int pix_fmt, int width, int height,
582
                     unsigned char *dest, int dest_size)
583
{
584
    const PixFmtInfo* pf = &pix_fmt_info[pix_fmt];
585
    int i, j, w, h, data_planes;
586
    const unsigned char* s;
587
    int size = avpicture_get_size(pix_fmt, width, height);
588

    
589
    if (size > dest_size || size < 0)
590
        return -1;
591

    
592
    if (pf->pixel_type == FF_PIXEL_PACKED || pf->pixel_type == FF_PIXEL_PALETTE) {
593
        if (pix_fmt == PIX_FMT_YUYV422 ||
594
            pix_fmt == PIX_FMT_UYVY422 ||
595
            pix_fmt == PIX_FMT_BGR565 ||
596
            pix_fmt == PIX_FMT_BGR555 ||
597
            pix_fmt == PIX_FMT_RGB565 ||
598
            pix_fmt == PIX_FMT_RGB555)
599
            w = width * 2;
600
        else if (pix_fmt == PIX_FMT_UYYVYY411)
601
          w = width + width/2;
602
        else if (pix_fmt == PIX_FMT_PAL8)
603
          w = width;
604
        else
605
          w = width * (pf->depth * pf->nb_channels / 8);
606

    
607
        data_planes = 1;
608
        h = height;
609
    } else {
610
        data_planes = pf->nb_channels;
611
        w = (width*pf->depth + 7)/8;
612
        h = height;
613
    }
614

    
615
    for (i=0; i<data_planes; i++) {
616
         if (i == 1) {
617
             w = width >> pf->x_chroma_shift;
618
             h = height >> pf->y_chroma_shift;
619
         }
620
         s = src->data[i];
621
         for(j=0; j<h; j++) {
622
             memcpy(dest, s, w);
623
             dest += w;
624
             s += src->linesize[i];
625
         }
626
    }
627

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

    
631
    return size;
632
}
633

    
634
int avpicture_get_size(int pix_fmt, int width, int height)
635
{
636
    AVPicture dummy_pict;
637
    return avpicture_fill(&dummy_pict, NULL, pix_fmt, width, height);
638
}
639

    
640
int avcodec_get_pix_fmt_loss(int dst_pix_fmt, int src_pix_fmt,
641
                             int has_alpha)
642
{
643
    const PixFmtInfo *pf, *ps;
644
    int loss;
645

    
646
    ps = &pix_fmt_info[src_pix_fmt];
647
    pf = &pix_fmt_info[dst_pix_fmt];
648

    
649
    /* compute loss */
650
    loss = 0;
651
    pf = &pix_fmt_info[dst_pix_fmt];
652
    if (pf->depth < ps->depth ||
653
        (dst_pix_fmt == PIX_FMT_RGB555 && src_pix_fmt == PIX_FMT_RGB565))
654
        loss |= FF_LOSS_DEPTH;
655
    if (pf->x_chroma_shift > ps->x_chroma_shift ||
656
        pf->y_chroma_shift > ps->y_chroma_shift)
657
        loss |= FF_LOSS_RESOLUTION;
658
    switch(pf->color_type) {
659
    case FF_COLOR_RGB:
660
        if (ps->color_type != FF_COLOR_RGB &&
661
            ps->color_type != FF_COLOR_GRAY)
662
            loss |= FF_LOSS_COLORSPACE;
663
        break;
664
    case FF_COLOR_GRAY:
665
        if (ps->color_type != FF_COLOR_GRAY)
666
            loss |= FF_LOSS_COLORSPACE;
667
        break;
668
    case FF_COLOR_YUV:
669
        if (ps->color_type != FF_COLOR_YUV)
670
            loss |= FF_LOSS_COLORSPACE;
671
        break;
672
    case FF_COLOR_YUV_JPEG:
673
        if (ps->color_type != FF_COLOR_YUV_JPEG &&
674
            ps->color_type != FF_COLOR_YUV &&
675
            ps->color_type != FF_COLOR_GRAY)
676
            loss |= FF_LOSS_COLORSPACE;
677
        break;
678
    default:
679
        /* fail safe test */
680
        if (ps->color_type != pf->color_type)
681
            loss |= FF_LOSS_COLORSPACE;
682
        break;
683
    }
684
    if (pf->color_type == FF_COLOR_GRAY &&
685
        ps->color_type != FF_COLOR_GRAY)
686
        loss |= FF_LOSS_CHROMA;
687
    if (!pf->is_alpha && (ps->is_alpha && has_alpha))
688
        loss |= FF_LOSS_ALPHA;
689
    if (pf->pixel_type == FF_PIXEL_PALETTE &&
690
        (ps->pixel_type != FF_PIXEL_PALETTE && ps->color_type != FF_COLOR_GRAY))
691
        loss |= FF_LOSS_COLORQUANT;
692
    return loss;
693
}
694

    
695
static int avg_bits_per_pixel(int pix_fmt)
696
{
697
    int bits;
698
    const PixFmtInfo *pf;
699

    
700
    pf = &pix_fmt_info[pix_fmt];
701
    switch(pf->pixel_type) {
702
    case FF_PIXEL_PACKED:
703
        switch(pix_fmt) {
704
        case PIX_FMT_YUYV422:
705
        case PIX_FMT_UYVY422:
706
        case PIX_FMT_RGB565:
707
        case PIX_FMT_RGB555:
708
        case PIX_FMT_BGR565:
709
        case PIX_FMT_BGR555:
710
            bits = 16;
711
            break;
712
        case PIX_FMT_UYYVYY411:
713
            bits = 12;
714
            break;
715
        default:
716
            bits = pf->depth * pf->nb_channels;
717
            break;
718
        }
719
        break;
720
    case FF_PIXEL_PLANAR:
721
        if (pf->x_chroma_shift == 0 && pf->y_chroma_shift == 0) {
722
            bits = pf->depth * pf->nb_channels;
723
        } else {
724
            bits = pf->depth + ((2 * pf->depth) >>
725
                                (pf->x_chroma_shift + pf->y_chroma_shift));
726
        }
727
        break;
728
    case FF_PIXEL_PALETTE:
729
        bits = 8;
730
        break;
731
    default:
732
        bits = -1;
733
        break;
734
    }
735
    return bits;
736
}
737

    
738
static int avcodec_find_best_pix_fmt1(int pix_fmt_mask,
739
                                      int src_pix_fmt,
740
                                      int has_alpha,
741
                                      int loss_mask)
742
{
743
    int dist, i, loss, min_dist, dst_pix_fmt;
744

    
745
    /* find exact color match with smallest size */
746
    dst_pix_fmt = -1;
747
    min_dist = 0x7fffffff;
748
    for(i = 0;i < PIX_FMT_NB; i++) {
749
        if (pix_fmt_mask & (1 << i)) {
750
            loss = avcodec_get_pix_fmt_loss(i, src_pix_fmt, has_alpha) & loss_mask;
751
            if (loss == 0) {
752
                dist = avg_bits_per_pixel(i);
753
                if (dist < min_dist) {
754
                    min_dist = dist;
755
                    dst_pix_fmt = i;
756
                }
757
            }
758
        }
759
    }
760
    return dst_pix_fmt;
761
}
762

    
763
int avcodec_find_best_pix_fmt(int pix_fmt_mask, int src_pix_fmt,
764
                              int has_alpha, int *loss_ptr)
765
{
766
    int dst_pix_fmt, loss_mask, i;
767
    static const int loss_mask_order[] = {
768
        ~0, /* no loss first */
769
        ~FF_LOSS_ALPHA,
770
        ~FF_LOSS_RESOLUTION,
771
        ~(FF_LOSS_COLORSPACE | FF_LOSS_RESOLUTION),
772
        ~FF_LOSS_COLORQUANT,
773
        ~FF_LOSS_DEPTH,
774
        0,
775
    };
776

    
777
    /* try with successive loss */
778
    i = 0;
779
    for(;;) {
780
        loss_mask = loss_mask_order[i++];
781
        dst_pix_fmt = avcodec_find_best_pix_fmt1(pix_fmt_mask, src_pix_fmt,
782
                                                 has_alpha, loss_mask);
783
        if (dst_pix_fmt >= 0)
784
            goto found;
785
        if (loss_mask == 0)
786
            break;
787
    }
788
    return -1;
789
 found:
790
    if (loss_ptr)
791
        *loss_ptr = avcodec_get_pix_fmt_loss(dst_pix_fmt, src_pix_fmt, has_alpha);
792
    return dst_pix_fmt;
793
}
794

    
795
void ff_img_copy_plane(uint8_t *dst, int dst_wrap,
796
                           const uint8_t *src, int src_wrap,
797
                           int width, int height)
798
{
799
    if((!dst) || (!src))
800
        return;
801
    for(;height > 0; height--) {
802
        memcpy(dst, src, width);
803
        dst += dst_wrap;
804
        src += src_wrap;
805
    }
806
}
807

    
808
void av_picture_copy(AVPicture *dst, const AVPicture *src,
809
              int pix_fmt, int width, int height)
810
{
811
    int bwidth, bits, i;
812
    const PixFmtInfo *pf = &pix_fmt_info[pix_fmt];
813

    
814
    pf = &pix_fmt_info[pix_fmt];
815
    switch(pf->pixel_type) {
816
    case FF_PIXEL_PACKED:
817
        switch(pix_fmt) {
818
        case PIX_FMT_YUYV422:
819
        case PIX_FMT_UYVY422:
820
        case PIX_FMT_RGB565:
821
        case PIX_FMT_RGB555:
822
        case PIX_FMT_BGR565:
823
        case PIX_FMT_BGR555:
824
            bits = 16;
825
            break;
826
        case PIX_FMT_UYYVYY411:
827
            bits = 12;
828
            break;
829
        default:
830
            bits = pf->depth * pf->nb_channels;
831
            break;
832
        }
833
        bwidth = (width * bits + 7) >> 3;
834
        ff_img_copy_plane(dst->data[0], dst->linesize[0],
835
                       src->data[0], src->linesize[0],
836
                       bwidth, height);
837
        break;
838
    case FF_PIXEL_PLANAR:
839
        for(i = 0; i < pf->nb_channels; i++) {
840
            int w, h;
841
            w = width;
842
            h = height;
843
            if (i == 1 || i == 2) {
844
                w >>= pf->x_chroma_shift;
845
                h >>= pf->y_chroma_shift;
846
            }
847
            bwidth = (w * pf->depth + 7) >> 3;
848
            ff_img_copy_plane(dst->data[i], dst->linesize[i],
849
                           src->data[i], src->linesize[i],
850
                           bwidth, h);
851
        }
852
        break;
853
    case FF_PIXEL_PALETTE:
854
        ff_img_copy_plane(dst->data[0], dst->linesize[0],
855
                       src->data[0], src->linesize[0],
856
                       width, height);
857
        /* copy the palette */
858
        ff_img_copy_plane(dst->data[1], dst->linesize[1],
859
                       src->data[1], src->linesize[1],
860
                       4, 256);
861
        break;
862
    }
863
}
864

    
865
/* XXX: totally non optimized */
866

    
867
static void yuyv422_to_yuv420p(AVPicture *dst, const AVPicture *src,
868
                              int width, int height)
869
{
870
    const uint8_t *p, *p1;
871
    uint8_t *lum, *cr, *cb, *lum1, *cr1, *cb1;
872
    int w;
873

    
874
    p1 = src->data[0];
875
    lum1 = dst->data[0];
876
    cb1 = dst->data[1];
877
    cr1 = dst->data[2];
878

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

    
923
static void uyvy422_to_yuv420p(AVPicture *dst, const AVPicture *src,
924
                              int width, int height)
925
{
926
    const uint8_t *p, *p1;
927
    uint8_t *lum, *cr, *cb, *lum1, *cr1, *cb1;
928
    int w;
929

    
930
    p1 = src->data[0];
931

    
932
    lum1 = dst->data[0];
933
    cb1 = dst->data[1];
934
    cr1 = dst->data[2];
935

    
936
    for(;height >= 1; height -= 2) {
937
        p = p1;
938
        lum = lum1;
939
        cb = cb1;
940
        cr = cr1;
941
        for(w = width; w >= 2; w -= 2) {
942
            lum[0] = p[1];
943
            cb[0] = p[0];
944
            lum[1] = p[3];
945
            cr[0] = p[2];
946
            p += 4;
947
            lum += 2;
948
            cb++;
949
            cr++;
950
        }
951
        if (w) {
952
            lum[0] = p[1];
953
            cb[0] = p[0];
954
            cr[0] = p[2];
955
            cb++;
956
            cr++;
957
        }
958
        p1 += src->linesize[0];
959
        lum1 += dst->linesize[0];
960
        if (height>1) {
961
            p = p1;
962
            lum = lum1;
963
            for(w = width; w >= 2; w -= 2) {
964
                lum[0] = p[1];
965
                lum[1] = p[3];
966
                p += 4;
967
                lum += 2;
968
            }
969
            if (w) {
970
                lum[0] = p[1];
971
            }
972
            p1 += src->linesize[0];
973
            lum1 += dst->linesize[0];
974
        }
975
        cb1 += dst->linesize[1];
976
        cr1 += dst->linesize[2];
977
    }
978
}
979

    
980

    
981
static void uyvy422_to_yuv422p(AVPicture *dst, const AVPicture *src,
982
                              int width, int height)
983
{
984
    const uint8_t *p, *p1;
985
    uint8_t *lum, *cr, *cb, *lum1, *cr1, *cb1;
986
    int w;
987

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

    
1014

    
1015
static void yuyv422_to_yuv422p(AVPicture *dst, const AVPicture *src,
1016
                              int width, int height)
1017
{
1018
    const uint8_t *p, *p1;
1019
    uint8_t *lum, *cr, *cb, *lum1, *cr1, *cb1;
1020
    int w;
1021

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

    
1048
static void yuv422p_to_yuyv422(AVPicture *dst, const AVPicture *src,
1049
                              int width, int height)
1050
{
1051
    uint8_t *p, *p1;
1052
    const uint8_t *lum, *cr, *cb, *lum1, *cr1, *cb1;
1053
    int w;
1054

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

    
1081
static void yuv422p_to_uyvy422(AVPicture *dst, const AVPicture *src,
1082
                              int width, int height)
1083
{
1084
    uint8_t *p, *p1;
1085
    const uint8_t *lum, *cr, *cb, *lum1, *cr1, *cb1;
1086
    int w;
1087

    
1088
    p1 = dst->data[0];
1089
    lum1 = src->data[0];
1090
    cb1 = src->data[1];
1091
    cr1 = src->data[2];
1092
    for(;height > 0; height--) {
1093
        p = p1;
1094
        lum = lum1;
1095
        cb = cb1;
1096
        cr = cr1;
1097
        for(w = width; w >= 2; w -= 2) {
1098
            p[1] = lum[0];
1099
            p[0] = cb[0];
1100
            p[3] = lum[1];
1101
            p[2] = cr[0];
1102
            p += 4;
1103
            lum += 2;
1104
            cb++;
1105
            cr++;
1106
        }
1107
        p1 += dst->linesize[0];
1108
        lum1 += src->linesize[0];
1109
        cb1 += src->linesize[1];
1110
        cr1 += src->linesize[2];
1111
    }
1112
}
1113

    
1114
static void uyyvyy411_to_yuv411p(AVPicture *dst, const AVPicture *src,
1115
                              int width, int height)
1116
{
1117
    const uint8_t *p, *p1;
1118
    uint8_t *lum, *cr, *cb, *lum1, *cr1, *cb1;
1119
    int w;
1120

    
1121
    p1 = src->data[0];
1122
    lum1 = dst->data[0];
1123
    cb1 = dst->data[1];
1124
    cr1 = dst->data[2];
1125
    for(;height > 0; height--) {
1126
        p = p1;
1127
        lum = lum1;
1128
        cb = cb1;
1129
        cr = cr1;
1130
        for(w = width; w >= 4; w -= 4) {
1131
            cb[0] = p[0];
1132
            lum[0] = p[1];
1133
            lum[1] = p[2];
1134
            cr[0] = p[3];
1135
            lum[2] = p[4];
1136
            lum[3] = p[5];
1137
            p += 6;
1138
            lum += 4;
1139
            cb++;
1140
            cr++;
1141
        }
1142
        p1 += src->linesize[0];
1143
        lum1 += dst->linesize[0];
1144
        cb1 += dst->linesize[1];
1145
        cr1 += dst->linesize[2];
1146
    }
1147
}
1148

    
1149

    
1150
static void yuv420p_to_yuyv422(AVPicture *dst, const AVPicture *src,
1151
                              int width, int height)
1152
{
1153
    int w, h;
1154
    uint8_t *line1, *line2, *linesrc = dst->data[0];
1155
    uint8_t *lum1, *lum2, *lumsrc = src->data[0];
1156
    uint8_t *cb1, *cb2 = src->data[1];
1157
    uint8_t *cr1, *cr2 = src->data[2];
1158

    
1159
    for(h = height / 2; h--;) {
1160
        line1 = linesrc;
1161
        line2 = linesrc + dst->linesize[0];
1162

    
1163
        lum1 = lumsrc;
1164
        lum2 = lumsrc + src->linesize[0];
1165

    
1166
        cb1 = cb2;
1167
        cr1 = cr2;
1168

    
1169
        for(w = width / 2; w--;) {
1170
                *line1++ = *lum1++; *line2++ = *lum2++;
1171
                *line1++ =          *line2++ = *cb1++;
1172
                *line1++ = *lum1++; *line2++ = *lum2++;
1173
                *line1++ =          *line2++ = *cr1++;
1174
        }
1175

    
1176
        linesrc += dst->linesize[0] * 2;
1177
        lumsrc += src->linesize[0] * 2;
1178
        cb2 += src->linesize[1];
1179
        cr2 += src->linesize[2];
1180
    }
1181
}
1182

    
1183
static void yuv420p_to_uyvy422(AVPicture *dst, const AVPicture *src,
1184
                              int width, int height)
1185
{
1186
    int w, h;
1187
    uint8_t *line1, *line2, *linesrc = dst->data[0];
1188
    uint8_t *lum1, *lum2, *lumsrc = src->data[0];
1189
    uint8_t *cb1, *cb2 = src->data[1];
1190
    uint8_t *cr1, *cr2 = src->data[2];
1191

    
1192
    for(h = height / 2; h--;) {
1193
        line1 = linesrc;
1194
        line2 = linesrc + dst->linesize[0];
1195

    
1196
        lum1 = lumsrc;
1197
        lum2 = lumsrc + src->linesize[0];
1198

    
1199
        cb1 = cb2;
1200
        cr1 = cr2;
1201

    
1202
        for(w = width / 2; w--;) {
1203
                *line1++ =          *line2++ = *cb1++;
1204
                *line1++ = *lum1++; *line2++ = *lum2++;
1205
                *line1++ =          *line2++ = *cr1++;
1206
                *line1++ = *lum1++; *line2++ = *lum2++;
1207
        }
1208

    
1209
        linesrc += dst->linesize[0] * 2;
1210
        lumsrc += src->linesize[0] * 2;
1211
        cb2 += src->linesize[1];
1212
        cr2 += src->linesize[2];
1213
    }
1214
}
1215

    
1216
static uint8_t y_ccir_to_jpeg[256];
1217
static uint8_t y_jpeg_to_ccir[256];
1218
static uint8_t c_ccir_to_jpeg[256];
1219
static uint8_t c_jpeg_to_ccir[256];
1220

    
1221
/* init various conversion tables */
1222
static void img_convert_init(void)
1223
{
1224
    int i;
1225
    uint8_t *cm = ff_cropTbl + MAX_NEG_CROP;
1226

    
1227
    for(i = 0;i < 256; i++) {
1228
        y_ccir_to_jpeg[i] = Y_CCIR_TO_JPEG(i);
1229
        y_jpeg_to_ccir[i] = Y_JPEG_TO_CCIR(i);
1230
        c_ccir_to_jpeg[i] = C_CCIR_TO_JPEG(i);
1231
        c_jpeg_to_ccir[i] = C_JPEG_TO_CCIR(i);
1232
    }
1233
}
1234

    
1235
/* apply to each pixel the given table */
1236
static void img_apply_table(uint8_t *dst, int dst_wrap,
1237
                            const uint8_t *src, int src_wrap,
1238
                            int width, int height, const uint8_t *table1)
1239
{
1240
    int n;
1241
    const uint8_t *s;
1242
    uint8_t *d;
1243
    const uint8_t *table;
1244

    
1245
    table = table1;
1246
    for(;height > 0; height--) {
1247
        s = src;
1248
        d = dst;
1249
        n = width;
1250
        while (n >= 4) {
1251
            d[0] = table[s[0]];
1252
            d[1] = table[s[1]];
1253
            d[2] = table[s[2]];
1254
            d[3] = table[s[3]];
1255
            d += 4;
1256
            s += 4;
1257
            n -= 4;
1258
        }
1259
        while (n > 0) {
1260
            d[0] = table[s[0]];
1261
            d++;
1262
            s++;
1263
            n--;
1264
        }
1265
        dst += dst_wrap;
1266
        src += src_wrap;
1267
    }
1268
}
1269

    
1270
/* XXX: use generic filter ? */
1271
/* XXX: in most cases, the sampling position is incorrect */
1272

    
1273
/* 4x1 -> 1x1 */
1274
static void shrink41(uint8_t *dst, int dst_wrap,
1275
                     const uint8_t *src, int src_wrap,
1276
                     int width, int height)
1277
{
1278
    int w;
1279
    const uint8_t *s;
1280
    uint8_t *d;
1281

    
1282
    for(;height > 0; height--) {
1283
        s = src;
1284
        d = dst;
1285
        for(w = width;w > 0; w--) {
1286
            d[0] = (s[0] + s[1] + s[2] + s[3] + 2) >> 2;
1287
            s += 4;
1288
            d++;
1289
        }
1290
        src += src_wrap;
1291
        dst += dst_wrap;
1292
    }
1293
}
1294

    
1295
/* 2x1 -> 1x1 */
1296
static void shrink21(uint8_t *dst, int dst_wrap,
1297
                     const uint8_t *src, int src_wrap,
1298
                     int width, int height)
1299
{
1300
    int w;
1301
    const uint8_t *s;
1302
    uint8_t *d;
1303

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

    
1317
/* 1x2 -> 1x1 */
1318
static void shrink12(uint8_t *dst, int dst_wrap,
1319
                     const uint8_t *src, int src_wrap,
1320
                     int width, int height)
1321
{
1322
    int w;
1323
    uint8_t *d;
1324
    const uint8_t *s1, *s2;
1325

    
1326
    for(;height > 0; height--) {
1327
        s1 = src;
1328
        s2 = s1 + src_wrap;
1329
        d = dst;
1330
        for(w = width;w >= 4; w-=4) {
1331
            d[0] = (s1[0] + s2[0]) >> 1;
1332
            d[1] = (s1[1] + s2[1]) >> 1;
1333
            d[2] = (s1[2] + s2[2]) >> 1;
1334
            d[3] = (s1[3] + s2[3]) >> 1;
1335
            s1 += 4;
1336
            s2 += 4;
1337
            d += 4;
1338
        }
1339
        for(;w > 0; w--) {
1340
            d[0] = (s1[0] + s2[0]) >> 1;
1341
            s1++;
1342
            s2++;
1343
            d++;
1344
        }
1345
        src += 2 * src_wrap;
1346
        dst += dst_wrap;
1347
    }
1348
}
1349

    
1350
/* 2x2 -> 1x1 */
1351
void ff_shrink22(uint8_t *dst, int dst_wrap,
1352
                     const uint8_t *src, int src_wrap,
1353
                     int width, int height)
1354
{
1355
    int w;
1356
    const uint8_t *s1, *s2;
1357
    uint8_t *d;
1358

    
1359
    for(;height > 0; height--) {
1360
        s1 = src;
1361
        s2 = s1 + src_wrap;
1362
        d = dst;
1363
        for(w = width;w >= 4; w-=4) {
1364
            d[0] = (s1[0] + s1[1] + s2[0] + s2[1] + 2) >> 2;
1365
            d[1] = (s1[2] + s1[3] + s2[2] + s2[3] + 2) >> 2;
1366
            d[2] = (s1[4] + s1[5] + s2[4] + s2[5] + 2) >> 2;
1367
            d[3] = (s1[6] + s1[7] + s2[6] + s2[7] + 2) >> 2;
1368
            s1 += 8;
1369
            s2 += 8;
1370
            d += 4;
1371
        }
1372
        for(;w > 0; w--) {
1373
            d[0] = (s1[0] + s1[1] + s2[0] + s2[1] + 2) >> 2;
1374
            s1 += 2;
1375
            s2 += 2;
1376
            d++;
1377
        }
1378
        src += 2 * src_wrap;
1379
        dst += dst_wrap;
1380
    }
1381
}
1382

    
1383
/* 4x4 -> 1x1 */
1384
void ff_shrink44(uint8_t *dst, int dst_wrap,
1385
                     const uint8_t *src, int src_wrap,
1386
                     int width, int height)
1387
{
1388
    int w;
1389
    const uint8_t *s1, *s2, *s3, *s4;
1390
    uint8_t *d;
1391

    
1392
    for(;height > 0; height--) {
1393
        s1 = src;
1394
        s2 = s1 + src_wrap;
1395
        s3 = s2 + src_wrap;
1396
        s4 = s3 + src_wrap;
1397
        d = dst;
1398
        for(w = width;w > 0; w--) {
1399
            d[0] = (s1[0] + s1[1] + s1[2] + s1[3] +
1400
                    s2[0] + s2[1] + s2[2] + s2[3] +
1401
                    s3[0] + s3[1] + s3[2] + s3[3] +
1402
                    s4[0] + s4[1] + s4[2] + s4[3] + 8) >> 4;
1403
            s1 += 4;
1404
            s2 += 4;
1405
            s3 += 4;
1406
            s4 += 4;
1407
            d++;
1408
        }
1409
        src += 4 * src_wrap;
1410
        dst += dst_wrap;
1411
    }
1412
}
1413

    
1414
/* 8x8 -> 1x1 */
1415
void ff_shrink88(uint8_t *dst, int dst_wrap,
1416
                     const uint8_t *src, int src_wrap,
1417
                     int width, int height)
1418
{
1419
    int w, i;
1420

    
1421
    for(;height > 0; height--) {
1422
        for(w = width;w > 0; w--) {
1423
            int tmp=0;
1424
            for(i=0; i<8; i++){
1425
                tmp += src[0] + src[1] + src[2] + src[3] + src[4] + src[5] + src[6] + src[7];
1426
                src += src_wrap;
1427
            }
1428
            *(dst++) = (tmp + 32)>>6;
1429
            src += 8 - 8*src_wrap;
1430
        }
1431
        src += 8*src_wrap - 8*width;
1432
        dst += dst_wrap - width;
1433
    }
1434
}
1435

    
1436
static void grow21_line(uint8_t *dst, const uint8_t *src,
1437
                        int width)
1438
{
1439
    int w;
1440
    const uint8_t *s1;
1441
    uint8_t *d;
1442

    
1443
    s1 = src;
1444
    d = dst;
1445
    for(w = width;w >= 4; w-=4) {
1446
        d[1] = d[0] = s1[0];
1447
        d[3] = d[2] = s1[1];
1448
        s1 += 2;
1449
        d += 4;
1450
    }
1451
    for(;w >= 2; w -= 2) {
1452
        d[1] = d[0] = s1[0];
1453
        s1 ++;
1454
        d += 2;
1455
    }
1456
    /* only needed if width is not a multiple of two */
1457
    /* XXX: veryfy that */
1458
    if (w) {
1459
        d[0] = s1[0];
1460
    }
1461
}
1462

    
1463
static void grow41_line(uint8_t *dst, const uint8_t *src,
1464
                        int width)
1465
{
1466
    int w, v;
1467
    const uint8_t *s1;
1468
    uint8_t *d;
1469

    
1470
    s1 = src;
1471
    d = dst;
1472
    for(w = width;w >= 4; w-=4) {
1473
        v = s1[0];
1474
        d[0] = v;
1475
        d[1] = v;
1476
        d[2] = v;
1477
        d[3] = v;
1478
        s1 ++;
1479
        d += 4;
1480
    }
1481
}
1482

    
1483
/* 1x1 -> 2x1 */
1484
static void grow21(uint8_t *dst, int dst_wrap,
1485
                   const uint8_t *src, int src_wrap,
1486
                   int width, int height)
1487
{
1488
    for(;height > 0; height--) {
1489
        grow21_line(dst, src, width);
1490
        src += src_wrap;
1491
        dst += dst_wrap;
1492
    }
1493
}
1494

    
1495
/* 1x1 -> 1x2 */
1496
static void grow12(uint8_t *dst, int dst_wrap,
1497
                   const uint8_t *src, int src_wrap,
1498
                   int width, int height)
1499
{
1500
    for(;height > 0; height-=2) {
1501
        memcpy(dst, src, width);
1502
        dst += dst_wrap;
1503
        memcpy(dst, src, width);
1504
        dst += dst_wrap;
1505
        src += src_wrap;
1506
    }
1507
}
1508

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

    
1522
/* 1x1 -> 4x1 */
1523
static void grow41(uint8_t *dst, int dst_wrap,
1524
                   const uint8_t *src, int src_wrap,
1525
                   int width, int height)
1526
{
1527
    for(;height > 0; height--) {
1528
        grow41_line(dst, src, width);
1529
        src += src_wrap;
1530
        dst += dst_wrap;
1531
    }
1532
}
1533

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

    
1547
/* 1x2 -> 2x1 */
1548
static void conv411(uint8_t *dst, int dst_wrap,
1549
                    const uint8_t *src, int src_wrap,
1550
                    int width, int height)
1551
{
1552
    int w, c;
1553
    const uint8_t *s1, *s2;
1554
    uint8_t *d;
1555

    
1556
    width>>=1;
1557

    
1558
    for(;height > 0; height--) {
1559
        s1 = src;
1560
        s2 = src + src_wrap;
1561
        d = dst;
1562
        for(w = width;w > 0; w--) {
1563
            c = (s1[0] + s2[0]) >> 1;
1564
            d[0] = c;
1565
            d[1] = c;
1566
            s1++;
1567
            s2++;
1568
            d += 2;
1569
        }
1570
        src += src_wrap * 2;
1571
        dst += dst_wrap;
1572
    }
1573
}
1574

    
1575
/* XXX: add jpeg quantize code */
1576

    
1577
#define TRANSP_INDEX (6*6*6)
1578

    
1579
/* this is maybe slow, but allows for extensions */
1580
static inline unsigned char gif_clut_index(uint8_t r, uint8_t g, uint8_t b)
1581
{
1582
    return ((((r)/47)%6)*6*6+(((g)/47)%6)*6+(((b)/47)%6));
1583
}
1584

    
1585
static void build_rgb_palette(uint8_t *palette, int has_alpha)
1586
{
1587
    uint32_t *pal;
1588
    static const uint8_t pal_value[6] = { 0x00, 0x33, 0x66, 0x99, 0xcc, 0xff };
1589
    int i, r, g, b;
1590

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

    
1607
/* copy bit n to bits 0 ... n - 1 */
1608
static inline unsigned int bitcopy_n(unsigned int a, int n)
1609
{
1610
    int mask;
1611
    mask = (1 << n) - 1;
1612
    return (a & (0xff & ~mask)) | ((-((a >> n) & 1)) & mask);
1613
}
1614

    
1615
/* rgb555 handling */
1616

    
1617
#define RGB_NAME rgb555
1618

    
1619
#define RGB_IN(r, g, b, s)\
1620
{\
1621
    unsigned int v = ((const uint16_t *)(s))[0];\
1622
    r = bitcopy_n(v >> (10 - 3), 3);\
1623
    g = bitcopy_n(v >> (5 - 3), 3);\
1624
    b = bitcopy_n(v << 3, 3);\
1625
}
1626

    
1627

    
1628
#define RGB_OUT(d, r, g, b)\
1629
{\
1630
    ((uint16_t *)(d))[0] = ((r >> 3) << 10) | ((g >> 3) << 5) | (b >> 3);\
1631
}
1632

    
1633
#define BPP 2
1634

    
1635
#include "imgconvert_template.h"
1636

    
1637
/* rgb565 handling */
1638

    
1639
#define RGB_NAME rgb565
1640

    
1641
#define RGB_IN(r, g, b, s)\
1642
{\
1643
    unsigned int v = ((const uint16_t *)(s))[0];\
1644
    r = bitcopy_n(v >> (11 - 3), 3);\
1645
    g = bitcopy_n(v >> (5 - 2), 2);\
1646
    b = bitcopy_n(v << 3, 3);\
1647
}
1648

    
1649
#define RGB_OUT(d, r, g, b)\
1650
{\
1651
    ((uint16_t *)(d))[0] = ((r >> 3) << 11) | ((g >> 2) << 5) | (b >> 3);\
1652
}
1653

    
1654
#define BPP 2
1655

    
1656
#include "imgconvert_template.h"
1657

    
1658
/* bgr24 handling */
1659

    
1660
#define RGB_NAME bgr24
1661

    
1662
#define RGB_IN(r, g, b, s)\
1663
{\
1664
    b = (s)[0];\
1665
    g = (s)[1];\
1666
    r = (s)[2];\
1667
}
1668

    
1669
#define RGB_OUT(d, r, g, b)\
1670
{\
1671
    (d)[0] = b;\
1672
    (d)[1] = g;\
1673
    (d)[2] = r;\
1674
}
1675

    
1676
#define BPP 3
1677

    
1678
#include "imgconvert_template.h"
1679

    
1680
#undef RGB_IN
1681
#undef RGB_OUT
1682
#undef BPP
1683

    
1684
/* rgb24 handling */
1685

    
1686
#define RGB_NAME rgb24
1687
#define FMT_RGB24
1688

    
1689
#define RGB_IN(r, g, b, s)\
1690
{\
1691
    r = (s)[0];\
1692
    g = (s)[1];\
1693
    b = (s)[2];\
1694
}
1695

    
1696
#define RGB_OUT(d, r, g, b)\
1697
{\
1698
    (d)[0] = r;\
1699
    (d)[1] = g;\
1700
    (d)[2] = b;\
1701
}
1702

    
1703
#define BPP 3
1704

    
1705
#include "imgconvert_template.h"
1706

    
1707
/* rgb32 handling */
1708

    
1709
#define RGB_NAME rgb32
1710
#define FMT_RGB32
1711

    
1712
#define RGB_IN(r, g, b, s)\
1713
{\
1714
    unsigned int v = ((const uint32_t *)(s))[0];\
1715
    r = (v >> 16) & 0xff;\
1716
    g = (v >> 8) & 0xff;\
1717
    b = v & 0xff;\
1718
}
1719

    
1720
#define RGBA_IN(r, g, b, a, s)\
1721
{\
1722
    unsigned int v = ((const uint32_t *)(s))[0];\
1723
    a = (v >> 24) & 0xff;\
1724
    r = (v >> 16) & 0xff;\
1725
    g = (v >> 8) & 0xff;\
1726
    b = v & 0xff;\
1727
}
1728

    
1729
#define RGBA_OUT(d, r, g, b, a)\
1730
{\
1731
    ((uint32_t *)(d))[0] = (a << 24) | (r << 16) | (g << 8) | b;\
1732
}
1733

    
1734
#define BPP 4
1735

    
1736
#include "imgconvert_template.h"
1737

    
1738
static void mono_to_gray(AVPicture *dst, const AVPicture *src,
1739
                         int width, int height, int xor_mask)
1740
{
1741
    const unsigned char *p;
1742
    unsigned char *q;
1743
    int v, dst_wrap, src_wrap;
1744
    int y, w;
1745

    
1746
    p = src->data[0];
1747
    src_wrap = src->linesize[0] - ((width + 7) >> 3);
1748

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

    
1779
static void monowhite_to_gray(AVPicture *dst, const AVPicture *src,
1780
                               int width, int height)
1781
{
1782
    mono_to_gray(dst, src, width, height, 0xff);
1783
}
1784

    
1785
static void monoblack_to_gray(AVPicture *dst, const AVPicture *src,
1786
                               int width, int height)
1787
{
1788
    mono_to_gray(dst, src, width, height, 0x00);
1789
}
1790

    
1791
static void gray_to_mono(AVPicture *dst, const AVPicture *src,
1792
                         int width, int height, int xor_mask)
1793
{
1794
    int n;
1795
    const uint8_t *s;
1796
    uint8_t *d;
1797
    int j, b, v, n1, src_wrap, dst_wrap, y;
1798

    
1799
    s = src->data[0];
1800
    src_wrap = src->linesize[0] - width;
1801

    
1802
    d = dst->data[0];
1803
    dst_wrap = dst->linesize[0] - ((width + 7) >> 3);
1804

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

    
1835
static void gray_to_monowhite(AVPicture *dst, const AVPicture *src,
1836
                              int width, int height)
1837
{
1838
    gray_to_mono(dst, src, width, height, 0xff);
1839
}
1840

    
1841
static void gray_to_monoblack(AVPicture *dst, const AVPicture *src,
1842
                              int width, int height)
1843
{
1844
    gray_to_mono(dst, src, width, height, 0x00);
1845
}
1846

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

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

    
1885
static void gray16be_to_gray(AVPicture *dst, const AVPicture *src,
1886
                              int width, int height)
1887
{
1888
    gray16_to_gray(dst, src, width, height);
1889
}
1890

    
1891
static void gray16le_to_gray(AVPicture *dst, const AVPicture *src,
1892
                              int width, int height)
1893
{
1894
    AVPicture tmpsrc = *src;
1895
    tmpsrc.data[0]++;
1896
    gray16_to_gray(dst, &tmpsrc, width, height);
1897
}
1898

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

    
1917

    
1918
typedef struct ConvertEntry {
1919
    void (*convert)(AVPicture *dst,
1920
                    const AVPicture *src, int width, int height);
1921
} ConvertEntry;
1922

    
1923
/* Add each new conversion function in this table. In order to be able
1924
   to convert from any format to any format, the following constraints
1925
   must be satisfied:
1926

1927
   - all FF_COLOR_RGB formats must convert to and from PIX_FMT_RGB24
1928

1929
   - all FF_COLOR_GRAY formats must convert to and from PIX_FMT_GRAY8
1930

1931
   - all FF_COLOR_RGB formats with alpha must convert to and from PIX_FMT_RGB32
1932

1933
   - PIX_FMT_YUV444P and PIX_FMT_YUVJ444P must convert to and from
1934
     PIX_FMT_RGB24.
1935

1936
   - PIX_FMT_422 must convert to and from PIX_FMT_422P.
1937

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

    
2190
};
2191

    
2192
int avpicture_alloc(AVPicture *picture,
2193
                           int pix_fmt, int width, int height)
2194
{
2195
    int size;
2196
    void *ptr;
2197

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

    
2211
void avpicture_free(AVPicture *picture)
2212
{
2213
    av_free(picture->data[0]);
2214
}
2215

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

    
2224
int av_picture_crop(AVPicture *dst, const AVPicture *src,
2225
              int pix_fmt, int top_band, int left_band)
2226
{
2227
    int y_shift;
2228
    int x_shift;
2229

    
2230
    if (pix_fmt < 0 || pix_fmt >= PIX_FMT_NB || !is_yuv_planar(&pix_fmt_info[pix_fmt]))
2231
        return -1;
2232

    
2233
    y_shift = pix_fmt_info[pix_fmt].y_chroma_shift;
2234
    x_shift = pix_fmt_info[pix_fmt].x_chroma_shift;
2235

    
2236
    dst->data[0] = src->data[0] + (top_band * src->linesize[0]) + left_band;
2237
    dst->data[1] = src->data[1] + ((top_band >> y_shift) * src->linesize[1]) + (left_band >> x_shift);
2238
    dst->data[2] = src->data[2] + ((top_band >> y_shift) * src->linesize[2]) + (left_band >> x_shift);
2239

    
2240
    dst->linesize[0] = src->linesize[0];
2241
    dst->linesize[1] = src->linesize[1];
2242
    dst->linesize[2] = src->linesize[2];
2243
    return 0;
2244
}
2245

    
2246
int av_picture_pad(AVPicture *dst, const AVPicture *src, int height, int width,
2247
            int pix_fmt, int padtop, int padbottom, int padleft, int padright,
2248
            int *color)
2249
{
2250
    uint8_t *optr;
2251
    int y_shift;
2252
    int x_shift;
2253
    int yheight;
2254
    int i, y;
2255

    
2256
    if (pix_fmt < 0 || pix_fmt >= PIX_FMT_NB ||
2257
        !is_yuv_planar(&pix_fmt_info[pix_fmt])) return -1;
2258

    
2259
    for (i = 0; i < 3; i++) {
2260
        x_shift = i ? pix_fmt_info[pix_fmt].x_chroma_shift : 0;
2261
        y_shift = i ? pix_fmt_info[pix_fmt].y_chroma_shift : 0;
2262

    
2263
        if (padtop || padleft) {
2264
            memset(dst->data[i], color[i],
2265
                dst->linesize[i] * (padtop >> y_shift) + (padleft >> x_shift));
2266
        }
2267

    
2268
        if (padleft || padright) {
2269
            optr = dst->data[i] + dst->linesize[i] * (padtop >> y_shift) +
2270
                (dst->linesize[i] - (padright >> x_shift));
2271
            yheight = (height - 1 - (padtop + padbottom)) >> y_shift;
2272
            for (y = 0; y < yheight; y++) {
2273
                memset(optr, color[i], (padleft + padright) >> x_shift);
2274
                optr += dst->linesize[i];
2275
            }
2276
        }
2277

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

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

    
2306
#if LIBAVCODEC_VERSION_INT < ((52<<16)+(0<<8)+0)
2307
void img_copy(AVPicture *dst, const AVPicture *src,
2308
              int pix_fmt, int width, int height)
2309
{
2310
    av_picture_copy(dst, src, pix_fmt, width, height);
2311
}
2312

    
2313
int img_crop(AVPicture *dst, const AVPicture *src,
2314
              int pix_fmt, int top_band, int left_band)
2315
{
2316
    return av_picture_crop(dst, src, pix_fmt, top_band, left_band);
2317
}
2318

    
2319
int img_pad(AVPicture *dst, const AVPicture *src, int height, int width,
2320
            int pix_fmt, int padtop, int padbottom, int padleft, int padright,
2321
            int *color)
2322
{
2323
    return av_picture_pad(dst, src, height, width, pix_fmt, padtop, padbottom, padleft, padright, color);
2324
}
2325
#endif
2326

    
2327
#ifndef CONFIG_SWSCALER
2328
/* XXX: always use linesize. Return -1 if not supported */
2329
int img_convert(AVPicture *dst, int dst_pix_fmt,
2330
                const AVPicture *src, int src_pix_fmt,
2331
                int src_width, int src_height)
2332
{
2333
    static int inited;
2334
    int i, ret, dst_width, dst_height, int_pix_fmt;
2335
    const PixFmtInfo *src_pix, *dst_pix;
2336
    const ConvertEntry *ce;
2337
    AVPicture tmp1, *tmp = &tmp1;
2338

    
2339
    if (src_pix_fmt < 0 || src_pix_fmt >= PIX_FMT_NB ||
2340
        dst_pix_fmt < 0 || dst_pix_fmt >= PIX_FMT_NB)
2341
        return -1;
2342
    if (src_width <= 0 || src_height <= 0)
2343
        return 0;
2344

    
2345
    if (!inited) {
2346
        inited = 1;
2347
        img_convert_init();
2348
    }
2349

    
2350
    dst_width = src_width;
2351
    dst_height = src_height;
2352

    
2353
    dst_pix = &pix_fmt_info[dst_pix_fmt];
2354
    src_pix = &pix_fmt_info[src_pix_fmt];
2355
    if (src_pix_fmt == dst_pix_fmt) {
2356
        /* no conversion needed: just copy */
2357
        av_picture_copy(dst, src, dst_pix_fmt, dst_width, dst_height);
2358
        return 0;
2359
    }
2360

    
2361
    ce = &convert_table[src_pix_fmt][dst_pix_fmt];
2362
    if (ce->convert) {
2363
        /* specific conversion routine */
2364
        ce->convert(dst, src, dst_width, dst_height);
2365
        return 0;
2366
    }
2367

    
2368
    /* gray to YUV */
2369
    if (is_yuv_planar(dst_pix) &&
2370
        src_pix_fmt == PIX_FMT_GRAY8) {
2371
        int w, h, y;
2372
        uint8_t *d;
2373

    
2374
        if (dst_pix->color_type == FF_COLOR_YUV_JPEG) {
2375
            ff_img_copy_plane(dst->data[0], dst->linesize[0],
2376
                     src->data[0], src->linesize[0],
2377
                     dst_width, dst_height);
2378
        } else {
2379
            img_apply_table(dst->data[0], dst->linesize[0],
2380
                            src->data[0], src->linesize[0],
2381
                            dst_width, dst_height,
2382
                            y_jpeg_to_ccir);
2383
        }
2384
        /* fill U and V with 128 */
2385
        w = dst_width;
2386
        h = dst_height;
2387
        w >>= dst_pix->x_chroma_shift;
2388
        h >>= dst_pix->y_chroma_shift;
2389
        for(i = 1; i <= 2; i++) {
2390
            d = dst->data[i];
2391
            for(y = 0; y< h; y++) {
2392
                memset(d, 128, w);
2393
                d += dst->linesize[i];
2394
            }
2395
        }
2396
        return 0;
2397
    }
2398

    
2399
    /* YUV to gray */
2400
    if (is_yuv_planar(src_pix) &&
2401
        dst_pix_fmt == PIX_FMT_GRAY8) {
2402
        if (src_pix->color_type == FF_COLOR_YUV_JPEG) {
2403
            ff_img_copy_plane(dst->data[0], dst->linesize[0],
2404
                     src->data[0], src->linesize[0],
2405
                     dst_width, dst_height);
2406
        } else {
2407
            img_apply_table(dst->data[0], dst->linesize[0],
2408
                            src->data[0], src->linesize[0],
2409
                            dst_width, dst_height,
2410
                            y_ccir_to_jpeg);
2411
        }
2412
        return 0;
2413
    }
2414

    
2415
    /* YUV to YUV planar */
2416
    if (is_yuv_planar(dst_pix) && is_yuv_planar(src_pix)) {
2417
        int x_shift, y_shift, w, h, xy_shift;
2418
        void (*resize_func)(uint8_t *dst, int dst_wrap,
2419
                            const uint8_t *src, int src_wrap,
2420
                            int width, int height);
2421

    
2422
        /* compute chroma size of the smallest dimensions */
2423
        w = dst_width;
2424
        h = dst_height;
2425
        if (dst_pix->x_chroma_shift >= src_pix->x_chroma_shift)
2426
            w >>= dst_pix->x_chroma_shift;
2427
        else
2428
            w >>= src_pix->x_chroma_shift;
2429
        if (dst_pix->y_chroma_shift >= src_pix->y_chroma_shift)
2430
            h >>= dst_pix->y_chroma_shift;
2431
        else
2432
            h >>= src_pix->y_chroma_shift;
2433

    
2434
        x_shift = (dst_pix->x_chroma_shift - src_pix->x_chroma_shift);
2435
        y_shift = (dst_pix->y_chroma_shift - src_pix->y_chroma_shift);
2436
        xy_shift = ((x_shift & 0xf) << 4) | (y_shift & 0xf);
2437
        /* there must be filters for conversion at least from and to
2438
           YUV444 format */
2439
        switch(xy_shift) {
2440
        case 0x00:
2441
            resize_func = ff_img_copy_plane;
2442
            break;
2443
        case 0x10:
2444
            resize_func = shrink21;
2445
            break;
2446
        case 0x20:
2447
            resize_func = shrink41;
2448
            break;
2449
        case 0x01:
2450
            resize_func = shrink12;
2451
            break;
2452
        case 0x11:
2453
            resize_func = ff_shrink22;
2454
            break;
2455
        case 0x22:
2456
            resize_func = ff_shrink44;
2457
            break;
2458
        case 0xf0:
2459
            resize_func = grow21;
2460
            break;
2461
        case 0x0f:
2462
            resize_func = grow12;
2463
            break;
2464
        case 0xe0:
2465
            resize_func = grow41;
2466
            break;
2467
        case 0xff:
2468
            resize_func = grow22;
2469
            break;
2470
        case 0xee:
2471
            resize_func = grow44;
2472
            break;
2473
        case 0xf1:
2474
            resize_func = conv411;
2475
            break;
2476
        default:
2477
            /* currently not handled */
2478
            goto no_chroma_filter;
2479
        }
2480

    
2481
        ff_img_copy_plane(dst->data[0], dst->linesize[0],
2482
                       src->data[0], src->linesize[0],
2483
                       dst_width, dst_height);
2484

    
2485
        for(i = 1;i <= 2; i++)
2486
            resize_func(dst->data[i], dst->linesize[i],
2487
                        src->data[i], src->linesize[i],
2488
                        dst_width>>dst_pix->x_chroma_shift, dst_height>>dst_pix->y_chroma_shift);
2489
        /* if yuv color space conversion is needed, we do it here on
2490
           the destination image */
2491
        if (dst_pix->color_type != src_pix->color_type) {
2492
            const uint8_t *y_table, *c_table;
2493
            if (dst_pix->color_type == FF_COLOR_YUV) {
2494
                y_table = y_jpeg_to_ccir;
2495
                c_table = c_jpeg_to_ccir;
2496
            } else {
2497
                y_table = y_ccir_to_jpeg;
2498
                c_table = c_ccir_to_jpeg;
2499
            }
2500
            img_apply_table(dst->data[0], dst->linesize[0],
2501
                            dst->data[0], dst->linesize[0],
2502
                            dst_width, dst_height,
2503
                            y_table);
2504

    
2505
            for(i = 1;i <= 2; i++)
2506
                img_apply_table(dst->data[i], dst->linesize[i],
2507
                                dst->data[i], dst->linesize[i],
2508
                                dst_width>>dst_pix->x_chroma_shift,
2509
                                dst_height>>dst_pix->y_chroma_shift,
2510
                                c_table);
2511
        }
2512
        return 0;
2513
    }
2514
 no_chroma_filter:
2515

    
2516
    /* try to use an intermediate format */
2517
    if (src_pix_fmt == PIX_FMT_YUYV422 ||
2518
        dst_pix_fmt == PIX_FMT_YUYV422) {
2519
        /* specific case: convert to YUV422P first */
2520
        int_pix_fmt = PIX_FMT_YUV422P;
2521
    } else if (src_pix_fmt == PIX_FMT_UYVY422 ||
2522
        dst_pix_fmt == PIX_FMT_UYVY422) {
2523
        /* specific case: convert to YUV422P first */
2524
        int_pix_fmt = PIX_FMT_YUV422P;
2525
    } else if (src_pix_fmt == PIX_FMT_UYYVYY411 ||
2526
        dst_pix_fmt == PIX_FMT_UYYVYY411) {
2527
        /* specific case: convert to YUV411P first */
2528
        int_pix_fmt = PIX_FMT_YUV411P;
2529
    } else if ((src_pix->color_type == FF_COLOR_GRAY &&
2530
                src_pix_fmt != PIX_FMT_GRAY8) ||
2531
               (dst_pix->color_type == FF_COLOR_GRAY &&
2532
                dst_pix_fmt != PIX_FMT_GRAY8)) {
2533
        /* gray8 is the normalized format */
2534
        int_pix_fmt = PIX_FMT_GRAY8;
2535
    } else if ((is_yuv_planar(src_pix) &&
2536
                src_pix_fmt != PIX_FMT_YUV444P &&
2537
                src_pix_fmt != PIX_FMT_YUVJ444P)) {
2538
        /* yuv444 is the normalized format */
2539
        if (src_pix->color_type == FF_COLOR_YUV_JPEG)
2540
            int_pix_fmt = PIX_FMT_YUVJ444P;
2541
        else
2542
            int_pix_fmt = PIX_FMT_YUV444P;
2543
    } else if ((is_yuv_planar(dst_pix) &&
2544
                dst_pix_fmt != PIX_FMT_YUV444P &&
2545
                dst_pix_fmt != PIX_FMT_YUVJ444P)) {
2546
        /* yuv444 is the normalized format */
2547
        if (dst_pix->color_type == FF_COLOR_YUV_JPEG)
2548
            int_pix_fmt = PIX_FMT_YUVJ444P;
2549
        else
2550
            int_pix_fmt = PIX_FMT_YUV444P;
2551
    } else {
2552
        /* the two formats are rgb or gray8 or yuv[j]444p */
2553
        if (src_pix->is_alpha && dst_pix->is_alpha)
2554
            int_pix_fmt = PIX_FMT_RGB32;
2555
        else
2556
            int_pix_fmt = PIX_FMT_RGB24;
2557
    }
2558
    if (avpicture_alloc(tmp, int_pix_fmt, dst_width, dst_height) < 0)
2559
        return -1;
2560
    ret = -1;
2561
    if (img_convert(tmp, int_pix_fmt,
2562
                    src, src_pix_fmt, src_width, src_height) < 0)
2563
        goto fail1;
2564
    if (img_convert(dst, dst_pix_fmt,
2565
                    tmp, int_pix_fmt, dst_width, dst_height) < 0)
2566
        goto fail1;
2567
    ret = 0;
2568
 fail1:
2569
    avpicture_free(tmp);
2570
    return ret;
2571
}
2572
#endif
2573

    
2574
/* NOTE: we scan all the pixels to have an exact information */
2575
static int get_alpha_info_pal8(const AVPicture *src, int width, int height)
2576
{
2577
    const unsigned char *p;
2578
    int src_wrap, ret, x, y;
2579
    unsigned int a;
2580
    uint32_t *palette = (uint32_t *)src->data[1];
2581

    
2582
    p = src->data[0];
2583
    src_wrap = src->linesize[0] - width;
2584
    ret = 0;
2585
    for(y=0;y<height;y++) {
2586
        for(x=0;x<width;x++) {
2587
            a = palette[p[0]] >> 24;
2588
            if (a == 0x00) {
2589
                ret |= FF_ALPHA_TRANSP;
2590
            } else if (a != 0xff) {
2591
                ret |= FF_ALPHA_SEMI_TRANSP;
2592
            }
2593
            p++;
2594
        }
2595
        p += src_wrap;
2596
    }
2597
    return ret;
2598
}
2599

    
2600
int img_get_alpha_info(const AVPicture *src,
2601
                       int pix_fmt, int width, int height)
2602
{
2603
    const PixFmtInfo *pf = &pix_fmt_info[pix_fmt];
2604
    int ret;
2605

    
2606
    pf = &pix_fmt_info[pix_fmt];
2607
    /* no alpha can be represented in format */
2608
    if (!pf->is_alpha)
2609
        return 0;
2610
    switch(pix_fmt) {
2611
    case PIX_FMT_RGB32:
2612
        ret = get_alpha_info_rgb32(src, width, height);
2613
        break;
2614
    case PIX_FMT_PAL8:
2615
        ret = get_alpha_info_pal8(src, width, height);
2616
        break;
2617
    default:
2618
        /* we do not know, so everything is indicated */
2619
        ret = FF_ALPHA_TRANSP | FF_ALPHA_SEMI_TRANSP;
2620
        break;
2621
    }
2622
    return ret;
2623
}
2624

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

    
2649
#define DEINT_LINE_LUM \
2650
                    movd_m2r(lum_m4[0],mm0);\
2651
                    movd_m2r(lum_m3[0],mm1);\
2652
                    movd_m2r(lum_m2[0],mm2);\
2653
                    movd_m2r(lum_m1[0],mm3);\
2654
                    movd_m2r(lum[0],mm4);\
2655
                    punpcklbw_r2r(mm7,mm0);\
2656
                    punpcklbw_r2r(mm7,mm1);\
2657
                    punpcklbw_r2r(mm7,mm2);\
2658
                    punpcklbw_r2r(mm7,mm3);\
2659
                    punpcklbw_r2r(mm7,mm4);\
2660
                    paddw_r2r(mm3,mm1);\
2661
                    psllw_i2r(1,mm2);\
2662
                    paddw_r2r(mm4,mm0);\
2663
                    psllw_i2r(2,mm1);\
2664
                    paddw_r2r(mm6,mm2);\
2665
                    paddw_r2r(mm2,mm1);\
2666
                    psubusw_r2r(mm0,mm1);\
2667
                    psrlw_i2r(3,mm1);\
2668
                    packuswb_r2r(mm7,mm1);\
2669
                    movd_r2m(mm1,dst[0]);
2670
#endif
2671

    
2672
/* filter parameters: [-1 4 2 4 -1] // 8 */
2673
static void deinterlace_line(uint8_t *dst,
2674
                             const uint8_t *lum_m4, const uint8_t *lum_m3,
2675
                             const uint8_t *lum_m2, const uint8_t *lum_m1,
2676
                             const uint8_t *lum,
2677
                             int size)
2678
{
2679
#ifndef HAVE_MMX
2680
    uint8_t *cm = ff_cropTbl + MAX_NEG_CROP;
2681
    int sum;
2682

    
2683
    for(;size > 0;size--) {
2684
        sum = -lum_m4[0];
2685
        sum += lum_m3[0] << 2;
2686
        sum += lum_m2[0] << 1;
2687
        sum += lum_m1[0] << 2;
2688
        sum += -lum[0];
2689
        dst[0] = cm[(sum + 4) >> 3];
2690
        lum_m4++;
2691
        lum_m3++;
2692
        lum_m2++;
2693
        lum_m1++;
2694
        lum++;
2695
        dst++;
2696
    }
2697
#else
2698

    
2699
    {
2700
        mmx_t rounder;
2701
        rounder.uw[0]=4;
2702
        rounder.uw[1]=4;
2703
        rounder.uw[2]=4;
2704
        rounder.uw[3]=4;
2705
        pxor_r2r(mm7,mm7);
2706
        movq_m2r(rounder,mm6);
2707
    }
2708
    for (;size > 3; size-=4) {
2709
        DEINT_LINE_LUM
2710
        lum_m4+=4;
2711
        lum_m3+=4;
2712
        lum_m2+=4;
2713
        lum_m1+=4;
2714
        lum+=4;
2715
        dst+=4;
2716
    }
2717
#endif
2718
}
2719
static void deinterlace_line_inplace(uint8_t *lum_m4, uint8_t *lum_m3, uint8_t *lum_m2, uint8_t *lum_m1, uint8_t *lum,
2720
                             int size)
2721
{
2722
#ifndef HAVE_MMX
2723
    uint8_t *cm = ff_cropTbl + MAX_NEG_CROP;
2724
    int sum;
2725

    
2726
    for(;size > 0;size--) {
2727
        sum = -lum_m4[0];
2728
        sum += lum_m3[0] << 2;
2729
        sum += lum_m2[0] << 1;
2730
        lum_m4[0]=lum_m2[0];
2731
        sum += lum_m1[0] << 2;
2732
        sum += -lum[0];
2733
        lum_m2[0] = cm[(sum + 4) >> 3];
2734
        lum_m4++;
2735
        lum_m3++;
2736
        lum_m2++;
2737
        lum_m1++;
2738
        lum++;
2739
    }
2740
#else
2741

    
2742
    {
2743
        mmx_t rounder;
2744
        rounder.uw[0]=4;
2745
        rounder.uw[1]=4;
2746
        rounder.uw[2]=4;
2747
        rounder.uw[3]=4;
2748
        pxor_r2r(mm7,mm7);
2749
        movq_m2r(rounder,mm6);
2750
    }
2751
    for (;size > 3; size-=4) {
2752
        DEINT_INPLACE_LINE_LUM
2753
        lum_m4+=4;
2754
        lum_m3+=4;
2755
        lum_m2+=4;
2756
        lum_m1+=4;
2757
        lum+=4;
2758
    }
2759
#endif
2760
}
2761

    
2762
/* deinterlacing : 2 temporal taps, 3 spatial taps linear filter. The
2763
   top field is copied as is, but the bottom field is deinterlaced
2764
   against the top field. */
2765
static void deinterlace_bottom_field(uint8_t *dst, int dst_wrap,
2766
                                    const uint8_t *src1, int src_wrap,
2767
                                    int width, int height)
2768
{
2769
    const uint8_t *src_m2, *src_m1, *src_0, *src_p1, *src_p2;
2770
    int y;
2771

    
2772
    src_m2 = src1;
2773
    src_m1 = src1;
2774
    src_0=&src_m1[src_wrap];
2775
    src_p1=&src_0[src_wrap];
2776
    src_p2=&src_p1[src_wrap];
2777
    for(y=0;y<(height-2);y+=2) {
2778
        memcpy(dst,src_m1,width);
2779
        dst += dst_wrap;
2780
        deinterlace_line(dst,src_m2,src_m1,src_0,src_p1,src_p2,width);
2781
        src_m2 = src_0;
2782
        src_m1 = src_p1;
2783
        src_0 = src_p2;
2784
        src_p1 += 2*src_wrap;
2785
        src_p2 += 2*src_wrap;
2786
        dst += dst_wrap;
2787
    }
2788
    memcpy(dst,src_m1,width);
2789
    dst += dst_wrap;
2790
    /* do last line */
2791
    deinterlace_line(dst,src_m2,src_m1,src_0,src_0,src_0,width);
2792
}
2793

    
2794
static void deinterlace_bottom_field_inplace(uint8_t *src1, int src_wrap,
2795
                                             int width, int height)
2796
{
2797
    uint8_t *src_m1, *src_0, *src_p1, *src_p2;
2798
    int y;
2799
    uint8_t *buf;
2800
    buf = (uint8_t*)av_malloc(width);
2801

    
2802
    src_m1 = src1;
2803
    memcpy(buf,src_m1,width);
2804
    src_0=&src_m1[src_wrap];
2805
    src_p1=&src_0[src_wrap];
2806
    src_p2=&src_p1[src_wrap];
2807
    for(y=0;y<(height-2);y+=2) {
2808
        deinterlace_line_inplace(buf,src_m1,src_0,src_p1,src_p2,width);
2809
        src_m1 = src_p1;
2810
        src_0 = src_p2;
2811
        src_p1 += 2*src_wrap;
2812
        src_p2 += 2*src_wrap;
2813
    }
2814
    /* do last line */
2815
    deinterlace_line_inplace(buf,src_m1,src_0,src_0,src_0,width);
2816
    av_free(buf);
2817
}
2818

    
2819
int avpicture_deinterlace(AVPicture *dst, const AVPicture *src,
2820
                          int pix_fmt, int width, int height)
2821
{
2822
    int i;
2823

    
2824
    if (pix_fmt != PIX_FMT_YUV420P &&
2825
        pix_fmt != PIX_FMT_YUV422P &&
2826
        pix_fmt != PIX_FMT_YUV444P &&
2827
        pix_fmt != PIX_FMT_YUV411P)
2828
        return -1;
2829
    if ((width & 3) != 0 || (height & 3) != 0)
2830
        return -1;
2831

    
2832
    for(i=0;i<3;i++) {
2833
        if (i == 1) {
2834
            switch(pix_fmt) {
2835
            case PIX_FMT_YUV420P:
2836
                width >>= 1;
2837
                height >>= 1;
2838
                break;
2839
            case PIX_FMT_YUV422P:
2840
                width >>= 1;
2841
                break;
2842
            case PIX_FMT_YUV411P:
2843
                width >>= 2;
2844
                break;
2845
            default:
2846
                break;
2847
            }
2848
        }
2849
        if (src == dst) {
2850
            deinterlace_bottom_field_inplace(dst->data[i], dst->linesize[i],
2851
                                 width, height);
2852
        } else {
2853
            deinterlace_bottom_field(dst->data[i],dst->linesize[i],
2854
                                        src->data[i], src->linesize[i],
2855
                                        width, height);
2856
        }
2857
    }
2858
    emms_c();
2859
    return 0;
2860
}
2861