Statistics
| Branch: | Revision:

ffmpeg / libavcodec / imgconvert.c @ a6493a8f

History | View | Annotate | Download (77.2 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 "x86/mmx.h"
39
#include "x86/dsputil_mmx.h"
40
#endif
41

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
409
void avcodec_pix_fmt_string (char *buf, int buf_size, int pix_fmt)
410
{
411
    /* print header */
412
    if (pix_fmt < 0)
413
        snprintf (buf, buf_size,
414
                  "name      " " nb_channels" " depth" " is_alpha"
415
            );
416
    else{
417
        PixFmtInfo info= pix_fmt_info[pix_fmt];
418

    
419
        char is_alpha_char= info.is_alpha ? 'y' : 'n';
420

    
421
        snprintf (buf, buf_size,
422
                  "%-10s" "      %1d     " "   %2d " "     %c   ",
423
                  info.name,
424
                  info.nb_channels,
425
                  info.depth,
426
                  is_alpha_char
427
            );
428
    }
429
}
430

    
431
int ff_fill_linesize(AVPicture *picture, int pix_fmt, int width)
432
{
433
    int w2;
434
    const PixFmtInfo *pinfo;
435

    
436
    memset(picture->linesize, 0, sizeof(picture->linesize));
437

    
438
    pinfo = &pix_fmt_info[pix_fmt];
439
    switch(pix_fmt) {
440
    case PIX_FMT_YUV420P:
441
    case PIX_FMT_YUV422P:
442
    case PIX_FMT_YUV444P:
443
    case PIX_FMT_YUV410P:
444
    case PIX_FMT_YUV411P:
445
    case PIX_FMT_YUV440P:
446
    case PIX_FMT_YUVJ420P:
447
    case PIX_FMT_YUVJ422P:
448
    case PIX_FMT_YUVJ444P:
449
    case PIX_FMT_YUVJ440P:
450
        w2 = (width + (1 << pinfo->x_chroma_shift) - 1) >> pinfo->x_chroma_shift;
451
        picture->linesize[0] = width;
452
        picture->linesize[1] = w2;
453
        picture->linesize[2] = w2;
454
        break;
455
    case PIX_FMT_YUVA420P:
456
        w2 = (width + (1 << pinfo->x_chroma_shift) - 1) >> pinfo->x_chroma_shift;
457
        picture->linesize[0] = width;
458
        picture->linesize[1] = w2;
459
        picture->linesize[2] = w2;
460
        picture->linesize[3] = width;
461
        break;
462
    case PIX_FMT_NV12:
463
    case PIX_FMT_NV21:
464
        w2 = (width + (1 << pinfo->x_chroma_shift) - 1) >> pinfo->x_chroma_shift;
465
        picture->linesize[0] = width;
466
        picture->linesize[1] = w2;
467
        break;
468
    case PIX_FMT_RGB24:
469
    case PIX_FMT_BGR24:
470
        picture->linesize[0] = width * 3;
471
        break;
472
    case PIX_FMT_RGB32:
473
    case PIX_FMT_BGR32:
474
    case PIX_FMT_RGB32_1:
475
    case PIX_FMT_BGR32_1:
476
        picture->linesize[0] = width * 4;
477
        break;
478
    case PIX_FMT_GRAY16BE:
479
    case PIX_FMT_GRAY16LE:
480
    case PIX_FMT_BGR555:
481
    case PIX_FMT_BGR565:
482
    case PIX_FMT_RGB555:
483
    case PIX_FMT_RGB565:
484
    case PIX_FMT_YUYV422:
485
        picture->linesize[0] = width * 2;
486
        break;
487
    case PIX_FMT_UYVY422:
488
        picture->linesize[0] = width * 2;
489
        break;
490
    case PIX_FMT_UYYVYY411:
491
        picture->linesize[0] = width + width/2;
492
        break;
493
    case PIX_FMT_RGB8:
494
    case PIX_FMT_BGR8:
495
    case PIX_FMT_RGB4_BYTE:
496
    case PIX_FMT_BGR4_BYTE:
497
    case PIX_FMT_GRAY8:
498
        picture->linesize[0] = width;
499
        break;
500
    case PIX_FMT_RGB4:
501
    case PIX_FMT_BGR4:
502
        picture->linesize[0] = width / 2;
503
        break;
504
    case PIX_FMT_MONOWHITE:
505
    case PIX_FMT_MONOBLACK:
506
        picture->linesize[0] = (width + 7) >> 3;
507
        break;
508
    case PIX_FMT_PAL8:
509
        picture->linesize[0] = width;
510
        picture->linesize[1] = 4;
511
        break;
512
    default:
513
        return -1;
514
    }
515
    return 0;
516
}
517

    
518
int ff_fill_pointer(AVPicture *picture, uint8_t *ptr, int pix_fmt,
519
                    int height)
520
{
521
    int size, h2, size2;
522
    const PixFmtInfo *pinfo;
523

    
524
    pinfo = &pix_fmt_info[pix_fmt];
525
    size = picture->linesize[0] * height;
526
    switch(pix_fmt) {
527
    case PIX_FMT_YUV420P:
528
    case PIX_FMT_YUV422P:
529
    case PIX_FMT_YUV444P:
530
    case PIX_FMT_YUV410P:
531
    case PIX_FMT_YUV411P:
532
    case PIX_FMT_YUV440P:
533
    case PIX_FMT_YUVJ420P:
534
    case PIX_FMT_YUVJ422P:
535
    case PIX_FMT_YUVJ444P:
536
    case PIX_FMT_YUVJ440P:
537
        h2 = (height + (1 << pinfo->y_chroma_shift) - 1) >> pinfo->y_chroma_shift;
538
        size2 = picture->linesize[1] * h2;
539
        picture->data[0] = ptr;
540
        picture->data[1] = picture->data[0] + size;
541
        picture->data[2] = picture->data[1] + size2;
542
        picture->data[3] = NULL;
543
        return size + 2 * size2;
544
    case PIX_FMT_YUVA420P:
545
        h2 = (height + (1 << pinfo->y_chroma_shift) - 1) >> pinfo->y_chroma_shift;
546
        size2 = picture->linesize[1] * h2;
547
        picture->data[0] = ptr;
548
        picture->data[1] = picture->data[0] + size;
549
        picture->data[2] = picture->data[1] + size2;
550
        picture->data[3] = picture->data[1] + size2 + size2;
551
        return 2 * size + 2 * size2;
552
    case PIX_FMT_NV12:
553
    case PIX_FMT_NV21:
554
        h2 = (height + (1 << pinfo->y_chroma_shift) - 1) >> pinfo->y_chroma_shift;
555
        size2 = picture->linesize[1] * h2 * 2;
556
        picture->data[0] = ptr;
557
        picture->data[1] = picture->data[0] + size;
558
        picture->data[2] = NULL;
559
        picture->data[3] = NULL;
560
        return size + 2 * size2;
561
    case PIX_FMT_RGB24:
562
    case PIX_FMT_BGR24:
563
    case PIX_FMT_RGB32:
564
    case PIX_FMT_BGR32:
565
    case PIX_FMT_RGB32_1:
566
    case PIX_FMT_BGR32_1:
567
    case PIX_FMT_GRAY16BE:
568
    case PIX_FMT_GRAY16LE:
569
    case PIX_FMT_BGR555:
570
    case PIX_FMT_BGR565:
571
    case PIX_FMT_RGB555:
572
    case PIX_FMT_RGB565:
573
    case PIX_FMT_YUYV422:
574
    case PIX_FMT_UYVY422:
575
    case PIX_FMT_UYYVYY411:
576
    case PIX_FMT_RGB8:
577
    case PIX_FMT_BGR8:
578
    case PIX_FMT_RGB4_BYTE:
579
    case PIX_FMT_BGR4_BYTE:
580
    case PIX_FMT_GRAY8:
581
    case PIX_FMT_RGB4:
582
    case PIX_FMT_BGR4:
583
    case PIX_FMT_MONOWHITE:
584
    case PIX_FMT_MONOBLACK:
585
        picture->data[0] = ptr;
586
        picture->data[1] = NULL;
587
        picture->data[2] = NULL;
588
        picture->data[3] = NULL;
589
        return size;
590
    case PIX_FMT_PAL8:
591
        size2 = (size + 3) & ~3;
592
        picture->data[0] = ptr;
593
        picture->data[1] = ptr + size2; /* palette is stored here as 256 32 bit words */
594
        picture->data[2] = NULL;
595
        picture->data[3] = NULL;
596
        return size2 + 256 * 4;
597
    default:
598
        picture->data[0] = NULL;
599
        picture->data[1] = NULL;
600
        picture->data[2] = NULL;
601
        picture->data[3] = NULL;
602
        return -1;
603
    }
604
}
605

    
606
int avpicture_fill(AVPicture *picture, uint8_t *ptr,
607
                   int pix_fmt, int width, int height)
608
{
609

    
610
    if(avcodec_check_dimensions(NULL, width, height))
611
        return -1;
612

    
613
    if (ff_fill_linesize(picture, pix_fmt, width))
614
        return -1;
615

    
616
    return ff_fill_pointer(picture, ptr, pix_fmt, height);
617
}
618

    
619
int avpicture_layout(const AVPicture* src, int pix_fmt, int width, int height,
620
                     unsigned char *dest, int dest_size)
621
{
622
    const PixFmtInfo* pf = &pix_fmt_info[pix_fmt];
623
    int i, j, w, h, data_planes;
624
    const unsigned char* s;
625
    int size = avpicture_get_size(pix_fmt, width, height);
626

    
627
    if (size > dest_size || size < 0)
628
        return -1;
629

    
630
    if (pf->pixel_type == FF_PIXEL_PACKED || pf->pixel_type == FF_PIXEL_PALETTE) {
631
        if (pix_fmt == PIX_FMT_YUYV422 ||
632
            pix_fmt == PIX_FMT_UYVY422 ||
633
            pix_fmt == PIX_FMT_BGR565 ||
634
            pix_fmt == PIX_FMT_BGR555 ||
635
            pix_fmt == PIX_FMT_RGB565 ||
636
            pix_fmt == PIX_FMT_RGB555)
637
            w = width * 2;
638
        else if (pix_fmt == PIX_FMT_UYYVYY411)
639
          w = width + width/2;
640
        else if (pix_fmt == PIX_FMT_PAL8)
641
          w = width;
642
        else
643
          w = width * (pf->depth * pf->nb_channels / 8);
644

    
645
        data_planes = 1;
646
        h = height;
647
    } else {
648
        data_planes = pf->nb_channels;
649
        w = (width*pf->depth + 7)/8;
650
        h = height;
651
    }
652

    
653
    for (i=0; i<data_planes; i++) {
654
         if (i == 1) {
655
             w = width >> pf->x_chroma_shift;
656
             h = height >> pf->y_chroma_shift;
657
         }
658
         s = src->data[i];
659
         for(j=0; j<h; j++) {
660
             memcpy(dest, s, w);
661
             dest += w;
662
             s += src->linesize[i];
663
         }
664
    }
665

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

    
669
    return size;
670
}
671

    
672
int avpicture_get_size(int pix_fmt, int width, int height)
673
{
674
    AVPicture dummy_pict;
675
    return avpicture_fill(&dummy_pict, NULL, pix_fmt, width, height);
676
}
677

    
678
int avcodec_get_pix_fmt_loss(int dst_pix_fmt, int src_pix_fmt,
679
                             int has_alpha)
680
{
681
    const PixFmtInfo *pf, *ps;
682
    int loss;
683

    
684
    ps = &pix_fmt_info[src_pix_fmt];
685
    pf = &pix_fmt_info[dst_pix_fmt];
686

    
687
    /* compute loss */
688
    loss = 0;
689
    pf = &pix_fmt_info[dst_pix_fmt];
690
    if (pf->depth < ps->depth ||
691
        (dst_pix_fmt == PIX_FMT_RGB555 && src_pix_fmt == PIX_FMT_RGB565))
692
        loss |= FF_LOSS_DEPTH;
693
    if (pf->x_chroma_shift > ps->x_chroma_shift ||
694
        pf->y_chroma_shift > ps->y_chroma_shift)
695
        loss |= FF_LOSS_RESOLUTION;
696
    switch(pf->color_type) {
697
    case FF_COLOR_RGB:
698
        if (ps->color_type != FF_COLOR_RGB &&
699
            ps->color_type != FF_COLOR_GRAY)
700
            loss |= FF_LOSS_COLORSPACE;
701
        break;
702
    case FF_COLOR_GRAY:
703
        if (ps->color_type != FF_COLOR_GRAY)
704
            loss |= FF_LOSS_COLORSPACE;
705
        break;
706
    case FF_COLOR_YUV:
707
        if (ps->color_type != FF_COLOR_YUV)
708
            loss |= FF_LOSS_COLORSPACE;
709
        break;
710
    case FF_COLOR_YUV_JPEG:
711
        if (ps->color_type != FF_COLOR_YUV_JPEG &&
712
            ps->color_type != FF_COLOR_YUV &&
713
            ps->color_type != FF_COLOR_GRAY)
714
            loss |= FF_LOSS_COLORSPACE;
715
        break;
716
    default:
717
        /* fail safe test */
718
        if (ps->color_type != pf->color_type)
719
            loss |= FF_LOSS_COLORSPACE;
720
        break;
721
    }
722
    if (pf->color_type == FF_COLOR_GRAY &&
723
        ps->color_type != FF_COLOR_GRAY)
724
        loss |= FF_LOSS_CHROMA;
725
    if (!pf->is_alpha && (ps->is_alpha && has_alpha))
726
        loss |= FF_LOSS_ALPHA;
727
    if (pf->pixel_type == FF_PIXEL_PALETTE &&
728
        (ps->pixel_type != FF_PIXEL_PALETTE && ps->color_type != FF_COLOR_GRAY))
729
        loss |= FF_LOSS_COLORQUANT;
730
    return loss;
731
}
732

    
733
static int avg_bits_per_pixel(int pix_fmt)
734
{
735
    int bits;
736
    const PixFmtInfo *pf;
737

    
738
    pf = &pix_fmt_info[pix_fmt];
739
    switch(pf->pixel_type) {
740
    case FF_PIXEL_PACKED:
741
        switch(pix_fmt) {
742
        case PIX_FMT_YUYV422:
743
        case PIX_FMT_UYVY422:
744
        case PIX_FMT_RGB565:
745
        case PIX_FMT_RGB555:
746
        case PIX_FMT_BGR565:
747
        case PIX_FMT_BGR555:
748
            bits = 16;
749
            break;
750
        case PIX_FMT_UYYVYY411:
751
            bits = 12;
752
            break;
753
        default:
754
            bits = pf->depth * pf->nb_channels;
755
            break;
756
        }
757
        break;
758
    case FF_PIXEL_PLANAR:
759
        if (pf->x_chroma_shift == 0 && pf->y_chroma_shift == 0) {
760
            bits = pf->depth * pf->nb_channels;
761
        } else {
762
            bits = pf->depth + ((2 * pf->depth) >>
763
                                (pf->x_chroma_shift + pf->y_chroma_shift));
764
        }
765
        break;
766
    case FF_PIXEL_PALETTE:
767
        bits = 8;
768
        break;
769
    default:
770
        bits = -1;
771
        break;
772
    }
773
    return bits;
774
}
775

    
776
static int avcodec_find_best_pix_fmt1(int64_t pix_fmt_mask,
777
                                      int src_pix_fmt,
778
                                      int has_alpha,
779
                                      int loss_mask)
780
{
781
    int dist, i, loss, min_dist, dst_pix_fmt;
782

    
783
    /* find exact color match with smallest size */
784
    dst_pix_fmt = -1;
785
    min_dist = 0x7fffffff;
786
    for(i = 0;i < PIX_FMT_NB; i++) {
787
        if (pix_fmt_mask & (1ULL << i)) {
788
            loss = avcodec_get_pix_fmt_loss(i, src_pix_fmt, has_alpha) & loss_mask;
789
            if (loss == 0) {
790
                dist = avg_bits_per_pixel(i);
791
                if (dist < min_dist) {
792
                    min_dist = dist;
793
                    dst_pix_fmt = i;
794
                }
795
            }
796
        }
797
    }
798
    return dst_pix_fmt;
799
}
800

    
801
int avcodec_find_best_pix_fmt(int64_t pix_fmt_mask, int src_pix_fmt,
802
                              int has_alpha, int *loss_ptr)
803
{
804
    int dst_pix_fmt, loss_mask, i;
805
    static const int loss_mask_order[] = {
806
        ~0, /* no loss first */
807
        ~FF_LOSS_ALPHA,
808
        ~FF_LOSS_RESOLUTION,
809
        ~(FF_LOSS_COLORSPACE | FF_LOSS_RESOLUTION),
810
        ~FF_LOSS_COLORQUANT,
811
        ~FF_LOSS_DEPTH,
812
        0,
813
    };
814

    
815
    /* try with successive loss */
816
    i = 0;
817
    for(;;) {
818
        loss_mask = loss_mask_order[i++];
819
        dst_pix_fmt = avcodec_find_best_pix_fmt1(pix_fmt_mask, src_pix_fmt,
820
                                                 has_alpha, loss_mask);
821
        if (dst_pix_fmt >= 0)
822
            goto found;
823
        if (loss_mask == 0)
824
            break;
825
    }
826
    return -1;
827
 found:
828
    if (loss_ptr)
829
        *loss_ptr = avcodec_get_pix_fmt_loss(dst_pix_fmt, src_pix_fmt, has_alpha);
830
    return dst_pix_fmt;
831
}
832

    
833
void ff_img_copy_plane(uint8_t *dst, int dst_wrap,
834
                           const uint8_t *src, int src_wrap,
835
                           int width, int height)
836
{
837
    if((!dst) || (!src))
838
        return;
839
    for(;height > 0; height--) {
840
        memcpy(dst, src, width);
841
        dst += dst_wrap;
842
        src += src_wrap;
843
    }
844
}
845

    
846
int ff_get_plane_bytewidth(enum PixelFormat pix_fmt, int width, int plane)
847
{
848
    int bits;
849
    const PixFmtInfo *pf = &pix_fmt_info[pix_fmt];
850

    
851
    pf = &pix_fmt_info[pix_fmt];
852
    switch(pf->pixel_type) {
853
    case FF_PIXEL_PACKED:
854
        switch(pix_fmt) {
855
        case PIX_FMT_YUYV422:
856
        case PIX_FMT_UYVY422:
857
        case PIX_FMT_RGB565:
858
        case PIX_FMT_RGB555:
859
        case PIX_FMT_BGR565:
860
        case PIX_FMT_BGR555:
861
            bits = 16;
862
            break;
863
        case PIX_FMT_UYYVYY411:
864
            bits = 12;
865
            break;
866
        default:
867
            bits = pf->depth * pf->nb_channels;
868
            break;
869
        }
870
        return (width * bits + 7) >> 3;
871
        break;
872
    case FF_PIXEL_PLANAR:
873
            if (plane == 1 || plane == 2)
874
                width= -((-width)>>pf->x_chroma_shift);
875

    
876
            return (width * pf->depth + 7) >> 3;
877
        break;
878
    case FF_PIXEL_PALETTE:
879
        if (plane == 0)
880
            return width;
881
        break;
882
    }
883

    
884
    return -1;
885
}
886

    
887
void av_picture_copy(AVPicture *dst, const AVPicture *src,
888
              int pix_fmt, int width, int height)
889
{
890
    int i;
891
    const PixFmtInfo *pf = &pix_fmt_info[pix_fmt];
892

    
893
    pf = &pix_fmt_info[pix_fmt];
894
    switch(pf->pixel_type) {
895
    case FF_PIXEL_PACKED:
896
    case FF_PIXEL_PLANAR:
897
        for(i = 0; i < pf->nb_channels; i++) {
898
            int h;
899
            int bwidth = ff_get_plane_bytewidth(pix_fmt, width, i);
900
            h = height;
901
            if (i == 1 || i == 2) {
902
                h= -((-height)>>pf->y_chroma_shift);
903
            }
904
            ff_img_copy_plane(dst->data[i], dst->linesize[i],
905
                           src->data[i], src->linesize[i],
906
                           bwidth, h);
907
        }
908
        break;
909
    case FF_PIXEL_PALETTE:
910
        ff_img_copy_plane(dst->data[0], dst->linesize[0],
911
                       src->data[0], src->linesize[0],
912
                       width, height);
913
        /* copy the palette */
914
        ff_img_copy_plane(dst->data[1], dst->linesize[1],
915
                       src->data[1], src->linesize[1],
916
                       4, 256);
917
        break;
918
    }
919
}
920

    
921
/* XXX: totally non optimized */
922

    
923
static void yuyv422_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
    lum1 = dst->data[0];
932
    cb1 = dst->data[1];
933
    cr1 = dst->data[2];
934

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

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

    
986
    p1 = src->data[0];
987

    
988
    lum1 = dst->data[0];
989
    cb1 = dst->data[1];
990
    cr1 = dst->data[2];
991

    
992
    for(;height >= 1; height -= 2) {
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
        if (w) {
1008
            lum[0] = p[1];
1009
            cb[0] = p[0];
1010
            cr[0] = p[2];
1011
            cb++;
1012
            cr++;
1013
        }
1014
        p1 += src->linesize[0];
1015
        lum1 += dst->linesize[0];
1016
        if (height>1) {
1017
            p = p1;
1018
            lum = lum1;
1019
            for(w = width; w >= 2; w -= 2) {
1020
                lum[0] = p[1];
1021
                lum[1] = p[3];
1022
                p += 4;
1023
                lum += 2;
1024
            }
1025
            if (w) {
1026
                lum[0] = p[1];
1027
            }
1028
            p1 += src->linesize[0];
1029
            lum1 += dst->linesize[0];
1030
        }
1031
        cb1 += dst->linesize[1];
1032
        cr1 += dst->linesize[2];
1033
    }
1034
}
1035

    
1036

    
1037
static void uyvy422_to_yuv422p(AVPicture *dst, const AVPicture *src,
1038
                              int width, int height)
