Statistics
| Branch: | Revision:

ffmpeg / libavcodec / imgconvert.c @ de481d7f

History | View | Annotate | Download (45.1 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_ARGB] = {
196
        .name = "argb",
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_RGB565BE] = {
220
        .name = "rgb565be",
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_RGB565LE] = {
228
        .name = "rgb565le",
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
    [PIX_FMT_RGB555BE] = {
236
        .name = "rgb555be",
237
        .nb_channels = 3,
238
        .color_type = FF_COLOR_RGB,
239
        .pixel_type = FF_PIXEL_PACKED,
240
        .depth = 5,
241
        .x_chroma_shift = 0, .y_chroma_shift = 0,
242
    },
243
    [PIX_FMT_RGB555LE] = {
244
        .name = "rgb555le",
245
        .nb_channels = 3,
246
        .color_type = FF_COLOR_RGB,
247
        .pixel_type = FF_PIXEL_PACKED,
248
        .depth = 5,
249
        .x_chroma_shift = 0, .y_chroma_shift = 0,
250
    },
251

    
252
    /* gray / mono formats */
253
    [PIX_FMT_GRAY16BE] = {
254
        .name = "gray16be",
255
        .nb_channels = 1,
256
        .color_type = FF_COLOR_GRAY,
257
        .pixel_type = FF_PIXEL_PLANAR,
258
        .depth = 16,
259
    },
260
    [PIX_FMT_GRAY16LE] = {
261
        .name = "gray16le",
262
        .nb_channels = 1,
263
        .color_type = FF_COLOR_GRAY,
264
        .pixel_type = FF_PIXEL_PLANAR,
265
        .depth = 16,
266
    },
267
    [PIX_FMT_GRAY8] = {
268
        .name = "gray",
269
        .nb_channels = 1,
270
        .color_type = FF_COLOR_GRAY,
271
        .pixel_type = FF_PIXEL_PLANAR,
272
        .depth = 8,
273
    },
274
    [PIX_FMT_MONOWHITE] = {
275
        .name = "monow",
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
        .name = "monob",
283
        .nb_channels = 1,
284
        .color_type = FF_COLOR_GRAY,
285
        .pixel_type = FF_PIXEL_PLANAR,
286
        .depth = 1,
287
    },
288

    
289
    /* paletted formats */
290
    [PIX_FMT_PAL8] = {
291
        .name = "pal8",
292
        .nb_channels = 4, .is_alpha = 1,
293
        .color_type = FF_COLOR_RGB,
294
        .pixel_type = FF_PIXEL_PALETTE,
295
        .depth = 8,
296
    },
297
    [PIX_FMT_XVMC_MPEG2_MC] = {
298
        .name = "xvmcmc",
299
        .is_hwaccel = 1,
300
    },
301
    [PIX_FMT_XVMC_MPEG2_IDCT] = {
302
        .name = "xvmcidct",
303
        .is_hwaccel = 1,
304
    },
305
    [PIX_FMT_VDPAU_MPEG1] = {
306
        .name = "vdpau_mpeg1",
307
        .is_hwaccel = 1,
308
        .x_chroma_shift = 1, .y_chroma_shift = 1,
309
    },
310
    [PIX_FMT_VDPAU_MPEG2] = {
311
        .name = "vdpau_mpeg2",
312
        .is_hwaccel = 1,
313
        .x_chroma_shift = 1, .y_chroma_shift = 1,
314
    },
315
    [PIX_FMT_VDPAU_H264] = {
316
        .name = "vdpau_h264",
317
        .is_hwaccel = 1,
318
        .x_chroma_shift = 1, .y_chroma_shift = 1,
319
    },
320
    [PIX_FMT_VDPAU_WMV3] = {
321
        .name = "vdpau_wmv3",
322
        .is_hwaccel = 1,
323
        .x_chroma_shift = 1, .y_chroma_shift = 1,
324
    },
325
    [PIX_FMT_VDPAU_VC1] = {
326
        .name = "vdpau_vc1",
327
        .is_hwaccel = 1,
328
        .x_chroma_shift = 1, .y_chroma_shift = 1,
329
    },
330
    [PIX_FMT_UYYVYY411] = {
331
        .name = "uyyvyy411",
332
        .nb_channels = 1,
333
        .color_type = FF_COLOR_YUV,
334
        .pixel_type = FF_PIXEL_PACKED,
335
        .depth = 8,
336
        .x_chroma_shift = 2, .y_chroma_shift = 0,
337
    },
338
    [PIX_FMT_ABGR] = {
339
        .name = "abgr",
340
        .nb_channels = 4, .is_alpha = 1,
341
        .color_type = FF_COLOR_RGB,
342
        .pixel_type = FF_PIXEL_PACKED,
343
        .depth = 8,
344
        .x_chroma_shift = 0, .y_chroma_shift = 0,
345
    },
346
    [PIX_FMT_BGR565BE] = {
347
        .name = "bgr565be",
348
        .nb_channels = 3,
349
        .color_type = FF_COLOR_RGB,
350
        .pixel_type = FF_PIXEL_PACKED,
351
        .depth = 5,
352
        .x_chroma_shift = 0, .y_chroma_shift = 0,
353
    },
354
    [PIX_FMT_BGR565LE] = {
355
        .name = "bgr565le",
356
        .nb_channels = 3,
357
        .color_type = FF_COLOR_RGB,
358
        .pixel_type = FF_PIXEL_PACKED,
359
        .depth = 5,
360
        .x_chroma_shift = 0, .y_chroma_shift = 0,
361
    },
362
    [PIX_FMT_BGR555BE] = {
363
        .name = "bgr555be",
364
        .nb_channels = 3,
365
        .color_type = FF_COLOR_RGB,
366
        .pixel_type = FF_PIXEL_PACKED,
367
        .depth = 5,
368
        .x_chroma_shift = 0, .y_chroma_shift = 0,
369
    },
370
    [PIX_FMT_BGR555LE] = {
371
        .name = "bgr555le",
372
        .nb_channels = 3,
373
        .color_type = FF_COLOR_RGB,
374
        .pixel_type = FF_PIXEL_PACKED,
375
        .depth = 5,
376
        .x_chroma_shift = 0, .y_chroma_shift = 0,
377
    },
378
    [PIX_FMT_RGB8] = {
379
        .name = "rgb8",
380
        .nb_channels = 1,
381
        .color_type = FF_COLOR_RGB,
382
        .pixel_type = FF_PIXEL_PACKED,
383
        .depth = 8,
384
        .x_chroma_shift = 0, .y_chroma_shift = 0,
385
    },
386
    [PIX_FMT_RGB4] = {
387
        .name = "rgb4",
388
        .nb_channels = 1,
389
        .color_type = FF_COLOR_RGB,
390
        .pixel_type = FF_PIXEL_PACKED,
391
        .depth = 4,
392
        .x_chroma_shift = 0, .y_chroma_shift = 0,
393
    },
394
    [PIX_FMT_RGB4_BYTE] = {
395
        .name = "rgb4_byte",
396
        .nb_channels = 1,
397
        .color_type = FF_COLOR_RGB,
398
        .pixel_type = FF_PIXEL_PACKED,
399
        .depth = 8,
400
        .x_chroma_shift = 0, .y_chroma_shift = 0,
401
    },
402
    [PIX_FMT_BGR8] = {
403
        .name = "bgr8",
404
        .nb_channels = 1,
405
        .color_type = FF_COLOR_RGB,
406
        .pixel_type = FF_PIXEL_PACKED,
407
        .depth = 8,
408
        .x_chroma_shift = 0, .y_chroma_shift = 0,
409
    },
410
    [PIX_FMT_BGR4] = {
411
        .name = "bgr4",
412
        .nb_channels = 1,
413
        .color_type = FF_COLOR_RGB,
414
        .pixel_type = FF_PIXEL_PACKED,
415
        .depth = 4,
416
        .x_chroma_shift = 0, .y_chroma_shift = 0,
417
    },
418
    [PIX_FMT_BGR4_BYTE] = {
419
        .name = "bgr4_byte",
420
        .nb_channels = 1,
421
        .color_type = FF_COLOR_RGB,
422
        .pixel_type = FF_PIXEL_PACKED,
423
        .depth = 8,
424
        .x_chroma_shift = 0, .y_chroma_shift = 0,
425
    },
426
    [PIX_FMT_NV12] = {
427
        .name = "nv12",
428
        .nb_channels = 2,
429
        .color_type = FF_COLOR_YUV,
430
        .pixel_type = FF_PIXEL_PLANAR,
431
        .depth = 8,
432
        .x_chroma_shift = 1, .y_chroma_shift = 1,
433
    },
434
    [PIX_FMT_NV21] = {
435
        .name = "nv12",
436
        .nb_channels = 2,
437
        .color_type = FF_COLOR_YUV,
438
        .pixel_type = FF_PIXEL_PLANAR,
439
        .depth = 8,
440
        .x_chroma_shift = 1, .y_chroma_shift = 1,
441
    },
442

    
443
    [PIX_FMT_BGRA] = {
444
        .name = "bgra",
445
        .nb_channels = 4, .is_alpha = 1,
446
        .color_type = FF_COLOR_RGB,
447
        .pixel_type = FF_PIXEL_PACKED,
448
        .depth = 8,
449
        .x_chroma_shift = 0, .y_chroma_shift = 0,
450
    },
451
    [PIX_FMT_RGBA] = {
452
        .name = "rgba",
453
        .nb_channels = 4, .is_alpha = 1,
454
        .color_type = FF_COLOR_RGB,
455
        .pixel_type = FF_PIXEL_PACKED,
456
        .depth = 8,
457
        .x_chroma_shift = 0, .y_chroma_shift = 0,
458
    },
459

    
460
    /* VA API formats */
461
    [PIX_FMT_VAAPI_MOCO] = {
462
        .name = "vaapi_moco",
463
        .is_hwaccel = 1,
464
        .x_chroma_shift = 1, .y_chroma_shift = 1,
465
    },
466
    [PIX_FMT_VAAPI_IDCT] = {
467
        .name = "vaapi_idct",
468
        .is_hwaccel = 1,
469
        .x_chroma_shift = 1, .y_chroma_shift = 1,
470
    },
471
    [PIX_FMT_VAAPI_VLD] = {
472
        .name = "vaapi_vld",
473
        .is_hwaccel = 1,
474
        .x_chroma_shift = 1, .y_chroma_shift = 1,
475
    },
476
};
477

    
478
void avcodec_get_chroma_sub_sample(enum PixelFormat pix_fmt, int *h_shift, int *v_shift)
479
{
480
    *h_shift = pix_fmt_info[pix_fmt].x_chroma_shift;
481
    *v_shift = pix_fmt_info[pix_fmt].y_chroma_shift;
482
}
483

    
484
const char *avcodec_get_pix_fmt_name(enum PixelFormat pix_fmt)
485
{
486
    if (pix_fmt < 0 || pix_fmt >= PIX_FMT_NB)
487
        return NULL;
488
    else
489
        return pix_fmt_info[pix_fmt].name;
490
}
491

    
492
static enum PixelFormat avcodec_get_pix_fmt_internal(const char *name)
493
{
494
    int i;
495

    
496
    for (i=0; i < PIX_FMT_NB; i++)
497
        if (pix_fmt_info[i].name && !strcmp(pix_fmt_info[i].name, name))
498
             return i;
499
    return PIX_FMT_NONE;
500
}
501

    
502
#ifdef WORDS_BIGENDIAN
503
#   define X_NE(be, le) be
504
#else
505
#   define X_NE(be, le) le
506
#endif
507

    
508
enum PixelFormat avcodec_get_pix_fmt(const char *name)
509
{
510
    enum PixelFormat pix_fmt;
511

    
512
    if (!strcmp(name, "rgb32"))
513
        name = X_NE("argb", "bgra");
514
    else if (!strcmp(name, "bgr32"))
515
        name = X_NE("abgr", "rgba");
516

    
517
    pix_fmt = avcodec_get_pix_fmt_internal(name);
518
    if (pix_fmt == PIX_FMT_NONE) {
519
        char name2[32];
520
        snprintf(name2, sizeof(name2), "%s%s", name, X_NE("be", "le"));
521
        pix_fmt = avcodec_get_pix_fmt_internal(name2);
522
    }
523
    return pix_fmt;
524
}
525

    
526
void avcodec_pix_fmt_string (char *buf, int buf_size, enum PixelFormat pix_fmt)
527
{
528
    /* print header */
529
    if (pix_fmt < 0)
530
        snprintf (buf, buf_size,
531
                  "name      " " nb_channels" " depth" " is_alpha"
532
            );
533
    else{
534
        PixFmtInfo info= pix_fmt_info[pix_fmt];
535

    
536
        char is_alpha_char= info.is_alpha ? 'y' : 'n';
537

    
538
        snprintf (buf, buf_size,
539
                  "%-10s" "      %1d     " "   %2d " "     %c   ",
540
                  info.name,
541
                  info.nb_channels,
542
                  info.depth,
543
                  is_alpha_char
544
            );
545
    }
546
}
547

    
548
int ff_is_hwaccel_pix_fmt(enum PixelFormat pix_fmt)
549
{
550
    return pix_fmt_info[pix_fmt].is_hwaccel;
551
}
552

    
553
int ff_set_systematic_pal(uint32_t pal[256], enum PixelFormat pix_fmt){
554
    int i;
555

    
556
    for(i=0; i<256; i++){
557
        int r,g,b;
558

    
559
        switch(pix_fmt) {
560
        case PIX_FMT_RGB8:
561
            r= (i>>5    )*36;
562
            g= ((i>>2)&7)*36;
563
            b= (i&3     )*85;
564
            break;
565
        case PIX_FMT_BGR8:
566
            b= (i>>6    )*85;
567
            g= ((i>>3)&7)*36;
568
            r= (i&7     )*36;
569
            break;
570
        case PIX_FMT_RGB4_BYTE:
571
            r= (i>>3    )*255;
572
            g= ((i>>1)&3)*85;
573
            b= (i&1     )*255;
574
            break;
575
        case PIX_FMT_BGR4_BYTE:
576
            b= (i>>3    )*255;
577
            g= ((i>>1)&3)*85;
578
            r= (i&1     )*255;
579
            break;
580
        case PIX_FMT_GRAY8:
581
            r=b=g= i;
582
            break;
583
        default:
584
            return -1;
585
        }
586
        pal[i] =  b + (g<<8) + (r<<16);
587
    }
588

    
589
    return 0;
590
}
591

    
592
int ff_fill_linesize(AVPicture *picture, enum PixelFormat pix_fmt, int width)
593
{
594
    int w2;
595
    const PixFmtInfo *pinfo;
596

    
597
    memset(picture->linesize, 0, sizeof(picture->linesize));
598

    
599
    pinfo = &pix_fmt_info[pix_fmt];
600
    switch(pix_fmt) {
601
    case PIX_FMT_YUV420P:
602
    case PIX_FMT_YUV422P:
603
    case PIX_FMT_YUV444P:
604
    case PIX_FMT_YUV410P:
605
    case PIX_FMT_YUV411P:
606
    case PIX_FMT_YUV440P:
607
    case PIX_FMT_YUVJ420P:
608
    case PIX_FMT_YUVJ422P:
609
    case PIX_FMT_YUVJ444P:
610
    case PIX_FMT_YUVJ440P:
611
        w2 = (width + (1 << pinfo->x_chroma_shift) - 1) >> pinfo->x_chroma_shift;
612
        picture->linesize[0] = width;
613
        picture->linesize[1] = w2;
614
        picture->linesize[2] = w2;
615
        break;
616
    case PIX_FMT_YUVA420P:
617
        w2 = (width + (1 << pinfo->x_chroma_shift) - 1) >> pinfo->x_chroma_shift;
618
        picture->linesize[0] = width;
619
        picture->linesize[1] = w2;
620
        picture->linesize[2] = w2;
621
        picture->linesize[3] = width;
622
        break;
623
    case PIX_FMT_NV12:
624
    case PIX_FMT_NV21:
625
        w2 = (width + (1 << pinfo->x_chroma_shift) - 1) >> pinfo->x_chroma_shift;
626
        picture->linesize[0] = width;
627
        picture->linesize[1] = w2;
628
        break;
629
    case PIX_FMT_RGB24:
630
    case PIX_FMT_BGR24:
631
        picture->linesize[0] = width * 3;
632
        break;
633
    case PIX_FMT_ARGB:
634
    case PIX_FMT_ABGR:
635
    case PIX_FMT_RGBA:
636
    case PIX_FMT_BGRA:
637
        picture->linesize[0] = width * 4;
638
        break;
639
    case PIX_FMT_RGB48BE:
640
    case PIX_FMT_RGB48LE:
641
        picture->linesize[0] = width * 6;
642
        break;
643
    case PIX_FMT_GRAY16BE:
644
    case PIX_FMT_GRAY16LE:
645
    case PIX_FMT_BGR555:
646
    case PIX_FMT_BGR565:
647
    case PIX_FMT_RGB555:
648
    case PIX_FMT_RGB565:
649
    case PIX_FMT_YUYV422:
650
        picture->linesize[0] = width * 2;
651
        break;
652
    case PIX_FMT_UYVY422:
653
        picture->linesize[0] = width * 2;
654
        break;
655
    case PIX_FMT_UYYVYY411:
656
        picture->linesize[0] = width + width/2;
657
        break;
658
    case PIX_FMT_RGB4:
659
    case PIX_FMT_BGR4:
660
        picture->linesize[0] = width / 2;
661
        break;
662
    case PIX_FMT_MONOWHITE:
663
    case PIX_FMT_MONOBLACK:
664
        picture->linesize[0] = (width + 7) >> 3;
665
        break;
666
    case PIX_FMT_PAL8:
667
    case PIX_FMT_RGB8:
668
    case PIX_FMT_BGR8:
669
    case PIX_FMT_RGB4_BYTE:
670
    case PIX_FMT_BGR4_BYTE:
671
    case PIX_FMT_GRAY8:
672
        picture->linesize[0] = width;
673
        break;
674
    default:
675
        return -1;
676
    }
677
    return 0;
678
}
679

    
680
int ff_fill_pointer(AVPicture *picture, uint8_t *ptr, enum PixelFormat pix_fmt,
681
                    int height)
