Statistics
| Branch: | Revision:

ffmpeg / libavcodec / imgconvert.c @ 78149213

History | View | Annotate | Download (43.3 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 libavcodec/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
#include "libavutil/pixdesc.h"
37

    
38
#if HAVE_MMX
39
#include "x86/mmx.h"
40
#include "x86/dsputil_mmx.h"
41
#endif
42

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

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

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

    
55
typedef struct PixFmtInfo {
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 depth;           /**< bit depth of the color components */
61
} PixFmtInfo;
62

    
63
/* this table gives more information about formats */
64
static const PixFmtInfo pix_fmt_info[PIX_FMT_NB] = {
65
    /* YUV formats */
66
    [PIX_FMT_YUV420P] = {
67
        .nb_channels = 3,
68
        .color_type = FF_COLOR_YUV,
69
        .pixel_type = FF_PIXEL_PLANAR,
70
        .depth = 8,
71
    },
72
    [PIX_FMT_YUV422P] = {
73
        .nb_channels = 3,
74
        .color_type = FF_COLOR_YUV,
75
        .pixel_type = FF_PIXEL_PLANAR,
76
        .depth = 8,
77
    },
78
    [PIX_FMT_YUV444P] = {
79
        .nb_channels = 3,
80
        .color_type = FF_COLOR_YUV,
81
        .pixel_type = FF_PIXEL_PLANAR,
82
        .depth = 8,
83
    },
84
    [PIX_FMT_YUYV422] = {
85
        .nb_channels = 1,
86
        .color_type = FF_COLOR_YUV,
87
        .pixel_type = FF_PIXEL_PACKED,
88
        .depth = 8,
89
    },
90
    [PIX_FMT_UYVY422] = {
91
        .nb_channels = 1,
92
        .color_type = FF_COLOR_YUV,
93
        .pixel_type = FF_PIXEL_PACKED,
94
        .depth = 8,
95
    },
96
    [PIX_FMT_YUV410P] = {
97
        .nb_channels = 3,
98
        .color_type = FF_COLOR_YUV,
99
        .pixel_type = FF_PIXEL_PLANAR,
100
        .depth = 8,
101
    },
102
    [PIX_FMT_YUV411P] = {
103
        .nb_channels = 3,
104
        .color_type = FF_COLOR_YUV,
105
        .pixel_type = FF_PIXEL_PLANAR,
106
        .depth = 8,
107
    },
108
    [PIX_FMT_YUV440P] = {
109
        .nb_channels = 3,
110
        .color_type = FF_COLOR_YUV,
111
        .pixel_type = FF_PIXEL_PLANAR,
112
        .depth = 8,
113
    },
114
    [PIX_FMT_YUV420P16LE] = {
115
        .nb_channels = 3,
116
        .color_type = FF_COLOR_YUV,
117
        .pixel_type = FF_PIXEL_PLANAR,
118
        .depth = 16,
119
    },
120
    [PIX_FMT_YUV422P16LE] = {
121
        .nb_channels = 3,
122
        .color_type = FF_COLOR_YUV,
123
        .pixel_type = FF_PIXEL_PLANAR,
124
        .depth = 16,
125
    },
126
    [PIX_FMT_YUV444P16LE] = {
127
        .nb_channels = 3,
128
        .color_type = FF_COLOR_YUV,
129
        .pixel_type = FF_PIXEL_PLANAR,
130
        .depth = 16,
131
    },
132
    [PIX_FMT_YUV420P16BE] = {
133
        .nb_channels = 3,
134
        .color_type = FF_COLOR_YUV,
135
        .pixel_type = FF_PIXEL_PLANAR,
136
        .depth = 16,
137
    },
138
    [PIX_FMT_YUV422P16BE] = {
139
        .nb_channels = 3,
140
        .color_type = FF_COLOR_YUV,
141
        .pixel_type = FF_PIXEL_PLANAR,
142
        .depth = 16,
143
    },
144
    [PIX_FMT_YUV444P16BE] = {
145
        .nb_channels = 3,
146
        .color_type = FF_COLOR_YUV,
147
        .pixel_type = FF_PIXEL_PLANAR,
148
        .depth = 16,
149
    },
150

    
151

    
152
    /* YUV formats with alpha plane */
153
    [PIX_FMT_YUVA420P] = {
154
        .nb_channels = 4,
155
        .color_type = FF_COLOR_YUV,
156
        .pixel_type = FF_PIXEL_PLANAR,
157
        .depth = 8,
158
    },
159

    
160
    /* JPEG YUV */
161
    [PIX_FMT_YUVJ420P] = {
162
        .nb_channels = 3,
163
        .color_type = FF_COLOR_YUV_JPEG,
164
        .pixel_type = FF_PIXEL_PLANAR,
165
        .depth = 8,
166
    },
167
    [PIX_FMT_YUVJ422P] = {
168
        .nb_channels = 3,
169
        .color_type = FF_COLOR_YUV_JPEG,
170
        .pixel_type = FF_PIXEL_PLANAR,
171
        .depth = 8,
172
    },
173
    [PIX_FMT_YUVJ444P] = {
174
        .nb_channels = 3,
175
        .color_type = FF_COLOR_YUV_JPEG,
176
        .pixel_type = FF_PIXEL_PLANAR,
177
        .depth = 8,
178
    },
179
    [PIX_FMT_YUVJ440P] = {
180
        .nb_channels = 3,
181
        .color_type = FF_COLOR_YUV_JPEG,
182
        .pixel_type = FF_PIXEL_PLANAR,
183
        .depth = 8,
184
    },
185

    
186
    /* RGB formats */
187
    [PIX_FMT_RGB24] = {
188
        .nb_channels = 3,
189
        .color_type = FF_COLOR_RGB,
190
        .pixel_type = FF_PIXEL_PACKED,
191
        .depth = 8,
192
    },
193
    [PIX_FMT_BGR24] = {
194
        .nb_channels = 3,
195
        .color_type = FF_COLOR_RGB,
196
        .pixel_type = FF_PIXEL_PACKED,
197
        .depth = 8,
198
    },
199
    [PIX_FMT_ARGB] = {
200
        .nb_channels = 4, .is_alpha = 1,
201
        .color_type = FF_COLOR_RGB,
202
        .pixel_type = FF_PIXEL_PACKED,
203
        .depth = 8,
204
    },
205
    [PIX_FMT_RGB48BE] = {
206
        .nb_channels = 3,
207
        .color_type = FF_COLOR_RGB,
208
        .pixel_type = FF_PIXEL_PACKED,
209
        .depth = 16,
210
    },
211
    [PIX_FMT_RGB48LE] = {
212
        .nb_channels = 3,
213
        .color_type = FF_COLOR_RGB,
214
        .pixel_type = FF_PIXEL_PACKED,
215
        .depth = 16,
216
    },
217
    [PIX_FMT_RGB565BE] = {
218
        .nb_channels = 3,
219
        .color_type = FF_COLOR_RGB,
220
        .pixel_type = FF_PIXEL_PACKED,
221
        .depth = 5,
222
    },
223
    [PIX_FMT_RGB565LE] = {
224
        .nb_channels = 3,
225
        .color_type = FF_COLOR_RGB,
226
        .pixel_type = FF_PIXEL_PACKED,
227
        .depth = 5,
228
    },
229
    [PIX_FMT_RGB555BE] = {
230
        .nb_channels = 3,
231
        .color_type = FF_COLOR_RGB,
232
        .pixel_type = FF_PIXEL_PACKED,
233
        .depth = 5,
234
    },
235
    [PIX_FMT_RGB555LE] = {
236
        .nb_channels = 3,
237
        .color_type = FF_COLOR_RGB,
238
        .pixel_type = FF_PIXEL_PACKED,
239
        .depth = 5,
240
    },
241

    
242
    /* gray / mono formats */
243
    [PIX_FMT_GRAY16BE] = {
244
        .nb_channels = 1,
245
        .color_type = FF_COLOR_GRAY,
246
        .pixel_type = FF_PIXEL_PLANAR,
247
        .depth = 16,
248
    },
249
    [PIX_FMT_GRAY16LE] = {
250
        .nb_channels = 1,
251
        .color_type = FF_COLOR_GRAY,
252
        .pixel_type = FF_PIXEL_PLANAR,
253
        .depth = 16,
254
    },
255
    [PIX_FMT_GRAY8] = {
256
        .nb_channels = 1,
257
        .color_type = FF_COLOR_GRAY,
258
        .pixel_type = FF_PIXEL_PLANAR,
259
        .depth = 8,
260
    },
261
    [PIX_FMT_MONOWHITE] = {
262
        .nb_channels = 1,
263
        .color_type = FF_COLOR_GRAY,
264
        .pixel_type = FF_PIXEL_PLANAR,
265
        .depth = 1,
266
    },
267
    [PIX_FMT_MONOBLACK] = {
268
        .nb_channels = 1,
269
        .color_type = FF_COLOR_GRAY,
270
        .pixel_type = FF_PIXEL_PLANAR,
271
        .depth = 1,
272
    },
273

    
274
    /* paletted formats */
275
    [PIX_FMT_PAL8] = {
276
        .nb_channels = 4, .is_alpha = 1,
277
        .color_type = FF_COLOR_RGB,
278
        .pixel_type = FF_PIXEL_PALETTE,
279
        .depth = 8,
280
    },
281
    [PIX_FMT_UYYVYY411] = {
282
        .nb_channels = 1,
283
        .color_type = FF_COLOR_YUV,
284
        .pixel_type = FF_PIXEL_PACKED,
285
        .depth = 8,
286
    },
287
    [PIX_FMT_ABGR] = {
288
        .nb_channels = 4, .is_alpha = 1,
289
        .color_type = FF_COLOR_RGB,
290
        .pixel_type = FF_PIXEL_PACKED,
291
        .depth = 8,
292
    },
293
    [PIX_FMT_BGR565BE] = {
294
        .nb_channels = 3,
295
        .color_type = FF_COLOR_RGB,
296
        .pixel_type = FF_PIXEL_PACKED,
297
        .depth = 5,
298
    },
299
    [PIX_FMT_BGR565LE] = {
300
        .nb_channels = 3,
301
        .color_type = FF_COLOR_RGB,
302
        .pixel_type = FF_PIXEL_PACKED,
303
        .depth = 5,
304
    },
305
    [PIX_FMT_BGR555BE] = {
306
        .nb_channels = 3,
307
        .color_type = FF_COLOR_RGB,
308
        .pixel_type = FF_PIXEL_PACKED,
309
        .depth = 5,
310
    },
311
    [PIX_FMT_BGR555LE] = {
312
        .nb_channels = 3,
313
        .color_type = FF_COLOR_RGB,
314
        .pixel_type = FF_PIXEL_PACKED,
315
        .depth = 5,
316
    },
317
    [PIX_FMT_RGB8] = {
318
        .nb_channels = 1,
319
        .color_type = FF_COLOR_RGB,
320
        .pixel_type = FF_PIXEL_PACKED,
321
        .depth = 8,
322
    },
323
    [PIX_FMT_RGB4] = {
324
        .nb_channels = 1,
325
        .color_type = FF_COLOR_RGB,
326
        .pixel_type = FF_PIXEL_PACKED,
327
        .depth = 4,
328
    },
329
    [PIX_FMT_RGB4_BYTE] = {
330
        .nb_channels = 1,
331
        .color_type = FF_COLOR_RGB,
332
        .pixel_type = FF_PIXEL_PACKED,
333
        .depth = 8,
334
    },
335
    [PIX_FMT_BGR8] = {
336
        .nb_channels = 1,
337
        .color_type = FF_COLOR_RGB,
338
        .pixel_type = FF_PIXEL_PACKED,
339
        .depth = 8,
340
    },
341
    [PIX_FMT_BGR4] = {
342
        .nb_channels = 1,
343
        .color_type = FF_COLOR_RGB,
344
        .pixel_type = FF_PIXEL_PACKED,
345
        .depth = 4,
346
    },
347
    [PIX_FMT_BGR4_BYTE] = {
348
        .nb_channels = 1,
349
        .color_type = FF_COLOR_RGB,
350
        .pixel_type = FF_PIXEL_PACKED,
351
        .depth = 8,
352
    },
353
    [PIX_FMT_NV12] = {
354
        .nb_channels = 2,
355
        .color_type = FF_COLOR_YUV,
356
        .pixel_type = FF_PIXEL_PLANAR,
357
        .depth = 8,
358
    },
359
    [PIX_FMT_NV21] = {
360
        .nb_channels = 2,
361
        .color_type = FF_COLOR_YUV,
362
        .pixel_type = FF_PIXEL_PLANAR,
363
        .depth = 8,
364
    },
365

    
366
    [PIX_FMT_BGRA] = {
367
        .nb_channels = 4, .is_alpha = 1,
368
        .color_type = FF_COLOR_RGB,
369
        .pixel_type = FF_PIXEL_PACKED,
370
        .depth = 8,
371
    },
372
    [PIX_FMT_RGBA] = {
373
        .nb_channels = 4, .is_alpha = 1,
374
        .color_type = FF_COLOR_RGB,
375
        .pixel_type = FF_PIXEL_PACKED,
376
        .depth = 8,
377
    },
378
};
379

    
380
void avcodec_get_chroma_sub_sample(enum PixelFormat pix_fmt, int *h_shift, int *v_shift)
381
{
382
    *h_shift = av_pix_fmt_descriptors[pix_fmt].log2_chroma_w;
383
    *v_shift = av_pix_fmt_descriptors[pix_fmt].log2_chroma_h;
384
}
385

    
386
const char *avcodec_get_pix_fmt_name(enum PixelFormat pix_fmt)
387
{
388
    if (pix_fmt < 0 || pix_fmt >= PIX_FMT_NB)
389
        return NULL;
390
    else
391
        return av_pix_fmt_descriptors[pix_fmt].name;
392
}
393

    
394
static enum PixelFormat avcodec_get_pix_fmt_internal(const char *name)
395
{
396
    int i;
397

    
398
    for (i=0; i < PIX_FMT_NB; i++)
399
        if (av_pix_fmt_descriptors[i].name && !strcmp(av_pix_fmt_descriptors[i].name, name))
400
            return i;
401
    return PIX_FMT_NONE;
402
}
403

    
404
#if HAVE_BIGENDIAN
405
#   define X_NE(be, le) be
406
#else
407
#   define X_NE(be, le) le
408
#endif
409

    
410
enum PixelFormat avcodec_get_pix_fmt(const char *name)
411
{
412
    enum PixelFormat pix_fmt;
413

    
414
    if (!strcmp(name, "rgb32"))
415
        name = X_NE("argb", "bgra");
416
    else if (!strcmp(name, "bgr32"))
417
        name = X_NE("abgr", "rgba");
418

    
419
    pix_fmt = avcodec_get_pix_fmt_internal(name);
420
    if (pix_fmt == PIX_FMT_NONE) {
421
        char name2[32];
422
        snprintf(name2, sizeof(name2), "%s%s", name, X_NE("be", "le"));
423
        pix_fmt = avcodec_get_pix_fmt_internal(name2);
424
    }
425
    return pix_fmt;
426
}
427

    
428
void avcodec_pix_fmt_string (char *buf, int buf_size, enum PixelFormat pix_fmt)
429
{
430
    /* print header */
431
    if (pix_fmt < 0)
432
        snprintf (buf, buf_size,
433
                  "name      " " nb_channels" " depth" " is_alpha"
434
            );
435
    else{
436
        PixFmtInfo info= pix_fmt_info[pix_fmt];
437

    
438
        char is_alpha_char= info.is_alpha ? 'y' : 'n';
439

    
440
        snprintf (buf, buf_size,
441
                  "%-11s %5d %9d %6c",
442
                  av_pix_fmt_descriptors[pix_fmt].name,
443
                  info.nb_channels,
444
                  info.depth,
445
                  is_alpha_char
446
            );
447
    }
448
}
449

    
450
int ff_is_hwaccel_pix_fmt(enum PixelFormat pix_fmt)
451
{
452
    return av_pix_fmt_descriptors[pix_fmt].flags & PIX_FMT_HWACCEL;
453
}
454

    
455
int ff_set_systematic_pal(uint32_t pal[256], enum PixelFormat pix_fmt){
456
    int i;
457

    
458
    for(i=0; i<256; i++){
459
        int r,g,b;
460

    
461
        switch(pix_fmt) {
462
        case PIX_FMT_RGB8:
463
            r= (i>>5    )*36;
464
            g= ((i>>2)&7)*36;
465
            b= (i&3     )*85;
466
            break;
467
        case PIX_FMT_BGR8:
468
            b= (i>>6    )*85;
469
            g= ((i>>3)&7)*36;
470
            r= (i&7     )*36;
471
            break;
472
        case PIX_FMT_RGB4_BYTE:
473
            r= (i>>3    )*255;
474
            g= ((i>>1)&3)*85;
475
            b= (i&1     )*255;
476
            break;
477
        case PIX_FMT_BGR4_BYTE:
478
            b= (i>>3    )*255;
479
            g= ((i>>1)&3)*85;
480
            r= (i&1     )*255;
481
            break;
482
        case PIX_FMT_GRAY8:
483
            r=b=g= i;
484
            break;
485
        default:
486
            return -1;
487
        }
488
        pal[i] =  b + (g<<8) + (r<<16);
489
    }
490

    
491
    return 0;
492
}
493

    
494
int ff_fill_linesize(AVPicture *picture, enum PixelFormat pix_fmt, int width)
495
{
496
    int w2;
497
    const AVPixFmtDescriptor *desc = &av_pix_fmt_descriptors[pix_fmt];
498

    
499
    memset(picture->linesize, 0, sizeof(picture->linesize));
500

    
501
    switch(pix_fmt) {
502
    case PIX_FMT_YUV420P:
503
    case PIX_FMT_YUV422P:
504
    case PIX_FMT_YUV444P:
505
    case PIX_FMT_YUV410P:
506
    case PIX_FMT_YUV411P:
507
    case PIX_FMT_YUV440P:
508
    case PIX_FMT_YUVJ420P:
509
    case PIX_FMT_YUVJ422P:
510
    case PIX_FMT_YUVJ444P:
511
    case PIX_FMT_YUVJ440P:
512
        w2 = (width + (1 << desc->log2_chroma_w) - 1) >> desc->log2_chroma_w;
513
        picture->linesize[0] = width;
514
        picture->linesize[1] = w2;
515
        picture->linesize[2] = w2;
516
        break;
517
    case PIX_FMT_YUV420P16LE:
518
    case PIX_FMT_YUV422P16LE:
519
    case PIX_FMT_YUV444P16LE:
520
    case PIX_FMT_YUV420P16BE:
521
    case PIX_FMT_YUV422P16BE:
522
    case PIX_FMT_YUV444P16BE:
523
        w2 = (width + (1 << desc->log2_chroma_w) - 1) >> desc->log2_chroma_w;
524
        picture->linesize[0] = 2*width;
525
        picture->linesize[1] = 2*w2;
526
        picture->linesize[2] = 2*w2;
527
        break;
528
    case PIX_FMT_YUVA420P:
529
        w2 = (width + (1 << desc->log2_chroma_w) - 1) >> desc->log2_chroma_w;
530
        picture->linesize[0] = width;
531
        picture->linesize[1] = w2;
532
        picture->linesize[2] = w2;
533
        picture->linesize[3] = width;
534
        break;
535
    case PIX_FMT_NV12:
536
    case PIX_FMT_NV21:
537
        w2 = (width + (1 << desc->log2_chroma_w) - 1) >> desc->log2_chroma_w;
538
        picture->linesize[0] = width;
539
        picture->linesize[1] = 2 * w2;
540
        break;
541
    case PIX_FMT_RGB24:
542
    case PIX_FMT_BGR24:
543
        picture->linesize[0] = width * 3;
544
        break;
545
    case PIX_FMT_ARGB:
546
    case PIX_FMT_ABGR:
547
    case PIX_FMT_RGBA:
548
    case PIX_FMT_BGRA:
549
        picture->linesize[0] = width * 4;
550
        break;
551
    case PIX_FMT_RGB48BE:
552
    case PIX_FMT_RGB48LE:
553
        picture->linesize[0] = width * 6;
554
        break;
555
    case PIX_FMT_GRAY16BE:
556
    case PIX_FMT_GRAY16LE:
557
    case PIX_FMT_BGR555BE:
558
    case PIX_FMT_BGR555LE:
559
    case PIX_FMT_BGR565BE:
560
    case PIX_FMT_BGR565LE:
561
    case PIX_FMT_RGB555BE:
562
    case PIX_FMT_RGB555LE:
563
    case PIX_FMT_RGB565BE:
564
    case PIX_FMT_RGB565LE:
565
    case PIX_FMT_YUYV422:
566
        picture->linesize[0] = width * 2;
567
        break;
568
    case PIX_FMT_UYVY422:
569
        picture->linesize[0] = width * 2;
570
        break;
571
    case PIX_FMT_UYYVYY411:
572
        picture->linesize[0] = width + width/2;
573
        break;
574
    case PIX_FMT_RGB4:
575
    case PIX_FMT_BGR4:
576
        picture->linesize[0] = width / 2;
577
        break;
578
    case PIX_FMT_MONOWHITE:
579
    case PIX_FMT_MONOBLACK:
580
        picture->linesize[0] = (width + 7) >> 3;
581
        break;
582
    case PIX_FMT_PAL8:
583
    case PIX_FMT_RGB8:
584
    case PIX_FMT_BGR8:
585
    case PIX_FMT_RGB4_BYTE:
586
    case PIX_FMT_BGR4_BYTE:
587
    case PIX_FMT_GRAY8:
588
        picture->linesize[0] = width;
589
        break;
590
    default:
591
        return -1;
592
    }
593
    return 0;
594
}
595

    
596
int ff_fill_pointer(AVPicture *picture, uint8_t *ptr, enum PixelFormat pix_fmt,
597
                    int height)
598
{
599
    int size, h2, size2;
600
    const AVPixFmtDescriptor *desc = &av_pix_fmt_descriptors[pix_fmt];
601

    
602
    size = picture->linesize[0] * height;
603
    switch(pix_fmt) {
604
    case PIX_FMT_YUV420P:
605
    case PIX_FMT_YUV422P:
606
    case PIX_FMT_YUV444P:
607
    case PIX_FMT_YUV410P:
608
    case PIX_FMT_YUV411P:
609
    case PIX_FMT_YUV440P:
610
    case PIX_FMT_YUVJ420P:
611
    case PIX_FMT_YUVJ422P:
612
    case PIX_FMT_YUVJ444P:
613
    case PIX_FMT_YUVJ440P:
614
    case PIX_FMT_YUV420P16LE:
615
    case PIX_FMT_YUV422P16LE:
616
    case PIX_FMT_YUV444P16LE:
617
    case PIX_FMT_YUV420P16BE:
618
    case PIX_FMT_YUV422P16BE:
619
    case PIX_FMT_YUV444P16BE:
620
        h2 = (height + (1 << desc->log2_chroma_h) - 1) >> desc->log2_chroma_h;
621
        size2 = picture->linesize[1] * h2;
622
        picture->data[0] = ptr;
623
        picture->data[1] = picture->data[0] + size;
624
        picture->data[2] = picture->data[1] + size2;
625
        picture->data[3] = NULL;
626
        return size + 2 * size2;
627
    case PIX_FMT_YUVA420P:
628
        h2 = (height + (1 << desc->log2_chroma_h) - 1) >> desc->log2_chroma_h;
629
        size2 = picture->linesize[1] * h2;
630
        picture->data[0] = ptr;
631
        picture->data[1] = picture->data[0] + size;
632
        picture->data[2] = picture->data[1] + size2;
633
        picture->data[3] = picture->data[1] + size2 + size2;
634
        return 2 * size + 2 * size2;
635
    case PIX_FMT_NV12:
636
    case PIX_FMT_NV21:
637
        h2 = (height + (1 << desc->log2_chroma_h) - 1) >> desc->log2_chroma_h;
638
        size2 = picture->linesize[1] * h2;
639
        picture->data[0] = ptr;
640
        picture->data[1] = picture->data[0] + size;
641
        picture->data[2] = NULL;
642
        picture->data[3] = NULL;
643
        return size + size2;
644
    case PIX_FMT_RGB24:
645
    case PIX_FMT_BGR24:
646
    case PIX_FMT_ARGB:
647
    case PIX_FMT_ABGR:
648
    case PIX_FMT_RGBA:
649
    case PIX_FMT_BGRA:
650
    case PIX_FMT_RGB48BE:
651
    case PIX_FMT_RGB48LE:
652
    case PIX_FMT_GRAY16BE:
653
    case PIX_FMT_GRAY16LE:
654
    case PIX_FMT_BGR555BE:
655
    case PIX_FMT_BGR555LE:
656
    case PIX_FMT_BGR565BE:
657
    case PIX_FMT_BGR565LE:
658
    case PIX_FMT_RGB555BE:
659
    case PIX_FMT_RGB555LE:
660
    case PIX_FMT_RGB565BE:
661
    case PIX_FMT_RGB565LE:
662
    case PIX_FMT_YUYV422:
663
    case PIX_FMT_UYVY422:
664
    case PIX_FMT_UYYVYY411:
665
    case PIX_FMT_RGB4:
666
    case PIX_FMT_BGR4:
667
    case PIX_FMT_MONOWHITE:
668
    case PIX_FMT_MONOBLACK:
669
        picture->data[0] = ptr;
670
        picture->data[1] = NULL;
671
        picture->data[2] = NULL;
672
        picture->data[3] = NULL;
673
        return size;
674
    case PIX_FMT_PAL8:
675
    case PIX_FMT_RGB8:
676
    case PIX_FMT_BGR8:
677
    case PIX_FMT_RGB4_BYTE:
678
    case PIX_FMT_BGR4_BYTE:
679
    case PIX_FMT_GRAY8:
680
        size2 = (size + 3) & ~3;
681
        picture->data[0] = ptr;
682
        picture->data[1] = ptr + size2; /* palette is stored here as 256 32 bit words */
683
        picture->data[2] = NULL;
684
        picture->data[3] = NULL;
685
        return size2 + 256 * 4;
686
    default:
687
        picture->data[0] = NULL;
688
        picture->data[1] = NULL;
689
        picture->data[2] = NULL;
690
        picture->data[3] = NULL;
691
        return -1;
692
    }
693
}
694

    
695
int avpicture_fill(AVPicture *picture, uint8_t *ptr,
696
                   enum PixelFormat pix_fmt, int width, int height)
697
{
698

    
699
    if(avcodec_check_dimensions(NULL, width, height))
700
        return -1;
701

    
702
    if (ff_fill_linesize(picture, pix_fmt, width))
703
        return -1;
704

    
705
    return ff_fill_pointer(picture, ptr, pix_fmt, height);
706
}
707

    
708
int avpicture_layout(const AVPicture* src, enum PixelFormat pix_fmt, int width, int height,
709
                     unsigned char *dest, int dest_size)
710
{
711
    const PixFmtInfo* pf = &pix_fmt_info[pix_fmt];
712
    const AVPixFmtDescriptor *desc = &av_pix_fmt_descriptors[pix_fmt];
713
    int i, j, w, ow, h, oh, data_planes;
714
    const unsigned char* s;
715
    int size = avpicture_get_size(pix_fmt, width, height);
716

    
717
    if (size > dest_size || size < 0)
718
        return -1;
719

    
720
    if (pf->pixel_type == FF_PIXEL_PACKED || pf->pixel_type == FF_PIXEL_PALETTE) {
721
        if (pix_fmt == PIX_FMT_YUYV422 ||
722
            pix_fmt == PIX_FMT_UYVY422 ||
723
            pix_fmt == PIX_FMT_BGR565BE ||
724
            pix_fmt == PIX_FMT_BGR565LE ||
725
            pix_fmt == PIX_FMT_BGR555BE ||
726
            pix_fmt == PIX_FMT_BGR555LE ||
727
            pix_fmt == PIX_FMT_RGB565BE ||
728
            pix_fmt == PIX_FMT_RGB565LE ||
729
            pix_fmt == PIX_FMT_RGB555BE ||
730
            pix_fmt == PIX_FMT_RGB555LE)
731
            w = width * 2;
732
        else if (pix_fmt == PIX_FMT_UYYVYY411)
733
            w = width + width/2;
734
        else if (pix_fmt == PIX_FMT_PAL8)
735
            w = width;
736
        else
737
            w = width * (pf->depth * pf->nb_channels / 8);
738

    
739
        data_planes = 1;
740
        h = height;
741
    } else {
742
        data_planes = pf->nb_channels;
743
        w = (width*pf->depth + 7)/8;
744
        h = height;
745
    }
746

    
747
    ow = w;
748
    oh = h;
749

    
750
    for (i=0; i<data_planes; i++) {
751
        if (i == 1) {
752
            w = ((width >> desc->log2_chroma_w) * pf->depth + 7) / 8;
753
            h = height >> desc->log2_chroma_h;
754
            if (pix_fmt == PIX_FMT_NV12 || pix_fmt == PIX_FMT_NV21)
755
                w <<= 1;
756
        } else if (i == 3) {
757
            w = ow;
758
            h = oh;
759
        }
760
        s = src->data[i];
761
        for(j=0; j<h; j++) {
762
            memcpy(dest, s, w);
763
            dest += w;
764
            s += src->linesize[i];
765
        }
766
    }
767

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

    
771
    return size;
772
}
773

    
774
int avpicture_get_size(enum PixelFormat pix_fmt, int width, int height)
775
{
776
    AVPicture dummy_pict;
777
    if(avcodec_check_dimensions(NULL, width, height))
778
        return -1;
779
    switch (pix_fmt) {
780
    case PIX_FMT_RGB8:
781
    case PIX_FMT_BGR8:
782
    case PIX_FMT_RGB4_BYTE:
783
    case PIX_FMT_BGR4_BYTE:
784
    case PIX_FMT_GRAY8:
785
        // do not include palette for these pseudo-paletted formats
786
        return width * height;
787
    }
788
    return avpicture_fill(&dummy_pict, NULL, pix_fmt, width, height);
789
}
790

    
791
int avcodec_get_pix_fmt_loss(enum PixelFormat dst_pix_fmt, enum PixelFormat src_pix_fmt,
792
                             int has_alpha)
793
{
794
    const PixFmtInfo *pf, *ps;
795
    const AVPixFmtDescriptor *src_desc = &av_pix_fmt_descriptors[src_pix_fmt];
796
    const AVPixFmtDescriptor *dst_desc = &av_pix_fmt_descriptors[dst_pix_fmt];
797
    int loss;
798

    
799
    ps = &pix_fmt_info[src_pix_fmt];
800

    
801
    /* compute loss */
802
    loss = 0;
803
    pf = &pix_fmt_info[dst_pix_fmt];
804
    if (pf->depth < ps->depth ||
805
        ((dst_pix_fmt == PIX_FMT_RGB555BE || dst_pix_fmt == PIX_FMT_RGB555LE) &&
806
         (src_pix_fmt == PIX_FMT_RGB565BE || src_pix_fmt == PIX_FMT_RGB565LE)))
807
        loss |= FF_LOSS_DEPTH;
808
    if (dst_desc->log2_chroma_w > src_desc->log2_chroma_w ||
809
        dst_desc->log2_chroma_h > src_desc->log2_chroma_h)
810
        loss |= FF_LOSS_RESOLUTION;
811
    switch(pf->color_type) {
812
    case FF_COLOR_RGB:
813
        if (ps->color_type != FF_COLOR_RGB &&
814
            ps->color_type != FF_COLOR_GRAY)
815
            loss |= FF_LOSS_COLORSPACE;
816
        break;
817
    case FF_COLOR_GRAY:
818
        if (ps->color_type != FF_COLOR_GRAY)
819
            loss |= FF_LOSS_COLORSPACE;
820
        break;
821
    case FF_COLOR_YUV:
822
        if (ps->color_type != FF_COLOR_YUV)
823
            loss |= FF_LOSS_COLORSPACE;
824
        break;
825
    case FF_COLOR_YUV_JPEG:
826
        if (ps->color_type != FF_COLOR_YUV_JPEG &&
827
            ps->color_type != FF_COLOR_YUV &&
828
            ps->color_type != FF_COLOR_GRAY)
829
            loss |= FF_LOSS_COLORSPACE;
830
        break;
831
    default:
832
        /* fail safe test */
833
        if (ps->color_type != pf->color_type)
834
            loss |= FF_LOSS_COLORSPACE;
835
        break;
836
    }
837
    if (pf->color_type == FF_COLOR_GRAY &&
838
        ps->color_type != FF_COLOR_GRAY)
839
        loss |= FF_LOSS_CHROMA;
840
    if (!pf->is_alpha && (ps->is_alpha && has_alpha))
841
        loss |= FF_LOSS_ALPHA;
842
    if (pf->pixel_type == FF_PIXEL_PALETTE &&
843
        (ps->pixel_type != FF_PIXEL_PALETTE && ps->color_type != FF_COLOR_GRAY))
844
        loss |= FF_LOSS_COLORQUANT;
845
    return loss;
846
}
847

    
848
static int avg_bits_per_pixel(enum PixelFormat pix_fmt)
849
{
850
    int bits;
851
    const PixFmtInfo *pf;
852
    const AVPixFmtDescriptor *desc = &av_pix_fmt_descriptors[pix_fmt];
853

    
854
    pf = &pix_fmt_info[pix_fmt];
855
    switch(pf->pixel_type) {
856
    case FF_PIXEL_PACKED:
857
        switch(pix_fmt) {
858
        case PIX_FMT_YUYV422:
859
        case PIX_FMT_UYVY422:
860
        case PIX_FMT_RGB565BE:
861
        case PIX_FMT_RGB565LE:
862
        case PIX_FMT_RGB555BE:
863
        case PIX_FMT_RGB555LE:
864
        case PIX_FMT_BGR565BE:
865
        case PIX_FMT_BGR565LE:
866
        case PIX_FMT_BGR555BE:
867
        case PIX_FMT_BGR555LE:
868
            bits = 16;
869
            break;
870
        case PIX_FMT_UYYVYY411:
871
            bits = 12;
872
            break;
873
        default:
874
            bits = pf->depth * pf->nb_channels;
875
            break;
876
        }
877
        break;
878
    case FF_PIXEL_PLANAR:
879
        if (desc->log2_chroma_w == 0 && desc->log2_chroma_h == 0) {
880
            bits = pf->depth * pf->nb_channels;
881
        } else {
882
            bits = pf->depth + ((2 * pf->depth) >>
883
                                (desc->log2_chroma_w + desc->log2_chroma_h));
884
        }
885
        break;
886
    case FF_PIXEL_PALETTE:
887
        bits = 8;
888
        break;
889
    default:
890
        bits = -1;
891
        break;
892
    }
893
    return bits;
894
}
895

    
896
static enum PixelFormat avcodec_find_best_pix_fmt1(int64_t pix_fmt_mask,
897
                                      enum PixelFormat src_pix_fmt,
898
                                      int has_alpha,
899
                                      int loss_mask)
900
{
901
    int dist, i, loss, min_dist;
902
    enum PixelFormat dst_pix_fmt;
903

    
904
    /* find exact color match with smallest size */
905
    dst_pix_fmt = -1;
906
    min_dist = 0x7fffffff;
907
    for(i = 0;i < PIX_FMT_NB; i++) {
908
        if (pix_fmt_mask & (1ULL << i)) {
909
            loss = avcodec_get_pix_fmt_loss(i, src_pix_fmt, has_alpha) & loss_mask;
910
            if (loss == 0) {
911
                dist = avg_bits_per_pixel(i);
912
                if (dist < min_dist) {
913
                    min_dist = dist;
914
                    dst_pix_fmt = i;
915
                }
916
            }
917
        }
918
    }
919
    return dst_pix_fmt;
920
}
921

    
922
enum PixelFormat avcodec_find_best_pix_fmt(int64_t pix_fmt_mask, enum PixelFormat src_pix_fmt,
923
                              int has_alpha, int *loss_ptr)
924
{
925
    enum PixelFormat dst_pix_fmt;
926
    int loss_mask, i;
927
    static const int loss_mask_order[] = {
928
        ~0, /* no loss first */
929
        ~FF_LOSS_ALPHA,
930
        ~FF_LOSS_RESOLUTION,
931
        ~(FF_LOSS_COLORSPACE | FF_LOSS_RESOLUTION),
932
        ~FF_LOSS_COLORQUANT,
933
        ~FF_LOSS_DEPTH,
934
        0,
935
    };
936

    
937
    /* try with successive loss */
938
    i = 0;
939
    for(;;) {
940
        loss_mask = loss_mask_order[i++];
941
        dst_pix_fmt = avcodec_find_best_pix_fmt1(pix_fmt_mask, src_pix_fmt,
942
                                                 has_alpha, loss_mask);
943
        if (dst_pix_fmt >= 0)
944
            goto found;
945
        if (loss_mask == 0)
946
            break;
947
    }
948
    return -1;
949
 found:
950
    if (loss_ptr)
951
        *loss_ptr = avcodec_get_pix_fmt_loss(dst_pix_fmt, src_pix_fmt, has_alpha);
952
    return dst_pix_fmt;
953
}
954

    
955
void ff_img_copy_plane(uint8_t *dst, int dst_wrap,
956
                           const uint8_t *src, int src_wrap,
957
                           int width, int height)
958
{
959
    if((!dst) || (!src))
960
        return;
961
    for(;height > 0; height--) {
962
        memcpy(dst, src, width);
963
        dst += dst_wrap;
964
        src += src_wrap;
965
    }
966
}
967

    
968
int ff_get_plane_bytewidth(enum PixelFormat pix_fmt, int width, int plane)
969
{
970
    int bits;
971
    const PixFmtInfo *pf = &pix_fmt_info[pix_fmt];
972
    const AVPixFmtDescriptor *desc = &av_pix_fmt_descriptors[pix_fmt];
973

    
974
    pf = &pix_fmt_info[pix_fmt];
975
    switch(pf->pixel_type) {
976
    case FF_PIXEL_PACKED:
977
        switch(pix_fmt) {
978
        case PIX_FMT_YUYV422:
979
        case PIX_FMT_UYVY422:
980
        case PIX_FMT_RGB565BE:
981
        case PIX_FMT_RGB565LE:
982
        case PIX_FMT_RGB555BE:
983
        case PIX_FMT_RGB555LE:
984
        case PIX_FMT_BGR565BE:
985
        case PIX_FMT_BGR565LE:
986
        case PIX_FMT_BGR555BE:
987
        case PIX_FMT_BGR555LE:
988
            bits = 16;
989
            break;
990
        case PIX_FMT_UYYVYY411:
991
            bits = 12;
992
            break;
993
        default:
994
            bits = pf->depth * pf->nb_channels;
995
            break;
996
        }
997
        return (width * bits + 7) >> 3;
998
        break;
999
    case FF_PIXEL_PLANAR:
1000
            if (plane == 1 || plane == 2)
1001
                width= -((-width)>>desc->log2_chroma_w);
1002

    
1003
            return (width * pf->depth + 7) >> 3;
1004
        break;
1005
    case FF_PIXEL_PALETTE:
1006
        if (plane == 0)
1007
            return width;
1008
        break;
1009
    }
1010

    
1011
    return -1;
1012
}
1013

    
1014
void av_picture_copy(AVPicture *dst, const AVPicture *src,
1015
                     enum PixelFormat pix_fmt, int width, int height)
1016
{
1017
    int i;
1018
    const PixFmtInfo *pf = &pix_fmt_info[pix_fmt];
1019
    const AVPixFmtDescriptor *desc = &av_pix_fmt_descriptors[pix_fmt];
1020

    
1021
    switch(pf->pixel_type) {
1022
    case FF_PIXEL_PACKED:
1023
    case FF_PIXEL_PLANAR:
1024
        for(i = 0; i < pf->nb_channels; i++) {
1025
            int h;
1026
            int bwidth = ff_get_plane_bytewidth(pix_fmt, width, i);
1027
            h = height;
1028
            if (i == 1 || i == 2) {
1029
                h= -((-height)>>desc->log2_chroma_h);
1030
            }
1031
            ff_img_copy_plane(dst->data[i], dst->linesize[i],
1032
                           src->data[i], src->linesize[i],
1033
                           bwidth, h);
1034
        }
1035
        break;
1036
    case FF_PIXEL_PALETTE:
1037
        ff_img_copy_plane(dst->data[0], dst->linesize[0],
1038
                       src->data[0], src->linesize[0],
1039
                       width, height);
1040
        /* copy the palette */
1041
        memcpy(dst->data[1], src->data[1], 4*256);
1042
        break;
1043
    }
1044
}
1045

    
1046
/* 2x2 -> 1x1 */
1047
void ff_shrink22(uint8_t *dst, int dst_wrap,
1048
                     const uint8_t *src, int src_wrap,
1049
                     int width, int height)
1050
{
1051
    int w;
1052
    const uint8_t *s1, *s2;
1053
    uint8_t *d;
1054

    
1055
    for(;height > 0; height--) {
1056
        s1 = src;
1057
        s2 = s1 + src_wrap;
1058
        d = dst;
1059
        for(w = width;w >= 4; w-=4) {
1060
            d[0] = (s1[0] + s1[1] + s2[0] + s2[1] + 2) >> 2;
1061
            d[1] = (s1[2] + s1[3] + s2[2] + s2[3] + 2) >> 2;
1062
            d[2] = (s1[4] + s1[5] + s2[4] + s2[5] + 2) >> 2;
1063
            d[3] = (s1[6] + s1[7] + s2[6] + s2[7] + 2) >> 2;
1064
            s1 += 8;
1065
            s2 += 8;
1066
            d += 4;
1067
        }
1068
        for(;w > 0; w--) {
1069
            d[0] = (s1[0] + s1[1] + s2[0] + s2[1] + 2) >> 2;
1070
            s1 += 2;
1071
            s2 += 2;
1072
            d++;
1073
        }
1074
        src += 2 * src_wrap;
1075
        dst += dst_wrap;
1076
    }
1077
}
1078

    
1079
/* 4x4 -> 1x1 */
1080
void ff_shrink44(uint8_t *dst, int dst_wrap,
1081
                     const uint8_t *src, int src_wrap,
1082
                     int width, int height)
1083
{
1084
    int w;
1085
    const uint8_t *s1, *s2, *s3, *s4;
1086
    uint8_t *d;
1087

    
1088
    for(;height > 0; height--) {
1089
        s1 = src;
1090
        s2 = s1 + src_wrap;
1091
        s3 = s2 + src_wrap;
1092
        s4 = s3 + src_wrap;
1093
        d = dst;
1094
        for(w = width;w > 0; w--) {
1095
            d[0] = (s1[0] + s1[1] + s1[2] + s1[3] +
1096
                    s2[0] + s2[1] + s2[2] + s2[3] +
1097
                    s3[0] + s3[1] + s3[2] + s3[3] +
1098
                    s4[0] + s4[1] + s4[2] + s4[3] + 8) >> 4;
1099
            s1 += 4;
1100
            s2 += 4;
1101
            s3 += 4;
1102
            s4 += 4;
1103
            d++;
1104
        }
1105
        src += 4 * src_wrap;
1106
        dst += dst_wrap;
1107
    }
1108
}
1109

    
1110
/* 8x8 -> 1x1 */
1111
void ff_shrink88(uint8_t *dst, int dst_wrap,
1112
                     const uint8_t *src, int src_wrap,
1113
                     int width, int height)
1114
{
1115
    int w, i;
1116

    
1117
    for(;height > 0; height--) {
1118
        for(w = width;w > 0; w--) {
1119
            int tmp=0;
1120
            for(i=0; i<8; i++){
1121
                tmp += src[0] + src[1] + src[2] + src[3] + src[4] + src[5] + src[6] + src[7];
1122
                src += src_wrap;
1123
            }
1124
            *(dst++) = (tmp + 32)>>6;
1125
            src += 8 - 8*src_wrap;
1126
        }
1127
        src += 8*src_wrap - 8*width;
1128
        dst += dst_wrap - width;
1129
    }
1130
}
1131

    
1132

    
1133
int avpicture_alloc(AVPicture *picture,
1134
                    enum PixelFormat pix_fmt, int width, int height)
1135
{
1136
    int size;
1137
    void *ptr;
1138

    
1139
    size = avpicture_fill(picture, NULL, pix_fmt, width, height);
1140
    if(size<0)
1141
        goto fail;
1142
    ptr = av_malloc(size);
1143
    if (!ptr)
1144
        goto fail;
1145
    avpicture_fill(picture, ptr, pix_fmt, width, height);
1146
    if(picture->data[1] && !picture->data[2])
1147
        ff_set_systematic_pal((uint32_t*)picture->data[1], pix_fmt);
1148

    
1149
    return 0;
1150
 fail:
1151
    memset(picture, 0, sizeof(AVPicture));
1152
    return -1;
1153
}
1154

    
1155
void avpicture_free(AVPicture *picture)
1156
{
1157
    av_free(picture->data[0]);
1158
}
1159

    
1160
/* return true if yuv planar */
1161
static inline int is_yuv_planar(const PixFmtInfo *ps)
1162
{
1163
    return (ps->color_type == FF_COLOR_YUV ||
1164
            ps->color_type == FF_COLOR_YUV_JPEG) &&
1165
        ps->pixel_type == FF_PIXEL_PLANAR;
1166
}
1167

    
1168
int av_picture_crop(AVPicture *dst, const AVPicture *src,
1169
                    enum PixelFormat pix_fmt, int top_band, int left_band)
1170
{
1171
    int y_shift;
1172
    int x_shift;
1173

    
1174
    if (pix_fmt < 0 || pix_fmt >= PIX_FMT_NB || !is_yuv_planar(&pix_fmt_info[pix_fmt]))
1175
        return -1;
1176

    
1177
    y_shift = av_pix_fmt_descriptors[pix_fmt].log2_chroma_h;
1178
    x_shift = av_pix_fmt_descriptors[pix_fmt].log2_chroma_w;
1179

    
1180
    dst->data[0] = src->data[0] + (top_band * src->linesize[0]) + left_band;
1181
    dst->data[1] = src->data[1] + ((top_band >> y_shift) * src->linesize[1]) + (left_band >> x_shift);
1182
    dst->data[2] = src->data[2] + ((top_band >> y_shift) * src->linesize[2]) + (left_band >> x_shift);
1183

    
1184
    dst->linesize[0] = src->linesize[0];
1185
    dst->linesize[1] = src->linesize[1];
1186
    dst->linesize[2] = src->linesize[2];
1187
    return 0;
1188
}
1189

    
1190
int av_picture_pad(AVPicture *dst, const AVPicture *src, int height, int width,
1191
                   enum PixelFormat pix_fmt, int padtop, int padbottom, int padleft, int padright,
1192
            int *color)
1193
{
1194
    uint8_t *optr;
1195
    int y_shift;
1196
    int x_shift;
1197
    int yheight;
1198
    int i, y;
1199

    
1200
    if (pix_fmt < 0 || pix_fmt >= PIX_FMT_NB ||
1201
        !is_yuv_planar(&pix_fmt_info[pix_fmt])) return -1;
1202

    
1203
    for (i = 0; i < 3; i++) {
1204
        x_shift = i ? av_pix_fmt_descriptors[pix_fmt].log2_chroma_w : 0;
1205
        y_shift = i ? av_pix_fmt_descriptors[pix_fmt].log2_chroma_h : 0;
1206

    
1207
        if (padtop || padleft) {
1208
            memset(dst->data[i], color[i],
1209
                dst->linesize[i] * (padtop >> y_shift) + (padleft >> x_shift));
1210
        }
1211

    
1212
        if (padleft || padright) {
1213
            optr = dst->data[i] + dst->linesize[i] * (padtop >> y_shift) +
1214
                (dst->linesize[i] - (padright >> x_shift));
1215
            yheight = (height - 1 - (padtop + padbottom)) >> y_shift;
1216
            for (y = 0; y < yheight; y++) {
1217
                memset(optr, color[i], (padleft + padright) >> x_shift);
1218
                optr += dst->linesize[i];
1219
            }
1220
        }
1221

    
1222
        if (src) { /* first line */
1223
            uint8_t *iptr = src->data[i];
1224
            optr = dst->data[i] + dst->linesize[i] * (padtop >> y_shift) +
1225
                    (padleft >> x_shift);
1226
            memcpy(optr, iptr, (width - padleft - padright) >> x_shift);
1227
            iptr += src->linesize[i];
1228
            optr = dst->data[i] + dst->linesize[i] * (padtop >> y_shift) +
1229
                (dst->linesize[i] - (padright >> x_shift));
1230
            yheight = (height - 1 - (padtop + padbottom)) >> y_shift;
1231
            for (y = 0; y < yheight; y++) {
1232
                memset(optr, color[i], (padleft + padright) >> x_shift);
1233
                memcpy(optr + ((padleft + padright) >> x_shift), iptr,
1234
                       (width - padleft - padright) >> x_shift);
1235
                iptr += src->linesize[i];
1236
                optr += dst->linesize[i];
1237
            }
1238
        }
1239

    
1240
        if (padbottom || padright) {
1241
            optr = dst->data[i] + dst->linesize[i] *
1242
                ((height - padbottom) >> y_shift) - (padright >> x_shift);
1243
            memset(optr, color[i],dst->linesize[i] *
1244
                (padbottom >> y_shift) + (padright >> x_shift));
1245
        }
1246
    }
1247
    return 0;
1248
}
1249

    
1250
/* NOTE: we scan all the pixels to have an exact information */
1251
static int get_alpha_info_pal8(const AVPicture *src, int width, int height)
1252
{
1253
    const unsigned char *p;
1254
    int src_wrap, ret, x, y;
1255
    unsigned int a;
1256
    uint32_t *palette = (uint32_t *)src->data[1];
1257

    
1258
    p = src->data[0];
1259
    src_wrap = src->linesize[0] - width;
1260
    ret = 0;
1261
    for(y=0;y<height;y++) {
1262
        for(x=0;x<width;x++) {
1263
            a = palette[p[0]] >> 24;
1264
            if (a == 0x00) {
1265
                ret |= FF_ALPHA_TRANSP;
1266
            } else if (a != 0xff) {
1267
                ret |= FF_ALPHA_SEMI_TRANSP;
1268
            }
1269
            p++;
1270
        }
1271
        p += src_wrap;
1272
    }
1273
    return ret;
1274
}
1275

    
1276
int img_get_alpha_info(const AVPicture *src,
1277
                       enum PixelFormat pix_fmt, int width, int height)
1278
{
1279
    const PixFmtInfo *pf = &pix_fmt_info[pix_fmt];
1280
    int ret;
1281

    
1282
    /* no alpha can be represented in format */
1283
    if (!pf->is_alpha)
1284
        return 0;
1285
    switch(pix_fmt) {
1286
    case PIX_FMT_PAL8:
1287
        ret = get_alpha_info_pal8(src, width, height);
1288
        break;
1289
    default:
1290
        /* we do not know, so everything is indicated */
1291
        ret = FF_ALPHA_TRANSP | FF_ALPHA_SEMI_TRANSP;
1292
        break;
1293
    }
1294
    return ret;
1295
}
1296

    
1297
#if HAVE_MMX
1298
#define DEINT_INPLACE_LINE_LUM \
1299
                    movd_m2r(lum_m4[0],mm0);\
1300
                    movd_m2r(lum_m3[0],mm1);\
1301
                    movd_m2r(lum_m2[0],mm2);\
1302
                    movd_m2r(lum_m1[0],mm3);\
1303
                    movd_m2r(lum[0],mm4);\
1304
                    punpcklbw_r2r(mm7,mm0);\
1305
                    movd_r2m(mm2,lum_m4[0]);\
1306
                    punpcklbw_r2r(mm7,mm1);\
1307
                    punpcklbw_r2r(mm7,mm2);\
1308
                    punpcklbw_r2r(mm7,mm3);\
1309
                    punpcklbw_r2r(mm7,mm4);\
1310
                    paddw_r2r(mm3,mm1);\
1311
                    psllw_i2r(1,mm2);\
1312
                    paddw_r2r(mm4,mm0);\
1313
                    psllw_i2r(2,mm1);\
1314
                    paddw_r2r(mm6,mm2);\
1315
                    paddw_r2r(mm2,mm1);\
1316
                    psubusw_r2r(mm0,mm1);\
1317
                    psrlw_i2r(3,mm1);\
1318
                    packuswb_r2r(mm7,mm1);\
1319
                    movd_r2m(mm1,lum_m2[0]);
1320

    
1321
#define DEINT_LINE_LUM \
1322
                    movd_m2r(lum_m4[0],mm0);\
1323
                    movd_m2r(lum_m3[0],mm1);\
1324
                    movd_m2r(lum_m2[0],mm2);\
1325
                    movd_m2r(lum_m1[0],mm3);\
1326
                    movd_m2r(lum[0],mm4);\
1327
                    punpcklbw_r2r(mm7,mm0);\
1328
                    punpcklbw_r2r(mm7,mm1);\
1329
                    punpcklbw_r2r(mm7,mm2);\
1330
                    punpcklbw_r2r(mm7,mm3);\
1331
                    punpcklbw_r2r(mm7,mm4);\
1332
                    paddw_r2r(mm3,mm1);\
1333
                    psllw_i2r(1,mm2);\
1334
                    paddw_r2r(mm4,mm0);\
1335
                    psllw_i2r(2,mm1);\
1336
                    paddw_r2r(mm6,mm2);\
1337
                    paddw_r2r(mm2,mm1);\
1338
                    psubusw_r2r(mm0,mm1);\
1339
                    psrlw_i2r(3,mm1);\
1340
                    packuswb_r2r(mm7,mm1);\
1341
                    movd_r2m(mm1,dst[0]);
1342
#endif
1343

    
1344
/* filter parameters: [-1 4 2 4 -1] // 8 */
1345
static void deinterlace_line(uint8_t *dst,
1346
                             const uint8_t *lum_m4, const uint8_t *lum_m3,
1347
                             const uint8_t *lum_m2, const uint8_t *lum_m1,
1348
                             const uint8_t *lum,
1349
                             int size)
1350
{
1351
#if !HAVE_MMX
1352
    uint8_t *cm = ff_cropTbl + MAX_NEG_CROP;
1353
    int sum;
1354

    
1355
    for(;size > 0;size--) {
1356
        sum = -lum_m4[0];
1357
        sum += lum_m3[0] << 2;
1358
        sum += lum_m2[0] << 1;
1359
        sum += lum_m1[0] << 2;
1360
        sum += -lum[0];
1361
        dst[0] = cm[(sum + 4) >> 3];
1362
        lum_m4++;
1363
        lum_m3++;
1364
        lum_m2++;
1365
        lum_m1++;
1366
        lum++;
1367
        dst++;
1368
    }
1369
#else
1370

    
1371
    {
1372
        pxor_r2r(mm7,mm7);
1373
        movq_m2r(ff_pw_4,mm6);
1374
    }
1375
    for (;size > 3; size-=4) {
1376
        DEINT_LINE_LUM
1377
        lum_m4+=4;
1378
        lum_m3+=4;
1379
        lum_m2+=4;
1380
        lum_m1+=4;
1381
        lum+=4;
1382
        dst+=4;
1383
    }
1384
#endif
1385
}
1386
static void deinterlace_line_inplace(uint8_t *lum_m4, uint8_t *lum_m3, uint8_t *lum_m2, uint8_t *lum_m1, uint8_t *lum,
1387
                             int size)
1388
{
1389
#if !HAVE_MMX
1390
    uint8_t *cm = ff_cropTbl + MAX_NEG_CROP;
1391
    int sum;
1392

    
1393
    for(;size > 0;size--) {
1394
        sum = -lum_m4[0];
1395
        sum += lum_m3[0] << 2;
1396
        sum += lum_m2[0] << 1;
1397
        lum_m4[0]=lum_m2[0];
1398
        sum += lum_m1[0] << 2;
1399
        sum += -lum[0];
1400
        lum_m2[0] = cm[(sum + 4) >> 3];
1401
        lum_m4++;
1402
        lum_m3++;
1403
        lum_m2++;
1404
        lum_m1++;
1405
        lum++;
1406
    }
1407
#else
1408

    
1409
    {
1410
        pxor_r2r(mm7,mm7);
1411
        movq_m2r(ff_pw_4,mm6);
1412
    }
1413
    for (;size > 3; size-=4) {
1414
        DEINT_INPLACE_LINE_LUM
1415
        lum_m4+=4;
1416
        lum_m3+=4;
1417
        lum_m2+=4;
1418
        lum_m1+=4;
1419
        lum+=4;
1420
    }
1421
#endif
1422
}
1423

    
1424
/* deinterlacing : 2 temporal taps, 3 spatial taps linear filter. The
1425
   top field is copied as is, but the bottom field is deinterlaced
1426
   against the top field. */
1427
static void deinterlace_bottom_field(uint8_t *dst, int dst_wrap,
1428
                                    const uint8_t *src1, int src_wrap,
1429
                                    int width, int height)
1430
{
1431
    const uint8_t *src_m2, *src_m1, *src_0, *src_p1, *src_p2;
1432
    int y;
1433

    
1434
    src_m2 = src1;
1435
    src_m1 = src1;
1436
    src_0=&src_m1[src_wrap];
1437
    src_p1=&src_0[src_wrap];
1438
    src_p2=&src_p1[src_wrap];
1439
    for(y=0;y<(height-2);y+=2) {
1440
        memcpy(dst,src_m1,width);
1441
        dst += dst_wrap;
1442
        deinterlace_line(dst,src_m2,src_m1,src_0,src_p1,src_p2,width);
1443
        src_m2 = src_0;
1444
        src_m1 = src_p1;
1445
        src_0 = src_p2;
1446
        src_p1 += 2*src_wrap;
1447
        src_p2 += 2*src_wrap;
1448
        dst += dst_wrap;
1449
    }
1450
    memcpy(dst,src_m1,width);
1451
    dst += dst_wrap;
1452
    /* do last line */
1453
    deinterlace_line(dst,src_m2,src_m1,src_0,src_0,src_0,width);
1454
}
1455

    
1456
static void deinterlace_bottom_field_inplace(uint8_t *src1, int src_wrap,
1457
                                             int width, int height)
1458
{
1459
    uint8_t *src_m1, *src_0, *src_p1, *src_p2;
1460
    int y;
1461
    uint8_t *buf;
1462
    buf = (uint8_t*)av_malloc(width);
1463

    
1464
    src_m1 = src1;
1465
    memcpy(buf,src_m1,width);
1466
    src_0=&src_m1[src_wrap];
1467
    src_p1=&src_0[src_wrap];
1468
    src_p2=&src_p1[src_wrap];
1469
    for(y=0;y<(height-2);y+=2) {
1470
        deinterlace_line_inplace(buf,src_m1,src_0,src_p1,src_p2,width);
1471
        src_m1 = src_p1;
1472
        src_0 = src_p2;
1473
        src_p1 += 2*src_wrap;
1474
        src_p2 += 2*src_wrap;
1475
    }
1476
    /* do last line */
1477
    deinterlace_line_inplace(buf,src_m1,src_0,src_0,src_0,width);
1478
    av_free(buf);
1479
}
1480

    
1481
int avpicture_deinterlace(AVPicture *dst, const AVPicture *src,
1482
                          enum PixelFormat pix_fmt, int width, int height)
1483
{
1484
    int i;
1485

    
1486
    if (pix_fmt != PIX_FMT_YUV420P &&
1487
        pix_fmt != PIX_FMT_YUV422P &&
1488
        pix_fmt != PIX_FMT_YUV444P &&
1489
        pix_fmt != PIX_FMT_YUV411P &&
1490
        pix_fmt != PIX_FMT_GRAY8)
1491
        return -1;
1492
    if ((width & 3) != 0 || (height & 3) != 0)
1493
        return -1;
1494

    
1495
    for(i=0;i<3;i++) {
1496
        if (i == 1) {
1497
            switch(pix_fmt) {
1498
            case PIX_FMT_YUV420P:
1499
                width >>= 1;
1500
                height >>= 1;
1501
                break;
1502
            case PIX_FMT_YUV422P:
1503
                width >>= 1;
1504
                break;
1505
            case PIX_FMT_YUV411P:
1506
                width >>= 2;
1507
                break;
1508
            default:
1509
                break;
1510
            }
1511
            if (pix_fmt == PIX_FMT_GRAY8) {
1512
                break;
1513
            }
1514
        }
1515
        if (src == dst) {
1516
            deinterlace_bottom_field_inplace(dst->data[i], dst->linesize[i],
1517
                                 width, height);
1518
        } else {
1519
            deinterlace_bottom_field(dst->data[i],dst->linesize[i],
1520
                                        src->data[i], src->linesize[i],
1521
                                        width, height);
1522
        }
1523
    }
1524
    emms_c();
1525
    return 0;
1526
}
1527