1039
{
1040
    const uint8_t *p, *p1;
1041
    uint8_t *lum, *cr, *cb, *lum1, *cr1, *cb1;
1042
    int w;
1043

    
1044
    p1 = src->data[0];
1045
    lum1 = dst->data[0];
1046
    cb1 = dst->data[1];
1047
    cr1 = dst->data[2];
1048
    for(;height > 0; height--) {
1049
        p = p1;
1050
        lum = lum1;
1051
        cb = cb1;
1052
        cr = cr1;
1053
        for(w = width; w >= 2; w -= 2) {
1054
            lum[0] = p[1];
1055
            cb[0] = p[0];
1056
            lum[1] = p[3];
1057
            cr[0] = p[2];
1058
            p += 4;
1059
            lum += 2;
1060
            cb++;
1061
            cr++;
1062
        }
1063
        p1 += src->linesize[0];
1064
        lum1 += dst->linesize[0];
1065
        cb1 += dst->linesize[1];
1066
        cr1 += dst->linesize[2];
1067
    }
1068
}
1069

    
1070

    
1071
static void yuyv422_to_yuv422p(AVPicture *dst, const AVPicture *src,
1072
                              int width, int height)
1073
{
1074
    const uint8_t *p, *p1;
1075
    uint8_t *lum, *cr, *cb, *lum1, *cr1, *cb1;
1076
    int w;
1077

    
1078
    p1 = src->data[0];
1079
    lum1 = dst->data[0];
1080
    cb1 = dst->data[1];
1081
    cr1 = dst->data[2];
1082
    for(;height > 0; height--) {
1083
        p = p1;
1084
        lum = lum1;
1085
        cb = cb1;
1086
        cr = cr1;
1087
        for(w = width; w >= 2; w -= 2) {
1088
            lum[0] = p[0];
1089
            cb[0] = p[1];
1090
            lum[1] = p[2];
1091
            cr[0] = p[3];
1092
            p += 4;
1093
            lum += 2;
1094
            cb++;
1095
            cr++;
1096
        }
1097
        p1 += src->linesize[0];
1098
        lum1 += dst->linesize[0];
1099
        cb1 += dst->linesize[1];
1100
        cr1 += dst->linesize[2];
1101
    }
1102
}
1103

    
1104
static void yuv422p_to_yuyv422(AVPicture *dst, const AVPicture *src,
1105
                              int width, int height)
