Statistics
| Branch: | Revision:

ffmpeg / libavcodec / imgconvert.c @ b435725b

History | View | Annotate | Download (43 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

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

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

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

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

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

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

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

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

    
178
    /* RGB formats */
179
    [PIX_FMT_RGB24] = {
180
        .name = "rgb24",
181
        .nb_channels = 3,
182
        .color_type = FF_COLOR_RGB,
183
        .pixel_type = FF_PIXEL_PACKED,
184
        .depth = 8,
185
        .x_chroma_shift = 0, .y_chroma_shift = 0,
186
    },
187
    [PIX_FMT_BGR24] = {
188
        .name = "bgr24",
189
        .nb_channels = 3,
190
        .color_type = FF_COLOR_RGB,
191
        .pixel_type = FF_PIXEL_PACKED,
192
        .depth = 8,
193
        .x_chroma_shift = 0, .y_chroma_shift = 0,
194
    },
195
    [PIX_FMT_RGB32] = {
196
        .name = "rgb32",
197
        .nb_channels = 4, .is_alpha = 1,
198
        .color_type = FF_COLOR_RGB,
199
        .pixel_type = FF_PIXEL_PACKED,
200
        .depth = 8,
201
        .x_chroma_shift = 0, .y_chroma_shift = 0,
202
    },
203
    [PIX_FMT_RGB48BE] = {
204
        .name = "rgb48be",
205
        .nb_channels = 3,
206
        .color_type = FF_COLOR_RGB,
207
        .pixel_type = FF_PIXEL_PACKED,
208
        .depth = 16,
209
        .x_chroma_shift = 0, .y_chroma_shift = 0,
210
    },
211
    [PIX_FMT_RGB48LE] = {
212
        .name = "rgb48le",
213
        .nb_channels = 3,
214
        .color_type = FF_COLOR_RGB,
215
        .pixel_type = FF_PIXEL_PACKED,
216
        .depth = 16,
217
        .x_chroma_shift = 0, .y_chroma_shift = 0,
218
    },
219
    [PIX_FMT_RGB565] = {
220
        .name = "rgb565",
221
        .nb_channels = 3,
222
        .color_type = FF_COLOR_RGB,
223
        .pixel_type = FF_PIXEL_PACKED,
224
        .depth = 5,
225
        .x_chroma_shift = 0, .y_chroma_shift = 0,
226
    },
227
    [PIX_FMT_RGB555] = {
228
        .name = "rgb555",
229
        .nb_channels = 3,
230
        .color_type = FF_COLOR_RGB,
231
        .pixel_type = FF_PIXEL_PACKED,
232
        .depth = 5,
233
        .x_chroma_shift = 0, .y_chroma_shift = 0,
234
    },
235

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

    
273
    /* paletted formats */
274
    [PIX_FMT_PAL8] = {
275
        .name = "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_XVMC_MPEG2_MC] = {
282
        .name = "xvmcmc",
283
        .is_hwaccel = 1,
284
    },
285
    [PIX_FMT_XVMC_MPEG2_IDCT] = {
286
        .name = "xvmcidct",
287
        .is_hwaccel = 1,
288
    },
289
    [PIX_FMT_VDPAU_MPEG1] = {
290
        .name = "vdpau_mpeg1",
291
        .is_hwaccel = 1,
292
        .x_chroma_shift = 1, .y_chroma_shift = 1,
293
    },
294
    [PIX_FMT_VDPAU_MPEG2] = {
295
        .name = "vdpau_mpeg2",
296
        .is_hwaccel = 1,
297
        .x_chroma_shift = 1, .y_chroma_shift = 1,
298
    },
299
    [PIX_FMT_VDPAU_H264] = {
300
        .name = "vdpau_h264",
301
        .is_hwaccel = 1,
302
        .x_chroma_shift = 1, .y_chroma_shift = 1,
303
    },
304
    [PIX_FMT_VDPAU_WMV3] = {
305
        .name = "vdpau_wmv3",
306
        .is_hwaccel = 1,
307
        .x_chroma_shift = 1, .y_chroma_shift = 1,
308
    },
309
    [PIX_FMT_VDPAU_VC1] = {
310
        .name = "vdpau_vc1",
311
        .is_hwaccel = 1,
312
        .x_chroma_shift = 1, .y_chroma_shift = 1,
313
    },
314
    [PIX_FMT_UYYVYY411] = {
315
        .name = "uyyvyy411",
316
        .nb_channels = 1,
317
        .color_type = FF_COLOR_YUV,
318
        .pixel_type = FF_PIXEL_PACKED,
319
        .depth = 8,
320
        .x_chroma_shift = 2, .y_chroma_shift = 0,
321
    },
322
    [PIX_FMT_BGR32] = {
323
        .name = "bgr32",
324
        .nb_channels = 4, .is_alpha = 1,
325
        .color_type = FF_COLOR_RGB,
326
        .pixel_type = FF_PIXEL_PACKED,
327
        .depth = 8,
328
        .x_chroma_shift = 0, .y_chroma_shift = 0,
329
    },
330
    [PIX_FMT_BGR565] = {
331
        .name = "bgr565",
332
        .nb_channels = 3,
333
        .color_type = FF_COLOR_RGB,
334
        .pixel_type = FF_PIXEL_PACKED,
335
        .depth = 5,
336
        .x_chroma_shift = 0, .y_chroma_shift = 0,
337
    },
338
    [PIX_FMT_BGR555] = {
339
        .name = "bgr555",
340
        .nb_channels = 3,
341
        .color_type = FF_COLOR_RGB,
342
        .pixel_type = FF_PIXEL_PACKED,
343
        .depth = 5,
344
        .x_chroma_shift = 0, .y_chroma_shift = 0,
345
    },
346
    [PIX_FMT_RGB8] = {
347
        .name = "rgb8",
348
        .nb_channels = 1,
349
        .color_type = FF_COLOR_RGB,
350
        .pixel_type = FF_PIXEL_PACKED,
351
        .depth = 8,
352
        .x_chroma_shift = 0, .y_chroma_shift = 0,
353
    },
354
    [PIX_FMT_RGB4] = {
355
        .name = "rgb4",
356
        .nb_channels = 1,
357
        .color_type = FF_COLOR_RGB,
358
        .pixel_type = FF_PIXEL_PACKED,
359
        .depth = 4,
360
        .x_chroma_shift = 0, .y_chroma_shift = 0,
361
    },
362
    [PIX_FMT_RGB4_BYTE] = {
363
        .name = "rgb4_byte",
364
        .nb_channels = 1,
365
        .color_type = FF_COLOR_RGB,
366
        .pixel_type = FF_PIXEL_PACKED,
367
        .depth = 8,
368
        .x_chroma_shift = 0, .y_chroma_shift = 0,
369
    },
370
    [PIX_FMT_BGR8] = {
371
        .name = "bgr8",
372
        .nb_channels = 1,
373
        .color_type = FF_COLOR_RGB,
374
        .pixel_type = FF_PIXEL_PACKED,
375
        .depth = 8,
376
        .x_chroma_shift = 0, .y_chroma_shift = 0,
377
    },
378
    [PIX_FMT_BGR4] = {
379
        .name = "bgr4",
380
        .nb_channels = 1,
381
        .color_type = FF_COLOR_RGB,
382
        .pixel_type = FF_PIXEL_PACKED,
383
        .depth = 4,
384
        .x_chroma_shift = 0, .y_chroma_shift = 0,
385
    },
386
    [PIX_FMT_BGR4_BYTE] = {
387
        .name = "bgr4_byte",
388
        .nb_channels = 1,
389
        .color_type = FF_COLOR_RGB,
390
        .pixel_type = FF_PIXEL_PACKED,
391
        .depth = 8,
392
        .x_chroma_shift = 0, .y_chroma_shift = 0,
393
    },
394
    [PIX_FMT_NV12] = {
395
        .name = "nv12",
396
        .nb_channels = 2,
397
        .color_type = FF_COLOR_YUV,
398
        .pixel_type = FF_PIXEL_PLANAR,
399
        .depth = 8,
400
        .x_chroma_shift = 1, .y_chroma_shift = 1,
401
    },
402
    [PIX_FMT_NV21] = {
403
        .name = "nv12",
404
        .nb_channels = 2,
405
        .color_type = FF_COLOR_YUV,
406
        .pixel_type = FF_PIXEL_PLANAR,
407
        .depth = 8,
408
        .x_chroma_shift = 1, .y_chroma_shift = 1,
409
    },
410

    
411
    [PIX_FMT_BGR32_1] = {
412
        .name = "bgr32_1",
413
        .nb_channels = 4, .is_alpha = 1,
414
        .color_type = FF_COLOR_RGB,
415
        .pixel_type = FF_PIXEL_PACKED,
416
        .depth = 8,
417
        .x_chroma_shift = 0, .y_chroma_shift = 0,
418
    },
419
    [PIX_FMT_RGB32_1] = {
420
        .name = "rgb32_1",
421
        .nb_channels = 4, .is_alpha = 1,
422
        .color_type = FF_COLOR_RGB,
423
        .pixel_type = FF_PIXEL_PACKED,
424
        .depth = 8,
425
        .x_chroma_shift = 0, .y_chroma_shift = 0,
426
    },
427

    
428
    /* VA API formats */
429
    [PIX_FMT_VAAPI_MOCO] = {
430
        .name = "vaapi_moco",
431
        .is_hwaccel = 1,
432
        .x_chroma_shift = 1, .y_chroma_shift = 1,
433
    },
434
    [PIX_FMT_VAAPI_IDCT] = {
435
        .name = "vaapi_idct",
436
        .is_hwaccel = 1,
437
        .x_chroma_shift = 1, .y_chroma_shift = 1,
438
    },
439
    [PIX_FMT_VAAPI_VLD] = {
440
        .name = "vaapi_vld",
441
        .is_hwaccel = 1,
442
        .x_chroma_shift = 1, .y_chroma_shift = 1,
443
    },
444
};
445

    
446
void avcodec_get_chroma_sub_sample(int pix_fmt, int *h_shift, int *v_shift)
447
{
448
    *h_shift = pix_fmt_info[pix_fmt].x_chroma_shift;
449
    *v_shift = pix_fmt_info[pix_fmt].y_chroma_shift;
450
}
451

    
452
const char *avcodec_get_pix_fmt_name(int pix_fmt)
453
{
454
    if (pix_fmt < 0 || pix_fmt >= PIX_FMT_NB)
455
        return NULL;
456
    else
457
        return pix_fmt_info[pix_fmt].name;
458
}
459

    
460
enum PixelFormat avcodec_get_pix_fmt(const char* name)
461
{
462
    int i;
463

    
464
    for (i=0; i < PIX_FMT_NB; i++)
465
         if (!strcmp(pix_fmt_info[i].name, name))
466
             return i;
467
    return PIX_FMT_NONE;
468
}
469

    
470
void avcodec_pix_fmt_string (char *buf, int buf_size, int pix_fmt)
471
{
472
    /* print header */
473
    if (pix_fmt < 0)
474
        snprintf (buf, buf_size,
475
                  "name      " " nb_channels" " depth" " is_alpha"
476
            );
477
    else{
478
        PixFmtInfo info= pix_fmt_info[pix_fmt];
479

    
480
        char is_alpha_char= info.is_alpha ? 'y' : 'n';
481

    
482
        snprintf (buf, buf_size,
483
                  "%-10s" "      %1d     " "   %2d " "     %c   ",
484
                  info.name,
485
                  info.nb_channels,
486
                  info.depth,
487
                  is_alpha_char
488
            );
489
    }
490
}
491

    
492
int ff_is_hwaccel_pix_fmt(enum PixelFormat pix_fmt)
493
{
494
    return pix_fmt_info[pix_fmt].is_hwaccel;
495
}
496

    
497
int ff_set_systematic_pal(uint32_t pal[256], enum PixelFormat pix_fmt){
498
    int i;
499

    
500
    for(i=0; i<256; i++){
501
        int r,g,b;
502

    
503
        switch(pix_fmt) {
504
        case PIX_FMT_RGB8:
505
            r= (i>>5    )*36;
506
            g= ((i>>2)&7)*36;
507
            b= (i&3     )*85;
508
            break;
509
        case PIX_FMT_BGR8:
510
            b= (i>>6    )*85;
511
            g= ((i>>3)&7)*36;
512
            r= (i&7     )*36;
513
            break;
514
        case PIX_FMT_RGB4_BYTE:
515
            r= (i>>3    )*255;
516
            g= ((i>>1)&3)*85;
517
            b= (i&1     )*255;
518
            break;
519
        case PIX_FMT_BGR4_BYTE:
520
            b= (i>>3    )*255;
521
            g= ((i>>1)&3)*85;
522
            r= (i&1     )*255;
523
            break;
524
        case PIX_FMT_GRAY8:
525
            r=b=g= i;
526
            break;
527
        default:
528
            return -1;
529
        }
530
        pal[i] =  b + (g<<8) + (r<<16);
531
    }
532

    
533
    return 0;
534
}
535

    
536
int ff_fill_linesize(AVPicture *picture, int pix_fmt, int width)
537
{
538
    int w2;
539
    const PixFmtInfo *pinfo;
540

    
541
    memset(picture->linesize, 0, sizeof(picture->linesize));
542

    
543
    pinfo = &pix_fmt_info[pix_fmt];
544
    switch(pix_fmt) {
545
    case PIX_FMT_YUV420P:
546
    case PIX_FMT_YUV422P:
547
    case PIX_FMT_YUV444P:
548
    case PIX_FMT_YUV410P:
549
    case PIX_FMT_YUV411P:
550
    case PIX_FMT_YUV440P:
551
    case PIX_FMT_YUVJ420P:
552
    case PIX_FMT_YUVJ422P:
553
    case PIX_FMT_YUVJ444P:
554
    case PIX_FMT_YUVJ440P:
555
        w2 = (width + (1 << pinfo->x_chroma_shift) - 1) >> pinfo->x_chroma_shift;
556
        picture->linesize[0] = width;
557
        picture->linesize[1] = w2;
558
        picture->linesize[2] = w2;
559
        break;
560
    case PIX_FMT_YUVA420P:
561
        w2 = (width + (1 << pinfo->x_chroma_shift) - 1) >> pinfo->x_chroma_shift;
562
        picture->linesize[0] = width;
563
        picture->linesize[1] = w2;
564
        picture->linesize[2] = w2;
565
        picture->linesize[3] = width;
566
        break;
567
    case PIX_FMT_NV12:
568
    case PIX_FMT_NV21:
569
        w2 = (width + (1 << pinfo->x_chroma_shift) - 1) >> pinfo->x_chroma_shift;
570
        picture->linesize[0] = width;
571
        picture->linesize[1] = w2;
572
        break;
573
    case PIX_FMT_RGB24:
574
    case PIX_FMT_BGR24:
575
        picture->linesize[0] = width * 3;
576
        break;
577
    case PIX_FMT_RGB32:
578
    case PIX_FMT_BGR32:
579
    case PIX_FMT_RGB32_1:
580
    case PIX_FMT_BGR32_1:
581
        picture->linesize[0] = width * 4;
582
        break;
583
    case PIX_FMT_RGB48BE:
584
    case PIX_FMT_RGB48LE:
585
        picture->linesize[0] = width * 6;
586
        break;
587
    case PIX_FMT_GRAY16BE:
588
    case PIX_FMT_GRAY16LE:
589
    case PIX_FMT_BGR555:
590
    case PIX_FMT_BGR565:
591
    case PIX_FMT_RGB555:
592
    case PIX_FMT_RGB565:
593
    case PIX_FMT_YUYV422:
594
        picture->linesize[0] = width * 2;
595
        break;
596
    case PIX_FMT_UYVY422:
597
        picture->linesize[0] = width * 2;
598
        break;
599
    case PIX_FMT_UYYVYY411:
600
        picture->linesize[0] = width + width/2;
601
        break;
602
    case PIX_FMT_RGB4:
603
    case PIX_FMT_BGR4:
604
        picture->linesize[0] = width / 2;
605
        break;
606
    case PIX_FMT_MONOWHITE:
607
    case PIX_FMT_MONOBLACK:
608
        picture->linesize[0] = (width + 7) >> 3;
609
        break;
610
    case PIX_FMT_PAL8:
611
    case PIX_FMT_RGB8:
612
    case PIX_FMT_BGR8:
613
    case PIX_FMT_RGB4_BYTE:
614
    case PIX_FMT_BGR4_BYTE:
615
    case PIX_FMT_GRAY8:
616
        picture->linesize[0] = width;
617
        break;
618
    default:
619
        return -1;
620
    }
621
    return 0;
622
}
623

    
624
int ff_fill_pointer(AVPicture *picture, uint8_t *ptr, int pix_fmt,
625
                    int height)