682
{
683
    int size, h2, size2;
684
    const PixFmtInfo *pinfo;
685

    
686
    pinfo = &pix_fmt_info[pix_fmt];
687
    size = picture->linesize[0] * height;
688
    switch(pix_fmt) {
689
    case PIX_FMT_YUV420P:
690
    case PIX_FMT_YUV422P:
691
    case PIX_FMT_YUV444P:
692
    case PIX_FMT_YUV410P:
693
    case PIX_FMT_YUV411P:
694
    case PIX_FMT_YUV440P:
695
    case PIX_FMT_YUVJ420P:
696
    case PIX_FMT_YUVJ422P:
697
    case PIX_FMT_YUVJ444P:
698
    case PIX_FMT_YUVJ440P:
699
        h2 = (height + (1 << pinfo->y_chroma_shift) - 1) >> pinfo->y_chroma_shift;
700
        size2 = picture->linesize[1] * h2;
701
        picture->data[0] = ptr;
702
        picture->data[1] = picture->data[0] + size;
703
        picture->data[2] = picture->data[1] + size2;
704
        picture->data[3] = NULL;
705
        return size + 2 * size2;
706
    case PIX_FMT_YUVA420P:
707
        h2 = (height + (1 << pinfo->y_chroma_shift) - 1) >> pinfo->y_chroma_shift;
708
        size2 = picture->linesize[1] * h2;
709
        picture->data[0] = ptr;
710
        picture->data[1] = picture->data[0] + size;
711
        picture->data[2] = picture->data[1] + size2;
712
        picture->data[3] = picture->data[1] + size2 + size2;
713
        return 2 * size + 2 * size2;
714
    case PIX_FMT_NV12:
715
    case PIX_FMT_NV21:
716
        h2 = (height + (1 << pinfo->y_chroma_shift) - 1) >> pinfo->y_chroma_shift;
717
        size2 = picture->linesize[1] * h2 * 2;
718
        picture->data[0] = ptr;
719
        picture->data[1] = picture->data[0] + size;
720
        picture->data[2] = NULL;
721
        picture->data[3] = NULL;
722
        return size + 2 * size2;
723
    case PIX_FMT_RGB24:
724
    case PIX_FMT_BGR24:
725
    case PIX_FMT_ARGB:
726
    case PIX_FMT_ABGR:
727
    case PIX_FMT_RGBA:
728
    case PIX_FMT_BGRA:
729
    case PIX_FMT_RGB48BE:
730
    case PIX_FMT_RGB48LE:
731
    case PIX_FMT_GRAY16BE:
732
    case PIX_FMT_GRAY16LE:
733
    case PIX_FMT_BGR555:
734
    case PIX_FMT_BGR565:
735
    case PIX_FMT_RGB555:
736
    case PIX_FMT_RGB565:
737
    case PIX_FMT_YUYV422:
738
    case PIX_FMT_UYVY422:
739
    case PIX_FMT_UYYVYY411:
740
    case PIX_FMT_RGB4:
741
    case PIX_FMT_BGR4:
742
    case PIX_FMT_MONOWHITE:
743
    case PIX_FMT_MONOBLACK:
744
        picture->data[0] = ptr;
745
        picture->data[1] = NULL;
746
        picture->data[2] = NULL;
747
        picture->data[3] = NULL;
748
        return size;
749
    case PIX_FMT_PAL8:
750
    case PIX_FMT_RGB8:
751
    case PIX_FMT_BGR8:
752
    case PIX_FMT_RGB4_BYTE:
753
    case PIX_FMT_BGR4_BYTE:
754
    case PIX_FMT_GRAY8:
755
        size2 = (size + 3) & ~3;
756
        picture->data[0] = ptr;
757
        picture->data[1] = ptr + size2; /* palette is stored here as 256 32 bit words */
758
        picture->data[2] = NULL;
759
        picture->data[3] = NULL;
760
        return size2 + 256 * 4;
761
    default:
762
        picture->data[0] = NULL;
763
        picture->data[1] = NULL;
764
        picture->data[2] = NULL;
765
        picture->data[3] = NULL;
766
        return -1;
767
    }
768
}
769

    
770
int avpicture_fill(AVPicture *picture, uint8_t *ptr,
771
                   enum PixelFormat pix_fmt, int width, int height)