1106
{
1107
    uint8_t *p, *p1;
1108
    const uint8_t *lum, *cr, *cb, *lum1, *cr1, *cb1;
1109
    int w;
1110

    
1111
    p1 = dst->data[0];
1112
    lum1 = src->data[0];
1113
    cb1 = src->data[1];
1114
    cr1 = src->data[2];
1115
    for(;height > 0; height--) {
1116
        p = p1;
1117
        lum = lum1;
1118
        cb = cb1;
1119
        cr = cr1;
1120
        for(w = width; w >= 2; w -= 2) {
1121
            p[0] = lum[0];
1122
            p[1] = cb[0];
1123
            p[2] = lum[1];
1124
            p[3] = cr[0];
1125
            p += 4;
1126
            lum += 2;
1127
            cb++;
1128
            cr++;
1129
        }
1130
        p1 += dst->linesize[0];
1131
        lum1 += src->linesize[0];
1132
        cb1 += src->linesize[1];
1133
        cr1 += src->linesize[2];
1134
    }
1135
}
1136

    
1137
static void yuv422p_to_uyvy422(AVPicture *dst, const AVPicture *src,
1138
                              int width, int height)
1139
{
1140
    uint8_t *p, *p1;
1141
    const uint8_t *lum, *cr, *cb, *lum1, *cr1, *cb1;
1142
    int w;
1143

    
1144
    p1 = dst->data[0];
1145
    lum1 = src->data[0];
1146
    cb1 = src->data[1];
1147
    cr1 = src->data[2];
1148
    for(;height > 0; height--) {
1149
        p = p1;
1150
        lum = lum1;
1151
        cb = cb1;
1152
        cr = cr1;
1153
        for(w = width; w >= 2; w -= 2) {
1154
            p[1] = lum[0];
1155
            p[0] = cb[0];
1156
            p[3] = lum[1];
1157
            p[2] = cr[0];
1158
            p += 4;
1159
            lum += 2;
1160
            cb++;
1161
            cr++;
1162
        }
1163
        p1 += dst->linesize[0];
1164
        lum1 += src->linesize[0];
1165
        cb1 += src->linesize[1];
1166
        cr1 += src->linesize[2];
1167
    }
1168
}
1169

    
1170
static void uyyvyy411_to_yuv411p(AVPicture *dst, const AVPicture *src,
1171
                              int width, int height)
1172
{
1173
    const uint8_t *p, *p1;
1174
    uint8_t *lum, *cr, *cb, *lum1, *cr1, *cb1;
1175
    int w;
1176

    
1177
    p1 = src->data[0];
1178
    lum1 = dst->data[0];
1179
    cb1 = dst->data[1];
1180
    cr1 = dst->data[2];
1181
    for(;height > 0; height--) {
1182
        p = p1;
1183
        lum = lum1;
1184
        cb = cb1;
1185
        cr = cr1;
1186
        for(w = width; w >= 4; w -= 4) {
1187
            cb[0] = p[0];
1188
            lum[0] = p[1];
1189
            lum[1] = p[2];
1190
            cr[0] = p[3];
1191
            lum[2] = p[4];
1192
            lum[3] = p[5];
1193
            p += 6;
1194
            lum += 4;
1195
            cb++;
1196
            cr++;
1197
        }
1198
        p1 += src->linesize[0];
1199
        lum1 += dst->linesize[0];
1200
        cb1 += dst->linesize[1];
1201
        cr1 += dst->linesize[2];
1202
    }
1203
}
1204

    
1205

    
1206
static void yuv420p_to_yuyv422(AVPicture *dst, const AVPicture *src,
1207
                              int width, int height)
1208
{
1209
    int w, h;
1210
    uint8_t *line1, *line2, *linesrc = dst->data[0];
1211
    uint8_t *lum1, *lum2, *lumsrc = src->data[0];
1212
    uint8_t *cb1, *cb2 = src->data[1];
1213
    uint8_t *cr1, *cr2 = src->data[2];
1214

    
1215
    for(h = height / 2; h--;) {
1216
        line1 = linesrc;
1217
        line2 = linesrc + dst->linesize[0];
1218

    
1219
        lum1 = lumsrc;
1220
        lum2 = lumsrc + src->linesize[0];
1221

    
1222
        cb1 = cb2;
1223
        cr1 = cr2;
1224

    
1225
        for(w = width / 2; w--;) {
1226
                *line1++ = *lum1++; *line2++ = *lum2++;
1227
                *line1++ =          *line2++ = *cb1++;
1228
                *line1++ = *lum1++; *line2++ = *lum2++;
1229
                *line1++ =          *line2++ = *cr1++;
1230
        }
1231

    
1232
        linesrc += dst->linesize[0] * 2;
1233
        lumsrc += src->linesize[0] * 2;
1234
        cb2 += src->linesize[1];
1235
        cr2 += src->linesize[2];
1236
    }
1237
}
1238

    
1239
static void yuv420p_to_uyvy422(AVPicture *dst, const AVPicture *src,
1240
                              int width, int height)
1241
{
1242
    int w, h;
1243
    uint8_t *line1, *line2, *linesrc = dst->data[0];
1244
    uint8_t *lum1, *lum2, *lumsrc = src->data[0];
1245
    uint8_t *cb1, *cb2 = src->data[1];
1246
    uint8_t *cr1, *cr2 = src->data[2];
1247

    
1248
    for(h = height / 2; h--;) {
1249
        line1 = linesrc;
1250
        line2 = linesrc + dst->linesize[0];
1251

    
1252
        lum1 = lumsrc;
1253
        lum2 = lumsrc + src->linesize[0];
1254

    
1255
        cb1 = cb2;
1256
        cr1 = cr2;
1257

    
1258
        for(w = width / 2; w--;) {
1259
                *line1++ =          *line2++ = *cb1++;
1260
                *line1++ = *lum1++; *line2++ = *lum2++;
1261
                *line1++ =          *line2++ = *cr1++;
1262
                *line1++ = *lum1++; *line2++ = *lum2++;
1263
        }
1264

    
1265
        linesrc += dst->linesize[0] * 2;
1266
        lumsrc += src->linesize[0] * 2;
1267
        cb2 += src->linesize[1];
1268
        cr2 += src->linesize[2];
1269
    }
1270
}
1271

    
1272
/* 2x2 -> 1x1 */
1273
void ff_shrink22(uint8_t *dst, int dst_wrap,
1274
                     const uint8_t *src, int src_wrap,
1275
                     int width, int height)
1276
{
1277
    int w;
1278
    const uint8_t *s1, *s2;
1279
    uint8_t *d;
1280

    
1281
    for(;height > 0; height--) {
1282
        s1 = src;
1283
        s2 = s1 + src_wrap;
1284
        d = dst;
1285
        for(w = width;w >= 4; w-=4) {
1286
            d[0] = (s1[0] + s1[1] + s2[0] + s2[1] + 2) >> 2;
1287
            d[1] = (s1[2] + s1[3] + s2[2] + s2[3] + 2) >> 2;
1288
            d[2] = (s1[4] + s1[5] + s2[4] + s2[5] + 2) >> 2;
1289
            d[3] = (s1[6] + s1[7] + s2[6] + s2[7] + 2) >> 2;
1290
            s1 += 8;
1291
            s2 += 8;
1292
            d += 4;
1293
        }
1294
        for(;w > 0; w--) {
1295
            d[0] = (s1[0] + s1[1] + s2[0] + s2[1] + 2) >> 2;
1296
            s1 += 2;
1297
            s2 += 2;
1298
            d++;
1299
        }
1300
        src += 2 * src_wrap;
1301
        dst += dst_wrap;
1302
    }
1303
}
1304

    
1305
/* 4x4 -> 1x1 */
1306
void ff_shrink44(uint8_t *dst, int dst_wrap,
1307
                     const uint8_t *src, int src_wrap,
1308
                     int width, int height)
1309
{
1310
    int w;
1311
    const uint8_t *s1, *s2, *s3, *s4;
1312
    uint8_t *d;
1313

    
1314
    for(;height > 0; height--) {
1315
        s1 = src;
1316
        s2 = s1 + src_wrap;
1317
        s3 = s2 + src_wrap;
1318
        s4 = s3 + src_wrap;
1319
        d = dst;
1320
        for(w = width;w > 0; w--) {
1321
            d[0] = (s1[0] + s1[1] + s1[2] + s1[3] +
1322
                    s2[0] + s2[1] + s2[2] + s2[3] +
1323
                    s3[0] + s3[1] + s3[2] + s3[3] +
1324
                    s4[0] + s4[1] + s4[2] + s4[3] + 8) >> 4;
1325
            s1 += 4;
1326
            s2 += 4;
1327
            s3 += 4;
1328
            s4 += 4;
1329
            d++;
1330
        }
1331
        src += 4 * src_wrap;
1332
        dst += dst_wrap;
1333
    }
1334
}
1335

    
1336
/* 8x8 -> 1x1 */
1337
void ff_shrink88(uint8_t *dst, int dst_wrap,
1338
                     const uint8_t *src, int src_wrap,
1339
                     int width, int height)