626
{
627
    int size, h2, size2;
628
    const PixFmtInfo *pinfo;
629

    
630
    pinfo = &pix_fmt_info[pix_fmt];
631
    size = picture->linesize[0] * height;
632
    switch(pix_fmt) {
633
    case PIX_FMT_YUV420P:
634
    case PIX_FMT_YUV422P:
635
    case PIX_FMT_YUV444P:
636
    case PIX_FMT_YUV410P:
637
    case PIX_FMT_YUV411P:
638
    case PIX_FMT_YUV440P:
639
    case PIX_FMT_YUVJ420P:
640
    case PIX_FMT_YUVJ422P:
641
    case PIX_FMT_YUVJ444P:
642
    case PIX_FMT_YUVJ440P:
643
        h2 = (height + (1 << pinfo->y_chroma_shift) - 1) >> pinfo->y_chroma_shift;
644
        size2 = picture->linesize[1] * h2;
645
        picture->data[0] = ptr;
646
        picture->data[1] = picture->data[0] + size;
647
        picture->data[2] = picture->data[1] + size2;
648
        picture->data[3] = NULL;
649
        return size + 2 * size2;
650
    case PIX_FMT_YUVA420P:
651
        h2 = (height + (1 << pinfo->y_chroma_shift) - 1) >> pinfo->y_chroma_shift;
652
        size2 = picture->linesize[1] * h2;
653
        picture->data[0] = ptr;
654
        picture->data[1] = picture->data[0] + size;
655
        picture->data[2] = picture->data[1] + size2;
656
        picture->data[3] = picture->data[1] + size2 + size2;
657
        return 2 * size + 2 * size2;
658
    case PIX_FMT_NV12:
659
    case PIX_FMT_NV21:
660
        h2 = (height + (1 << pinfo->y_chroma_shift) - 1) >> pinfo->y_chroma_shift;
661
        size2 = picture->linesize[1] * h2 * 2;
662
        picture->data[0] = ptr;
663
        picture->data[1] = picture->data[0] + size;
664
        picture->data[2] = NULL;
665
        picture->data[3] = NULL;
666
        return size + 2 * size2;
667
    case PIX_FMT_RGB24:
668
    case PIX_FMT_BGR24:
669
    case PIX_FMT_RGB32:
670
    case PIX_FMT_BGR32:
671
    case PIX_FMT_RGB32_1:
672
    case PIX_FMT_BGR32_1:
673
    case PIX_FMT_RGB48BE:
674
    case PIX_FMT_RGB48LE:
675
    case PIX_FMT_GRAY16BE:
676
    case PIX_FMT_GRAY16LE:
677
    case PIX_FMT_BGR555:
678
    case PIX_FMT_BGR565:
679
    case PIX_FMT_RGB555:
680
    case PIX_FMT_RGB565:
681
    case PIX_FMT_YUYV422:
682
    case PIX_FMT_UYVY422:
683
    case PIX_FMT_UYYVYY411:
684
    case PIX_FMT_RGB4:
685
    case PIX_FMT_BGR4:
686
    case PIX_FMT_MONOWHITE:
687
    case PIX_FMT_MONOBLACK:
688
        picture->data[0] = ptr;
689
        picture->data[1] = NULL;
690
        picture->data[2] = NULL;
691
        picture->data[3] = NULL;
692
        return size;
693
    case PIX_FMT_PAL8:
694
    case PIX_FMT_RGB8:
695
    case PIX_FMT_BGR8:
696
    case PIX_FMT_RGB4_BYTE:
697
    case PIX_FMT_BGR4_BYTE:
698
    case PIX_FMT_GRAY8:
699
        size2 = (size + 3) & ~3;
700
        picture->data[0] = ptr;
701
        picture->data[1] = ptr + size2; /* palette is stored here as 256 32 bit words */
702
        picture->data[2] = NULL;
703
        picture->data[3] = NULL;
704
        return size2 + 256 * 4;
705
    default:
706
        picture->data[0] = NULL;
707
        picture->data[1] = NULL;
708
        picture->data[2] = NULL;
709
        picture->data[3] = NULL;
710
        return -1;
711
    }
712
}
713

    
714
int avpicture_fill(AVPicture *picture, uint8_t *ptr,
715
                   int pix_fmt, int width, int height)