772
{
773

    
774
    if(avcodec_check_dimensions(NULL, width, height))
775
        return -1;
776

    
777
    if (ff_fill_linesize(picture, pix_fmt, width))
778
        return -1;
779

    
780
    return ff_fill_pointer(picture, ptr, pix_fmt, height);
781
}
782

    
783
int avpicture_layout(const AVPicture* src, enum PixelFormat pix_fmt, int width, int height,
784
                     unsigned char *dest, int dest_size)
785
{
786
    const PixFmtInfo* pf = &pix_fmt_info[pix_fmt];
787
    int i, j, w, ow, h, oh, data_planes;
788
    const unsigned char* s;
789
    int size = avpicture_get_size(pix_fmt, width, height);
790

    
791
    if (size > dest_size || size < 0)
792
        return -1;
793

    
794
    if (pf->pixel_type == FF_PIXEL_PACKED || pf->pixel_type == FF_PIXEL_PALETTE) {
795
        if (pix_fmt == PIX_FMT_YUYV422 ||
796
            pix_fmt == PIX_FMT_UYVY422 ||
797
            pix_fmt == PIX_FMT_BGR565 ||
798
            pix_fmt == PIX_FMT_BGR555 ||
799
            pix_fmt == PIX_FMT_RGB565 ||
800
            pix_fmt == PIX_FMT_RGB555)
801
            w = width * 2;
802
        else if (pix_fmt == PIX_FMT_UYYVYY411)
803
          w = width + width/2;
804
        else if (pix_fmt == PIX_FMT_PAL8)
805
          w = width;
806
        else
807
          w = width * (pf->depth * pf->nb_channels / 8);
808

    
809
        data_planes = 1;
810
        h = height;
811
    } else {
812
        data_planes = pf->nb_channels;
813
        w = (width*pf->depth + 7)/8;
814
        h = height;
815
    }
816

    
817
    ow = w;
818
    oh = h;
819

    
820
    for (i=0; i<data_planes; i++) {
821
         if (i == 1) {
822
             w = width >> pf->x_chroma_shift;
823
             h = height >> pf->y_chroma_shift;
824
         } else if (i == 3) {
825
             w = ow;
826
             h = oh;
827
         }
828
         s = src->data[i];
829
         for(j=0; j<h; j++) {
830
             memcpy(dest, s, w);
831
             dest += w;
832
             s += src->linesize[i];
833
         }
834
    }
835

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

    
839
    return size;
840
}
841

    
842
int avpicture_get_size(enum PixelFormat pix_fmt, int width, int height)
843
{
844
    AVPicture dummy_pict;
845
    if(avcodec_check_dimensions(NULL, width, height))
846
        return -1;
847
    switch (pix_fmt) {
848
    case PIX_FMT_RGB8:
849
    case PIX_FMT_BGR8:
850
    case PIX_FMT_RGB4_BYTE:
851
    case PIX_FMT_BGR4_BYTE:
852
    case PIX_FMT_GRAY8:
853
        // do not include palette for these pseudo-paletted formats
854
        return width * height;
855
    }
856
    return avpicture_fill(&dummy_pict, NULL, pix_fmt, width, height);
857
}
858

    
859
int avcodec_get_pix_fmt_loss(enum PixelFormat dst_pix_fmt, enum PixelFormat src_pix_fmt,
860
                             int has_alpha)