1340
{
1341
    int w, i;
1342

    
1343
    for(;height > 0; height--) {
1344
        for(w = width;w > 0; w--) {
1345
            int tmp=0;
1346
            for(i=0; i<8; i++){
1347
                tmp += src[0] + src[1] + src[2] + src[3] + src[4] + src[5] + src[6] + src[7];
1348
                src += src_wrap;
1349
            }
1350
            *(dst++) = (tmp + 32)>>6;
1351
            src += 8 - 8*src_wrap;
1352
        }
1353
        src += 8*src_wrap - 8*width;
1354
        dst += dst_wrap - width;
1355
    }
1356
}
1357

    
1358
/* XXX: add jpeg quantize code */
1359

    
1360
#define TRANSP_INDEX (6*6*6)
1361

    
1362
/* this is maybe slow, but allows for extensions */
1363
static inline unsigned char gif_clut_index(uint8_t r, uint8_t g, uint8_t b)
1364
{
1365
    return (((r) / 47) % 6) * 6 * 6 + (((g) / 47) % 6) * 6 + (((b) / 47) % 6);
1366
}
1367

    
1368
static void build_rgb_palette(uint8_t *palette, int has_alpha)
1369
{
1370
    uint32_t *pal;
1371
    static const uint8_t pal_value[6] = { 0x00, 0x33, 0x66, 0x99, 0xcc, 0xff };
1372
    int i, r, g, b;
1373

    
1374
    pal = (uint32_t *)palette;
1375
    i = 0;
1376
    for(r = 0; r < 6; r++) {
1377
        for(g = 0; g < 6; g++) {
1378
            for(b = 0; b < 6; b++) {
1379
                pal[i++] = (0xff << 24) | (pal_value[r] << 16) |
1380
                    (pal_value[g] << 8) | pal_value[b];
1381
            }
1382
        }
1383
    }
1384
    if (has_alpha)
1385
        pal[i++] = 0;
1386
    while (i < 256)
1387
        pal[i++] = 0xff000000;
1388
}
1389

    
1390
/* copy bit n to bits 0 ... n - 1 */
1391
static inline unsigned int bitcopy_n(unsigned int a, int n)
1392
{
1393
    int mask;
1394
    mask = (1 << n) - 1;
1395
    return (a & (0xff & ~mask)) | ((-((a >> n) & 1)) & mask);
1396
}
1397

    
1398
/* rgb555 handling */
1399

    
1400
#define RGB_NAME rgb555
1401

    
1402
#define RGB_IN(r, g, b, s)\
1403
{\
1404
    unsigned int v = ((const uint16_t *)(s))[0];\
1405
    r = bitcopy_n(v >> (10 - 3), 3);\
1406
    g = bitcopy_n(v >> (5 - 3), 3);\
1407
    b = bitcopy_n(v << 3, 3);\
1408
}
1409

    
1410

    
1411
#define RGB_OUT(d, r, g, b)\
1412
{\
1413
    ((uint16_t *)(d))[0] = ((r >> 3) << 10) | ((g >> 3) << 5) | (b >> 3);\
1414
}
1415

    
1416
#define BPP 2
1417

    
1418
#include "imgconvert_template.c"
1419

    
1420
/* rgb565 handling */
1421

    
1422
#define RGB_NAME rgb565
1423

    
1424
#define RGB_IN(r, g, b, s)\
1425
{\
1426
    unsigned int v = ((const uint16_t *)(s))[0];\
1427
    r = bitcopy_n(v >> (11 - 3), 3);\
1428
    g = bitcopy_n(v >> (5 - 2), 2);\
1429
    b = bitcopy_n(v << 3, 3);\
1430
}
1431

    
1432
#define RGB_OUT(d, r, g, b)\
1433
{\
1434
    ((uint16_t *)(d))[0] = ((r >> 3) << 11) | ((g >> 2) << 5) | (b >> 3);\
1435
}
1436

    
1437
#define BPP 2
1438

    
1439
#include "imgconvert_template.c"
1440

    
1441
/* bgr24 handling */
1442

    
1443
#define RGB_NAME bgr24
1444

    
1445
#define RGB_IN(r, g, b, s)\
1446
{\
1447
    b = (s)[0];\
1448
    g = (s)[1];\
1449
    r = (s)[2];\
1450
}
1451

    
1452
#define RGB_OUT(d, r, g, b)\
1453
{\
1454
    (d)[0] = b;\
1455
    (d)[1] = g;\
1456
    (d)[2] = r;\
1457
}
1458

    
1459
#define BPP 3
1460

    
1461
#include "imgconvert_template.c"
1462

    
1463
#undef RGB_IN
1464
#undef RGB_OUT
1465
#undef BPP
1466

    
1467
/* rgb24 handling */
1468

    
1469
#define RGB_NAME rgb24
1470
#define FMT_RGB24
1471

    
1472
#define RGB_IN(r, g, b, s)\
1473
{\
1474
    r = (s)[0];\
1475
    g = (s)[1];\
1476
    b = (s)[2];\
1477
}
1478

    
1479
#define RGB_OUT(d, r, g, b)\
1480
{\
1481
    (d)[0] = r;\
1482
    (d)[1] = g;\
1483
    (d)[2] = b;\
1484
}
1485

    
1486
#define BPP 3
1487

    
1488
#include "imgconvert_template.c"
1489

    
1490
/* rgb32 handling */
1491

    
1492
#define RGB_NAME rgb32
1493
#define FMT_RGB32
1494

    
1495
#define RGB_IN(r, g, b, s)\
1496
{\
1497
    unsigned int v = ((const uint32_t *)(s))[0];\
1498
    r = (v >> 16) & 0xff;\
1499
    g = (v >> 8) & 0xff;\
1500
    b = v & 0xff;\
1501
}
1502

    
1503
#define RGBA_IN(r, g, b, a, s)\
1504
{\
1505
    unsigned int v = ((const uint32_t *)(s))[0];\
1506
    a = (v >> 24) & 0xff;\
1507
    r = (v >> 16) & 0xff;\
1508
    g = (v >> 8) & 0xff;\
1509
    b = v & 0xff;\
1510
}
1511

    
1512
#define RGBA_OUT(d, r, g, b, a)\
1513
{\
1514
    ((uint32_t *)(d))[0] = (a << 24) | (r << 16) | (g << 8) | b;\
1515
}
1516

    
1517
#define BPP 4
1518

    
1519
#include "imgconvert_template.c"
1520

    
1521
static void mono_to_gray(AVPicture *dst, const AVPicture *src,
1522
                         int width, int height, int xor_mask)
1523
{
1524
    const unsigned char *p;
1525
    unsigned char *q;
1526
    int v, dst_wrap, src_wrap;
1527
    int y, w;
1528

    
1529
    p = src->data[0];
1530
    src_wrap = src->linesize[0] - ((width + 7) >> 3);
1531

    
1532
    q = dst->data[0];
1533
    dst_wrap = dst->linesize[0] - width;
1534
    for(y=0;y<height;y++) {
1535
        w = width;
1536
        while (w >= 8) {
1537
            v = *p++ ^ xor_mask;
1538
            q[0] = -(v >> 7);
1539
            q[1] = -((v >> 6) & 1);
1540
            q[2] = -((v >> 5) & 1);
1541
            q[3] = -((v >> 4) & 1);
1542
            q[4] = -((v >> 3) & 1);
1543
            q[5] = -((v >> 2) & 1);
1544
            q[6] = -((v >> 1) & 1);
1545
            q[7] = -((v >> 0) & 1);
1546
            w -= 8;
1547
            q += 8;
1548
        }
1549
        if (w > 0) {
1550
            v = *p++ ^ xor_mask;
1551
            do {
1552
                q[0] = -((v >> 7) & 1);
1553
                q++;
1554
                v <<= 1;
1555
            } while (--w);
1556
        }
1557
        p += src_wrap;
1558
        q += dst_wrap;
1559
    }
1560
}
1561

    
1562
static void monowhite_to_gray(AVPicture *dst, const AVPicture *src,
1563
                               int width, int height)
1564
{
1565
    mono_to_gray(dst, src, width, height, 0xff);
1566
}
1567

    
1568
static void monoblack_to_gray(AVPicture *dst, const AVPicture *src,
1569
                               int width, int height)
1570
{
1571
    mono_to_gray(dst, src, width, height, 0x00);
1572
}
1573

    
1574
static void gray_to_mono(AVPicture *dst, const AVPicture *src,
1575
                         int width, int height, int xor_mask)
1576
{
1577
    int n;
1578
    const uint8_t *s;
1579
    uint8_t *d;
1580
    int j, b, v, n1, src_wrap, dst_wrap, y;
1581

    
1582
    s = src->data[0];
1583
    src_wrap = src->linesize[0] - width;
1584

    
1585
    d = dst->data[0];
1586
    dst_wrap = dst->linesize[0] - ((width + 7) >> 3);
1587

    
1588
    for(y=0;y<height;y++) {
1589
        n = width;
1590
        while (n >= 8) {
1591
            v = 0;
1592
            for(j=0;j<8;j++) {
1593
                b = s[0];
1594
                s++;
1595
                v = (v << 1) | (b >> 7);
1596
            }
1597
            d[0] = v ^ xor_mask;
1598
            d++;
1599
            n -= 8;
1600
        }
1601
        if (n > 0) {
1602
            n1 = n;
1603
            v = 0;
1604
            while (n > 0) {
1605
                b = s[0];
1606
                s++;
1607
                v = (v << 1) | (b >> 7);
1608
                n--;
1609
            }
1610
            d[0] = (v << (8 - (n1 & 7))) ^ xor_mask;
1611
            d++;
1612
        }
1613
        s += src_wrap;
1614
        d += dst_wrap;
1615
    }
1616
}
1617

    
1618
static void gray_to_monowhite(AVPicture *dst, const AVPicture *src,
1619
                              int width, int height)
1620
{
1621
    gray_to_mono(dst, src, width, height, 0xff);
1622
}
1623

    
1624
static void gray_to_monoblack(AVPicture *dst, const AVPicture *src,
1625
                              int width, int height)
1626
{
1627
    gray_to_mono(dst, src, width, height, 0x00);
1628
}
1629

    
1630
static void gray_to_gray16(AVPicture *dst, const AVPicture *src,
1631
                              int width, int height)
1632
{
1633
    int x, y, src_wrap, dst_wrap;
1634
    uint8_t *s, *d;
1635
    s = src->data[0];
1636
    src_wrap = src->linesize[0] - width;
1637
    d = dst->data[0];
1638
    dst_wrap = dst->linesize[0] - width * 2;
1639
    for(y=0; y<height; y++){
1640
        for(x=0; x<width; x++){
1641
            *d++ = *s;
1642
            *d++ = *s++;
1643
        }
1644
        s += src_wrap;
1645
        d += dst_wrap;
1646
    }
1647
}
1648

    
1649
static void gray16_to_gray(AVPicture *dst, const AVPicture *src,
1650
                              int width, int height)
1651
{
1652
    int x, y, src_wrap, dst_wrap;
1653
    uint8_t *s, *d;
1654
    s = src->data[0];
1655
    src_wrap = src->linesize[0] - width * 2;
1656
    d = dst->data[0];
1657
    dst_wrap = dst->linesize[0] - width;
1658
    for(y=0; y<height; y++){
1659
        for(x=0; x<width; x++){
1660
            *d++ = *s;
1661
            s += 2;
1662
        }
1663
        s += src_wrap;
1664
        d += dst_wrap;
1665
    }
1666
}
1667

    
1668
static void gray16be_to_gray(AVPicture *dst, const AVPicture *src,
1669
                              int width, int height)
1670
{
1671
    gray16_to_gray(dst, src, width, height);
1672
}
1673

    
1674
static void gray16le_to_gray(AVPicture *dst, const AVPicture *src,
1675
                              int width, int height)
1676
{
1677
    AVPicture tmpsrc = *src;
1678
    tmpsrc.data[0]++;
1679
    gray16_to_gray(dst, &tmpsrc, width, height);
1680
}
1681

    
1682
static void gray16_to_gray16(AVPicture *dst, const AVPicture *src,
1683
                              int width, int height)
