Statistics
| Branch: | Revision:

ffmpeg / libavcodec / imgconvert.c @ 4744f896

History | View | Annotate | Download (42.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 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 "internal.h"
37
#include "imgconvert.h"
38
#include "libavutil/pixdesc.h"
39

    
40
#if HAVE_MMX
41
#include "x86/mmx.h"
42
#include "x86/dsputil_mmx.h"
43
#endif
44

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

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

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

    
57
typedef struct PixFmtInfo {
58
    uint8_t nb_channels;     /**< number of channels (including alpha) */
59
    uint8_t color_type;      /**< color type (see FF_COLOR_xxx constants) */
60
    uint8_t pixel_type;      /**< pixel storage type (see FF_PIXEL_xxx constants) */
61
    uint8_t is_alpha : 1;    /**< true if alpha can be specified */
62
    uint8_t 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
        .nb_channels = 3,
70
        .color_type = FF_COLOR_YUV,
71
        .pixel_type = FF_PIXEL_PLANAR,
72
        .depth = 8,
73
    },
74
    [PIX_FMT_YUV422P] = {
75
        .nb_channels = 3,
76
        .color_type = FF_COLOR_YUV,
77
        .pixel_type = FF_PIXEL_PLANAR,
78
        .depth = 8,
79
    },
80
    [PIX_FMT_YUV444P] = {
81
        .nb_channels = 3,
82
        .color_type = FF_COLOR_YUV,
83
        .pixel_type = FF_PIXEL_PLANAR,
84
        .depth = 8,
85
    },
86
    [PIX_FMT_YUYV422] = {
87
        .nb_channels = 1,
88
        .color_type = FF_COLOR_YUV,
89
        .pixel_type = FF_PIXEL_PACKED,
90
        .depth = 8,
91
    },
92
    [PIX_FMT_UYVY422] = {
93
        .nb_channels = 1,
94
        .color_type = FF_COLOR_YUV,
95
        .pixel_type = FF_PIXEL_PACKED,
96
        .depth = 8,
97
    },
98
    [PIX_FMT_YUV410P] = {
99
        .nb_channels = 3,
100
        .color_type = FF_COLOR_YUV,
101
        .pixel_type = FF_PIXEL_PLANAR,
102
        .depth = 8,
103
    },
104
    [PIX_FMT_YUV411P] = {
105
        .nb_channels = 3,
106
        .color_type = FF_COLOR_YUV,
107
        .pixel_type = FF_PIXEL_PLANAR,
108
        .depth = 8,
109
    },
110
    [PIX_FMT_YUV440P] = {
111
        .nb_channels = 3,
112
        .color_type = FF_COLOR_YUV,
113
        .pixel_type = FF_PIXEL_PLANAR,
114
        .depth = 8,
115
    },
116
    [PIX_FMT_YUV420P16LE] = {
117
        .nb_channels = 3,
118
        .color_type = FF_COLOR_YUV,
119
        .pixel_type = FF_PIXEL_PLANAR,
120
        .depth = 16,
121
    },
122
    [PIX_FMT_YUV422P16LE] = {
123
        .nb_channels = 3,
124
        .color_type = FF_COLOR_YUV,
125
        .pixel_type = FF_PIXEL_PLANAR,
126
        .depth = 16,
127
    },
128
    [PIX_FMT_YUV444P16LE] = {
129
        .nb_channels = 3,
130
        .color_type = FF_COLOR_YUV,
131
        .pixel_type = FF_PIXEL_PLANAR,
132
        .depth = 16,
133
    },
134
    [PIX_FMT_YUV420P16BE] = {
135
        .nb_channels = 3,
136
        .color_type = FF_COLOR_YUV,
137
        .pixel_type = FF_PIXEL_PLANAR,
138
        .depth = 16,
139
    },
140
    [PIX_FMT_YUV422P16BE] = {
141
        .nb_channels = 3,
142
        .color_type = FF_COLOR_YUV,
143
        .pixel_type = FF_PIXEL_PLANAR,
144
        .depth = 16,
145
    },
146
    [PIX_FMT_YUV444P16BE] = {
147
        .nb_channels = 3,
148
        .color_type = FF_COLOR_YUV,
149
        .pixel_type = FF_PIXEL_PLANAR,
150
        .depth = 16,
151
    },
152

    
153

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

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

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

    
256
    /* gray / mono formats */
257
    [PIX_FMT_GRAY16BE] = {
258
        .nb_channels = 1,
259
        .color_type = FF_COLOR_GRAY,
260
        .pixel_type = FF_PIXEL_PLANAR,
261
        .depth = 16,
262
    },
263
    [PIX_FMT_GRAY16LE] = {
264
        .nb_channels = 1,
265
        .color_type = FF_COLOR_GRAY,
266
        .pixel_type = FF_PIXEL_PLANAR,
267
        .depth = 16,
268
    },
269
    [PIX_FMT_GRAY8] = {
270
        .nb_channels = 1,
271
        .color_type = FF_COLOR_GRAY,
272
        .pixel_type = FF_PIXEL_PLANAR,
273
        .depth = 8,
274
    },
275
    [PIX_FMT_MONOWHITE] = {
276
        .nb_channels = 1,
277
        .color_type = FF_COLOR_GRAY,
278
        .pixel_type = FF_PIXEL_PLANAR,
279
        .depth = 1,
280
    },
281
    [PIX_FMT_MONOBLACK] = {
282
        .nb_channels = 1,
283
        .color_type = FF_COLOR_GRAY,
284
        .pixel_type = FF_PIXEL_PLANAR,
285
        .depth = 1,
286
    },
287

    
288
    /* paletted formats */
289
    [PIX_FMT_PAL8] = {
290
        .nb_channels = 4, .is_alpha = 1,
291
        .color_type = FF_COLOR_RGB,
292
        .pixel_type = FF_PIXEL_PALETTE,
293
        .depth = 8,
294
    },
295
    [PIX_FMT_UYYVYY411] = {
296
        .nb_channels = 1,
297
        .color_type = FF_COLOR_YUV,
298
        .pixel_type = FF_PIXEL_PACKED,
299
        .depth = 8,
300
    },
301
    [PIX_FMT_ABGR] = {
302
        .nb_channels = 4, .is_alpha = 1,
303
        .color_type = FF_COLOR_RGB,
304
        .pixel_type = FF_PIXEL_PACKED,
305
        .depth = 8,
306
    },
307
    [PIX_FMT_BGR565BE] = {
308
        .nb_channels = 3,
309
        .color_type = FF_COLOR_RGB,
310
        .pixel_type = FF_PIXEL_PACKED,
311
        .depth = 5,
312
    },
313
    [PIX_FMT_BGR565LE] = {
314
        .nb_channels = 3,
315
        .color_type = FF_COLOR_RGB,
316
        .pixel_type = FF_PIXEL_PACKED,
317
        .depth = 5,
318
    },
319
    [PIX_FMT_BGR555BE] = {
320
        .nb_channels = 3,
321
        .color_type = FF_COLOR_RGB,
322
        .pixel_type = FF_PIXEL_PACKED,
323
        .depth = 5,
324
    },
325
    [PIX_FMT_BGR555LE] = {
326
        .nb_channels = 3,
327
        .color_type = FF_COLOR_RGB,
328
        .pixel_type = FF_PIXEL_PACKED,
329
        .depth = 5,
330
    },
331
    [PIX_FMT_BGR444BE] = {
332
        .nb_channels = 3,
333
        .color_type = FF_COLOR_RGB,
334
        .pixel_type = FF_PIXEL_PACKED,
335
        .depth = 4,
336
    },
337
    [PIX_FMT_BGR444LE] = {
338
        .nb_channels = 3,
339
        .color_type = FF_COLOR_RGB,
340
        .pixel_type = FF_PIXEL_PACKED,
341
        .depth = 4,
342
    },
343
    [PIX_FMT_RGB8] = {
344
        .nb_channels = 1,
345
        .color_type = FF_COLOR_RGB,
346
        .pixel_type = FF_PIXEL_PACKED,
347
        .depth = 8,
348
    },
349
    [PIX_FMT_RGB4] = {
350
        .nb_channels = 1,
351
        .color_type = FF_COLOR_RGB,
352
        .pixel_type = FF_PIXEL_PACKED,
353
        .depth = 4,
354
    },
355
    [PIX_FMT_RGB4_BYTE] = {
356
        .nb_channels = 1,
357
        .color_type = FF_COLOR_RGB,
358
        .pixel_type = FF_PIXEL_PACKED,
359
        .depth = 8,
360
    },
361
    [PIX_FMT_BGR8] = {
362
        .nb_channels = 1,
363
        .color_type = FF_COLOR_RGB,
364
        .pixel_type = FF_PIXEL_PACKED,
365
        .depth = 8,
366
    },
367
    [PIX_FMT_BGR4] = {
368
        .nb_channels = 1,
369
        .color_type = FF_COLOR_RGB,
370
        .pixel_type = FF_PIXEL_PACKED,
371
        .depth = 4,
372
    },
373
    [PIX_FMT_BGR4_BYTE] = {
374
        .nb_channels = 1,
375
        .color_type = FF_COLOR_RGB,
376
        .pixel_type = FF_PIXEL_PACKED,
377
        .depth = 8,
378
    },
379
    [PIX_FMT_NV12] = {
380
        .nb_channels = 2,
381
        .color_type = FF_COLOR_YUV,
382
        .pixel_type = FF_PIXEL_PLANAR,
383
        .depth = 8,
384
    },
385
    [PIX_FMT_NV21] = {
386
        .nb_channels = 2,
387
        .color_type = FF_COLOR_YUV,
388
        .pixel_type = FF_PIXEL_PLANAR,
389
        .depth = 8,
390
    },
391

    
392
    [PIX_FMT_BGRA] = {
393
        .nb_channels = 4, .is_alpha = 1,
394
        .color_type = FF_COLOR_RGB,
395
        .pixel_type = FF_PIXEL_PACKED,
396
        .depth = 8,
397
    },
398
    [PIX_FMT_RGBA] = {
399
        .nb_channels = 4, .is_alpha = 1,
400
        .color_type = FF_COLOR_RGB,
401
        .pixel_type = FF_PIXEL_PACKED,
402
        .depth = 8,
403
    },
404
};
405

    
406
void avcodec_get_chroma_sub_sample(enum PixelFormat pix_fmt, int *h_shift, int *v_shift)
407
{
408
    *h_shift = av_pix_fmt_descriptors[pix_fmt].log2_chroma_w;
409
    *v_shift = av_pix_fmt_descriptors[pix_fmt].log2_chroma_h;
410
}
411

    
412
const char *avcodec_get_pix_fmt_name(enum PixelFormat pix_fmt)
413
{
414
    if (pix_fmt < 0 || pix_fmt >= PIX_FMT_NB)
415
        return NULL;
416
    else
417
        return av_pix_fmt_descriptors[pix_fmt].name;
418
}
419

    
420
#if LIBAVCODEC_VERSION_MAJOR < 53
421
enum PixelFormat avcodec_get_pix_fmt(const char *name)
422
{
423
    return av_get_pix_fmt(name);
424
}
425
#endif
426

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

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

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

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

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

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

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

    
490
    return 0;