861
{
862
    const PixFmtInfo *pf, *ps;
863
    int loss;
864

    
865
    ps = &pix_fmt_info[src_pix_fmt];
866
    pf = &pix_fmt_info[dst_pix_fmt];
867

    
868
    /* compute loss */
869
    loss = 0;
870
    pf = &pix_fmt_info[dst_pix_fmt];
871
    if (pf->depth < ps->depth ||
872
        (dst_pix_fmt == PIX_FMT_RGB555 && src_pix_fmt == PIX_FMT_RGB565))
873
        loss |= FF_LOSS_DEPTH;
874
    if (pf->x_chroma_shift > ps->x_chroma_shift ||
875
        pf->y_chroma_shift > ps->y_chroma_shift)
876
        loss |= FF_LOSS_RESOLUTION;
877
    switch(pf->color_type) {
878
    case FF_COLOR_RGB:
879
        if (ps->color_type != FF_COLOR_RGB &&
880
            ps->color_type != FF_COLOR_GRAY)
881
            loss |= FF_LOSS_COLORSPACE;
882
        break;
883
    case FF_COLOR_GRAY:
884
        if (ps->color_type != FF_COLOR_GRAY)
885
            loss |= FF_LOSS_COLORSPACE;
886
        break;
887
    case FF_COLOR_YUV:
888
        if (ps->color_type != FF_COLOR_YUV)
889
            loss |= FF_LOSS_COLORSPACE;
890
        break;
891
    case FF_COLOR_YUV_JPEG:
892
        if (ps->color_type != FF_COLOR_YUV_JPEG &&
893
            ps->color_type != FF_COLOR_YUV &&
894
            ps->color_type != FF_COLOR_GRAY)
895
            loss |= FF_LOSS_COLORSPACE;
896
        break;
897
    default:
898
        /* fail safe test */
899
        if (ps->color_type != pf->color_type)
900
            loss |= FF_LOSS_COLORSPACE;
901
        break;
902
    }
903
    if (pf->color_type == FF_COLOR_GRAY &&
904
        ps->color_type != FF_COLOR_GRAY)
905
        loss |= FF_LOSS_CHROMA;
906
    if (!pf->is_alpha && (ps->is_alpha && has_alpha))
907
        loss |= FF_LOSS_ALPHA;
908
    if (pf->pixel_type == FF_PIXEL_PALETTE &&
909
        (ps->pixel_type != FF_PIXEL_PALETTE && ps->color_type != FF_COLOR_GRAY))
910
        loss |= FF_LOSS_COLORQUANT;
911
    return loss;
912
}
913

    
914
static int avg_bits_per_pixel(enum PixelFormat pix_fmt)
915
{
916
    int bits;
917
    const PixFmtInfo *pf;
918

    
919
    pf = &pix_fmt_info[pix_fmt];
920
    switch(pf->pixel_type) {
921
    case FF_PIXEL_PACKED:
922
        switch(pix_fmt) {
923
        case PIX_FMT_YUYV422:
924
        case PIX_FMT_UYVY422:
925
        case PIX_FMT_RGB565:
926
        case PIX_FMT_RGB555:
927
        case PIX_FMT_BGR565:
928
        case PIX_FMT_BGR555:
929
            bits = 16;
930
            break;
931
        case PIX_FMT_UYYVYY411:
932
            bits = 12;
933
            break;
934
        default:
935
            bits = pf->depth * pf->nb_channels;
936
            break;
937
        }
938
        break;
939
    case FF_PIXEL_PLANAR:
940
        if (pf->x_chroma_shift == 0 && pf->y_chroma_shift == 0) {
941
            bits = pf->depth * pf->nb_channels;
942
        } else {
943
            bits = pf->depth + ((2 * pf->depth) >>
944
                                (pf->x_chroma_shift + pf->y_chroma_shift));
945
        }
946
        break;
947
    case FF_PIXEL_PALETTE:
948
        bits = 8;
949
        break;
950
    default:
951
        bits = -1;
952
        break;
953
    }
954
    return bits;
955
}
956

    
957
static enum PixelFormat avcodec_find_best_pix_fmt1(int64_t pix_fmt_mask,
958
                                      enum PixelFormat src_pix_fmt,
959
                                      int has_alpha,
960
                                      int loss_mask)