1684
{
1685
    int x, y, src_wrap, dst_wrap;
1686
    uint16_t *s, *d;
1687
    s = (uint16_t*)src->data[0];
1688
    src_wrap = (src->linesize[0] - width * 2)/2;
1689
    d = (uint16_t*)dst->data[0];
1690
    dst_wrap = (dst->linesize[0] - width * 2)/2;
1691
    for(y=0; y<height; y++){
1692
        for(x=0; x<width; x++){
1693
            *d++ = bswap_16(*s++);
1694
        }
1695
        s += src_wrap;
1696
        d += dst_wrap;
1697
    }
1698
}
1699

    
1700

    
1701
typedef struct ConvertEntry {
1702
    void (*convert)(AVPicture *dst,
1703
                    const AVPicture *src, int width, int height);
1704
} ConvertEntry;
1705

    
1706
/* Add each new conversion function in this table. In order to be able
1707
   to convert from any format to any format, the following constraints
1708
   must be satisfied:
1709

1710
   - all FF_COLOR_RGB formats must convert to and from PIX_FMT_RGB24
1711

1712
   - all FF_COLOR_GRAY formats must convert to and from PIX_FMT_GRAY8
1713

1714
   - all FF_COLOR_RGB formats with alpha must convert to and from PIX_FMT_RGB32
1715

1716
   - PIX_FMT_YUV444P and PIX_FMT_YUVJ444P must convert to and from
1717
     PIX_FMT_RGB24.
1718

1719
   - PIX_FMT_422 must convert to and from PIX_FMT_422P.
1720

1721
   The other conversion functions are just optimizations for common cases.
1722
*/
1723
static const ConvertEntry convert_table[PIX_FMT_NB][PIX_FMT_NB] = {
1724
    [PIX_FMT_YUV420P] = {
1725
        [PIX_FMT_YUYV422] = {
1726
            .convert = yuv420p_to_yuyv422,
1727
        },
1728
        [PIX_FMT_RGB555] = {
1729
            .convert = yuv420p_to_rgb555
1730
        },
1731
        [PIX_FMT_RGB565] = {
1732
            .convert = yuv420p_to_rgb565
1733
        },
1734
        [PIX_FMT_BGR24] = {
1735
            .convert = yuv420p_to_bgr24
1736
        },
1737
        [PIX_FMT_RGB24] = {
1738
            .convert = yuv420p_to_rgb24
1739
        },
1740
        [PIX_FMT_RGB32] = {
1741
            .convert = yuv420p_to_rgb32
1742
        },
1743
        [PIX_FMT_UYVY422] = {
1744
            .convert = yuv420p_to_uyvy422,
1745
        },
1746
    },
1747
    [PIX_FMT_YUV422P] = {
1748
        [PIX_FMT_YUYV422] = {
1749
            .convert = yuv422p_to_yuyv422,
1750
        },
1751
        [PIX_FMT_UYVY422] = {
1752
            .convert = yuv422p_to_uyvy422,
1753
        },
1754
    },
1755
    [PIX_FMT_YUV444P] = {
1756
        [PIX_FMT_RGB24] = {
1757
            .convert = yuv444p_to_rgb24
1758
        },
1759
    },
1760
    [PIX_FMT_YUVJ420P] = {
1761
        [PIX_FMT_RGB555] = {
1762
            .convert = yuvj420p_to_rgb555
1763
        },
1764
        [PIX_FMT_RGB565] = {
1765
            .convert = yuvj420p_to_rgb565
1766
        },
1767
        [PIX_FMT_BGR24] = {
1768
            .convert = yuvj420p_to_bgr24
1769
        },
1770
        [PIX_FMT_RGB24] = {
1771
            .convert = yuvj420p_to_rgb24
1772
        },
1773
        [PIX_FMT_RGB32] = {
1774
            .convert = yuvj420p_to_rgb32
1775
        },
1776
    },
1777
    [PIX_FMT_YUVJ444P] = {
1778
        [PIX_FMT_RGB24] = {
1779
            .convert = yuvj444p_to_rgb24
1780
        },
1781
    },
1782
    [PIX_FMT_YUYV422] = {
1783
        [PIX_FMT_YUV420P] = {
1784
            .convert = yuyv422_to_yuv420p,
1785
        },
1786
        [PIX_FMT_YUV422P] = {
1787
            .convert = yuyv422_to_yuv422p,
1788
        },
1789
    },
1790
    [PIX_FMT_UYVY422] = {
1791
        [PIX_FMT_YUV420P] = {
1792
            .convert = uyvy422_to_yuv420p,
1793
        },
1794
        [PIX_FMT_YUV422P] = {
1795
            .convert = uyvy422_to_yuv422p,
1796
        },
1797
    },
1798
    [PIX_FMT_RGB24] = {
1799
        [PIX_FMT_YUV420P] = {
1800
            .convert = rgb24_to_yuv420p
1801
        },
1802
        [PIX_FMT_RGB565] = {
1803
            .convert = rgb24_to_rgb565
1804
        },
1805
        [PIX_FMT_RGB555] = {
1806
            .convert = rgb24_to_rgb555
1807
        },
1808
        [PIX_FMT_RGB32] = {
1809
            .convert = rgb24_to_rgb32
1810
        },
1811
        [PIX_FMT_BGR24] = {
1812
            .convert = rgb24_to_bgr24
1813
        },
1814
        [PIX_FMT_GRAY8] = {
1815
            .convert = rgb24_to_gray
1816
        },
1817
        [PIX_FMT_PAL8] = {
1818
            .convert = rgb24_to_pal8
1819
        },
1820
        [PIX_FMT_YUV444P] = {
1821
            .convert = rgb24_to_yuv444p
1822
        },
1823
        [PIX_FMT_YUVJ420P] = {
1824
            .convert = rgb24_to_yuvj420p
1825
        },
1826
        [PIX_FMT_YUVJ444P] = {
1827
            .convert = rgb24_to_yuvj444p
1828
        },
1829
    },
1830
    [PIX_FMT_RGB32] = {
1831
        [PIX_FMT_RGB24] = {
1832
            .convert = rgb32_to_rgb24
1833
        },
1834
        [PIX_FMT_BGR24] = {
1835
            .convert = rgb32_to_bgr24
1836
        },
1837
        [PIX_FMT_RGB565] = {
1838
            .convert = rgb32_to_rgb565
1839
        },
1840
        [PIX_FMT_RGB555] = {
1841
            .convert = rgb32_to_rgb555
1842
        },
1843
        [PIX_FMT_PAL8] = {
1844
            .convert = rgb32_to_pal8
1845
        },
1846
        [PIX_FMT_YUV420P] = {
1847
            .convert = rgb32_to_yuv420p
1848
        },
1849
        [PIX_FMT_GRAY8] = {
1850
            .convert = rgb32_to_gray
1851
        },
1852
    },
1853
    [PIX_FMT_BGR24] = {
1854
        [PIX_FMT_RGB32] = {
1855
            .convert = bgr24_to_rgb32
1856
        },
1857
        [PIX_FMT_RGB24] = {
1858
            .convert = bgr24_to_rgb24
1859
        },
1860
        [PIX_FMT_YUV420P] = {
1861
            .convert = bgr24_to_yuv420p
1862
        },
1863
        [PIX_FMT_GRAY8] = {
1864
            .convert = bgr24_to_gray
1865
        },
1866
    },
1867
    [PIX_FMT_RGB555] = {
1868
        [PIX_FMT_RGB24] = {
1869
            .convert = rgb555_to_rgb24
1870
        },
1871
        [PIX_FMT_RGB32] = {
1872
            .convert = rgb555_to_rgb32
1873
        },
1874
        [PIX_FMT_YUV420P] = {
1875
            .convert = rgb555_to_yuv420p
1876
        },
1877
        [PIX_FMT_GRAY8] = {
1878
            .convert = rgb555_to_gray
1879
        },
1880
    },
1881
    [PIX_FMT_RGB565] = {
1882
        [PIX_FMT_RGB32] = {
1883
            .convert = rgb565_to_rgb32
1884
        },
1885
        [PIX_FMT_RGB24] = {
1886
            .convert = rgb565_to_rgb24
1887
        },
1888
        [PIX_FMT_YUV420P] = {
1889
            .convert = rgb565_to_yuv420p
1890
        },
1891
        [PIX_FMT_GRAY8] = {
1892
            .convert = rgb565_to_gray
1893
        },
1894
    },
1895
    [PIX_FMT_GRAY16BE] = {
1896
        [PIX_FMT_GRAY8] = {
1897
            .convert = gray16be_to_gray
1898
        },
1899
        [PIX_FMT_GRAY16LE] = {
1900
            .convert = gray16_to_gray16
1901
        },
1902
    },
1903
    [PIX_FMT_GRAY16LE] = {
1904
        [PIX_FMT_GRAY8] = {
1905
            .convert = gray16le_to_gray
1906
        },
1907
        [PIX_FMT_GRAY16BE] = {
1908
            .convert = gray16_to_gray16
1909
        },
1910
    },
1911
    [PIX_FMT_GRAY8] = {
1912
        [PIX_FMT_RGB555] = {
1913
            .convert = gray_to_rgb555
1914
        },
1915
        [PIX_FMT_RGB565] = {
1916
            .convert = gray_to_rgb565
1917
        },
1918
        [PIX_FMT_RGB24] = {
1919
            .convert = gray_to_rgb24
1920
        },
1921
        [PIX_FMT_BGR24] = {
1922
            .convert = gray_to_bgr24
1923
        },
1924
        [PIX_FMT_RGB32] = {
1925
            .convert = gray_to_rgb32
1926
        },
1927
        [PIX_FMT_MONOWHITE] = {
1928
            .convert = gray_to_monowhite
1929
        },
1930
        [PIX_FMT_MONOBLACK] = {
1931
            .convert = gray_to_monoblack
1932
        },
1933
        [PIX_FMT_GRAY16LE] = {
1934
            .convert = gray_to_gray16
1935
        },
1936
        [PIX_FMT_GRAY16BE] = {
1937
            .convert = gray_to_gray16
1938
        },
1939
    },
1940
    [PIX_FMT_MONOWHITE] = {
1941
        [PIX_FMT_GRAY8] = {
1942
            .convert = monowhite_to_gray
1943
        },
1944
    },
1945
    [PIX_FMT_MONOBLACK] = {
1946
        [PIX_FMT_GRAY8] = {
1947
            .convert = monoblack_to_gray
1948
        },
1949
    },
1950
    [PIX_FMT_PAL8] = {
1951
        [PIX_FMT_RGB555] = {
1952
            .convert = pal8_to_rgb555
1953
        },
1954
        [PIX_FMT_RGB565] = {
1955
            .convert = pal8_to_rgb565
1956
        },
1957
        [PIX_FMT_BGR24] = {
1958
            .convert = pal8_to_bgr24
1959
        },
1960
        [PIX_FMT_RGB24] = {
1961
            .convert = pal8_to_rgb24
1962
        },
1963
        [PIX_FMT_RGB32] = {
1964
            .convert = pal8_to_rgb32
1965
        },
1966
    },
1967
    [PIX_FMT_UYYVYY411] = {
1968
        [PIX_FMT_YUV411P] = {
1969
            .convert = uyyvyy411_to_yuv411p,
1970
        },
1971
    },
1972

    
1973
};
1974

    
1975
int avpicture_alloc(AVPicture *picture,
1976
                           int pix_fmt, int width, int height)
1977
{
1978
    int size;
1979
    void *ptr;
1980

    
1981
    size = avpicture_get_size(pix_fmt, width, height);
1982
    if(size<0)
1983
        goto fail;
1984
    ptr = av_malloc(size);
1985
    if (!ptr)
1986
        goto fail;
1987
    avpicture_fill(picture, ptr, pix_fmt, width, height);
1988
    return 0;
1989
 fail:
1990
    memset(picture, 0, sizeof(AVPicture));
1991
    return -1;
1992
}
1993

    
1994
void avpicture_free(AVPicture *picture)
1995
{
1996
    av_free(picture->data[0]);
1997
}
1998

    
1999
/* return true if yuv planar */
2000
static inline int is_yuv_planar(const PixFmtInfo *ps)
2001
{
2002
    return (ps->color_type == FF_COLOR_YUV ||
2003
            ps->color_type == FF_COLOR_YUV_JPEG) &&
2004
        ps->pixel_type == FF_PIXEL_PLANAR;
2005
}
2006

    
2007
int av_picture_crop(AVPicture *dst, const AVPicture *src,
2008
              int pix_fmt, int top_band, int left_band)