491
}
492

    
493
int ff_fill_linesize(AVPicture *picture, enum PixelFormat pix_fmt, int width)
494
{
495
    int i;
496
    const AVPixFmtDescriptor *desc = &av_pix_fmt_descriptors[pix_fmt];
497
    int max_plane_step     [4];
498
    int max_plane_step_comp[4];
499

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

    
502
    if (desc->flags & PIX_FMT_HWACCEL)
503
        return -1;
504

    
505
    if (desc->flags & PIX_FMT_BITSTREAM) {
506
        picture->linesize[0] = (width * (desc->comp[0].step_minus1+1) + 7) >> 3;
507
        return 0;
508
    }
509

    
510
    memset(max_plane_step     , 0, sizeof(max_plane_step     ));
511
    memset(max_plane_step_comp, 0, sizeof(max_plane_step_comp));
512
    for (i = 0; i < 4; i++) {
513
        const AVComponentDescriptor *comp = &(desc->comp[i]);
514
        if ((comp->step_minus1+1) > max_plane_step[comp->plane]) {
515
            max_plane_step     [comp->plane] = comp->step_minus1+1;
516
            max_plane_step_comp[comp->plane] = i;
517
        }
518
    }
519

    
520
    for (i = 0; i < 4; i++) {
521
        int s = (max_plane_step_comp[i] == 1 || max_plane_step_comp[i] == 2) ? desc->log2_chroma_w : 0;
522
        picture->linesize[i] = max_plane_step[i] * (((width + (1 << s) - 1)) >> s);
523
    }
524

    
525
    return 0;
526
}
527

    
528
int ff_fill_pointer(AVPicture *picture, uint8_t *ptr, enum PixelFormat pix_fmt,
529
                    int height)