961
{
962
    int dist, i, loss, min_dist;
963
    enum PixelFormat dst_pix_fmt;
964

    
965
    /* find exact color match with smallest size */
966
    dst_pix_fmt = -1;
967
    min_dist = 0x7fffffff;
968
    for(i = 0;i < PIX_FMT_NB; i++) {
969
        if (pix_fmt_mask & (1ULL << i)) {
970
            loss = avcodec_get_pix_fmt_loss(i, src_pix_fmt, has_alpha) & loss_mask;
971
            if (loss == 0) {
972
                dist = avg_bits_per_pixel(i);
973
                if (dist < min_dist) {
974
                    min_dist = dist;
975
                    dst_pix_fmt = i;
976
                }
977
            }
978
        }
979
    }
980
    return dst_pix_fmt;
981
}
982

    
983
enum PixelFormat avcodec_find_best_pix_fmt(int64_t pix_fmt_mask, enum PixelFormat src_pix_fmt,
984
                              int has_alpha, int *loss_ptr)
985
{
986
    enum PixelFormat dst_pix_fmt;
987
    int loss_mask, i;
988
    static const int loss_mask_order[] = {
989
        ~0, /* no loss first */
990
        ~FF_LOSS_ALPHA,
991
        ~FF_LOSS_RESOLUTION,
992
        ~(FF_LOSS_COLORSPACE | FF_LOSS_RESOLUTION),
993
        ~FF_LOSS_COLORQUANT,
994
        ~FF_LOSS_DEPTH,
995
        0,
996
    };
997

    
998
    /* try with successive loss */
999
    i = 0;
1000
    for(;;) {
1001
        loss_mask = loss_mask_order[i++];
1002
        dst_pix_fmt = avcodec_find_best_pix_fmt1(pix_fmt_mask, src_pix_fmt,
1003
                                                 has_alpha, loss_mask);
1004
        if (dst_pix_fmt >= 0)
1005
            goto found;
1006
        if (loss_mask == 0)
1007
            break;
1008
    }
1009
    return -1;
1010
 found:
1011
    if (loss_ptr)
1012
        *loss_ptr = avcodec_get_pix_fmt_loss(dst_pix_fmt, src_pix_fmt, has_alpha);
1013
    return dst_pix_fmt;
1014
}
1015

    
1016
void ff_img_copy_plane(uint8_t *dst, int dst_wrap,
1017
                           const uint8_t *src, int src_wrap,
1018
                           int width, int height)
1019
{
1020
    if((!dst) || (!src))
1021
        return;
1022
    for(;height > 0; height--) {
1023
        memcpy(dst, src, width);
1024
        dst += dst_wrap;
1025
        src += src_wrap;
1026
    }
1027
}
1028

    
1029
int ff_get_plane_bytewidth(enum PixelFormat pix_fmt, int width, int plane)
1030
{
1031
    int bits;
1032
    const PixFmtInfo *pf = &pix_fmt_info[pix_fmt];
1033

    
1034
    pf = &pix_fmt_info[pix_fmt];
1035
    switch(pf->pixel_type) {
1036
    case FF_PIXEL_PACKED:
1037
        switch(pix_fmt) {
1038
        case PIX_FMT_YUYV422:
1039
        case PIX_FMT_UYVY422:
1040
        case PIX_FMT_RGB565:
1041
        case PIX_FMT_RGB555:
1042
        case PIX_FMT_BGR565:
1043
        case PIX_FMT_BGR555:
1044
            bits = 16;
1045
            break;
1046
        case PIX_FMT_UYYVYY411:
1047
            bits = 12;
1048
            break;
1049
        default:
1050
            bits = pf->depth * pf->nb_channels;
1051
            break;
1052
        }
1053
        return (width * bits + 7) >> 3;
1054
        break;
1055
    case FF_PIXEL_PLANAR:
1056
            if (plane == 1 || plane == 2)
1057
                width= -((-width)>>pf->x_chroma_shift);
1058

    
1059
            return (width * pf->depth + 7) >> 3;
1060
        break;
1061
    case FF_PIXEL_PALETTE:
1062
        if (plane == 0)
1063
            return width;
1064
        break;
1065
    }
1066

    
1067
    return -1;
1068
}
1069

    
1070
void av_picture_copy(AVPicture *dst, const AVPicture *src,
1071
                     enum PixelFormat pix_fmt, int width, int height)
1072
{
1073
    int i;
1074
    const PixFmtInfo *pf = &pix_fmt_info[pix_fmt];
1075

    
1076
    pf = &pix_fmt_info[pix_fmt];
1077
    switch(pf->pixel_type) {
1078
    case FF_PIXEL_PACKED:
1079
    case FF_PIXEL_PLANAR:
1080
        for(i = 0; i < pf->nb_channels; i++) {
1081
            int h;
1082
            int bwidth = ff_get_plane_bytewidth(pix_fmt, width, i);
1083
            h = height;
1084
            if (i == 1 || i == 2) {
1085
                h= -((-height)>>pf->y_chroma_shift);
1086
            }
1087
            ff_img_copy_plane(dst->data[i], dst->linesize[i],
1088
                           src->data[i], src->linesize[i],
1089
                           bwidth, h);
1090
        }
1091
        break;
1092
    case FF_PIXEL_PALETTE:
1093
        ff_img_copy_plane(dst->data[0], dst->linesize[0],
1094
                       src->data[0], src->linesize[0],
1095
                       width, height);
1096
        /* copy the palette */
1097
        ff_img_copy_plane(dst->data[1], dst->linesize[1],
1098
                       src->data[1], src->linesize[1],
1099
                       4, 256);
1100
        break;
1101
    }
1102
}
1103

    
1104
/* 2x2 -> 1x1 */
1105
void ff_shrink22(uint8_t *dst, int dst_wrap,
1106
                     const uint8_t *src, int src_wrap,
1107
                     int width, int height)