2009
{
2010
    int y_shift;
2011
    int x_shift;
2012

    
2013
    if (pix_fmt < 0 || pix_fmt >= PIX_FMT_NB || !is_yuv_planar(&pix_fmt_info[pix_fmt]))
2014
        return -1;
2015

    
2016
    y_shift = pix_fmt_info[pix_fmt].y_chroma_shift;
2017
    x_shift = pix_fmt_info[pix_fmt].x_chroma_shift;
2018

    
2019
    dst->data[0] = src->data[0] + (top_band * src->linesize[0]) + left_band;
2020
    dst->data[1] = src->data[1] + ((top_band >> y_shift) * src->linesize[1]) + (left_band >> x_shift);
2021
    dst->data[2] = src->data[2] + ((top_band >> y_shift) * src->linesize[2]) + (left_band >> x_shift);
2022

    
2023
    dst->linesize[0] = src->linesize[0];
2024
    dst->linesize[1] = src->linesize[1];
2025
    dst->linesize[2] = src->linesize[2];
2026
    return 0;
2027
}
2028

    
2029
int av_picture_pad(AVPicture *dst, const AVPicture *src, int height, int width,
2030
            int pix_fmt, int padtop, int padbottom, int padleft, int padright,
2031
            int *color)
2032
{
2033
    uint8_t *optr;
2034
    int y_shift;
2035
    int x_shift;
2036
    int yheight;
2037
    int i, y;
2038

    
2039
    if (pix_fmt < 0 || pix_fmt >= PIX_FMT_NB ||
2040
        !is_yuv_planar(&pix_fmt_info[pix_fmt])) return -1;
2041

    
2042
    for (i = 0; i < 3; i++) {
2043
        x_shift = i ? pix_fmt_info[pix_fmt].x_chroma_shift : 0;
2044
        y_shift = i ? pix_fmt_info[pix_fmt].y_chroma_shift : 0;
2045

    
2046
        if (padtop || padleft) {
2047
            memset(dst->data[i], color[i],
2048
                dst->linesize[i] * (padtop >> y_shift) + (padleft >> x_shift));
2049
        }
2050

    
2051
        if (padleft || padright) {
2052
            optr = dst->data[i] + dst->linesize[i] * (padtop >> y_shift) +
2053
                (dst->linesize[i] - (padright >> x_shift));
2054
            yheight = (height - 1 - (padtop + padbottom)) >> y_shift;
2055
            for (y = 0; y < yheight; y++) {
2056
                memset(optr, color[i], (padleft + padright) >> x_shift);
2057
                optr += dst->linesize[i];
2058
            }
2059
        }
2060

    
2061
        if (src) { /* first line */
2062
            uint8_t *iptr = src->data[i];
2063
            optr = dst->data[i] + dst->linesize[i] * (padtop >> y_shift) +
2064
                    (padleft >> x_shift);
2065
            memcpy(optr, iptr, (width - padleft - padright) >> x_shift);
2066
            iptr += src->linesize[i];
2067
            optr = dst->data[i] + dst->linesize[i] * (padtop >> y_shift) +
2068
                (dst->linesize[i] - (padright >> x_shift));
2069
            yheight = (height - 1 - (padtop + padbottom)) >> y_shift;
2070
            for (y = 0; y < yheight; y++) {
2071
                memset(optr, color[i], (padleft + padright) >> x_shift);
2072
                memcpy(optr + ((padleft + padright) >> x_shift), iptr,
2073
                       (width - padleft - padright) >> x_shift);
2074
                iptr += src->linesize[i];
2075
                optr += dst->linesize[i];
2076
            }
2077
        }
2078

    
2079
        if (padbottom || padright) {
2080
            optr = dst->data[i] + dst->linesize[i] *
2081
                ((height - padbottom) >> y_shift) - (padright >> x_shift);
2082
            memset(optr, color[i],dst->linesize[i] *
2083
                (padbottom >> y_shift) + (padright >> x_shift));
2084
        }
2085
    }
2086
    return 0;
2087
}
2088

    
2089
#ifndef CONFIG_SWSCALE
2090
static uint8_t y_ccir_to_jpeg[256];
2091
static uint8_t y_jpeg_to_ccir[256];
2092
static uint8_t c_ccir_to_jpeg[256];
2093
static uint8_t c_jpeg_to_ccir[256];
2094

    
2095
/* init various conversion tables */
2096
static void img_convert_init(void)
2097
{
2098
    int i;
2099
    uint8_t *cm = ff_cropTbl + MAX_NEG_CROP;
2100

    
2101
    for(i = 0;i < 256; i++) {
2102
        y_ccir_to_jpeg[i] = Y_CCIR_TO_JPEG(i);
2103
        y_jpeg_to_ccir[i] = Y_JPEG_TO_CCIR(i);
2104
        c_ccir_to_jpeg[i] = C_CCIR_TO_JPEG(i);
2105
        c_jpeg_to_ccir[i] = C_JPEG_TO_CCIR(i);
2106
    }
2107
}
2108

    
2109
/* apply to each pixel the given table */
2110
static void img_apply_table(uint8_t *dst, int dst_wrap,
2111
                            const uint8_t *src, int src_wrap,
2112
                            int width, int height, const uint8_t *table1)
2113
{
2114
    int n;
2115
    const uint8_t *s;
2116
    uint8_t *d;
2117
    const uint8_t *table;
2118

    
2119
    table = table1;
2120
    for(;height > 0; height--) {
2121
        s = src;
2122
        d = dst;
2123
        n = width;
2124
        while (n >= 4) {
2125
            d[0] = table[s[0]];
2126
            d[1] = table[s[1]];
2127
            d[2] = table[s[2]];
2128
            d[3] = table[s[3]];
2129
            d += 4;
2130
            s += 4;
2131
            n -= 4;
2132
        }
2133
        while (n > 0) {
2134
            d[0] = table[s[0]];
2135
            d++;
2136
            s++;
2137
            n--;
2138
        }
2139
        dst += dst_wrap;
2140
        src += src_wrap;
2141
    }
2142
}
2143

    
2144
/* XXX: use generic filter ? */
2145
/* XXX: in most cases, the sampling position is incorrect */
2146

    
2147
/* 4x1 -> 1x1 */
2148
static void shrink41(uint8_t *dst, int dst_wrap,
2149
                     const uint8_t *src, int src_wrap,
2150
                     int width, int height)
2151
{
2152
    int w;
2153
    const uint8_t *s;
2154
    uint8_t *d;
2155

    
2156
    for(;height > 0; height--) {
2157
        s = src;
2158
        d = dst;
2159
        for(w = width;w > 0; w--) {
2160
            d[0] = (s[0] + s[1] + s[2] + s[3] + 2) >> 2;
2161
            s += 4;
2162
            d++;
2163
        }
2164
        src += src_wrap;
2165
        dst += dst_wrap;
2166
    }
2167
}
2168

    
2169
/* 2x1 -> 1x1 */
2170
static void shrink21(uint8_t *dst, int dst_wrap,
2171
                     const uint8_t *src, int src_wrap,
2172
                     int width, int height)
2173
{
2174
    int w;
2175
    const uint8_t *s;
2176
    uint8_t *d;
2177

    
2178
    for(;height > 0; height--) {
2179
        s = src;
2180
        d = dst;
2181
        for(w = width;w > 0; w--) {
2182
            d[0] = (s[0] + s[1]) >> 1;
2183
            s += 2;
2184
            d++;
2185
        }
2186
        src += src_wrap;
2187
        dst += dst_wrap;
2188
    }
2189
}
2190

    
2191
/* 1x2 -> 1x1 */
2192
static void shrink12(uint8_t *dst, int dst_wrap,
2193
                     const uint8_t *src, int src_wrap,
2194
                     int width, int height)
2195
{
2196
    int w;
2197
    uint8_t *d;
2198
    const uint8_t *s1, *s2;
2199

    
2200
    for(;height > 0; height--) {
2201
        s1 = src;
2202
        s2 = s1 + src_wrap;
2203
        d = dst;
2204
        for(w = width;w >= 4; w-=4) {
2205
            d[0] = (s1[0] + s2[0]) >> 1;
2206
            d[1] = (s1[1] + s2[1]) >> 1;
2207
            d[2] = (s1[2] + s2[2]) >> 1;
2208
            d[3] = (s1[3] + s2[3]) >> 1;
2209
            s1 += 4;
2210
            s2 += 4;
2211
            d += 4;
2212
        }
2213
        for(;w > 0; w--) {
2214
            d[0] = (s1[0] + s2[0]) >> 1;
2215
            s1++;
2216
            s2++;
2217
            d++;
2218
        }
2219
        src += 2 * src_wrap;
2220
        dst += dst_wrap;
2221
    }
2222
}
2223

    
2224
static void grow21_line(uint8_t *dst, const uint8_t *src,
2225
                        int width)
2226
{
2227
    int w;
2228
    const uint8_t *s1;
2229
    uint8_t *d;
2230

    
2231
    s1 = src;
2232
    d = dst;
2233
    for(w = width;w >= 4; w-=4) {
2234
        d[1] = d[0] = s1[0];
2235
        d[3] = d[2] = s1[1];
2236
        s1 += 2;
2237
        d += 4;
2238
    }
2239
    for(;w >= 2; w -= 2) {
2240
        d[1] = d[0] = s1[0];
2241
        s1 ++;
2242
        d += 2;
2243
    }
2244
    /* only needed if width is not a multiple of two */
2245
    /* XXX: veryfy that */
2246
    if (w) {
2247
        d[0] = s1[0];
2248
    }
2249
}
2250

    
2251
static void grow41_line(uint8_t *dst, const uint8_t *src,
2252
                        int width)
2253
{
2254
    int w, v;
2255
    const uint8_t *s1;
2256
    uint8_t *d;
2257

    
2258
    s1 = src;
2259
    d = dst;
2260
    for(w = width;w >= 4; w-=4) {
2261
        v = s1[0];
2262
        d[0] = v;
2263
        d[1] = v;
2264
        d[2] = v;
2265
        d[3] = v;
2266
        s1 ++;
2267
        d += 4;
2268
    }
2269
}
2270

    
2271
/* 1x1 -> 2x1 */
2272
static void grow21(uint8_t *dst, int dst_wrap,
2273
                   const uint8_t *src, int src_wrap,
2274
                   int width, int height)
2275
{
2276
    for(;height > 0; height--) {
2277
        grow21_line(dst, src, width);
2278
        src += src_wrap;
2279
        dst += dst_wrap;
2280
    }
2281
}
2282

    
2283
/* 1x1 -> 1x2 */
2284
static void grow12(uint8_t *dst, int dst_wrap,
2285
                   const uint8_t *src, int src_wrap,
2286
                   int width, int height)
2287
{
2288
    for(;height > 0; height-=2) {
2289
        memcpy(dst, src, width);
2290
        dst += dst_wrap;
2291
        memcpy(dst, src, width);
2292
        dst += dst_wrap;
2293
        src += src_wrap;
2294
    }
2295
}
2296

    
2297
/* 1x1 -> 2x2 */
2298
static void grow22(uint8_t *dst, int dst_wrap,
2299
                   const uint8_t *src, int src_wrap,
2300
                   int width, int height)
2301
{
2302
    for(;height > 0; height--) {
2303
        grow21_line(dst, src, width);
2304
        if (height%2)
2305
            src += src_wrap;
2306
        dst += dst_wrap;
2307
    }
2308
}
2309

    
2310
/* 1x1 -> 4x1 */
2311
static void grow41(uint8_t *dst, int dst_wrap,
2312
                   const uint8_t *src, int src_wrap,
2313
                   int width, int height)