530
{
531
    int size, h2, size2;
532
    const AVPixFmtDescriptor *desc = &av_pix_fmt_descriptors[pix_fmt];
533

    
534
    size = picture->linesize[0] * height;
535
    switch(pix_fmt) {
536
    case PIX_FMT_YUV420P:
537
    case PIX_FMT_YUV422P:
538
    case PIX_FMT_YUV444P:
539
    case PIX_FMT_YUV410P:
540
    case PIX_FMT_YUV411P:
541
    case PIX_FMT_YUV440P:
542
    case PIX_FMT_YUVJ420P:
543
    case PIX_FMT_YUVJ422P:
544
    case PIX_FMT_YUVJ444P:
545
    case PIX_FMT_YUVJ440P:
546
    case PIX_FMT_YUV420P16LE:
547
    case PIX_FMT_YUV422P16LE:
548
    case PIX_FMT_YUV444P16LE:
549
    case PIX_FMT_YUV420P16BE:
550
    case PIX_FMT_YUV422P16BE:
551
    case PIX_FMT_YUV444P16BE:
552
        h2 = (height + (1 << desc->log2_chroma_h) - 1) >> desc->log2_chroma_h;
553
        size2 = picture->linesize[1] * h2;
554
        picture->data[0] = ptr;
555
        picture->data[1] = picture->data[0] + size;
556
        picture->data[2] = picture->data[1] + size2;
557
        picture->data[3] = NULL;
558
        return size + 2 * size2;
559
    case PIX_FMT_YUVA420P:
560
        h2 = (height + (1 << desc->log2_chroma_h) - 1) >> desc->log2_chroma_h;
561
        size2 = picture->linesize[1] * h2;
562
        picture->data[0] = ptr;
563
        picture->data[1] = picture->data[0] + size;
564
        picture->data[2] = picture->data[1] + size2;
565
        picture->data[3] = picture->data[1] + size2 + size2;
566
        return 2 * size + 2 * size2;
567
    case PIX_FMT_NV12:
568
    case PIX_FMT_NV21:
569
        h2 = (height + (1 << desc->log2_chroma_h) - 1) >> desc->log2_chroma_h;
570
        size2 = picture->linesize[1] * h2;
571
        picture->data[0] = ptr;
572
        picture->data[1] = picture->data[0] + size;
573
        picture->data[2] = NULL;
574
        picture->data[3] = NULL;
575
        return size + size2;
576
    case PIX_FMT_RGB24:
577
    case PIX_FMT_BGR24:
578
    case PIX_FMT_ARGB:
579
    case PIX_FMT_ABGR:
580
    case PIX_FMT_RGBA:
581
    case PIX_FMT_BGRA:
582
    case PIX_FMT_RGB48BE:
583
    case PIX_FMT_RGB48LE:
584
    case PIX_FMT_GRAY16BE:
585
    case PIX_FMT_GRAY16LE:
586
    case PIX_FMT_BGR444BE:
587
    case PIX_FMT_BGR444LE:
588
    case PIX_FMT_BGR555BE:
589
    case PIX_FMT_BGR555LE:
590
    case PIX_FMT_BGR565BE:
591
    case PIX_FMT_BGR565LE:
592
    case PIX_FMT_RGB444BE:
593
    case PIX_FMT_RGB444LE:
594
    case PIX_FMT_RGB555BE:
595
    case PIX_FMT_RGB555LE:
596
    case PIX_FMT_RGB565BE:
597
    case PIX_FMT_RGB565LE:
598
    case PIX_FMT_YUYV422:
599
    case PIX_FMT_UYVY422:
600
    case PIX_FMT_UYYVYY411:
601
    case PIX_FMT_RGB4:
602
    case PIX_FMT_BGR4:
603
    case PIX_FMT_MONOWHITE:
604
    case PIX_FMT_MONOBLACK:
605
    case PIX_FMT_Y400A:
606
        picture->data[0] = ptr;
607
        picture->data[1] = NULL;
608
        picture->data[2] = NULL;
609
        picture->data[3] = NULL;
610
        return size;
611
    case PIX_FMT_PAL8:
612
    case PIX_FMT_RGB8:
613
    case PIX_FMT_BGR8:
614
    case PIX_FMT_RGB4_BYTE:
615
    case PIX_FMT_BGR4_BYTE:
616
    case PIX_FMT_GRAY8:
617
        size2 = (size + 3) & ~3;
618
        picture->data[0] = ptr;
619
        picture->data[1] = ptr + size2; /* palette is stored here as 256 32 bit words */
620
        picture->data[2] = NULL;
621
        picture->data[3] = NULL;
622
        return size2 + 256 * 4;
623
    default:
624
        picture->data[0] = NULL;
625
        picture->data[1] = NULL;
626
        picture->data[2] = NULL;
627
        picture->data[3] = NULL;
628
        return -1;
629
    }
630
}
631

    
632
int avpicture_fill(AVPicture *picture, uint8_t *ptr,
633
                   enum PixelFormat pix_fmt, int width, int height)
634
{
635

    
636
    if(avcodec_check_dimensions(NULL, width, height))
637
        return -1;
638

    
639
    if (ff_fill_linesize(picture, pix_fmt, width))
640
        return -1;
641

    
642
    return ff_fill_pointer(picture, ptr, pix_fmt, height);
643
}
644

    
645
int avpicture_layout(const AVPicture* src, enum PixelFormat pix_fmt, int width, int height,
646
                     unsigned char *dest, int dest_size)
647
{
648
    const PixFmtInfo* pf = &pix_fmt_info[pix_fmt];
649
    const AVPixFmtDescriptor *desc = &av_pix_fmt_descriptors[pix_fmt];
650
    int i, j, w, ow, h, oh, data_planes;
651
    const unsigned char* s;
652
    int size = avpicture_get_size(pix_fmt, width, height);
653

    
654
    if (size > dest_size || size < 0)
655
        return -1;
656

    
657
    if (pf->pixel_type == FF_PIXEL_PACKED || pf->pixel_type == FF_PIXEL_PALETTE) {
658
        if (pix_fmt == PIX_FMT_YUYV422 ||
659
            pix_fmt == PIX_FMT_UYVY422 ||
660
            pix_fmt == PIX_FMT_BGR565BE ||
661
            pix_fmt == PIX_FMT_BGR565LE ||
662
            pix_fmt == PIX_FMT_BGR555BE ||
663
            pix_fmt == PIX_FMT_BGR555LE ||
664
            pix_fmt == PIX_FMT_BGR444BE ||
665
            pix_fmt == PIX_FMT_BGR444LE ||
666
            pix_fmt == PIX_FMT_RGB565BE ||
667
            pix_fmt == PIX_FMT_RGB565LE ||
668
            pix_fmt == PIX_FMT_RGB555BE ||
669
            pix_fmt == PIX_FMT_RGB555LE ||
670
            pix_fmt == PIX_FMT_RGB444BE ||
671
            pix_fmt == PIX_FMT_RGB444LE)
672
            w = width * 2;
673
        else if (pix_fmt == PIX_FMT_UYYVYY411)
674
            w = width + width/2;
675
        else if (pix_fmt == PIX_FMT_PAL8)
676
            w = width;
677
        else
678
            w = width * (pf->depth * pf->nb_channels / 8);
679

    
680
        data_planes = 1;
681
        h = height;
682
    } else {
683
        data_planes = pf->nb_channels;
684
        w = (width*pf->depth + 7)/8;
685
        h = height;
686
    }
687

    
688
    ow = w;
689
    oh = h;
690

    
691
    for (i=0; i<data_planes; i++) {
692
        if (i == 1) {
693
            w = (- ((-width) >> desc->log2_chroma_w) * pf->depth + 7) / 8;
694
            h = -((-height) >> desc->log2_chroma_h);
695
            if (pix_fmt == PIX_FMT_NV12 || pix_fmt == PIX_FMT_NV21)
696
                w <<= 1;
697
        } else if (i == 3) {
698
            w = ow;
699
            h = oh;
700
        }
701
        s = src->data[i];
702
        for(j=0; j<h; j++) {
703
            memcpy(dest, s, w);
704
            dest += w;
705
            s += src->linesize[i];
706
        }
707
    }
708

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

    
712
    return size;
713
}
714

    
715
int avpicture_get_size(enum PixelFormat pix_fmt, int width, int height)
716
{
717
    AVPicture dummy_pict;
718
    if(avcodec_check_dimensions(NULL, width, height))
719
        return -1;
720
    switch (pix_fmt) {
721
    case PIX_FMT_RGB8:
722
    case PIX_FMT_BGR8:
723
    case PIX_FMT_RGB4_BYTE:
724
    case PIX_FMT_BGR4_BYTE:
725
    case PIX_FMT_GRAY8:
726
        // do not include palette for these pseudo-paletted formats
727
        return width * height;
728
    }
729
    return avpicture_fill(&dummy_pict, NULL, pix_fmt, width, height);
730
}
731

    
732
int avcodec_get_pix_fmt_loss(enum PixelFormat dst_pix_fmt, enum PixelFormat src_pix_fmt,
733
                             int has_alpha)