1108
{
1109
    int w;
1110
    const uint8_t *s1, *s2;
1111
    uint8_t *d;
1112

    
1113
    for(;height > 0; height--) {
1114
        s1 = src;
1115
        s2 = s1 + src_wrap;
1116
        d = dst;
1117
        for(w = width;w >= 4; w-=4) {
1118
            d[0] = (s1[0] + s1[1] + s2[0] + s2[1] + 2) >> 2;
1119
            d[1] = (s1[2] + s1[3] + s2[2] + s2[3] + 2) >> 2;
1120
            d[2] = (s1[4] + s1[5] + s2[4] + s2[5] + 2) >> 2;
1121
            d[3] = (s1[6] + s1[7] + s2[6] + s2[7] + 2) >> 2;
1122
            s1 += 8;
1123
            s2 += 8;
1124
            d += 4;
1125
        }
1126
        for(;w > 0; w--) {
1127
            d[0] = (s1[0] + s1[1] + s2[0] + s2[1] + 2) >> 2;
1128
            s1 += 2;
1129
            s2 += 2;
1130
            d++;
1131
        }
1132
        src += 2 * src_wrap;
1133
        dst += dst_wrap;
1134
    }
1135
}
1136

    
1137
/* 4x4 -> 1x1 */
1138
void ff_shrink44(uint8_t *dst, int dst_wrap,
1139
                     const uint8_t *src, int src_wrap,
1140
                     int width, int height)
1141
{
1142
    int w;
1143
    const uint8_t *s1, *s2, *s3, *s4;
1144
    uint8_t *d;
1145

    
1146
    for(;height > 0; height--) {
1147
        s1 = src;
1148
        s2 = s1 + src_wrap;
1149
        s3 = s2 + src_wrap;
1150
        s4 = s3 + src_wrap;
1151
        d = dst;
1152
        for(w = width;w > 0; w--) {
1153
            d[0] = (s1[0] + s1[1] + s1[2] + s1[3] +
1154
                    s2[0] + s2[1] + s2[2] + s2[3] +
1155
                    s3[0] + s3[1] + s3[2] + s3[3] +
1156
                    s4[0] + s4[1] + s4[2] + s4[3] + 8) >> 4;
1157
            s1 += 4;
1158
            s2 += 4;
1159
            s3 += 4;
1160
            s4 += 4;
1161
            d++;
1162
        }
1163
        src += 4 * src_wrap;
1164
        dst += dst_wrap;
1165
    }
1166
}
1167

    
1168
/* 8x8 -> 1x1 */
1169
void ff_shrink88(uint8_t *dst, int dst_wrap,
1170
                     const uint8_t *src, int src_wrap,
1171
                     int width, int height)
1172
{
1173
    int w, i;
1174

    
1175
    for(;height > 0; height--) {
1176
        for(w = width;w > 0; w--) {
1177
            int tmp=0;
1178
            for(i=0; i<8; i++){
1179
                tmp += src[0] + src[1] + src[2] + src[3] + src[4] + src[5] + src[6] + src[7];
1180
                src += src_wrap;
1181
            }
1182
            *(dst++) = (tmp + 32)>>6;
1183
            src += 8 - 8*src_wrap;
1184
        }
1185
        src += 8*src_wrap - 8*width;
1186
        dst += dst_wrap - width;
1187
    }
1188
}
1189

    
1190

    
1191
int avpicture_alloc(AVPicture *picture,
1192
                    enum PixelFormat pix_fmt, int width, int height)
1193
{
1194
    int size;
1195
    void *ptr;
1196

    
1197
    size = avpicture_fill(picture, NULL, pix_fmt, width, height);
1198
    if(size<0)
1199
        goto fail;
1200
    ptr = av_malloc(size);
1201
    if (!ptr)
1202
        goto fail;
1203
    avpicture_fill(picture, ptr, pix_fmt, width, height);
1204
    if(picture->data[1] && !picture->data[2])
1205
        ff_set_systematic_pal((uint32_t*)picture->data[1], pix_fmt);
1206

    
1207
    return 0;
1208
 fail:
1209
    memset(picture, 0, sizeof(AVPicture));
1210
    return -1;
1211
}
1212

    
1213
void avpicture_free(AVPicture *picture)
1214
{
1215
    av_free(picture->data[0]);
1216
}
1217

    
1218
/* return true if yuv planar */
1219
static inline int is_yuv_planar(const PixFmtInfo *ps)
1220
{
1221
    return (ps->color_type == FF_COLOR_YUV ||
1222
            ps->color_type == FF_COLOR_YUV_JPEG) &&
1223
        ps->pixel_type == FF_PIXEL_PLANAR;
1224
}
1225

    
1226
int av_picture_crop(AVPicture *dst, const AVPicture *src,
1227
              int pix_fmt, int top_band, int left_band)
1228
{
1229
    int y_shift;
1230
    int x_shift;
1231

    
1232
    if (pix_fmt < 0 || pix_fmt >= PIX_FMT_NB || !is_yuv_planar(&pix_fmt_info[pix_fmt]))
1233
        return -1;
1234

    
1235
    y_shift = pix_fmt_info[pix_fmt].y_chroma_shift;
1236
    x_shift = pix_fmt_info[pix_fmt].x_chroma_shift;
1237

    
1238
    dst->data[0] = src->data[0] + (top_band * src->linesize[0]) + left_band;
1239
    dst->data[1] = src->data[1] + ((top_band >> y_shift) * src->linesize[1]) + (left_band >> x_shift);
1240
    dst->data[2] = src->data[2] + ((top_band >> y_shift) * src->linesize[2]) + (left_band >> x_shift);
1241

    
1242
    dst->linesize[0] = src->linesize[0];
1243
    dst->linesize[1] = src->linesize[1];
1244
    dst->linesize[2] = src->linesize[2];
1245
    return 0;
1246
}
1247

    
1248
int av_picture_pad(AVPicture *dst, const AVPicture *src, int height, int width,
1249
                   enum PixelFormat pix_fmt, int padtop, int padbottom, int padleft, int padright,
1250
            int *color)