2314
{
2315
    for(;height > 0; height--) {
2316
        grow41_line(dst, src, width);
2317
        src += src_wrap;
2318
        dst += dst_wrap;
2319
    }
2320
}
2321

    
2322
/* 1x1 -> 4x4 */
2323
static void grow44(uint8_t *dst, int dst_wrap,
2324
                   const uint8_t *src, int src_wrap,
2325
                   int width, int height)
2326
{
2327
    for(;height > 0; height--) {
2328
        grow41_line(dst, src, width);
2329
        if ((height & 3) == 1)
2330
            src += src_wrap;
2331
        dst += dst_wrap;
2332
    }
2333
}
2334

    
2335
/* 1x2 -> 2x1 */
2336
static void conv411(uint8_t *dst, int dst_wrap,
2337
                    const uint8_t *src, int src_wrap,
2338
                    int width, int height)
2339
{
2340
    int w, c;
2341
    const uint8_t *s1, *s2;
2342
    uint8_t *d;
2343

    
2344
    width>>=1;
2345

    
2346
    for(;height > 0; height--) {
2347
        s1 = src;
2348
        s2 = src + src_wrap;
2349
        d = dst;
2350
        for(w = width;w > 0; w--) {
2351
            c = (s1[0] + s2[0]) >> 1;
2352
            d[0] = c;
2353
            d[1] = c;
2354
            s1++;
2355
            s2++;
2356
            d += 2;
2357
        }
2358
        src += src_wrap * 2;
2359
        dst += dst_wrap;
2360
    }
2361
}
2362

    
2363
/* XXX: always use linesize. Return -1 if not supported */
2364
int img_convert(AVPicture *dst, int dst_pix_fmt,
2365
                const AVPicture *src, int src_pix_fmt,
2366
                int src_width, int src_height)
2367
{
2368
    static int initialized;
2369
    int i, ret, dst_width, dst_height, int_pix_fmt;
2370
    const PixFmtInfo *src_pix, *dst_pix;
2371
    const ConvertEntry *ce;
2372
    AVPicture tmp1, *tmp = &tmp1;
2373

    
2374
    if (src_pix_fmt < 0 || src_pix_fmt >= PIX_FMT_NB ||
2375
        dst_pix_fmt < 0 || dst_pix_fmt >= PIX_FMT_NB)
2376
        return -1;
2377
    if (src_width <= 0 || src_height <= 0)
2378
        return 0;
2379

    
2380
    if (!initialized) {
2381
        initialized = 1;
2382
        img_convert_init();
2383
    }
2384

    
2385
    dst_width = src_width;
2386
    dst_height = src_height;
2387

    
2388
    dst_pix = &pix_fmt_info[dst_pix_fmt];
2389
    src_pix = &pix_fmt_info[src_pix_fmt];
2390
    if (src_pix_fmt == dst_pix_fmt) {
2391
        /* no conversion needed: just copy */
2392
        av_picture_copy(dst, src, dst_pix_fmt, dst_width, dst_height);
2393
        return 0;
2394
    }
2395

    
2396
    ce = &convert_table[src_pix_fmt][dst_pix_fmt];
2397
    if (ce->convert) {
2398
        /* specific conversion routine */
2399
        ce->convert(dst, src, dst_width, dst_height);
2400
        return 0;
2401
    }
2402

    
2403
    /* gray to YUV */
2404
    if (is_yuv_planar(dst_pix) &&
2405
        src_pix_fmt == PIX_FMT_GRAY8) {
2406
        int w, h, y;
2407
        uint8_t *d;
2408

    
2409
        if (dst_pix->color_type == FF_COLOR_YUV_JPEG) {
2410
            ff_img_copy_plane(dst->data[0], dst->linesize[0],
2411
                     src->data[0], src->linesize[0],
2412
                     dst_width, dst_height);
2413
        } else {
2414
            img_apply_table(dst->data[0], dst->linesize[0],
2415
                            src->data[0], src->linesize[0],
2416
                            dst_width, dst_height,
2417
                            y_jpeg_to_ccir);
2418
        }
2419
        /* fill U and V with 128 */
2420
        w = dst_width;
2421
        h = dst_height;
2422
        w >>= dst_pix->x_chroma_shift;
2423
        h >>= dst_pix->y_chroma_shift;
2424
        for(i = 1; i <= 2; i++) {
2425
            d = dst->data[i];
2426
            for(y = 0; y< h; y++) {
2427
                memset(d, 128, w);
2428
                d += dst->linesize[i];
2429
            }
2430
        }
2431
        return 0;
2432
    }
2433

    
2434
    /* YUV to gray */
2435
    if (is_yuv_planar(src_pix) &&
2436
        dst_pix_fmt == PIX_FMT_GRAY8) {
2437
        if (src_pix->color_type == FF_COLOR_YUV_JPEG) {
2438
            ff_img_copy_plane(dst->data[0], dst->linesize[0],
2439
                     src->data[0], src->linesize[0],
2440
                     dst_width, dst_height);
2441
        } else {
2442
            img_apply_table(dst->data[0], dst->linesize[0],
2443
                            src->data[0], src->linesize[0],
2444
                            dst_width, dst_height,
2445
                            y_ccir_to_jpeg);
2446
        }
2447
        return 0;
2448
    }
2449

    
2450
    /* YUV to YUV planar */
2451
    if (is_yuv_planar(dst_pix) && is_yuv_planar(src_pix)) {
2452
        int x_shift, y_shift, w, h, xy_shift;
2453
        void (*resize_func)(uint8_t *dst, int dst_wrap,
2454
                            const uint8_t *src, int src_wrap,
2455
                            int width, int height);
2456

    
2457
        /* compute chroma size of the smallest dimensions */
2458
        w = dst_width;
2459
        h = dst_height;
2460
        if (dst_pix->x_chroma_shift >= src_pix->x_chroma_shift)
2461
            w >>= dst_pix->x_chroma_shift;
2462
        else
2463
            w >>= src_pix->x_chroma_shift;
2464
        if (dst_pix->y_chroma_shift >= src_pix->y_chroma_shift)
2465
            h >>= dst_pix->y_chroma_shift;
2466
        else
2467
            h >>= src_pix->y_chroma_shift;
2468

    
2469
        x_shift = (dst_pix->x_chroma_shift - src_pix->x_chroma_shift);
2470
        y_shift = (dst_pix->y_chroma_shift - src_pix->y_chroma_shift);
2471
        xy_shift = ((x_shift & 0xf) << 4) | (y_shift & 0xf);
2472
        /* there must be filters for conversion at least from and to
2473
           YUV444 format */
2474
        switch(xy_shift) {
2475
        case 0x00:
2476
            resize_func = ff_img_copy_plane;
2477
            break;
2478
        case 0x10:
2479
            resize_func = shrink21;
2480
            break;
2481
        case 0x20:
2482
            resize_func = shrink41;
2483
            break;
2484
        case 0x01:
2485
            resize_func = shrink12;
2486
            break;
2487
        case 0x11:
2488
            resize_func = ff_shrink22;
2489
            break;
2490
        case 0x22:
2491
            resize_func = ff_shrink44;
2492
            break;
2493
        case 0xf0:
2494
            resize_func = grow21;
2495
            break;
2496
        case 0x0f:
2497
            resize_func = grow12;
2498
            break;
2499
        case 0xe0:
2500
            resize_func = grow41;
2501
            break;
2502
        case 0xff:
2503
            resize_func = grow22;
2504
            break;
2505
        case 0xee:
2506
            resize_func = grow44;
2507
            break;
2508
        case 0xf1:
2509
            resize_func = conv411;
2510
            break;
2511
        default:
2512
            /* currently not handled */
2513
            goto no_chroma_filter;
2514
        }
2515

    
2516
        ff_img_copy_plane(dst->data[0], dst->linesize[0],
2517
                       src->data[0], src->linesize[0],
2518
                       dst_width, dst_height);
2519

    
2520
        for(i = 1;i <= 2; i++)
2521
            resize_func(dst->data[i], dst->linesize[i],
2522
                        src->data[i], src->linesize[i],
2523
                        dst_width>>dst_pix->x_chroma_shift, dst_height>>dst_pix->y_chroma_shift);
2524
        /* if yuv color space conversion is needed, we do it here on
2525
           the destination image */
2526
        if (dst_pix->color_type != src_pix->color_type) {
2527
            const uint8_t *y_table, *c_table;
2528
            if (dst_pix->color_type == FF_COLOR_YUV) {
2529
                y_table = y_jpeg_to_ccir;
2530
                c_table = c_jpeg_to_ccir;
2531
            } else {
2532
                y_table = y_ccir_to_jpeg;
2533
                c_table = c_ccir_to_jpeg;
2534
            }
2535
            img_apply_table(dst->data[0], dst->linesize[0],
2536
                            dst->data[0], dst->linesize[0],
2537
                            dst_width, dst_height,
2538
                            y_table);
2539

    
2540
            for(i = 1;i <= 2; i++)
2541
                img_apply_table(dst->data[i], dst->linesize[i],
2542
                                dst->data[i], dst->linesize[i],
2543
                                dst_width>>dst_pix->x_chroma_shift,
2544
                                dst_height>>dst_pix->y_chroma_shift,
2545
                                c_table);
2546
        }
2547
        return 0;
2548
    }
2549
 no_chroma_filter:
2550

    
2551
    /* try to use an intermediate format */
2552
    if (src_pix_fmt == PIX_FMT_YUYV422 ||
2553
        dst_pix_fmt == PIX_FMT_YUYV422) {
2554
        /* specific case: convert to YUV422P first */
2555
        int_pix_fmt = PIX_FMT_YUV422P;
2556
    } else if (src_pix_fmt == PIX_FMT_UYVY422 ||
2557
        dst_pix_fmt == PIX_FMT_UYVY422) {
2558
        /* specific case: convert to YUV422P first */
2559
        int_pix_fmt = PIX_FMT_YUV422P;
2560
    } else if (src_pix_fmt == PIX_FMT_UYYVYY411 ||
2561
        dst_pix_fmt == PIX_FMT_UYYVYY411) {
2562
        /* specific case: convert to YUV411P first */
2563
        int_pix_fmt = PIX_FMT_YUV411P;
2564
    } else if ((src_pix->color_type == FF_COLOR_GRAY &&
2565
                src_pix_fmt != PIX_FMT_GRAY8) ||
2566
               (dst_pix->color_type == FF_COLOR_GRAY &&
2567
                dst_pix_fmt != PIX_FMT_GRAY8)) {
2568
        /* gray8 is the normalized format */
2569
        int_pix_fmt = PIX_FMT_GRAY8;
2570
    } else if ((is_yuv_planar(src_pix) &&
2571
                src_pix_fmt != PIX_FMT_YUV444P &&
2572
                src_pix_fmt != PIX_FMT_YUVJ444P)) {
2573
        /* yuv444 is the normalized format */
2574
        if (src_pix->color_type == FF_COLOR_YUV_JPEG)
2575
            int_pix_fmt = PIX_FMT_YUVJ444P;
2576
        else
2577
            int_pix_fmt = PIX_FMT_YUV444P;
2578
    } else if ((is_yuv_planar(dst_pix) &&
2579
                dst_pix_fmt != PIX_FMT_YUV444P &&
2580
                dst_pix_fmt != PIX_FMT_YUVJ444P)) {
2581
        /* yuv444 is the normalized format */
2582
        if (dst_pix->color_type == FF_COLOR_YUV_JPEG)
2583
            int_pix_fmt = PIX_FMT_YUVJ444P;
2584
        else
2585
            int_pix_fmt = PIX_FMT_YUV444P;
2586
    } else {
2587
        /* the two formats are rgb or gray8 or yuv[j]444p */
2588
        if (src_pix->is_alpha && dst_pix->is_alpha)
2589
            int_pix_fmt = PIX_FMT_RGB32;
2590
        else
2591
            int_pix_fmt = PIX_FMT_RGB24;
2592
    }
2593
    if (src_pix_fmt == int_pix_fmt)
2594
        return -1;
2595
    if (avpicture_alloc(tmp, int_pix_fmt, dst_width, dst_height) < 0)
2596
        return -1;
2597
    ret = -1;
2598
    if (img_convert(tmp, int_pix_fmt,
2599
                    src, src_pix_fmt, src_width, src_height) < 0)
2600
        goto fail1;
2601
    if (img_convert(dst, dst_pix_fmt,
2602
                    tmp, int_pix_fmt, dst_width, dst_height) < 0)
2603
        goto fail1;
2604
    ret = 0;
2605
 fail1:
2606
    avpicture_free(tmp);
2607
    return ret;
2608
}
2609
#endif
2610

    
2611
/* NOTE: we scan all the pixels to have an exact information */
2612
static int get_alpha_info_pal8(const AVPicture *src, int width, int height)
2613
{
2614
    const unsigned char *p;
2615
    int src_wrap, ret, x, y;
2616
    unsigned int a;
2617
    uint32_t *palette = (uint32_t *)src->data[1];
2618

    
2619
    p = src->data[0];
2620
    src_wrap = src->linesize[0] - width;
2621
    ret = 0;
2622
    for(y=0;y<height;y++) {
2623
        for(x=0;x<width;x++) {
2624
            a = palette[p[0]] >> 24;
2625
            if (a == 0x00) {
2626
                ret |= FF_ALPHA_TRANSP;
2627
            } else if (a != 0xff) {
2628
                ret |= FF_ALPHA_SEMI_TRANSP;
2629
            }
2630
            p++;
2631
        }
2632
        p += src_wrap;
2633
    }
2634
    return ret;
2635
}
2636

    
2637
int img_get_alpha_info(const AVPicture *src,
2638
                       int pix_fmt, int width, int height)