734
{
735
    const PixFmtInfo *pf, *ps;
736
    const AVPixFmtDescriptor *src_desc = &av_pix_fmt_descriptors[src_pix_fmt];
737
    const AVPixFmtDescriptor *dst_desc = &av_pix_fmt_descriptors[dst_pix_fmt];
738
    int loss;
739

    
740
    ps = &pix_fmt_info[src_pix_fmt];
741

    
742
    /* compute loss */
743
    loss = 0;
744
    pf = &pix_fmt_info[dst_pix_fmt];
745
    if (pf->depth < ps->depth ||
746
        ((dst_pix_fmt == PIX_FMT_RGB555BE || dst_pix_fmt == PIX_FMT_RGB555LE ||
747
          dst_pix_fmt == PIX_FMT_BGR555BE || dst_pix_fmt == PIX_FMT_BGR555LE) &&
748
         (src_pix_fmt == PIX_FMT_RGB565BE || src_pix_fmt == PIX_FMT_RGB565LE ||
749
          src_pix_fmt == PIX_FMT_BGR565BE || src_pix_fmt == PIX_FMT_BGR565LE)))
750
        loss |= FF_LOSS_DEPTH;
751
    if (dst_desc->log2_chroma_w > src_desc->log2_chroma_w ||
752
        dst_desc->log2_chroma_h > src_desc->log2_chroma_h)
753
        loss |= FF_LOSS_RESOLUTION;
754
    switch(pf->color_type) {
755
    case FF_COLOR_RGB:
756
        if (ps->color_type != FF_COLOR_RGB &&
757
            ps->color_type != FF_COLOR_GRAY)
758
            loss |= FF_LOSS_COLORSPACE;
759
        break;
760
    case FF_COLOR_GRAY:
761
        if (ps->color_type != FF_COLOR_GRAY)
762
            loss |= FF_LOSS_COLORSPACE;
763
        break;
764
    case FF_COLOR_YUV:
765
        if (ps->color_type != FF_COLOR_YUV)
766
            loss |= FF_LOSS_COLORSPACE;
767
        break;
768
    case FF_COLOR_YUV_JPEG:
769
        if (ps->color_type != FF_COLOR_YUV_JPEG &&
770
            ps->color_type != FF_COLOR_YUV &&
771
            ps->color_type != FF_COLOR_GRAY)
772
            loss |= FF_LOSS_COLORSPACE;
773
        break;
774
    default:
775
        /* fail safe test */
776
        if (ps->color_type != pf->color_type)
777
            loss |= FF_LOSS_COLORSPACE;
778
        break;
779
    }
780
    if (pf->color_type == FF_COLOR_GRAY &&
781
        ps->color_type != FF_COLOR_GRAY)
782
        loss |= FF_LOSS_CHROMA;
783
    if (!pf->is_alpha && (ps->is_alpha && has_alpha))
784
        loss |= FF_LOSS_ALPHA;
785
    if (pf->pixel_type == FF_PIXEL_PALETTE &&
786
        (ps->pixel_type != FF_PIXEL_PALETTE && ps->color_type != FF_COLOR_GRAY))
787
        loss |= FF_LOSS_COLORQUANT;
788
    return loss;
789
}
790

    
791
static int avg_bits_per_pixel(enum PixelFormat pix_fmt)
792
{
793
    int bits;
794
    const PixFmtInfo *pf;
795
    const AVPixFmtDescriptor *desc = &av_pix_fmt_descriptors[pix_fmt];
796

    
797
    pf = &pix_fmt_info[pix_fmt];
798
    switch(pf->pixel_type) {
799
    case FF_PIXEL_PACKED:
800
        switch(pix_fmt) {
801
        case PIX_FMT_YUYV422:
802
        case PIX_FMT_UYVY422:
803
        case PIX_FMT_RGB565BE:
804
        case PIX_FMT_RGB565LE:
805
        case PIX_FMT_RGB555BE:
806
        case PIX_FMT_RGB555LE:
807
        case PIX_FMT_RGB444BE:
808
        case PIX_FMT_RGB444LE:
809
        case PIX_FMT_BGR565BE:
810
        case PIX_FMT_BGR565LE:
811
        case PIX_FMT_BGR555BE:
812
        case PIX_FMT_BGR555LE:
813
        case PIX_FMT_BGR444BE:
814
        case PIX_FMT_BGR444LE:
815
            bits = 16;
816
            break;
817
        case PIX_FMT_UYYVYY411:
818
            bits = 12;
819
            break;
820
        default:
821
            bits = pf->depth * pf->nb_channels;
822
            break;
823
        }
824
        break;
825
    case FF_PIXEL_PLANAR:
826
        if (desc->log2_chroma_w == 0 && desc->log2_chroma_h == 0) {
827
            bits = pf->depth * pf->nb_channels;
828
        } else {
829
            bits = pf->depth + ((2 * pf->depth) >>
830
                                (desc->log2_chroma_w + desc->log2_chroma_h));
831
        }
832
        break;
833
    case FF_PIXEL_PALETTE:
834
        bits = 8;
835
        break;
836
    default:
837
        bits = -1;
838
        break;
839
    }
840
    return bits;
841
}
842

    
843
static enum PixelFormat avcodec_find_best_pix_fmt1(int64_t pix_fmt_mask,
844
                                      enum PixelFormat src_pix_fmt,
845
                                      int has_alpha,
846
                                      int loss_mask)