716
{
717

    
718
    if(avcodec_check_dimensions(NULL, width, height))
719
        return -1;
720

    
721
    if (ff_fill_linesize(picture, pix_fmt, width))
722
        return -1;
723

    
724
    return ff_fill_pointer(picture, ptr, pix_fmt, height);
725
}
726

    
727
int avpicture_layout(const AVPicture* src, int pix_fmt, int width, int height,
728
                     unsigned char *dest, int dest_size)
729
{
730
    const PixFmtInfo* pf = &pix_fmt_info[pix_fmt];
731
    int i, j, w, ow, h, oh, data_planes;
732
    const unsigned char* s;
733
    int size = avpicture_get_size(pix_fmt, width, height);
734

    
735
    if (size > dest_size || size < 0)
736
        return -1;
737

    
738
    if (pf->pixel_type == FF_PIXEL_PACKED || pf->pixel_type == FF_PIXEL_PALETTE) {
739
        if (pix_fmt == PIX_FMT_YUYV422 ||
740
            pix_fmt == PIX_FMT_UYVY422 ||
741
            pix_fmt == PIX_FMT_BGR565 ||
742
            pix_fmt == PIX_FMT_BGR555 ||
743
            pix_fmt == PIX_FMT_RGB565 ||
744
            pix_fmt == PIX_FMT_RGB555)
745
            w = width * 2;
746
        else if (pix_fmt == PIX_FMT_UYYVYY411)
747
          w = width + width/2;
748
        else if (pix_fmt == PIX_FMT_PAL8)
749
          w = width;
750
        else
751
          w = width * (pf->depth * pf->nb_channels / 8);
752

    
753
        data_planes = 1;
754
        h = height;
755
    } else {
756
        data_planes = pf->nb_channels;
757
        w = (width*pf->depth + 7)/8;
758
        h = height;
759
    }
760

    
761
    ow = w;
762
    oh = h;
763

    
764
    for (i=0; i<data_planes; i++) {
765
         if (i == 1) {
766
             w = width >> pf->x_chroma_shift;
767
             h = height >> pf->y_chroma_shift;
768
         } else if (i == 3) {
769
             w = ow;
770
             h = oh;
771
         }
772
         s = src->data[i];
773
         for(j=0; j<h; j++) {
774
             memcpy(dest, s, w);
775
             dest += w;
776
             s += src->linesize[i];
777
         }
778
    }
779

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

    
783
    return size;
784
}
785

    
786
int avpicture_get_size(int pix_fmt, int width, int height)
787
{
788
    AVPicture dummy_pict;
789
    return avpicture_fill(&dummy_pict, NULL, pix_fmt, width, height);
790
}
791

    
792
int avcodec_get_pix_fmt_loss(int dst_pix_fmt, int src_pix_fmt,
793
                             int has_alpha)