1251
{
1252
    uint8_t *optr;
1253
    int y_shift;
1254
    int x_shift;
1255
    int yheight;
1256
    int i, y;
1257

    
1258
    if (pix_fmt < 0 || pix_fmt >= PIX_FMT_NB ||
1259
        !is_yuv_planar(&pix_fmt_info[pix_fmt])) return -1;
1260

    
1261
    for (i = 0; i < 3; i++) {
1262
        x_shift = i ? pix_fmt_info[pix_fmt].x_chroma_shift : 0;
1263
        y_shift = i ? pix_fmt_info[pix_fmt].y_chroma_shift : 0;
1264

    
1265
        if (padtop || padleft) {
1266
            memset(dst->data[i], color[i],
1267
                dst->linesize[i] * (padtop >> y_shift) + (padleft >> x_shift));
1268
        }
1269

    
1270
        if (padleft || padright) {
1271
            optr = dst->data[i] + dst->linesize[i] * (padtop >> y_shift) +
1272
                (dst->linesize[i] - (padright >> x_shift));
1273
            yheight = (height - 1 - (padtop + padbottom)) >> y_shift;
1274
            for (y = 0; y < yheight; y++) {
1275
                memset(optr, color[i], (padleft + padright) >> x_shift);
1276
                optr += dst->linesize[i];
1277
            }
1278
        }
1279

    
1280
        if (src) { /* first line */
1281
            uint8_t *iptr = src->data[i];
1282
            optr = dst->data[i] + dst->linesize[i] * (padtop >> y_shift) +
1283
                    (padleft >> x_shift);
1284
            memcpy(optr, iptr, (width - padleft - padright) >> x_shift);
1285
            iptr += src->linesize[i];
1286
            optr = dst->data[i] + dst->linesize[i] * (padtop >> y_shift) +
1287
                (dst->linesize[i] - (padright >> x_shift));
1288
            yheight = (height - 1 - (padtop + padbottom)) >> y_shift;
1289
            for (y = 0; y < yheight; y++) {
1290
                memset(optr, color[i], (padleft + padright) >> x_shift);
1291
                memcpy(optr + ((padleft + padright) >> x_shift), iptr,
1292
                       (width - padleft - padright) >> x_shift);
1293
                iptr += src->linesize[i];
1294
                optr += dst->linesize[i];
1295
            }
1296
        }
1297

    
1298
        if (padbottom || padright) {
1299
            optr = dst->data[i] + dst->linesize[i] *
1300
                ((height - padbottom) >> y_shift) - (padright >> x_shift);
1301
            memset(optr, color[i],dst->linesize[i] *
1302
                (padbottom >> y_shift) + (padright >> x_shift));
1303
        }
1304
    }
1305
    return 0;
1306
}
1307

    
1308
/* NOTE: we scan all the pixels to have an exact information */
1309
static int get_alpha_info_pal8(const AVPicture *src, int width, int height)
1310
{
1311
    const unsigned char *p;
1312
    int src_wrap, ret, x, y;
1313
    unsigned int a;
1314
    uint32_t *palette = (uint32_t *)src->data[1];
1315

    
1316
    p = src->data[0];
1317
    src_wrap = src->linesize[0] - width;
1318
    ret = 0;
1319
    for(y=0;y<height;y++) {
1320
        for(x=0;x<width;x++) {
1321
            a = palette[p[0]] >> 24;
1322
            if (a == 0x00) {
1323
                ret |= FF_ALPHA_TRANSP;
1324
            } else if (a != 0xff) {
1325
                ret |= FF_ALPHA_SEMI_TRANSP;
1326
            }
1327
            p++;
1328
        }
1329
        p += src_wrap;
1330
    }
1331
    return ret;
1332
}
1333

    
1334
int img_get_alpha_info(const AVPicture *src,
1335
                       enum PixelFormat pix_fmt, int width, int height)
1336
{
1337
    const PixFmtInfo *pf = &pix_fmt_info[pix_fmt];
1338
    int ret;
1339

    
1340
    pf = &pix_fmt_info[pix_fmt];
1341
    /* no alpha can be represented in format */
1342
    if (!pf->is_alpha)
1343
        return 0;
1344
    switch(pix_fmt) {
1345
    case PIX_FMT_PAL8:
1346
        ret = get_alpha_info_pal8(src, width, height);
1347
        break;
1348
    default:
1349
        /* we do not know, so everything is indicated */
1350
        ret = FF_ALPHA_TRANSP | FF_ALPHA_SEMI_TRANSP;
1351
        break;
1352
    }
1353
    return ret;
1354
}
1355

    
1356
#if HAVE_MMX
1357
#define DEINT_INPLACE_LINE_LUM \
1358
                    movd_m2r(lum_m4[0],mm0);\
1359
                    movd_m2r(lum_m3[0],mm1);\
1360
                    movd_m2r(lum_m2[0],mm2);\
1361
                    movd_m2r(lum_m1[0],mm3);\
1362
                    movd_m2r(lum[0],mm4);\
1363
                    punpcklbw_r2r(mm7,mm0);\
1364
                    movd_r2m(mm2,lum_m4[0]);\
1365
                    punpcklbw_r2r(mm7,mm1);\
1366
                    punpcklbw_r2r(mm7,mm2);\
1367
                    punpcklbw_r2r(mm7,mm3);\
1368
                    punpcklbw_r2r(mm7,mm4);\
1369
                    paddw_r2r(mm3,mm1);\
1370
                    psllw_i2r(1,mm2);\
1371
                    paddw_r2r(mm4,mm0);\
1372
                    psllw_i2r(2,mm1);\
1373
                    paddw_r2r(mm6,mm2);\
1374
                    paddw_r2r(mm2,mm1);\
1375
                    psubusw_r2r(mm0,mm1);\
1376
                    psrlw_i2r(3,mm1);\
1377
                    packuswb_r2r(mm7,mm1);\
1378
                    movd_r2m(mm1,lum_m2[0]);
1379

    
1380
#define DEINT_LINE_LUM \
1381
                    movd_m2r(lum_m4[0],mm0);\
1382
                    movd_m2r(lum_m3[0],mm1);\
1383
                    movd_m2r(lum_m2[0],mm2);\
1384
                    movd_m2r(lum_m1[0],mm3);\
1385
                    movd_m2r(lum[0],mm4);\
1386
                    punpcklbw_r2r(mm7,mm0);\
1387
                    punpcklbw_r2r(mm7,mm1);\
1388
                    punpcklbw_r2r(mm7,mm2);\
1389
                    punpcklbw_r2r(mm7,mm3);\
1390
                    punpcklbw_r2r(mm7,mm4);\
1391
                    paddw_r2r(mm3,mm1);\
1392
                    psllw_i2r(1,mm2);\
1393
                    paddw_r2r(mm4,mm0);\
1394
                    psllw_i2r(2,mm1);\
1395
                    paddw_r2r(mm6,mm2);\
1396
                    paddw_r2r(mm2,mm1);\
1397
                    psubusw_r2r(mm0,mm1);\
1398
                    psrlw_i2r(3,mm1);\
1399
                    packuswb_r2r(mm7,mm1);\
1400
                    movd_r2m(mm1,dst[0]);
1401
#endif
1402

    
1403
/* filter parameters: [-1 4 2 4 -1] // 8 */
1404
static void deinterlace_line(uint8_t *dst,
1405
                             const uint8_t *lum_m4, const uint8_t *lum_m3,
1406
                             const uint8_t *lum_m2, const uint8_t *lum_m1,
1407
                             const uint8_t *lum,
1408
                             int size)