847
{
848
    int dist, i, loss, min_dist;
849
    enum PixelFormat dst_pix_fmt;
850

    
851
    /* find exact color match with smallest size */
852
    dst_pix_fmt = PIX_FMT_NONE;
853
    min_dist = 0x7fffffff;
854
    for(i = 0;i < PIX_FMT_NB; i++) {
855
        if (pix_fmt_mask & (1ULL << i)) {
856
            loss = avcodec_get_pix_fmt_loss(i, src_pix_fmt, has_alpha) & loss_mask;
857
            if (loss == 0) {
858
                dist = avg_bits_per_pixel(i);
859
                if (dist < min_dist) {
860
                    min_dist = dist;
861
                    dst_pix_fmt = i;
862
                }
863
            }
864
        }
865
    }
866
    return dst_pix_fmt;
867
}
868

    
869
enum PixelFormat avcodec_find_best_pix_fmt(int64_t pix_fmt_mask, enum PixelFormat src_pix_fmt,
870
                              int has_alpha, int *loss_ptr)
871
{
872
    enum PixelFormat dst_pix_fmt;
873
    int loss_mask, i;
874
    static const int loss_mask_order[] = {
875
        ~0, /* no loss first */
876
        ~FF_LOSS_ALPHA,
877
        ~FF_LOSS_RESOLUTION,
878
        ~(FF_LOSS_COLORSPACE | FF_LOSS_RESOLUTION),
879
        ~FF_LOSS_COLORQUANT,
880
        ~FF_LOSS_DEPTH,
881
        0,
882
    };
883

    
884
    /* try with successive loss */
885
    i = 0;
886
    for(;;) {
887
        loss_mask = loss_mask_order[i++];
888
        dst_pix_fmt = avcodec_find_best_pix_fmt1(pix_fmt_mask, src_pix_fmt,
889
                                                 has_alpha, loss_mask);
890
        if (dst_pix_fmt >= 0)
891
            goto found;
892
        if (loss_mask == 0)
893
            break;
894
    }
895
    return PIX_FMT_NONE;
896
 found:
897
    if (loss_ptr)
898
        *loss_ptr = avcodec_get_pix_fmt_loss(dst_pix_fmt, src_pix_fmt, has_alpha);
899
    return dst_pix_fmt;
900
}
901

    
902
void ff_img_copy_plane(uint8_t *dst, int dst_wrap,
903
                           const uint8_t *src, int src_wrap,
904
                           int width, int height)
905
{
906
    if((!dst) || (!src))
907
        return;
908
    for(;height > 0; height--) {
909
        memcpy(dst, src, width);
910
        dst += dst_wrap;
911
        src += src_wrap;
912
    }
913
}
914

    
915
int ff_get_plane_bytewidth(enum PixelFormat pix_fmt, int width, int plane)
916
{
917
    int bits;
918
    const PixFmtInfo *pf = &pix_fmt_info[pix_fmt];
919
    const AVPixFmtDescriptor *desc = &av_pix_fmt_descriptors[pix_fmt];
920

    
921
    pf = &pix_fmt_info[pix_fmt];
922
    switch(pf->pixel_type) {
923
    case FF_PIXEL_PACKED:
924
        switch(pix_fmt) {
925
        case PIX_FMT_YUYV422:
926
        case PIX_FMT_UYVY422:
927
        case PIX_FMT_RGB565BE:
928
        case PIX_FMT_RGB565LE:
929
        case PIX_FMT_RGB555BE:
930
        case PIX_FMT_RGB555LE:
931
        case PIX_FMT_RGB444BE:
932
        case PIX_FMT_RGB444LE:
933
        case PIX_FMT_BGR565BE:
934
        case PIX_FMT_BGR565LE:
935
        case PIX_FMT_BGR555BE:
936
        case PIX_FMT_BGR555LE:
937
        case PIX_FMT_BGR444BE:
938
        case PIX_FMT_BGR444LE:
939
            bits = 16;
940
            break;
941
        case PIX_FMT_UYYVYY411:
942
            bits = 12;
943
            break;
944
        default:
945
            bits = pf->depth * pf->nb_channels;
946
            break;
947
        }
948
        return (width * bits + 7) >> 3;
949
        break;
950
    case FF_PIXEL_PLANAR:
951
            if (plane == 1 || plane == 2)
952
                width= -((-width)>>desc->log2_chroma_w);
953

    
954
            return (width * pf->depth + 7) >> 3;
955
        break;
956
    case FF_PIXEL_PALETTE:
957
        if (plane == 0)
958
            return width;
959
        break;
960
    }
961

    
962
    return -1;
963
}
964

    
965
void av_picture_copy(AVPicture *dst, const AVPicture *src,
966
                     enum PixelFormat pix_fmt, int width, int height)
967
{
968
    int i;
969
    const PixFmtInfo *pf = &pix_fmt_info[pix_fmt];
970
    const AVPixFmtDescriptor *desc = &av_pix_fmt_descriptors[pix_fmt];
971

    
972
    switch(pf->pixel_type) {
973
    case FF_PIXEL_PACKED:
974
    case FF_PIXEL_PLANAR:
975
        for(i = 0; i < pf->nb_channels; i++) {
976
            int h;
977
            int bwidth = ff_get_plane_bytewidth(pix_fmt, width, i);
978
            h = height;
979
            if (i == 1 || i == 2) {
980
                h= -((-height)>>desc->log2_chroma_h);
981
            }
982
            ff_img_copy_plane(dst->data[i], dst->linesize[i],
983
                           src->data[i], src->linesize[i],
984
                           bwidth, h);
985
        }
986
        break;
987
    case FF_PIXEL_PALETTE:
988
        ff_img_copy_plane(dst->data[0], dst->linesize[0],
989
                       src->data[0], src->linesize[0],
990
                       width, height);
991
        /* copy the palette */
992
        memcpy(dst->data[1], src->data[1], 4*256);
993
        break;
994
    }
995
}
996

    
997
/* 2x2 -> 1x1 */
998
void ff_shrink22(uint8_t *dst, int dst_wrap,
999
                     const uint8_t *src, int src_wrap,
1000
                     int width, int height)