794
{
795
    const PixFmtInfo *pf, *ps;
796
    int loss;
797

    
798
    ps = &pix_fmt_info[src_pix_fmt];
799
    pf = &pix_fmt_info[dst_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_RGB555 && src_pix_fmt == PIX_FMT_RGB565))
806
        loss |= FF_LOSS_DEPTH;
807
    if (pf->x_chroma_shift > ps->x_chroma_shift ||
808
        pf->y_chroma_shift > ps->y_chroma_shift)
809
        loss |= FF_LOSS_RESOLUTION;
810
    switch(pf->color_type) {
811
    case FF_COLOR_RGB:
812
        if (ps->color_type != FF_COLOR_RGB &&
813
            ps->color_type != FF_COLOR_GRAY)
814
            loss |= FF_LOSS_COLORSPACE;
815
        break;
816
    case FF_COLOR_GRAY:
817
        if (ps->color_type != FF_COLOR_GRAY)
818
            loss |= FF_LOSS_COLORSPACE;
819
        break;
820
    case FF_COLOR_YUV:
821
        if (ps->color_type != FF_COLOR_YUV)
822
            loss |= FF_LOSS_COLORSPACE;
823
        break;
824
    case FF_COLOR_YUV_JPEG:
825
        if (ps->color_type != FF_COLOR_YUV_JPEG &&
826
            ps->color_type != FF_COLOR_YUV &&
827
            ps->color_type != FF_COLOR_GRAY)
828
            loss |= FF_LOSS_COLORSPACE;
829
        break;
830
    default:
831
        /* fail safe test */
832
        if (ps->color_type != pf->color_type)
833
            loss |= FF_LOSS_COLORSPACE;
834
        break;
835
    }
836
    if (pf->color_type == FF_COLOR_GRAY &&
837
        ps->color_type != FF_COLOR_GRAY)
838
        loss |= FF_LOSS_CHROMA;
839
    if (!pf->is_alpha && (ps->is_alpha && has_alpha))
840
        loss |= FF_LOSS_ALPHA;
841
    if (pf->pixel_type == FF_PIXEL_PALETTE &&
842
        (ps->pixel_type != FF_PIXEL_PALETTE && ps->color_type != FF_COLOR_GRAY))
843
        loss |= FF_LOSS_COLORQUANT;
844
    return loss;