1409
{
1410
#if !HAVE_MMX
1411
    uint8_t *cm = ff_cropTbl + MAX_NEG_CROP;
1412
    int sum;
1413

    
1414
    for(;size > 0;size--) {
1415
        sum = -lum_m4[0];
1416
        sum += lum_m3[0] << 2;
1417
        sum += lum_m2[0] << 1;
1418
        sum += lum_m1[0] << 2;
1419
        sum += -lum[0];
1420
        dst[0] = cm[(sum + 4) >> 3];
1421
        lum_m4++;
1422
        lum_m3++;
1423
        lum_m2++;
1424
        lum_m1++;
1425
        lum++;
1426
        dst++;
1427
    }
1428
#else
1429

    
1430
    {
1431
        pxor_r2r(mm7,mm7);
1432
        movq_m2r(ff_pw_4,mm6);
1433
    }
1434
    for (;size > 3; size-=4) {
1435
        DEINT_LINE_LUM
1436
        lum_m4+=4;
1437
        lum_m3+=4;
1438
        lum_m2+=4;
1439
        lum_m1+=4;
1440
        lum+=4;
1441
        dst+=4;
1442
    }
1443
#endif
1444
}
1445
static void deinterlace_line_inplace(uint8_t *lum_m4, uint8_t *lum_m3, uint8_t *lum_m2, uint8_t *lum_m1, uint8_t *lum,
1446
                             int size)
1447
{
1448
#if !HAVE_MMX
1449
    uint8_t *cm = ff_cropTbl + MAX_NEG_CROP;
1450
    int sum;
1451

    
1452
    for(;size > 0;size--) {
1453
        sum = -lum_m4[0];
1454
        sum += lum_m3[0] << 2;
1455
        sum += lum_m2[0] << 1;
1456
        lum_m4[0]=lum_m2[0];
1457
        sum += lum_m1[0] << 2;
1458
        sum += -lum[0];
1459
        lum_m2[0] = cm[(sum + 4) >> 3];
1460
        lum_m4++;
1461
        lum_m3++;
1462
        lum_m2++;
1463
        lum_m1++;
1464
        lum++;
1465
    }
1466
#else
1467

    
1468
    {
1469
        pxor_r2r(mm7,mm7);
1470
        movq_m2r(ff_pw_4,mm6);
1471
    }
1472
    for (;size > 3; size-=4) {
1473
        DEINT_INPLACE_LINE_LUM
1474
        lum_m4+=4;
1475
        lum_m3+=4;
1476
        lum_m2+=4;
1477
        lum_m1+=4;
1478
        lum+=4;
1479
    }
1480
#endif
1481
}
1482

    
1483
/* deinterlacing : 2 temporal taps, 3 spatial taps linear filter. The
1484
   top field is copied as is, but the bottom field is deinterlaced
1485
   against the top field. */
1486
static void deinterlace_bottom_field(uint8_t *dst, int dst_wrap,
1487
                                    const uint8_t *src1, int src_wrap,
1488
                                    int width, int height)
1489
{
1490
    const uint8_t *src_m2, *src_m1, *src_0, *src_p1, *src_p2;
1491
    int y;
1492

    
1493
    src_m2 = src1;
1494
    src_m1 = src1;
1495
    src_0=&src_m1[src_wrap];
1496
    src_p1=&src_0[src_wrap];
1497
    src_p2=&src_p1[src_wrap];
1498
    for(y=0;y<(height-2);y+=2) {
1499
        memcpy(dst,src_m1,width);
1500
        dst += dst_wrap;
1501
        deinterlace_line(dst,src_m2,src_m1,src_0,src_p1,src_p2,width);
1502
        src_m2 = src_0;
1503
        src_m1 = src_p1;
1504
        src_0 = src_p2;
1505
        src_p1 += 2*src_wrap;
1506
        src_p2 += 2*src_wrap;
1507
        dst += dst_wrap;
1508
    }
1509
    memcpy(dst,src_m1,width);
1510
    dst += dst_wrap;
1511
    /* do last line */
1512
    deinterlace_line(dst,src_m2,src_m1,src_0,src_0,src_0,width);
1513
}
1514

    
1515
static void deinterlace_bottom_field_inplace(uint8_t *src1, int src_wrap,
1516
                                             int width, int height)
1517
{
1518
    uint8_t *src_m1, *src_0, *src_p1, *src_p2;
1519
    int y;
1520
    uint8_t *buf;
1521
    buf = (uint8_t*)av_malloc(width);
1522

    
1523
    src_m1 = src1;
1524
    memcpy(buf,src_m1,width);
1525
    src_0=&src_m1[src_wrap];
1526
    src_p1=&src_0[src_wrap];
1527
    src_p2=&src_p1[src_wrap];
1528
    for(y=0;y<(height-2);y+=2) {
1529
        deinterlace_line_inplace(buf,src_m1,src_0,src_p1,src_p2,width);
1530
        src_m1 = src_p1;
1531
        src_0 = src_p2;
1532
        src_p1 += 2*src_wrap;
1533
        src_p2 += 2*src_wrap;
1534
    }
1535
    /* do last line */
1536
    deinterlace_line_inplace(buf,src_m1,src_0,src_0,src_0,width);
1537
    av_free(buf);
1538
}
1539

    
1540
int avpicture_deinterlace(AVPicture *dst, const AVPicture *src,
1541
                          enum PixelFormat pix_fmt, int width, int height)
1542
{
1543
    int i;
1544

    
1545
    if (pix_fmt != PIX_FMT_YUV420P &&
1546
        pix_fmt != PIX_FMT_YUV422P &&
1547
        pix_fmt != PIX_FMT_YUV444P &&
1548
        pix_fmt != PIX_FMT_YUV411P &&
1549
        pix_fmt != PIX_FMT_GRAY8)
1550
        return -1;
1551
    if ((width & 3) != 0 || (height & 3) != 0)
1552
        return -1;
1553

    
1554
    for(i=0;i<3;i++) {
1555
        if (i == 1) {
1556
            switch(pix_fmt) {
1557
            case PIX_FMT_YUV420P:
1558
                width >>= 1;
1559
                height >>= 1;
1560
                break;
1561
            case PIX_FMT_YUV422P:
1562
                width >>= 1;
1563
                break;
1564
            case PIX_FMT_YUV411P:
1565
                width >>= 2;
1566
                break;
1567
            default:
1568
                break;
1569
            }
1570
            if (pix_fmt == PIX_FMT_GRAY8) {
1571
                break;
1572
            }
1573
        }
1574
        if (src == dst) {
1575
            deinterlace_bottom_field_inplace(dst->data[i], dst->linesize[i],
1576
                                 width, height);
1577
        } else {
1578
            deinterlace_bottom_field(dst->data[i],dst->linesize[i],
1579
                                        src->data[i], src->linesize[i],
1580
                                        width, height);
1581
        }
1582
    }
1583
    emms_c();
1584
    return 0;
1585
}
1586