1001
{
1002
    int w;
1003
    const uint8_t *s1, *s2;
1004
    uint8_t *d;
1005

    
1006
    for(;height > 0; height--) {
1007
        s1 = src;
1008
        s2 = s1 + src_wrap;
1009
        d = dst;
1010
        for(w = width;w >= 4; w-=4) {
1011
            d[0] = (s1[0] + s1[1] + s2[0] + s2[1] + 2) >> 2;
1012
            d[1] = (s1[2] + s1[3] + s2[2] + s2[3] + 2) >> 2;
1013
            d[2] = (s1[4] + s1[5] + s2[4] + s2[5] + 2) >> 2;
1014
            d[3] = (s1[6] + s1[7] + s2[6] + s2[7] + 2) >> 2;
1015
            s1 += 8;
1016
            s2 += 8;
1017
            d += 4;
1018
        }
1019
        for(;w > 0; w--) {
1020
            d[0] = (s1[0] + s1[1] + s2[0] + s2[1] + 2) >> 2;
1021
            s1 += 2;
1022
            s2 += 2;
1023
            d++;
1024
        }
1025
        src += 2 * src_wrap;
1026
        dst += dst_wrap;
1027
    }
1028
}
1029

    
1030
/* 4x4 -> 1x1 */
1031
void ff_shrink44(uint8_t *dst, int dst_wrap,
1032
                     const uint8_t *src, int src_wrap,
1033
                     int width, int height)
1034
{
1035
    int w;
1036
    const uint8_t *s1, *s2, *s3, *s4;
1037
    uint8_t *d;
1038

    
1039
    for(;height > 0; height--) {
1040
        s1 = src;
1041
        s2 = s1 + src_wrap;
1042
        s3 = s2 + src_wrap;
1043
        s4 = s3 + src_wrap;
1044
        d = dst;
1045
        for(w = width;w > 0; w--) {
1046
            d[0] = (s1[0] + s1[1] + s1[2] + s1[3] +
1047
                    s2[0] + s2[1] + s2[2] + s2[3] +
1048
                    s3[0] + s3[1] + s3[2] + s3[3] +
1049
                    s4[0] + s4[1] + s4[2] + s4[3] + 8) >> 4;
1050
            s1 += 4;
1051
            s2 += 4;
1052
            s3 += 4;
1053
            s4 += 4;
1054
            d++;
1055
        }
1056
        src += 4 * src_wrap;
1057
        dst += dst_wrap;
1058
    }
1059
}
1060

    
1061
/* 8x8 -> 1x1 */
1062
void ff_shrink88(uint8_t *dst, int dst_wrap,
1063
                     const uint8_t *src, int src_wrap,
1064
                     int width, int height)
1065
{
1066
    int w, i;
1067

    
1068
    for(;height > 0; height--) {
1069
        for(w = width;w > 0; w--) {
1070
            int tmp=0;
1071
            for(i=0; i<8; i++){
1072
                tmp += src[0] + src[1] + src[2] + src[3] + src[4] + src[5] + src[6] + src[7];
1073
                src += src_wrap;
1074
            }
1075
            *(dst++) = (tmp + 32)>>6;
1076
            src += 8 - 8*src_wrap;
1077
        }
1078
        src += 8*src_wrap - 8*width;
1079
        dst += dst_wrap - width;
1080
    }
1081
}
1082

    
1083

    
1084
int avpicture_alloc(AVPicture *picture,
1085
                    enum PixelFormat pix_fmt, int width, int height)
1086
{
1087
    int size;
1088
    void *ptr;
1089

    
1090
    size = avpicture_fill(picture, NULL, pix_fmt, width, height);
1091
    if(size<0)
1092
        goto fail;
1093
    ptr = av_malloc(size);
1094
    if (!ptr)
1095
        goto fail;
1096
    avpicture_fill(picture, ptr, pix_fmt, width, height);
1097
    if(picture->data[1] && !picture->data[2])
1098
        ff_set_systematic_pal((uint32_t*)picture->data[1], pix_fmt);
1099

    
1100
    return 0;
1101
 fail:
1102
    memset(picture, 0, sizeof(AVPicture));
1103
    return -1;
1104
}
1105

    
1106
void avpicture_free(AVPicture *picture)
1107
{
1108
    av_free(picture->data[0]);
1109
}
1110

    
1111
/* return true if yuv planar */
1112
static inline int is_yuv_planar(const PixFmtInfo *ps)
1113
{
1114
    return (ps->color_type == FF_COLOR_YUV ||
1115
            ps->color_type == FF_COLOR_YUV_JPEG) &&
1116
        ps->pixel_type == FF_PIXEL_PLANAR;
1117
}
1118

    
1119
int av_picture_crop(AVPicture *dst, const AVPicture *src,
1120
                    enum PixelFormat pix_fmt, int top_band, int left_band)
1121
{
1122
    int y_shift;
1123
    int x_shift;
1124

    
1125
    if (pix_fmt < 0 || pix_fmt >= PIX_FMT_NB || !is_yuv_planar(&pix_fmt_info[pix_fmt]))
1126
        return -1;
1127

    
1128
    y_shift = av_pix_fmt_descriptors[pix_fmt].log2_chroma_h;
1129
    x_shift = av_pix_fmt_descriptors[pix_fmt].log2_chroma_w;
1130

    
1131
    dst->data[0] = src->data[0] + (top_band * src->linesize[0]) + left_band;
1132
    dst->data[1] = src->data[1] + ((top_band >> y_shift) * src->linesize[1]) + (left_band >> x_shift);
1133
    dst->data[2] = src->data[2] + ((top_band >> y_shift) * src->linesize[2]) + (left_band >> x_shift);
1134

    
1135
    dst->linesize[0] = src->linesize[0];
1136
    dst->linesize[1] = src->linesize[1];
1137
    dst->linesize[2] = src->linesize[2];
1138
    return 0;
1139
}
1140

    
1141
int av_picture_pad(AVPicture *dst, const AVPicture *src, int height, int width,
1142
                   enum PixelFormat pix_fmt, int padtop, int padbottom, int padleft, int padright,
1143
            int *color)