845
}
846

    
847
static int avg_bits_per_pixel(int pix_fmt)
848
{
849
    int bits;
850
    const PixFmtInfo *pf;
851

    
852
    pf = &pix_fmt_info[pix_fmt];
853
    switch(pf->pixel_type) {
854
    case FF_PIXEL_PACKED:
855
        switch(pix_fmt) {
856
        case PIX_FMT_YUYV422:
857
        case PIX_FMT_UYVY422:
858
        case PIX_FMT_RGB565:
859
        case PIX_FMT_RGB555:
860
        case PIX_FMT_BGR565:
861
        case PIX_FMT_BGR555:
862
            bits = 16;
863
            break;
864
        case PIX_FMT_UYYVYY411:
865
            bits = 12;
866
            break;
867
        default:
868
            bits = pf->depth * pf->nb_channels;
869
            break;
870
        }
871
        break;
872
    case FF_PIXEL_PLANAR:
873
        if (pf->x_chroma_shift == 0 && pf->y_chroma_shift == 0) {
874
            bits = pf->depth * pf->nb_channels;
875
        } else {
876
            bits = pf->depth + ((2 * pf->depth) >>
877
                                (pf->x_chroma_shift + pf->y_chroma_shift));
878
        }
879
        break;
880
    case FF_PIXEL_PALETTE:
881
        bits = 8;
882
        break;
883
    default:
884
        bits = -1;
885
        break;
886
    }
887
    return bits;
888
}
889

    
890
static int avcodec_find_best_pix_fmt1(int64_t pix_fmt_mask,
891
                                      int src_pix_fmt,
892
                                      int has_alpha,
893
                                      int loss_mask)
894
{
895
    int dist, i, loss, min_dist, dst_pix_fmt;
896

    
897
    /* find exact color match with smallest size */
898
    dst_pix_fmt = -1;
899
    min_dist = 0x7fffffff;
900
    for(i = 0;i < PIX_FMT_NB; i++) {
901
        if (pix_fmt_mask & (1ULL << i)) {
902
            loss = avcodec_get_pix_fmt_loss(i, src_pix_fmt, has_alpha) & loss_mask;
903
            if (loss == 0) {
904
                dist = avg_bits_per_pixel(i);
905
                if (dist < min_dist) {
906
                    min_dist = dist;
907
                    dst_pix_fmt = i;
908
                }
909
            }
910
        }
911
    }
912
    return dst_pix_fmt;
913
}
914

    
915
int avcodec_find_best_pix_fmt(int64_t pix_fmt_mask, int src_pix_fmt,
916
                              int has_alpha, int *loss_ptr)
917
{
918
    int dst_pix_fmt, loss_mask, i;
919
    static const int loss_mask_order[] = {
920
        ~0, /* no loss first */
921
        ~FF_LOSS_ALPHA,
922
        ~FF_LOSS_RESOLUTION,
923
        ~(FF_LOSS_COLORSPACE | FF_LOSS_RESOLUTION),
924
        ~FF_LOSS_COLORQUANT,
925
        ~FF_LOSS_DEPTH,
926
        0,
927
    };
928

    
929
    /* try with successive loss */
930
    i = 0;
931
    for(;;) {
932
        loss_mask = loss_mask_order[i++];
933
        dst_pix_fmt = avcodec_find_best_pix_fmt1(pix_fmt_mask, src_pix_fmt,
934
                                                 has_alpha, loss_mask);
935
        if (dst_pix_fmt >= 0)
936
            goto found;
937
        if (loss_mask == 0)
938
            break;
939
    }
940
    return -1;
941
 found:
942
    if (loss_ptr)
943
        *loss_ptr = avcodec_get_pix_fmt_loss(dst_pix_fmt, src_pix_fmt, has_alpha);
944
    return dst_pix_fmt;
945
}
946

    
947
void ff_img_copy_plane(uint8_t *dst, int dst_wrap,
948
                           const uint8_t *src, int src_wrap,
949
                           int width, int height)
950
{
951
    if((!dst) || (!src))
952
        return;
953
    for(;height > 0; height--) {
954
        memcpy(dst, src, width);
955
        dst += dst_wrap;
956
        src += src_wrap;
957
    }
958
}
959

    
960
int ff_get_plane_bytewidth(enum PixelFormat pix_fmt, int width, int plane)
961
{
962
    int bits;
963
    const PixFmtInfo *pf = &pix_fmt_info[pix_fmt];
964

    
965
    pf = &pix_fmt_info[pix_fmt];
966
    switch(pf->pixel_type) {
967
    case FF_PIXEL_PACKED:
968
        switch(pix_fmt) {
969
        case PIX_FMT_YUYV422:
970
        case PIX_FMT_UYVY422:
971
        case PIX_FMT_RGB565:
972
        case PIX_FMT_RGB555:
973
        case PIX_FMT_BGR565:
974
        case PIX_FMT_BGR555:
975
            bits = 16;
976
            break;
977
        case PIX_FMT_UYYVYY411:
978
            bits = 12;
979
            break;
980
        default:
981
            bits = pf->depth * pf->nb_channels;
982
            break;
983
        }
984
        return (width * bits + 7) >> 3;
985
        break;
986
    case FF_PIXEL_PLANAR:
987
            if (plane == 1 || plane == 2)
988
                width= -((-width)>>pf->x_chroma_shift);
989

    
990
            return (width * pf->depth + 7) >> 3;
991
        break;
992
    case FF_PIXEL_PALETTE:
993
        if (plane == 0)
994
            return width;
995
        break;
996
    }
997

    
998
    return -1;
999
}
1000

    
1001
void av_picture_copy(AVPicture *dst, const AVPicture *src,
1002
              int pix_fmt, int width, int height)
1003
{
1004
    int i;
1005
    const PixFmtInfo *pf = &pix_fmt_info[pix_fmt];
1006

    
1007
    pf = &pix_fmt_info[pix_fmt];
1008
    switch(pf->pixel_type) {
1009
    case FF_PIXEL_PACKED:
1010
    case FF_PIXEL_PLANAR:
1011
        for(i = 0; i < pf->nb_channels; i++) {
1012
            int h;
1013
            int bwidth = ff_get_plane_bytewidth(pix_fmt, width, i);
1014
            h = height;
1015
            if (i == 1 || i == 2) {
1016
                h= -((-height)>>pf->y_chroma_shift);
1017
            }
1018
            ff_img_copy_plane(dst->data[i], dst->linesize[i],
1019
                           src->data[i], src->linesize[i],
1020
                           bwidth, h);
1021
        }
1022
        break;
1023
    case FF_PIXEL_PALETTE:
1024
        ff_img_copy_plane(dst->data[0], dst->linesize[0],
1025
                       src->data[0], src->linesize[0],
1026
                       width, height);
1027
        /* copy the palette */
1028
        ff_img_copy_plane(dst->data[1], dst->linesize[1],
1029
                       src->data[1], src->linesize[1],
1030
                       4, 256);
1031
        break;
1032
    }
1033
}
1034

    
1035
/* 2x2 -> 1x1 */
1036
void ff_shrink22(uint8_t *dst, int dst_wrap,
1037
                     const uint8_t *src, int src_wrap,
1038
                     int width, int height)