2639
{
2640
    const PixFmtInfo *pf = &pix_fmt_info[pix_fmt];
2641
    int ret;
2642

    
2643
    pf = &pix_fmt_info[pix_fmt];
2644
    /* no alpha can be represented in format */
2645
    if (!pf->is_alpha)
2646
        return 0;
2647
    switch(pix_fmt) {
2648
    case PIX_FMT_RGB32:
2649
        ret = get_alpha_info_rgb32(src, width, height);
2650
        break;
2651
    case PIX_FMT_PAL8:
2652
        ret = get_alpha_info_pal8(src, width, height);
2653
        break;
2654
    default:
2655
        /* we do not know, so everything is indicated */
2656
        ret = FF_ALPHA_TRANSP | FF_ALPHA_SEMI_TRANSP;
2657
        break;
2658
    }
2659
    return ret;
2660
}
2661

    
2662
#ifdef HAVE_MMX
2663
#define DEINT_INPLACE_LINE_LUM \
2664
                    movd_m2r(lum_m4[0],mm0);\
2665
                    movd_m2r(lum_m3[0],mm1);\
2666
                    movd_m2r(lum_m2[0],mm2);\
2667
                    movd_m2r(lum_m1[0],mm3);\
2668
                    movd_m2r(lum[0],mm4);\
2669
                    punpcklbw_r2r(mm7,mm0);\
2670
                    movd_r2m(mm2,lum_m4[0]);\
2671
                    punpcklbw_r2r(mm7,mm1);\
2672
                    punpcklbw_r2r(mm7,mm2);\
2673
                    punpcklbw_r2r(mm7,mm3);\
2674
                    punpcklbw_r2r(mm7,mm4);\
2675
                    paddw_r2r(mm3,mm1);\
2676
                    psllw_i2r(1,mm2);\
2677
                    paddw_r2r(mm4,mm0);\
2678
                    psllw_i2r(2,mm1);\
2679
                    paddw_r2r(mm6,mm2);\
2680
                    paddw_r2r(mm2,mm1);\
2681
                    psubusw_r2r(mm0,mm1);\
2682
                    psrlw_i2r(3,mm1);\
2683
                    packuswb_r2r(mm7,mm1);\
2684
                    movd_r2m(mm1,lum_m2[0]);
2685

    
2686
#define DEINT_LINE_LUM \
2687
                    movd_m2r(lum_m4[0],mm0);\
2688
                    movd_m2r(lum_m3[0],mm1);\
2689
                    movd_m2r(lum_m2[0],mm2);\
2690
                    movd_m2r(lum_m1[0],mm3);\
2691
                    movd_m2r(lum[0],mm4);\
2692
                    punpcklbw_r2r(mm7,mm0);\
2693
                    punpcklbw_r2r(mm7,mm1);\
2694
                    punpcklbw_r2r(mm7,mm2);\
2695
                    punpcklbw_r2r(mm7,mm3);\
2696
                    punpcklbw_r2r(mm7,mm4);\
2697
                    paddw_r2r(mm3,mm1);\
2698
                    psllw_i2r(1,mm2);\
2699
                    paddw_r2r(mm4,mm0);\
2700
                    psllw_i2r(2,mm1);\
2701
                    paddw_r2r(mm6,mm2);\
2702
                    paddw_r2r(mm2,mm1);\
2703
                    psubusw_r2r(mm0,mm1);\
2704
                    psrlw_i2r(3,mm1);\
2705
                    packuswb_r2r(mm7,mm1);\
2706
                    movd_r2m(mm1,dst[0]);
2707
#endif
2708

    
2709
/* filter parameters: [-1 4 2 4 -1] // 8 */
2710
static void deinterlace_line(uint8_t *dst,
2711
                             const uint8_t *lum_m4, const uint8_t *lum_m3,
2712
                             const uint8_t *lum_m2, const uint8_t *lum_m1,
2713
                             const uint8_t *lum,
2714
                             int size)
2715
{
2716
#ifndef HAVE_MMX
2717
    uint8_t *cm = ff_cropTbl + MAX_NEG_CROP;
2718
    int sum;
2719

    
2720
    for(;size > 0;size--) {
2721
        sum = -lum_m4[0];
2722
        sum += lum_m3[0] << 2;
2723
        sum += lum_m2[0] << 1;
2724
        sum += lum_m1[0] << 2;
2725
        sum += -lum[0];
2726
        dst[0] = cm[(sum + 4) >> 3];
2727
        lum_m4++;
2728
        lum_m3++;
2729
        lum_m2++;
2730
        lum_m1++;
2731
        lum++;
2732
        dst++;
2733
    }
2734
#else
2735

    
2736
    {
2737
        pxor_r2r(mm7,mm7);
2738
        movq_m2r(ff_pw_4,mm6);
2739
    }
2740
    for (;size > 3; size-=4) {
2741
        DEINT_LINE_LUM
2742
        lum_m4+=4;
2743
        lum_m3+=4;
2744
        lum_m2+=4;
2745
        lum_m1+=4;
2746
        lum+=4;
2747
        dst+=4;
2748
    }
2749
#endif
2750
}
2751
static void deinterlace_line_inplace(uint8_t *lum_m4, uint8_t *lum_m3, uint8_t *lum_m2, uint8_t *lum_m1, uint8_t *lum,
2752
                             int size)
2753
{
2754
#ifndef HAVE_MMX
2755
    uint8_t *cm = ff_cropTbl + MAX_NEG_CROP;
2756
    int sum;
2757

    
2758
    for(;size > 0;size--) {
2759
        sum = -lum_m4[0];
2760
        sum += lum_m3[0] << 2;
2761
        sum += lum_m2[0] << 1;
2762
        lum_m4[0]=lum_m2[0];
2763
        sum += lum_m1[0] << 2;
2764
        sum += -lum[0];
2765
        lum_m2[0] = cm[(sum + 4) >> 3];
2766
        lum_m4++;
2767
        lum_m3++;
2768
        lum_m2++;
2769
        lum_m1++;
2770
        lum++;
2771
    }
2772
#else
2773

    
2774
    {
2775
        pxor_r2r(mm7,mm7);
2776
        movq_m2r(ff_pw_4,mm6);
2777
    }
2778
    for (;size > 3; size-=4) {
2779
        DEINT_INPLACE_LINE_LUM
2780
        lum_m4+=4;
2781
        lum_m3+=4;
2782
        lum_m2+=4;
2783
        lum_m1+=4;
2784
        lum+=4;
2785
    }
2786
#endif
2787
}
2788

    
2789
/* deinterlacing : 2 temporal taps, 3 spatial taps linear filter. The
2790
   top field is copied as is, but the bottom field is deinterlaced
2791
   against the top field. */
2792
static void deinterlace_bottom_field(uint8_t *dst, int dst_wrap,
2793
                                    const uint8_t *src1, int src_wrap,
2794
                                    int width, int height)
2795
{
2796
    const uint8_t *src_m2, *src_m1, *src_0, *src_p1, *src_p2;
2797
    int y;
2798

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

    
2821
static void deinterlace_bottom_field_inplace(uint8_t *src1, int src_wrap,
2822
                                             int width, int height)
2823
{
2824
    uint8_t *src_m1, *src_0, *src_p1, *src_p2;
2825
    int y;
2826
    uint8_t *buf;
2827
    buf = (uint8_t*)av_malloc(width);
2828

    
2829
    src_m1 = src1;
2830
    memcpy(buf,src_m1,width);
2831
    src_0=&src_m1[src_wrap];
2832
    src_p1=&src_0[src_wrap];
2833
    src_p2=&src_p1[src_wrap];
2834
    for(y=0;y<(height-2);y+=2) {
2835
        deinterlace_line_inplace(buf,src_m1,src_0,src_p1,src_p2,width);
2836
        src_m1 = src_p1;
2837
        src_0 = src_p2;
2838
        src_p1 += 2*src_wrap;
2839
        src_p2 += 2*src_wrap;
2840
    }
2841
    /* do last line */
2842
    deinterlace_line_inplace(buf,src_m1,src_0,src_0,src_0,width);
2843
    av_free(buf);
2844
}
2845

    
2846
int avpicture_deinterlace(AVPicture *dst, const AVPicture *src,
2847
                          int pix_fmt, int width, int height)
2848
{
2849
    int i;
2850

    
2851
    if (pix_fmt != PIX_FMT_YUV420P &&
2852
        pix_fmt != PIX_FMT_YUV422P &&
2853
        pix_fmt != PIX_FMT_YUV444P &&
2854
        pix_fmt != PIX_FMT_YUV411P &&
2855
        pix_fmt != PIX_FMT_GRAY8)
2856
        return -1;
2857
    if ((width & 3) != 0 || (height & 3) != 0)
2858
        return -1;
2859

    
2860
    for(i=0;i<3;i++) {
2861
        if (i == 1) {
2862
            switch(pix_fmt) {
2863
            case PIX_FMT_YUV420P:
2864
                width >>= 1;
2865
                height >>= 1;
2866
                break;
2867
            case PIX_FMT_YUV422P:
2868
                width >>= 1;
2869
                break;
2870
            case PIX_FMT_YUV411P:
2871
                width >>= 2;
2872
                break;
2873
            default:
2874
                break;
2875
            }
2876
            if (pix_fmt == PIX_FMT_GRAY8) {
2877
                break;
2878
            }
2879
        }
2880
        if (src == dst) {
2881
            deinterlace_bottom_field_inplace(dst->data[i], dst->linesize[i],
2882
                                 width, height);
2883
        } else {
2884
            deinterlace_bottom_field(dst->data[i],dst->linesize[i],
2885
                                        src->data[i], src->linesize[i],
2886
                                        width, height);
2887
        }
2888
    }
2889
    emms_c();
2890
    return 0;
2891
}
2892