1144
{
1145
    uint8_t *optr;
1146
    int y_shift;
1147
    int x_shift;
1148
    int yheight;
1149
    int i, y;
1150

    
1151
    if (pix_fmt < 0 || pix_fmt >= PIX_FMT_NB ||
1152
        !is_yuv_planar(&pix_fmt_info[pix_fmt])) return -1;
1153

    
1154
    for (i = 0; i < 3; i++) {
1155
        x_shift = i ? av_pix_fmt_descriptors[pix_fmt].log2_chroma_w : 0;
1156
        y_shift = i ? av_pix_fmt_descriptors[pix_fmt].log2_chroma_h : 0;
1157

    
1158
        if (padtop || padleft) {
1159
            memset(dst->data[i], color[i],
1160
                dst->linesize[i] * (padtop >> y_shift) + (padleft >> x_shift));
1161
        }
1162

    
1163
        if (padleft || padright) {
1164
            optr = dst->data[i] + dst->linesize[i] * (padtop >> y_shift) +
1165
                (dst->linesize[i] - (padright >> x_shift));
1166
            yheight = (height - 1 - (padtop + padbottom)) >> y_shift;
1167
            for (y = 0; y < yheight; y++) {
1168
                memset(optr, color[i], (padleft + padright) >> x_shift);
1169
                optr += dst->linesize[i];
1170
            }
1171
        }
1172

    
1173
        if (src) { /* first line */
1174
            uint8_t *iptr = src->data[i];
1175
            optr = dst->data[i] + dst->linesize[i] * (padtop >> y_shift) +
1176
                    (padleft >> x_shift);
1177
            memcpy(optr, iptr, (width - padleft - padright) >> x_shift);
1178
            iptr += src->linesize[i];
1179
            optr = dst->data[i] + dst->linesize[i] * (padtop >> y_shift) +
1180
                (dst->linesize[i] - (padright >> x_shift));
1181
            yheight = (height - 1 - (padtop + padbottom)) >> y_shift;
1182
            for (y = 0; y < yheight; y++) {
1183
                memset(optr, color[i], (padleft + padright) >> x_shift);
1184
                memcpy(optr + ((padleft + padright) >> x_shift), iptr,
1185
                       (width - padleft - padright) >> x_shift);
1186
                iptr += src->linesize[i];
1187
                optr += dst->linesize[i];
1188
            }
1189
        }
1190

    
1191
        if (padbottom || padright) {
1192
            optr = dst->data[i] + dst->linesize[i] *
1193
                ((height - padbottom) >> y_shift) - (padright >> x_shift);
1194
            memset(optr, color[i],dst->linesize[i] *
1195
                (padbottom >> y_shift) + (padright >> x_shift));
1196
        }
1197
    }
1198
    return 0;
1199
}
1200

    
1201
/* NOTE: we scan all the pixels to have an exact information */
1202
static int get_alpha_info_pal8(const AVPicture *src, int width, int height)
1203
{
1204
    const unsigned char *p;
1205
    int src_wrap, ret, x, y;
1206
    unsigned int a;
1207
    uint32_t *palette = (uint32_t *)src->data[1];
1208

    
1209
    p = src->data[0];
1210
    src_wrap = src->linesize[0] - width;
1211
    ret = 0;
1212
    for(y=0;y<height;y++) {
1213
        for(x=0;x<width;x++) {
1214
            a = palette[p[0]] >> 24;
1215
            if (a == 0x00) {
1216
                ret |= FF_ALPHA_TRANSP;
1217
            } else if (a != 0xff) {
1218
                ret |= FF_ALPHA_SEMI_TRANSP;
1219
            }
1220
            p++;
1221
        }
1222
        p += src_wrap;
1223
    }
1224
    return ret;
1225
}
1226

    
1227
int img_get_alpha_info(const AVPicture *src,
1228
                       enum PixelFormat pix_fmt, int width, int height)
1229
{
1230
    const PixFmtInfo *pf = &pix_fmt_info[pix_fmt];
1231
    int ret;
1232

    
1233
    /* no alpha can be represented in format */
1234
    if (!pf->is_alpha)
1235
        return 0;
1236
    switch(pix_fmt) {
1237
    case PIX_FMT_PAL8:
1238
        ret = get_alpha_info_pal8(src, width, height);
1239
        break;
1240
    default:
1241
        /* we do not know, so everything is indicated */
1242
        ret = FF_ALPHA_TRANSP | FF_ALPHA_SEMI_TRANSP;
1243
        break;
1244
    }
1245
    return ret;
1246
}
1247

    
1248
#if HAVE_MMX
1249
#define DEINT_INPLACE_LINE_LUM \
1250
                    movd_m2r(lum_m4[0],mm0);\
1251
                    movd_m2r(lum_m3[0],mm1);\
1252
                    movd_m2r(lum_m2[0],mm2);\
1253
                    movd_m2r(lum_m1[0],mm3);\
1254
                    movd_m2r(lum[0],mm4);\
1255
                    punpcklbw_r2r(mm7,mm0);\
1256
                    movd_r2m(mm2,lum_m4[0]);\
1257
                    punpcklbw_r2r(mm7,mm1);\
1258
                    punpcklbw_r2r(mm7,mm2);\
1259
                    punpcklbw_r2r(mm7,mm3);\
1260
                    punpcklbw_r2r(mm7,mm4);\
1261
                    paddw_r2r(mm3,mm1);\
1262
                    psllw_i2r(1,mm2);\
1263
                    paddw_r2r(mm4,mm0);\
1264
                    psllw_i2r(2,mm1);\
1265
                    paddw_r2r(mm6,mm2);\
1266
                    paddw_r2r(mm2,mm1);\
1267
                    psubusw_r2r(mm0,mm1);\
1268
                    psrlw_i2r(3,mm1);\
1269
                    packuswb_r2r(mm7,mm1);\
1270
                    movd_r2m(mm1,lum_m2[0]);
1271

    
1272
#define DEINT_LINE_LUM \
1273
                    movd_m2r(lum_m4[0],mm0);\
1274
                    movd_m2r(lum_m3[0],mm1);\
1275
                    movd_m2r(lum_m2[0],mm2);\
1276
                    movd_m2r(lum_m1[0],mm3);\
1277
                    movd_m2r(lum[0],mm4);\
1278
                    punpcklbw_r2r(mm7,mm0);\
1279
                    punpcklbw_r2r(mm7,mm1);\
1280
                    punpcklbw_r2r(mm7,mm2);\
1281
                    punpcklbw_r2r(mm7,mm3);\
1282
                    punpcklbw_r2r(mm7,mm4);\
1283
                    paddw_r2r(mm3,mm1);\
1284
                    psllw_i2r(1,mm2);\
1285
                    paddw_r2r(mm4,mm0);\
1286
                    psllw_i2r(2,mm1);\
1287
                    paddw_r2r(mm6,mm2);\
1288
                    paddw_r2r(mm2,mm1);\
1289
                    psubusw_r2r(mm0,mm1);\
1290
                    psrlw_i2r(3,mm1);\
1291
                    packuswb_r2r(mm7,mm1);\
1292
                    movd_r2m(mm1,dst[0]);
1293
#endif
1294

    
1295
/* filter parameters: [-1 4 2 4 -1] // 8 */
1296
static void deinterlace_line(uint8_t *dst,
1297
                             const uint8_t *lum_m4, const uint8_t *lum_m3,
1298
                             const uint8_t *lum_m2, const uint8_t *lum_m1,
1299
                             const uint8_t *lum,
1300
                             int size)