1039
{
1040
    int w;
1041
    const uint8_t *s1, *s2;
1042
    uint8_t *d;
1043

    
1044
    for(;height > 0; height--) {
1045
        s1 = src;
1046
        s2 = s1 + src_wrap;
1047
        d = dst;
1048
        for(w = width;w >= 4; w-=4) {
1049
            d[0] = (s1[0] + s1[1] + s2[0] + s2[1] + 2) >> 2;
1050
            d[1] = (s1[2] + s1[3] + s2[2] + s2[3] + 2) >> 2;
1051
            d[2] = (s1[4] + s1[5] + s2[4] + s2[5] + 2) >> 2;
1052
            d[3] = (s1[6] + s1[7] + s2[6] + s2[7] + 2) >> 2;
1053
            s1 += 8;
1054
            s2 += 8;
1055
            d += 4;
1056
        }
1057
        for(;w > 0; w--) {
1058
            d[0] = (s1[0] + s1[1] + s2[0] + s2[1] + 2) >> 2;
1059
            s1 += 2;
1060
            s2 += 2;
1061
            d++;
1062
        }
1063
        src += 2 * src_wrap;
1064
        dst += dst_wrap;
1065
    }
1066
}
1067

    
1068
/* 4x4 -> 1x1 */
1069
void ff_shrink44(uint8_t *dst, int dst_wrap,
1070
                     const uint8_t *src, int src_wrap,
1071
                     int width, int height)
1072
{
1073
    int w;
1074
    const uint8_t *s1, *s2, *s3, *s4;
1075
    uint8_t *d;
1076

    
1077
    for(;height > 0; height--) {
1078
        s1 = src;
1079
        s2 = s1 + src_wrap;
1080
        s3 = s2 + src_wrap;
1081
        s4 = s3 + src_wrap;
1082
        d = dst;
1083
        for(w = width;w > 0; w--) {
1084
            d[0] = (s1[0] + s1[1] + s1[2] + s1[3] +
1085
                    s2[0] + s2[1] + s2[2] + s2[3] +
1086
                    s3[0] + s3[1] + s3[2] + s3[3] +
1087
                    s4[0] + s4[1] + s4[2] + s4[3] + 8) >> 4;
1088
            s1 += 4;
1089
            s2 += 4;
1090
            s3 += 4;
1091
            s4 += 4;
1092
            d++;
1093
        }
1094
        src += 4 * src_wrap;
1095
        dst += dst_wrap;
1096
    }
1097
}
1098

    
1099
/* 8x8 -> 1x1 */
1100
void ff_shrink88(uint8_t *dst, int dst_wrap,
1101
                     const uint8_t *src, int src_wrap,
1102
                     int width, int height)
1103
{
1104
    int w, i;
1105

    
1106
    for(;height > 0; height--) {
1107
        for(w = width;w > 0; w--) {
1108
            int tmp=0;
1109
            for(i=0; i<8; i++){
1110
                tmp += src[0] + src[1] + src[2] + src[3] + src[4] + src[5] + src[6] + src[7];
1111
                src += src_wrap;
1112
            }
1113
            *(dst++) = (tmp + 32)>>6;
1114
            src += 8 - 8*src_wrap;
1115
        }
1116
        src += 8*src_wrap - 8*width;
1117
        dst += dst_wrap - width;
1118
    }
1119
}
1120

    
1121

    
1122
int avpicture_alloc(AVPicture *picture,
1123
                           int pix_fmt, int width, int height)
1124
{
1125
    int size;
1126
    void *ptr;
1127

    
1128
    size = avpicture_get_size(pix_fmt, width, height);
1129
    if(size<0)
1130
        goto fail;
1131
    ptr = av_malloc(size);
1132
    if (!ptr)
1133
        goto fail;
1134
    avpicture_fill(picture, ptr, pix_fmt, width, height);
1135
    if(picture->data[1] && !picture->data[2])
1136
        ff_set_systematic_pal((uint32_t*)picture->data[1], pix_fmt);
1137

    
1138
    return 0;
1139
 fail:
1140
    memset(picture, 0, sizeof(AVPicture));
1141
    return -1;
1142
}
1143

    
1144
void avpicture_free(AVPicture *picture)
1145
{
1146
    av_free(picture->data[0]);
1147
}
1148

    
1149
/* return true if yuv planar */
1150
static inline int is_yuv_planar(const PixFmtInfo *ps)
1151
{
1152
    return (ps->color_type == FF_COLOR_YUV ||
1153
            ps->color_type == FF_COLOR_YUV_JPEG) &&
1154
        ps->pixel_type == FF_PIXEL_PLANAR;
1155
}
1156

    
1157
int av_picture_crop(AVPicture *dst, const AVPicture *src,
1158
              int pix_fmt, int top_band, int left_band)
1159
{
1160
    int y_shift;
1161
    int x_shift;
1162

    
1163
    if (pix_fmt < 0 || pix_fmt >= PIX_FMT_NB || !is_yuv_planar(&pix_fmt_info[pix_fmt]))
1164
        return -1;
1165

    
1166
    y_shift = pix_fmt_info[pix_fmt].y_chroma_shift;
1167
    x_shift = pix_fmt_info[pix_fmt].x_chroma_shift;
1168

    
1169
    dst->data[0] = src->data[0] + (top_band * src->linesize[0]) + left_band;
1170
    dst->data[1] = src->data[1] + ((top_band >> y_shift) * src->linesize[1]) + (left_band >> x_shift);
1171
    dst->data[2] = src->data[2] + ((top_band >> y_shift) * src->linesize[2]) + (left_band >> x_shift);
1172

    
1173
    dst->linesize[0] = src->linesize[0];
1174
    dst->linesize[1] = src->linesize[1];
1175
    dst->linesize[2] = src->linesize[2];
1176
    return 0;
1177
}
1178

    
1179
int av_picture_pad(AVPicture *dst, const AVPicture *src, int height, int width,
1180
            int pix_fmt, int padtop, int padbottom, int padleft, int padright,
1181
            int *color)
