Statistics
| Branch: | Revision:

ffmpeg / libavcodec / imgconvert.c @ 326e9eaa

History | View | Annotate | Download (45 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_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_BGR32] = {
339
        .name = "bgr32",
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_BGR32_1] = {
444
        .name = "bgr32_1",
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_RGB32_1] = {
452
        .name = "rgb32_1",
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 (!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 = avcodec_get_pix_fmt_internal(name);
511

    
512
    if (pix_fmt == PIX_FMT_NONE) {
513
        char name2[32];
514
        snprintf(name2, sizeof(name2), "%s%s", name, X_NE("be", "le"));
515
        pix_fmt = avcodec_get_pix_fmt_internal(name2);
516
    }
517
    return pix_fmt;
518
}
519

    
520
void avcodec_pix_fmt_string (char *buf, int buf_size, enum PixelFormat pix_fmt)
521
{
522
    /* print header */
523
    if (pix_fmt < 0)
524
        snprintf (buf, buf_size,
525
                  "name      " " nb_channels" " depth" " is_alpha"
526
            );
527
    else{
528
        PixFmtInfo info= pix_fmt_info[pix_fmt];
529

    
530
        char is_alpha_char= info.is_alpha ? 'y' : 'n';
531

    
532
        snprintf (buf, buf_size,
533
                  "%-10s" "      %1d     " "   %2d " "     %c   ",
534
                  info.name,
535
                  info.nb_channels,
536
                  info.depth,
537
                  is_alpha_char
538
            );
539
    }
540
}
541

    
542
int ff_is_hwaccel_pix_fmt(enum PixelFormat pix_fmt)
543
{
544
    return pix_fmt_info[pix_fmt].is_hwaccel;
545
}
546

    
547
int ff_set_systematic_pal(uint32_t pal[256], enum PixelFormat pix_fmt){
548
    int i;
549

    
550
    for(i=0; i<256; i++){
551
        int r,g,b;
552

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

    
583
    return 0;
584
}
585

    
586
int ff_fill_linesize(AVPicture *picture, enum PixelFormat pix_fmt, int width)
587
{
588
    int w2;
589
    const PixFmtInfo *pinfo;
590

    
591
    memset(picture->linesize, 0, sizeof(picture->linesize));
592

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

    
674
int ff_fill_pointer(AVPicture *picture, uint8_t *ptr, enum PixelFormat pix_fmt,
675
                    int height)
676
{
677
    int size, h2, size2;
678
    const PixFmtInfo *pinfo;
679

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

    
764
int avpicture_fill(AVPicture *picture, uint8_t *ptr,
765
                   enum PixelFormat pix_fmt, int width, int height)
766
{
767

    
768
    if(avcodec_check_dimensions(NULL, width, height))
769
        return -1;
770

    
771
    if (ff_fill_linesize(picture, pix_fmt, width))
772
        return -1;
773

    
774
    return ff_fill_pointer(picture, ptr, pix_fmt, height);
775
}
776

    
777
int avpicture_layout(const AVPicture* src, enum PixelFormat pix_fmt, int width, int height,
778
                     unsigned char *dest, int dest_size)
779
{
780
    const PixFmtInfo* pf = &pix_fmt_info[pix_fmt];
781
    int i, j, w, ow, h, oh, data_planes;
782
    const unsigned char* s;
783
    int size = avpicture_get_size(pix_fmt, width, height);
784

    
785
    if (size > dest_size || size < 0)
786
        return -1;
787

    
788
    if (pf->pixel_type == FF_PIXEL_PACKED || pf->pixel_type == FF_PIXEL_PALETTE) {
789
        if (pix_fmt == PIX_FMT_YUYV422 ||
790
            pix_fmt == PIX_FMT_UYVY422 ||
791
            pix_fmt == PIX_FMT_BGR565 ||
792
            pix_fmt == PIX_FMT_BGR555 ||
793
            pix_fmt == PIX_FMT_RGB565 ||
794
            pix_fmt == PIX_FMT_RGB555)
795
            w = width * 2;
796
        else if (pix_fmt == PIX_FMT_UYYVYY411)
797
          w = width + width/2;
798
        else if (pix_fmt == PIX_FMT_PAL8)
799
          w = width;
800
        else
801
          w = width * (pf->depth * pf->nb_channels / 8);
802

    
803
        data_planes = 1;
804
        h = height;
805
    } else {
806
        data_planes = pf->nb_channels;
807
        w = (width*pf->depth + 7)/8;
808
        h = height;
809
    }
810

    
811
    ow = w;
812
    oh = h;
813

    
814
    for (i=0; i<data_planes; i++) {
815
         if (i == 1) {
816
             w = width >> pf->x_chroma_shift;
817
             h = height >> pf->y_chroma_shift;
818
         } else if (i == 3) {
819
             w = ow;
820
             h = oh;
821
         }
822
         s = src->data[i];
823
         for(j=0; j<h; j++) {
824
             memcpy(dest, s, w);
825
             dest += w;
826
             s += src->linesize[i];
827
         }
828
    }
829

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

    
833
    return size;
834
}
835

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

    
853
int avcodec_get_pix_fmt_loss(enum PixelFormat dst_pix_fmt, enum PixelFormat src_pix_fmt,
854
                             int has_alpha)
855
{
856
    const PixFmtInfo *pf, *ps;
857
    int loss;
858

    
859
    ps = &pix_fmt_info[src_pix_fmt];
860
    pf = &pix_fmt_info[dst_pix_fmt];
861

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

    
908
static int avg_bits_per_pixel(enum PixelFormat pix_fmt)
909
{
910
    int bits;
911
    const PixFmtInfo *pf;
912

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

    
951
static enum PixelFormat avcodec_find_best_pix_fmt1(int64_t pix_fmt_mask,
952
                                      enum PixelFormat src_pix_fmt,
953
                                      int has_alpha,
954
                                      int loss_mask)
955
{
956
    int dist, i, loss, min_dist;
957
    enum PixelFormat dst_pix_fmt;
958

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

    
977
enum PixelFormat avcodec_find_best_pix_fmt(int64_t pix_fmt_mask, enum PixelFormat src_pix_fmt,
978
                              int has_alpha, int *loss_ptr)
979
{
980
    enum PixelFormat dst_pix_fmt;
981
    int loss_mask, i;
982
    static const int loss_mask_order[] = {
983
        ~0, /* no loss first */
984
        ~FF_LOSS_ALPHA,
985
        ~FF_LOSS_RESOLUTION,
986
        ~(FF_LOSS_COLORSPACE | FF_LOSS_RESOLUTION),
987
        ~FF_LOSS_COLORQUANT,
988
        ~FF_LOSS_DEPTH,
989
        0,
990
    };
991

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

    
1010
void ff_img_copy_plane(uint8_t *dst, int dst_wrap,
1011
                           const uint8_t *src, int src_wrap,
1012
                           int width, int height)
1013
{
1014
    if((!dst) || (!src))
1015
        return;
1016
    for(;height > 0; height--) {
1017
        memcpy(dst, src, width);
1018
        dst += dst_wrap;
1019
        src += src_wrap;
1020
    }
1021
}
1022

    
1023
int ff_get_plane_bytewidth(enum PixelFormat pix_fmt, int width, int plane)
1024
{
1025
    int bits;
1026
    const PixFmtInfo *pf = &pix_fmt_info[pix_fmt];
1027

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

    
1053
            return (width * pf->depth + 7) >> 3;
1054
        break;
1055
    case FF_PIXEL_PALETTE:
1056
        if (plane == 0)
1057
            return width;
1058
        break;
1059
    }
1060

    
1061
    return -1;
1062
}
1063

    
1064
void av_picture_copy(AVPicture *dst, const AVPicture *src,
1065
                     enum PixelFormat pix_fmt, int width, int height)
1066
{
1067
    int i;
1068
    const PixFmtInfo *pf = &pix_fmt_info[pix_fmt];
1069

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

    
1098
/* 2x2 -> 1x1 */
1099
void ff_shrink22(uint8_t *dst, int dst_wrap,
1100
                     const uint8_t *src, int src_wrap,
1101
                     int width, int height)
1102
{
1103
    int w;
1104
    const uint8_t *s1, *s2;
1105
    uint8_t *d;
1106

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

    
1131
/* 4x4 -> 1x1 */
1132
void ff_shrink44(uint8_t *dst, int dst_wrap,
1133
                     const uint8_t *src, int src_wrap,
1134
                     int width, int height)
1135
{
1136
    int w;
1137
    const uint8_t *s1, *s2, *s3, *s4;
1138
    uint8_t *d;
1139

    
1140
    for(;height > 0; height--) {
1141
        s1 = src;
1142
        s2 = s1 + src_wrap;
1143
        s3 = s2 + src_wrap;
1144
        s4 = s3 + src_wrap;
1145
        d = dst;
1146
        for(w = width;w > 0; w--) {
1147
            d[0] = (s1[0] + s1[1] + s1[2] + s1[3] +
1148
                    s2[0] + s2[1] + s2[2] + s2[3] +
1149
                    s3[0] + s3[1] + s3[2] + s3[3] +
1150
                    s4[0] + s4[1] + s4[2] + s4[3] + 8) >> 4;
1151
            s1 += 4;
1152
            s2 += 4;
1153
            s3 += 4;
1154
            s4 += 4;
1155
            d++;
1156
        }
1157
        src += 4 * src_wrap;
1158
        dst += dst_wrap;
1159
    }
1160
}
1161

    
1162
/* 8x8 -> 1x1 */
1163
void ff_shrink88(uint8_t *dst, int dst_wrap,
1164
                     const uint8_t *src, int src_wrap,
1165
                     int width, int height)
1166
{
1167
    int w, i;
1168

    
1169
    for(;height > 0; height--) {
1170
        for(w = width;w > 0; w--) {
1171
            int tmp=0;
1172
            for(i=0; i<8; i++){
1173
                tmp += src[0] + src[1] + src[2] + src[3] + src[4] + src[5] + src[6] + src[7];
1174
                src += src_wrap;
1175
            }
1176
            *(dst++) = (tmp + 32)>>6;
1177
            src += 8 - 8*src_wrap;
1178
        }
1179
        src += 8*src_wrap - 8*width;
1180
        dst += dst_wrap - width;
1181
    }
1182
}
1183

    
1184

    
1185
int avpicture_alloc(AVPicture *picture,
1186
                    enum PixelFormat pix_fmt, int width, int height)
1187
{
1188
    int size;
1189
    void *ptr;
1190

    
1191
    size = avpicture_fill(picture, NULL, pix_fmt, width, height);
1192
    if(size<0)
1193
        goto fail;
1194
    ptr = av_malloc(size);
1195
    if (!ptr)
1196
        goto fail;
1197
    avpicture_fill(picture, ptr, pix_fmt, width, height);
1198
    if(picture->data[1] && !picture->data[2])
1199
        ff_set_systematic_pal((uint32_t*)picture->data[1], pix_fmt);
1200

    
1201
    return 0;
1202
 fail:
1203
    memset(picture, 0, sizeof(AVPicture));
1204
    return -1;
1205
}
1206

    
1207
void avpicture_free(AVPicture *picture)
1208
{
1209
    av_free(picture->data[0]);
1210
}
1211

    
1212
/* return true if yuv planar */
1213
static inline int is_yuv_planar(const PixFmtInfo *ps)
1214
{
1215
    return (ps->color_type == FF_COLOR_YUV ||
1216
            ps->color_type == FF_COLOR_YUV_JPEG) &&
1217
        ps->pixel_type == FF_PIXEL_PLANAR;
1218
}
1219

    
1220
int av_picture_crop(AVPicture *dst, const AVPicture *src,
1221
              int pix_fmt, int top_band, int left_band)
1222
{
1223
    int y_shift;
1224
    int x_shift;
1225

    
1226
    if (pix_fmt < 0 || pix_fmt >= PIX_FMT_NB || !is_yuv_planar(&pix_fmt_info[pix_fmt]))
1227
        return -1;
1228

    
1229
    y_shift = pix_fmt_info[pix_fmt].y_chroma_shift;
1230
    x_shift = pix_fmt_info[pix_fmt].x_chroma_shift;
1231

    
1232
    dst->data[0] = src->data[0] + (top_band * src->linesize[0]) + left_band;
1233
    dst->data[1] = src->data[1] + ((top_band >> y_shift) * src->linesize[1]) + (left_band >> x_shift);
1234
    dst->data[2] = src->data[2] + ((top_band >> y_shift) * src->linesize[2]) + (left_band >> x_shift);
1235

    
1236
    dst->linesize[0] = src->linesize[0];
1237
    dst->linesize[1] = src->linesize[1];
1238
    dst->linesize[2] = src->linesize[2];
1239
    return 0;
1240
}
1241

    
1242
int av_picture_pad(AVPicture *dst, const AVPicture *src, int height, int width,
1243
                   enum PixelFormat pix_fmt, int padtop, int padbottom, int padleft, int padright,
1244
            int *color)
1245
{
1246
    uint8_t *optr;
1247
    int y_shift;
1248
    int x_shift;
1249
    int yheight;
1250
    int i, y;
1251

    
1252
    if (pix_fmt < 0 || pix_fmt >= PIX_FMT_NB ||
1253
        !is_yuv_planar(&pix_fmt_info[pix_fmt])) return -1;
1254

    
1255
    for (i = 0; i < 3; i++) {
1256
        x_shift = i ? pix_fmt_info[pix_fmt].x_chroma_shift : 0;
1257
        y_shift = i ? pix_fmt_info[pix_fmt].y_chroma_shift : 0;
1258

    
1259
        if (padtop || padleft) {
1260
            memset(dst->data[i], color[i],
1261
                dst->linesize[i] * (padtop >> y_shift) + (padleft >> x_shift));
1262
        }
1263

    
1264
        if (padleft || padright) {
1265
            optr = dst->data[i] + dst->linesize[i] * (padtop >> y_shift) +
1266
                (dst->linesize[i] - (padright >> x_shift));
1267
            yheight = (height - 1 - (padtop + padbottom)) >> y_shift;
1268
            for (y = 0; y < yheight; y++) {
1269
                memset(optr, color[i], (padleft + padright) >> x_shift);
1270
                optr += dst->linesize[i];
1271
            }
1272
        }
1273

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

    
1292
        if (padbottom || padright) {
1293
            optr = dst->data[i] + dst->linesize[i] *
1294
                ((height - padbottom) >> y_shift) - (padright >> x_shift);
1295
            memset(optr, color[i],dst->linesize[i] *
1296
                (padbottom >> y_shift) + (padright >> x_shift));
1297
        }
1298
    }
1299
    return 0;
1300
}
1301

    
1302
/* NOTE: we scan all the pixels to have an exact information */
1303
static int get_alpha_info_pal8(const AVPicture *src, int width, int height)
1304
{
1305
    const unsigned char *p;
1306
    int src_wrap, ret, x, y;
1307
    unsigned int a;
1308
    uint32_t *palette = (uint32_t *)src->data[1];
1309

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

    
1328
int img_get_alpha_info(const AVPicture *src,
1329
                       enum PixelFormat pix_fmt, int width, int height)
1330
{
1331
    const PixFmtInfo *pf = &pix_fmt_info[pix_fmt];
1332
    int ret;
1333

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

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

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

    
1397
/* filter parameters: [-1 4 2 4 -1] // 8 */
1398
static void deinterlace_line(uint8_t *dst,
1399
                             const uint8_t *lum_m4, const uint8_t *lum_m3,
1400
                             const uint8_t *lum_m2, const uint8_t *lum_m1,
1401
                             const uint8_t *lum,
1402
                             int size)
1403
{
1404
#if !HAVE_MMX
1405
    uint8_t *cm = ff_cropTbl + MAX_NEG_CROP;
1406
    int sum;
1407

    
1408
    for(;size > 0;size--) {
1409
        sum = -lum_m4[0];
1410
        sum += lum_m3[0] << 2;
1411
        sum += lum_m2[0] << 1;
1412
        sum += lum_m1[0] << 2;
1413
        sum += -lum[0];
1414
        dst[0] = cm[(sum + 4) >> 3];
1415
        lum_m4++;
1416
        lum_m3++;
1417
        lum_m2++;
1418
        lum_m1++;
1419
        lum++;
1420
        dst++;
1421
    }
1422
#else
1423

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

    
1446
    for(;size > 0;size--) {
1447
        sum = -lum_m4[0];
1448
        sum += lum_m3[0] << 2;
1449
        sum += lum_m2[0] << 1;
1450
        lum_m4[0]=lum_m2[0];
1451
        sum += lum_m1[0] << 2;
1452
        sum += -lum[0];
1453
        lum_m2[0] = cm[(sum + 4) >> 3];
1454
        lum_m4++;
1455
        lum_m3++;
1456
        lum_m2++;
1457
        lum_m1++;
1458
        lum++;
1459
    }
1460
#else
1461

    
1462
    {
1463
        pxor_r2r(mm7,mm7);
1464
        movq_m2r(ff_pw_4,mm6);
1465
    }
1466
    for (;size > 3; size-=4) {
1467
        DEINT_INPLACE_LINE_LUM
1468
        lum_m4+=4;
1469
        lum_m3+=4;
1470
        lum_m2+=4;
1471
        lum_m1+=4;
1472
        lum+=4;
1473
    }
1474
#endif
1475
}
1476

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

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

    
1509
static void deinterlace_bottom_field_inplace(uint8_t *src1, int src_wrap,
1510
                                             int width, int height)
1511
{
1512
    uint8_t *src_m1, *src_0, *src_p1, *src_p2;
1513
    int y;
1514
    uint8_t *buf;
1515
    buf = (uint8_t*)av_malloc(width);
1516

    
1517
    src_m1 = src1;
1518
    memcpy(buf,src_m1,width);
1519
    src_0=&src_m1[src_wrap];
1520
    src_p1=&src_0[src_wrap];
1521
    src_p2=&src_p1[src_wrap];
1522
    for(y=0;y<(height-2);y+=2) {
1523
        deinterlace_line_inplace(buf,src_m1,src_0,src_p1,src_p2,width);
1524
        src_m1 = src_p1;
1525
        src_0 = src_p2;
1526
        src_p1 += 2*src_wrap;
1527
        src_p2 += 2*src_wrap;
1528
    }
1529
    /* do last line */
1530
    deinterlace_line_inplace(buf,src_m1,src_0,src_0,src_0,width);
1531
    av_free(buf);
1532
}
1533

    
1534
int avpicture_deinterlace(AVPicture *dst, const AVPicture *src,
1535
                          enum PixelFormat pix_fmt, int width, int height)
1536
{
1537
    int i;
1538

    
1539
    if (pix_fmt != PIX_FMT_YUV420P &&
1540
        pix_fmt != PIX_FMT_YUV422P &&
1541
        pix_fmt != PIX_FMT_YUV444P &&
1542
        pix_fmt != PIX_FMT_YUV411P &&
1543
        pix_fmt != PIX_FMT_GRAY8)
1544
        return -1;
1545
    if ((width & 3) != 0 || (height & 3) != 0)
1546
        return -1;
1547

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