1301
{
1302
#if !HAVE_MMX
1303
    uint8_t *cm = ff_cropTbl + MAX_NEG_CROP;
1304
    int sum;
1305

    
1306
    for(;size > 0;size--) {
1307
        sum = -lum_m4[0];
1308
        sum += lum_m3[0] << 2;
1309
        sum += lum_m2[0] << 1;
1310
        sum += lum_m1[0] << 2;
1311
        sum += -lum[0];
1312
        dst[0] = cm[(sum + 4) >> 3];
1313
        lum_m4++;
1314
        lum_m3++;
1315
        lum_m2++;
1316
        lum_m1++;
1317
        lum++;
1318
        dst++;
1319
    }
1320
#else
1321

    
1322
    {
1323
        pxor_r2r(mm7,mm7);
1324
        movq_m2r(ff_pw_4,mm6);
1325
    }
1326
    for (;size > 3; size-=4) {
1327
        DEINT_LINE_LUM
1328
        lum_m4+=4;
1329
        lum_m3+=4;
1330
        lum_m2+=4;
1331
        lum_m1+=4;
1332
        lum+=4;
1333
        dst+=4;
1334
    }
1335
#endif
1336
}
1337
static void deinterlace_line_inplace(uint8_t *lum_m4, uint8_t *lum_m3, uint8_t *lum_m2, uint8_t *lum_m1, uint8_t *lum,
1338
                             int size)
1339
{
1340
#if !HAVE_MMX
1341
    uint8_t *cm = ff_cropTbl + MAX_NEG_CROP;
1342
    int sum;
1343

    
1344
    for(;size > 0;size--) {
1345
        sum = -lum_m4[0];
1346
        sum += lum_m3[0] << 2;
1347
        sum += lum_m2[0] << 1;
1348
        lum_m4[0]=lum_m2[0];
1349
        sum += lum_m1[0] << 2;
1350
        sum += -lum[0];
1351
        lum_m2[0] = cm[(sum + 4) >> 3];
1352
        lum_m4++;
1353
        lum_m3++;
1354
        lum_m2++;
1355
        lum_m1++;
1356
        lum++;
1357
    }
1358
#else
1359

    
1360
    {
1361
        pxor_r2r(mm7,mm7);
1362
        movq_m2r(ff_pw_4,mm6);
1363
    }
1364
    for (;size > 3; size-=4) {
1365
        DEINT_INPLACE_LINE_LUM
1366
        lum_m4+=4;
1367
        lum_m3+=4;
1368
        lum_m2+=4;
1369
        lum_m1+=4;
1370
        lum+=4;
1371
    }
1372
#endif
1373
}
1374

    
1375
/* deinterlacing : 2 temporal taps, 3 spatial taps linear filter. The
1376
   top field is copied as is, but the bottom field is deinterlaced
1377
   against the top field. */
1378
static void deinterlace_bottom_field(uint8_t *dst, int dst_wrap,
1379
                                    const uint8_t *src1, int src_wrap,
1380
                                    int width, int height)
1381
{
1382
    const uint8_t *src_m2, *src_m1, *src_0, *src_p1, *src_p2;
1383
    int y;
1384

    
1385
    src_m2 = src1;
1386
    src_m1 = src1;
1387
    src_0=&src_m1[src_wrap];
1388
    src_p1=&src_0[src_wrap];
1389
    src_p2=&src_p1[src_wrap];
1390
    for(y=0;y<(height-2);y+=2) {
1391
        memcpy(dst,src_m1,width);
1392
        dst += dst_wrap;
1393
        deinterlace_line(dst,src_m2,src_m1,src_0,src_p1,src_p2,width);
1394
        src_m2 = src_0;
1395
        src_m1 = src_p1;
1396
        src_0 = src_p2;
1397
        src_p1 += 2*src_wrap;
1398
        src_p2 += 2*src_wrap;
1399
        dst += dst_wrap;
1400
    }
1401
    memcpy(dst,src_m1,width);
1402
    dst += dst_wrap;
1403
    /* do last line */
1404
    deinterlace_line(dst,src_m2,src_m1,src_0,src_0,src_0,width);
1405
}
1406

    
1407
static void deinterlace_bottom_field_inplace(uint8_t *src1, int src_wrap,
1408
                                             int width, int height)
1409
{
1410
    uint8_t *src_m1, *src_0, *src_p1, *src_p2;
1411
    int y;
1412
    uint8_t *buf;
1413
    buf = (uint8_t*)av_malloc(width);
1414

    
1415
    src_m1 = src1;
1416
    memcpy(buf,src_m1,width);
1417
    src_0=&src_m1[src_wrap];
1418
    src_p1=&src_0[src_wrap];
1419
    src_p2=&src_p1[src_wrap];
1420
    for(y=0;y<(height-2);y+=2) {
1421
        deinterlace_line_inplace(buf,src_m1,src_0,src_p1,src_p2,width);
1422
        src_m1 = src_p1;
1423
        src_0 = src_p2;
1424
        src_p1 += 2*src_wrap;
1425
        src_p2 += 2*src_wrap;
1426
    }
1427
    /* do last line */
1428
    deinterlace_line_inplace(buf,src_m1,src_0,src_0,src_0,width);
1429
    av_free(buf);
1430
}
1431

    
1432
int avpicture_deinterlace(AVPicture *dst, const AVPicture *src,
1433
                          enum PixelFormat pix_fmt, int width, int height)
1434
{
1435
    int i;
1436

    
1437
    if (pix_fmt != PIX_FMT_YUV420P &&
1438
        pix_fmt != PIX_FMT_YUV422P &&
1439
        pix_fmt != PIX_FMT_YUV444P &&
1440
        pix_fmt != PIX_FMT_YUV411P &&
1441
        pix_fmt != PIX_FMT_GRAY8)
1442
        return -1;
1443
    if ((width & 3) != 0 || (height & 3) != 0)
1444
        return -1;
1445

    
1446
    for(i=0;i<3;i++) {
1447
        if (i == 1) {
1448
            switch(pix_fmt) {
1449
            case PIX_FMT_YUV420P:
1450
                width >>= 1;
1451
                height >>= 1;
1452
                break;
1453
            case PIX_FMT_YUV422P:
1454
                width >>= 1;
1455
                break;
1456
            case PIX_FMT_YUV411P:
1457
                width >>= 2;
1458
                break;
1459
            default:
1460
                break;
1461
            }
1462
            if (pix_fmt == PIX_FMT_GRAY8) {
1463
                break;
1464
            }
1465
        }
1466
        if (src == dst) {
1467
            deinterlace_bottom_field_inplace(dst->data[i], dst->linesize[i],
1468
                                 width, height);
1469
        } else {
1470
            deinterlace_bottom_field(dst->data[i],dst->linesize[i],
1471
                                        src->data[i], src->linesize[i],
1472
                                        width, height);
1473
        }
1474
    }
1475
    emms_c();
1476
    return 0;
1477
}
1478