1182
{
1183
    uint8_t *optr;
1184
    int y_shift;
1185
    int x_shift;
1186
    int yheight;
1187
    int i, y;
1188

    
1189
    if (pix_fmt < 0 || pix_fmt >= PIX_FMT_NB ||
1190
        !is_yuv_planar(&pix_fmt_info[pix_fmt])) return -1;
1191

    
1192
    for (i = 0; i < 3; i++) {
1193
        x_shift = i ? pix_fmt_info[pix_fmt].x_chroma_shift : 0;
1194
        y_shift = i ? pix_fmt_info[pix_fmt].y_chroma_shift : 0;
1195

    
1196
        if (padtop || padleft) {
1197
            memset(dst->data[i], color[i],
1198
                dst->linesize[i] * (padtop >> y_shift) + (padleft >> x_shift));
1199
        }
1200

    
1201
        if (padleft || padright) {
1202
            optr = dst->data[i] + dst->linesize[i] * (padtop >> y_shift) +
1203
                (dst->linesize[i] - (padright >> x_shift));
1204
            yheight = (height - 1 - (padtop + padbottom)) >> y_shift;
1205
            for (y = 0; y < yheight; y++) {
1206
                memset(optr, color[i], (padleft + padright) >> x_shift);
1207
                optr += dst->linesize[i];
1208
            }
1209
        }
1210

    
1211
        if (src) { /* first line */
1212
            uint8_t *iptr = src->data[i];
1213
            optr = dst->data[i] + dst->linesize[i] * (padtop >> y_shift) +
1214
                    (padleft >> x_shift);
1215
            memcpy(optr, iptr, (width - padleft - padright) >> x_shift);
1216
            iptr += src->linesize[i];
1217
            optr = dst->data[i] + dst->linesize[i] * (padtop >> y_shift) +
1218
                (dst->linesize[i] - (padright >> x_shift));
1219
            yheight = (height - 1 - (padtop + padbottom)) >> y_shift;
1220
            for (y = 0; y < yheight; y++) {
1221
                memset(optr, color[i], (padleft + padright) >> x_shift);
1222
                memcpy(optr + ((padleft + padright) >> x_shift), iptr,
1223
                       (width - padleft - padright) >> x_shift);
1224
                iptr += src->linesize[i];
1225
                optr += dst->linesize[i];
1226
            }
1227
        }
1228

    
1229
        if (padbottom || padright) {
1230
            optr = dst->data[i] + dst->linesize[i] *
1231
                ((height - padbottom) >> y_shift) - (padright >> x_shift);
1232
            memset(optr, color[i],dst->linesize[i] *
1233
                (padbottom >> y_shift) + (padright >> x_shift));
1234
        }
1235
    }
1236
    return 0;
1237
}
1238

    
1239
/* NOTE: we scan all the pixels to have an exact information */
1240
static int get_alpha_info_pal8(const AVPicture *src, int width, int height)
1241
{
1242
    const unsigned char *p;
1243
    int src_wrap, ret, x, y;
1244
    unsigned int a;
1245
    uint32_t *palette = (uint32_t *)src->data[1];
1246

    
1247
    p = src->data[0];
1248
    src_wrap = src->linesize[0] - width;
1249
    ret = 0;
1250
    for(y=0;y<height;y++) {
1251
        for(x=0;x<width;x++) {
1252
            a = palette[p[0]] >> 24;
1253
            if (a == 0x00) {
1254
                ret |= FF_ALPHA_TRANSP;
1255
            } else if (a != 0xff) {
1256
                ret |= FF_ALPHA_SEMI_TRANSP;
1257
            }
1258
            p++;
1259
        }
1260
        p += src_wrap;
1261
    }
1262
    return ret;
1263
}
1264

    
1265
int img_get_alpha_info(const AVPicture *src,
1266
                       int pix_fmt, int width, int height)
1267
{
1268
    const PixFmtInfo *pf = &pix_fmt_info[pix_fmt];
1269
    int ret;
1270

    
1271
    pf = &pix_fmt_info[pix_fmt];
1272
    /* no alpha can be represented in format */
1273
    if (!pf->is_alpha)
1274
        return 0;
1275
    switch(pix_fmt) {
1276
    case PIX_FMT_PAL8:
1277
        ret = get_alpha_info_pal8(src, width, height);
1278
        break;
1279
    default:
1280
        /* we do not know, so everything is indicated */
1281
        ret = FF_ALPHA_TRANSP | FF_ALPHA_SEMI_TRANSP;
1282
        break;
1283
    }
1284
    return ret;
1285
}
1286

    
1287
#if HAVE_MMX
1288
#define DEINT_INPLACE_LINE_LUM \
1289
                    movd_m2r(lum_m4[0],mm0);\
1290
                    movd_m2r(lum_m3[0],mm1);\
1291
                    movd_m2r(lum_m2[0],mm2);\
1292
                    movd_m2r(lum_m1[0],mm3);\
1293
                    movd_m2r(lum[0],mm4);\
1294
                    punpcklbw_r2r(mm7,mm0);\
1295
                    movd_r2m(mm2,lum_m4[0]);\
1296
                    punpcklbw_r2r(mm7,mm1);\
1297
                    punpcklbw_r2r(mm7,mm2);\
1298
                    punpcklbw_r2r(mm7,mm3);\
1299
                    punpcklbw_r2r(mm7,mm4);\
1300
                    paddw_r2r(mm3,mm1);\
1301
                    psllw_i2r(1,mm2);\
1302
                    paddw_r2r(mm4,mm0);\
1303
                    psllw_i2r(2,mm1);\
1304
                    paddw_r2r(mm6,mm2);\
1305
                    paddw_r2r(mm2,mm1);\
1306
                    psubusw_r2r(mm0,mm1);\
1307
                    psrlw_i2r(3,mm1);\
1308
                    packuswb_r2r(mm7,mm1);\
1309
                    movd_r2m(mm1,lum_m2[0]);
1310

    
1311
#define DEINT_LINE_LUM \
1312
                    movd_m2r(lum_m4[0],mm0);\
1313
                    movd_m2r(lum_m3[0],mm1);\
1314
                    movd_m2r(lum_m2[0],mm2);\
1315
                    movd_m2r(lum_m1[0],mm3);\
1316
                    movd_m2r(lum[0],mm4);\
1317
                    punpcklbw_r2r(mm7,mm0);\
1318
                    punpcklbw_r2r(mm7,mm1);\
1319
                    punpcklbw_r2r(mm7,mm2);\
1320
                    punpcklbw_r2r(mm7,mm3);\
1321
                    punpcklbw_r2r(mm7,mm4);\
1322
                    paddw_r2r(mm3,mm1);\
1323
                    psllw_i2r(1,mm2);\
1324
                    paddw_r2r(mm4,mm0);\
1325
                    psllw_i2r(2,mm1);\
1326
                    paddw_r2r(mm6,mm2);\
1327
                    paddw_r2r(mm2,mm1);\
1328
                    psubusw_r2r(mm0,mm1);\
1329
                    psrlw_i2r(3,mm1);\
1330
                    packuswb_r2r(mm7,mm1);\
1331
                    movd_r2m(mm1,dst[0]);
1332
#endif
1333

    
1334
/* filter parameters: [-1 4 2 4 -1] // 8 */
1335
static void deinterlace_line(uint8_t *dst,
1336
                             const uint8_t *lum_m4, const uint8_t *lum_m3,
1337
                             const uint8_t *lum_m2, const uint8_t *lum_m1,
1338
                             const uint8_t *lum,
1339
                             int size)
1340
{
1341
#if !HAVE_MMX
1342
    uint8_t *cm = ff_cropTbl + MAX_NEG_CROP;
1343
    int sum;
1344

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

    
1361
    {
1362
        pxor_r2r(mm7,mm7);
1363
        movq_m2r(ff_pw_4,mm6);
1364
    }
1365
    for (;size > 3; size-=4) {
1366
        DEINT_LINE_LUM
1367
        lum_m4+=4;
1368
        lum_m3+=4;
1369
        lum_m2+=4;
1370
        lum_m1+=4;
1371
        lum+=4;
1372
        dst+=4;
1373
    }
1374
#endif
1375
}
1376
static void deinterlace_line_inplace(uint8_t *lum_m4, uint8_t *lum_m3, uint8_t *lum_m2, uint8_t *lum_m1, uint8_t *lum,
1377
                             int size)
1378
{
1379
#if !HAVE_MMX
1380
    uint8_t *cm = ff_cropTbl + MAX_NEG_CROP;
1381
    int sum;
1382

    
1383
    for(;size > 0;size--) {
1384
        sum = -lum_m4[0];
1385
        sum += lum_m3[0] << 2;
1386
        sum += lum_m2[0] << 1;
1387
        lum_m4[0]=lum_m2[0];
1388
        sum += lum_m1[0] << 2;
1389
        sum += -lum[0];
1390
        lum_m2[0] = cm[(sum + 4) >> 3];
1391
        lum_m4++;
1392
        lum_m3++;
1393
        lum_m2++;
1394
        lum_m1++;
1395
        lum++;
1396
    }
1397
#else
1398

    
1399
    {
1400
        pxor_r2r(mm7,mm7);
1401
        movq_m2r(ff_pw_4,mm6);
1402
    }
1403
    for (;size > 3; size-=4) {
1404
        DEINT_INPLACE_LINE_LUM
1405
        lum_m4+=4;
1406
        lum_m3+=4;
1407
        lum_m2+=4;
1408
        lum_m1+=4;
1409
        lum+=4;
1410
    }
1411
#endif
1412
}
1413

    
1414
/* deinterlacing : 2 temporal taps, 3 spatial taps linear filter. The
1415
   top field is copied as is, but the bottom field is deinterlaced
1416
   against the top field. */
1417
static void deinterlace_bottom_field(uint8_t *dst, int dst_wrap,
1418
                                    const uint8_t *src1, int src_wrap,
1419
                                    int width, int height)
1420
{
1421
    const uint8_t *src_m2, *src_m1, *src_0, *src_p1, *src_p2;
1422
    int y;
1423

    
1424
    src_m2 = src1;
1425
    src_m1 = src1;
1426
    src_0=&src_m1[src_wrap];
1427
    src_p1=&src_0[src_wrap];
1428
    src_p2=&src_p1[src_wrap];
1429
    for(y=0;y<(height-2);y+=2) {
1430
        memcpy(dst,src_m1,width);
1431
        dst += dst_wrap;
1432
        deinterlace_line(dst,src_m2,src_m1,src_0,src_p1,src_p2,width);
1433
        src_m2 = src_0;
1434
        src_m1 = src_p1;
1435
        src_0 = src_p2;
1436
        src_p1 += 2*src_wrap;
1437
        src_p2 += 2*src_wrap;
1438
        dst += dst_wrap;
1439
    }
1440
    memcpy(dst,src_m1,width);
1441
    dst += dst_wrap;
1442
    /* do last line */
1443
    deinterlace_line(dst,src_m2,src_m1,src_0,src_0,src_0,width);
1444
}
1445

    
1446
static void deinterlace_bottom_field_inplace(uint8_t *src1, int src_wrap,
1447
                                             int width, int height)
1448
{
1449
    uint8_t *src_m1, *src_0, *src_p1, *src_p2;
1450
    int y;
1451
    uint8_t *buf;
1452
    buf = (uint8_t*)av_malloc(width);
1453

    
1454
    src_m1 = src1;
1455
    memcpy(buf,src_m1,width);
1456
    src_0=&src_m1[src_wrap];
1457
    src_p1=&src_0[src_wrap];
1458
    src_p2=&src_p1[src_wrap];
1459
    for(y=0;y<(height-2);y+=2) {
1460
        deinterlace_line_inplace(buf,src_m1,src_0,src_p1,src_p2,width);
1461
        src_m1 = src_p1;
1462
        src_0 = src_p2;
1463
        src_p1 += 2*src_wrap;
1464
        src_p2 += 2*src_wrap;
1465
    }
1466
    /* do last line */
1467
    deinterlace_line_inplace(buf,src_m1,src_0,src_0,src_0,width);
1468
    av_free(buf);
1469
}
1470

    
1471
int avpicture_deinterlace(AVPicture *dst, const AVPicture *src,
1472
                          int pix_fmt, int width, int height)
1473
{
1474
    int i;
1475

    
1476
    if (pix_fmt != PIX_FMT_YUV420P &&
1477
        pix_fmt != PIX_FMT_YUV422P &&
1478
        pix_fmt != PIX_FMT_YUV444P &&
1479
        pix_fmt != PIX_FMT_YUV411P &&
1480
        pix_fmt != PIX_FMT_GRAY8)
1481
        return -1;
1482
    if ((width & 3) != 0 || (height & 3) != 0)
1483
        return -1;
1484

    
1485
    for(i=0;i<3;i++) {
1486
        if (i == 1) {
1487
            switch(pix_fmt) {
1488
            case PIX_FMT_YUV420P:
1489
                width >>= 1;
1490
                height >>= 1;
1491
                break;
1492
            case PIX_FMT_YUV422P:
1493
                width >>= 1;
1494
                break;
1495
            case PIX_FMT_YUV411P:
1496
                width >>= 2;
1497
                break;
1498
            default:
1499
                break;
1500
            }
1501
            if (pix_fmt == PIX_FMT_GRAY8) {
1502
                break;
1503
            }
1504
        }
1505
        if (src == dst) {
1506
            deinterlace_bottom_field_inplace(dst->data[i], dst->linesize[i],
1507
                                 width, height);
1508
        } else {
1509
            deinterlace_bottom_field(dst->data[i],dst->linesize[i],
1510
                                        src->data[i], src->linesize[i],
1511
                                        width, height);
1512
        }
1513
    }
1514
    emms_c();
1515
    return 0;
1516
}
1517