Statistics
| Branch: | Revision:

ffmpeg / libavcodec / imgconvert.c @ 35f6c154

History | View | Annotate | Download (47.7 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
    [PIX_FMT_YUV420P16LE] = {
134
        .name = "yuv420p16le",
135
        .nb_channels = 3,
136
        .color_type = FF_COLOR_YUV,
137
        .pixel_type = FF_PIXEL_PLANAR,
138
        .depth = 16,
139
        .x_chroma_shift = 1, .y_chroma_shift = 1,
140
    },
141
    [PIX_FMT_YUV422P16LE] = {
142
        .name = "yuv422p16le",
143
        .nb_channels = 3,
144
        .color_type = FF_COLOR_YUV,
145
        .pixel_type = FF_PIXEL_PLANAR,
146
        .depth = 16,
147
        .x_chroma_shift = 1, .y_chroma_shift = 0,
148
    },
149
    [PIX_FMT_YUV444P16LE] = {
150
        .name = "yuv444p16le",
151
        .nb_channels = 3,
152
        .color_type = FF_COLOR_YUV,
153
        .pixel_type = FF_PIXEL_PLANAR,
154
        .depth = 16,
155
        .x_chroma_shift = 0, .y_chroma_shift = 0,
156
    },
157
    [PIX_FMT_YUV420P16BE] = {
158
        .name = "yuv420p16be",
159
        .nb_channels = 3,
160
        .color_type = FF_COLOR_YUV,
161
        .pixel_type = FF_PIXEL_PLANAR,
162
        .depth = 16,
163
        .x_chroma_shift = 1, .y_chroma_shift = 1,
164
    },
165
    [PIX_FMT_YUV422P16BE] = {
166
        .name = "yuv422p16be",
167
        .nb_channels = 3,
168
        .color_type = FF_COLOR_YUV,
169
        .pixel_type = FF_PIXEL_PLANAR,
170
        .depth = 16,
171
        .x_chroma_shift = 1, .y_chroma_shift = 0,
172
    },
173
    [PIX_FMT_YUV444P16BE] = {
174
        .name = "yuv444p16be",
175
        .nb_channels = 3,
176
        .color_type = FF_COLOR_YUV,
177
        .pixel_type = FF_PIXEL_PLANAR,
178
        .depth = 16,
179
        .x_chroma_shift = 0, .y_chroma_shift = 0,
180
    },
181

    
182

    
183
    /* YUV formats with alpha plane */
184
    [PIX_FMT_YUVA420P] = {
185
        .name = "yuva420p",
186
        .nb_channels = 4,
187
        .color_type = FF_COLOR_YUV,
188
        .pixel_type = FF_PIXEL_PLANAR,
189
        .depth = 8,
190
        .x_chroma_shift = 1, .y_chroma_shift = 1,
191
    },
192

    
193
    /* JPEG YUV */
194
    [PIX_FMT_YUVJ420P] = {
195
        .name = "yuvj420p",
196
        .nb_channels = 3,
197
        .color_type = FF_COLOR_YUV_JPEG,
198
        .pixel_type = FF_PIXEL_PLANAR,
199
        .depth = 8,
200
        .x_chroma_shift = 1, .y_chroma_shift = 1,
201
    },
202
    [PIX_FMT_YUVJ422P] = {
203
        .name = "yuvj422p",
204
        .nb_channels = 3,
205
        .color_type = FF_COLOR_YUV_JPEG,
206
        .pixel_type = FF_PIXEL_PLANAR,
207
        .depth = 8,
208
        .x_chroma_shift = 1, .y_chroma_shift = 0,
209
    },
210
    [PIX_FMT_YUVJ444P] = {
211
        .name = "yuvj444p",
212
        .nb_channels = 3,
213
        .color_type = FF_COLOR_YUV_JPEG,
214
        .pixel_type = FF_PIXEL_PLANAR,
215
        .depth = 8,
216
        .x_chroma_shift = 0, .y_chroma_shift = 0,
217
    },
218
    [PIX_FMT_YUVJ440P] = {
219
        .name = "yuvj440p",
220
        .nb_channels = 3,
221
        .color_type = FF_COLOR_YUV_JPEG,
222
        .pixel_type = FF_PIXEL_PLANAR,
223
        .depth = 8,
224
        .x_chroma_shift = 0, .y_chroma_shift = 1,
225
    },
226

    
227
    /* RGB formats */
228
    [PIX_FMT_RGB24] = {
229
        .name = "rgb24",
230
        .nb_channels = 3,
231
        .color_type = FF_COLOR_RGB,
232
        .pixel_type = FF_PIXEL_PACKED,
233
        .depth = 8,
234
        .x_chroma_shift = 0, .y_chroma_shift = 0,
235
    },
236
    [PIX_FMT_BGR24] = {
237
        .name = "bgr24",
238
        .nb_channels = 3,
239
        .color_type = FF_COLOR_RGB,
240
        .pixel_type = FF_PIXEL_PACKED,
241
        .depth = 8,
242
        .x_chroma_shift = 0, .y_chroma_shift = 0,
243
    },
244
    [PIX_FMT_ARGB] = {
245
        .name = "argb",
246
        .nb_channels = 4, .is_alpha = 1,
247
        .color_type = FF_COLOR_RGB,
248
        .pixel_type = FF_PIXEL_PACKED,
249
        .depth = 8,
250
        .x_chroma_shift = 0, .y_chroma_shift = 0,
251
    },
252
    [PIX_FMT_RGB48BE] = {
253
        .name = "rgb48be",
254
        .nb_channels = 3,
255
        .color_type = FF_COLOR_RGB,
256
        .pixel_type = FF_PIXEL_PACKED,
257
        .depth = 16,
258
        .x_chroma_shift = 0, .y_chroma_shift = 0,
259
    },
260
    [PIX_FMT_RGB48LE] = {
261
        .name = "rgb48le",
262
        .nb_channels = 3,
263
        .color_type = FF_COLOR_RGB,
264
        .pixel_type = FF_PIXEL_PACKED,
265
        .depth = 16,
266
        .x_chroma_shift = 0, .y_chroma_shift = 0,
267
    },
268
    [PIX_FMT_RGB565BE] = {
269
        .name = "rgb565be",
270
        .nb_channels = 3,
271
        .color_type = FF_COLOR_RGB,
272
        .pixel_type = FF_PIXEL_PACKED,
273
        .depth = 5,
274
        .x_chroma_shift = 0, .y_chroma_shift = 0,
275
    },
276
    [PIX_FMT_RGB565LE] = {
277
        .name = "rgb565le",
278
        .nb_channels = 3,
279
        .color_type = FF_COLOR_RGB,
280
        .pixel_type = FF_PIXEL_PACKED,
281
        .depth = 5,
282
        .x_chroma_shift = 0, .y_chroma_shift = 0,
283
    },
284
    [PIX_FMT_RGB555BE] = {
285
        .name = "rgb555be",
286
        .nb_channels = 3,
287
        .color_type = FF_COLOR_RGB,
288
        .pixel_type = FF_PIXEL_PACKED,
289
        .depth = 5,
290
        .x_chroma_shift = 0, .y_chroma_shift = 0,
291
    },
292
    [PIX_FMT_RGB555LE] = {
293
        .name = "rgb555le",
294
        .nb_channels = 3,
295
        .color_type = FF_COLOR_RGB,
296
        .pixel_type = FF_PIXEL_PACKED,
297
        .depth = 5,
298
        .x_chroma_shift = 0, .y_chroma_shift = 0,
299
    },
300

    
301
    /* gray / mono formats */
302
    [PIX_FMT_GRAY16BE] = {
303
        .name = "gray16be",
304
        .nb_channels = 1,
305
        .color_type = FF_COLOR_GRAY,
306
        .pixel_type = FF_PIXEL_PLANAR,
307
        .depth = 16,
308
    },
309
    [PIX_FMT_GRAY16LE] = {
310
        .name = "gray16le",
311
        .nb_channels = 1,
312
        .color_type = FF_COLOR_GRAY,
313
        .pixel_type = FF_PIXEL_PLANAR,
314
        .depth = 16,
315
    },
316
    [PIX_FMT_GRAY8] = {
317
        .name = "gray",
318
        .nb_channels = 1,
319
        .color_type = FF_COLOR_GRAY,
320
        .pixel_type = FF_PIXEL_PLANAR,
321
        .depth = 8,
322
    },
323
    [PIX_FMT_MONOWHITE] = {
324
        .name = "monow",
325
        .nb_channels = 1,
326
        .color_type = FF_COLOR_GRAY,
327
        .pixel_type = FF_PIXEL_PLANAR,
328
        .depth = 1,
329
    },
330
    [PIX_FMT_MONOBLACK] = {
331
        .name = "monob",
332
        .nb_channels = 1,
333
        .color_type = FF_COLOR_GRAY,
334
        .pixel_type = FF_PIXEL_PLANAR,
335
        .depth = 1,
336
    },
337

    
338
    /* paletted formats */
339
    [PIX_FMT_PAL8] = {
340
        .name = "pal8",
341
        .nb_channels = 4, .is_alpha = 1,
342
        .color_type = FF_COLOR_RGB,
343
        .pixel_type = FF_PIXEL_PALETTE,
344
        .depth = 8,
345
    },
346
    [PIX_FMT_XVMC_MPEG2_MC] = {
347
        .name = "xvmcmc",
348
        .is_hwaccel = 1,
349
    },
350
    [PIX_FMT_XVMC_MPEG2_IDCT] = {
351
        .name = "xvmcidct",
352
        .is_hwaccel = 1,
353
    },
354
    [PIX_FMT_VDPAU_MPEG1] = {
355
        .name = "vdpau_mpeg1",
356
        .is_hwaccel = 1,
357
        .x_chroma_shift = 1, .y_chroma_shift = 1,
358
    },
359
    [PIX_FMT_VDPAU_MPEG2] = {
360
        .name = "vdpau_mpeg2",
361
        .is_hwaccel = 1,
362
        .x_chroma_shift = 1, .y_chroma_shift = 1,
363
    },
364
    [PIX_FMT_VDPAU_H264] = {
365
        .name = "vdpau_h264",
366
        .is_hwaccel = 1,
367
        .x_chroma_shift = 1, .y_chroma_shift = 1,
368
    },
369
    [PIX_FMT_VDPAU_WMV3] = {
370
        .name = "vdpau_wmv3",
371
        .is_hwaccel = 1,
372
        .x_chroma_shift = 1, .y_chroma_shift = 1,
373
    },
374
    [PIX_FMT_VDPAU_VC1] = {
375
        .name = "vdpau_vc1",
376
        .is_hwaccel = 1,
377
        .x_chroma_shift = 1, .y_chroma_shift = 1,
378
    },
379
    [PIX_FMT_UYYVYY411] = {
380
        .name = "uyyvyy411",
381
        .nb_channels = 1,
382
        .color_type = FF_COLOR_YUV,
383
        .pixel_type = FF_PIXEL_PACKED,
384
        .depth = 8,
385
        .x_chroma_shift = 2, .y_chroma_shift = 0,
386
    },
387
    [PIX_FMT_ABGR] = {
388
        .name = "abgr",
389
        .nb_channels = 4, .is_alpha = 1,
390
        .color_type = FF_COLOR_RGB,
391
        .pixel_type = FF_PIXEL_PACKED,
392
        .depth = 8,
393
        .x_chroma_shift = 0, .y_chroma_shift = 0,
394
    },
395
    [PIX_FMT_BGR565BE] = {
396
        .name = "bgr565be",
397
        .nb_channels = 3,
398
        .color_type = FF_COLOR_RGB,
399
        .pixel_type = FF_PIXEL_PACKED,
400
        .depth = 5,
401
        .x_chroma_shift = 0, .y_chroma_shift = 0,
402
    },
403
    [PIX_FMT_BGR565LE] = {
404
        .name = "bgr565le",
405
        .nb_channels = 3,
406
        .color_type = FF_COLOR_RGB,
407
        .pixel_type = FF_PIXEL_PACKED,
408
        .depth = 5,
409
        .x_chroma_shift = 0, .y_chroma_shift = 0,
410
    },
411
    [PIX_FMT_BGR555BE] = {
412
        .name = "bgr555be",
413
        .nb_channels = 3,
414
        .color_type = FF_COLOR_RGB,
415
        .pixel_type = FF_PIXEL_PACKED,
416
        .depth = 5,
417
        .x_chroma_shift = 0, .y_chroma_shift = 0,
418
    },
419
    [PIX_FMT_BGR555LE] = {
420
        .name = "bgr555le",
421
        .nb_channels = 3,
422
        .color_type = FF_COLOR_RGB,
423
        .pixel_type = FF_PIXEL_PACKED,
424
        .depth = 5,
425
        .x_chroma_shift = 0, .y_chroma_shift = 0,
426
    },
427
    [PIX_FMT_RGB8] = {
428
        .name = "rgb8",
429
        .nb_channels = 1,
430
        .color_type = FF_COLOR_RGB,
431
        .pixel_type = FF_PIXEL_PACKED,
432
        .depth = 8,
433
        .x_chroma_shift = 0, .y_chroma_shift = 0,
434
    },
435
    [PIX_FMT_RGB4] = {
436
        .name = "rgb4",
437
        .nb_channels = 1,
438
        .color_type = FF_COLOR_RGB,
439
        .pixel_type = FF_PIXEL_PACKED,
440
        .depth = 4,
441
        .x_chroma_shift = 0, .y_chroma_shift = 0,
442
    },
443
    [PIX_FMT_RGB4_BYTE] = {
444
        .name = "rgb4_byte",
445
        .nb_channels = 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_BGR8] = {
452
        .name = "bgr8",
453
        .nb_channels = 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
    [PIX_FMT_BGR4] = {
460
        .name = "bgr4",
461
        .nb_channels = 1,
462
        .color_type = FF_COLOR_RGB,
463
        .pixel_type = FF_PIXEL_PACKED,
464
        .depth = 4,
465
        .x_chroma_shift = 0, .y_chroma_shift = 0,
466
    },
467
    [PIX_FMT_BGR4_BYTE] = {
468
        .name = "bgr4_byte",
469
        .nb_channels = 1,
470
        .color_type = FF_COLOR_RGB,
471
        .pixel_type = FF_PIXEL_PACKED,
472
        .depth = 8,
473
        .x_chroma_shift = 0, .y_chroma_shift = 0,
474
    },
475
    [PIX_FMT_NV12] = {
476
        .name = "nv12",
477
        .nb_channels = 2,
478
        .color_type = FF_COLOR_YUV,
479
        .pixel_type = FF_PIXEL_PLANAR,
480
        .depth = 8,
481
        .x_chroma_shift = 1, .y_chroma_shift = 1,
482
    },
483
    [PIX_FMT_NV21] = {
484
        .name = "nv12",
485
        .nb_channels = 2,
486
        .color_type = FF_COLOR_YUV,
487
        .pixel_type = FF_PIXEL_PLANAR,
488
        .depth = 8,
489
        .x_chroma_shift = 1, .y_chroma_shift = 1,
490
    },
491

    
492
    [PIX_FMT_BGRA] = {
493
        .name = "bgra",
494
        .nb_channels = 4, .is_alpha = 1,
495
        .color_type = FF_COLOR_RGB,
496
        .pixel_type = FF_PIXEL_PACKED,
497
        .depth = 8,
498
        .x_chroma_shift = 0, .y_chroma_shift = 0,
499
    },
500
    [PIX_FMT_RGBA] = {
501
        .name = "rgba",
502
        .nb_channels = 4, .is_alpha = 1,
503
        .color_type = FF_COLOR_RGB,
504
        .pixel_type = FF_PIXEL_PACKED,
505
        .depth = 8,
506
        .x_chroma_shift = 0, .y_chroma_shift = 0,
507
    },
508

    
509
    /* VA API formats */
510
    [PIX_FMT_VAAPI_MOCO] = {
511
        .name = "vaapi_moco",
512
        .is_hwaccel = 1,
513
        .x_chroma_shift = 1, .y_chroma_shift = 1,
514
    },
515
    [PIX_FMT_VAAPI_IDCT] = {
516
        .name = "vaapi_idct",
517
        .is_hwaccel = 1,
518
        .x_chroma_shift = 1, .y_chroma_shift = 1,
519
    },
520
    [PIX_FMT_VAAPI_VLD] = {
521
        .name = "vaapi_vld",
522
        .is_hwaccel = 1,
523
        .x_chroma_shift = 1, .y_chroma_shift = 1,
524
    },
525
};
526

    
527
void avcodec_get_chroma_sub_sample(enum PixelFormat pix_fmt, int *h_shift, int *v_shift)
528
{
529
    *h_shift = pix_fmt_info[pix_fmt].x_chroma_shift;
530
    *v_shift = pix_fmt_info[pix_fmt].y_chroma_shift;
531
}
532

    
533
const char *avcodec_get_pix_fmt_name(enum PixelFormat pix_fmt)
534
{
535
    if (pix_fmt < 0 || pix_fmt >= PIX_FMT_NB)
536
        return NULL;
537
    else
538
        return pix_fmt_info[pix_fmt].name;
539
}
540

    
541
static enum PixelFormat avcodec_get_pix_fmt_internal(const char *name)
542
{
543
    int i;
544

    
545
    for (i=0; i < PIX_FMT_NB; i++)
546
        if (pix_fmt_info[i].name && !strcmp(pix_fmt_info[i].name, name))
547
            return i;
548
    return PIX_FMT_NONE;
549
}
550

    
551
#if HAVE_BIGENDIAN
552
#   define X_NE(be, le) be
553
#else
554
#   define X_NE(be, le) le
555
#endif
556

    
557
enum PixelFormat avcodec_get_pix_fmt(const char *name)
558
{
559
    enum PixelFormat pix_fmt;
560

    
561
    if (!strcmp(name, "rgb32"))
562
        name = X_NE("argb", "bgra");
563
    else if (!strcmp(name, "bgr32"))
564
        name = X_NE("abgr", "rgba");
565

    
566
    pix_fmt = avcodec_get_pix_fmt_internal(name);
567
    if (pix_fmt == PIX_FMT_NONE) {
568
        char name2[32];
569
        snprintf(name2, sizeof(name2), "%s%s", name, X_NE("be", "le"));
570
        pix_fmt = avcodec_get_pix_fmt_internal(name2);
571
    }
572
    return pix_fmt;
573
}
574

    
575
void avcodec_pix_fmt_string (char *buf, int buf_size, enum PixelFormat pix_fmt)
576
{
577
    /* print header */
578
    if (pix_fmt < 0)
579
        snprintf (buf, buf_size,
580
                  "name      " " nb_channels" " depth" " is_alpha"
581
            );
582
    else{
583
        PixFmtInfo info= pix_fmt_info[pix_fmt];
584

    
585
        char is_alpha_char= info.is_alpha ? 'y' : 'n';
586

    
587
        snprintf (buf, buf_size,
588
                  "%-10s" "      %1d     " "   %2d " "     %c   ",
589
                  info.name,
590
                  info.nb_channels,
591
                  info.depth,
592
                  is_alpha_char
593
            );
594
    }
595
}
596

    
597
int ff_is_hwaccel_pix_fmt(enum PixelFormat pix_fmt)
598
{
599
    return pix_fmt_info[pix_fmt].is_hwaccel;
600
}
601

    
602
int ff_set_systematic_pal(uint32_t pal[256], enum PixelFormat pix_fmt){
603
    int i;
604

    
605
    for(i=0; i<256; i++){
606
        int r,g,b;
607

    
608
        switch(pix_fmt) {
609
        case PIX_FMT_RGB8:
610
            r= (i>>5    )*36;
611
            g= ((i>>2)&7)*36;
612
            b= (i&3     )*85;
613
            break;
614
        case PIX_FMT_BGR8:
615
            b= (i>>6    )*85;
616
            g= ((i>>3)&7)*36;
617
            r= (i&7     )*36;
618
            break;
619
        case PIX_FMT_RGB4_BYTE:
620
            r= (i>>3    )*255;
621
            g= ((i>>1)&3)*85;
622
            b= (i&1     )*255;
623
            break;
624
        case PIX_FMT_BGR4_BYTE:
625
            b= (i>>3    )*255;
626
            g= ((i>>1)&3)*85;
627
            r= (i&1     )*255;
628
            break;
629
        case PIX_FMT_GRAY8:
630
            r=b=g= i;
631
            break;
632
        default:
633
            return -1;
634
        }
635
        pal[i] =  b + (g<<8) + (r<<16);
636
    }
637

    
638
    return 0;
639
}
640

    
641
int ff_fill_linesize(AVPicture *picture, enum PixelFormat pix_fmt, int width)
642
{
643
    int w2;
644
    const PixFmtInfo *pinfo;
645

    
646
    memset(picture->linesize, 0, sizeof(picture->linesize));
647

    
648
    pinfo = &pix_fmt_info[pix_fmt];
649
    switch(pix_fmt) {
650
    case PIX_FMT_YUV420P:
651
    case PIX_FMT_YUV422P:
652
    case PIX_FMT_YUV444P:
653
    case PIX_FMT_YUV410P:
654
    case PIX_FMT_YUV411P:
655
    case PIX_FMT_YUV440P:
656
    case PIX_FMT_YUVJ420P:
657
    case PIX_FMT_YUVJ422P:
658
    case PIX_FMT_YUVJ444P:
659
    case PIX_FMT_YUVJ440P:
660
        w2 = (width + (1 << pinfo->x_chroma_shift) - 1) >> pinfo->x_chroma_shift;
661
        picture->linesize[0] = width;
662
        picture->linesize[1] = w2;
663
        picture->linesize[2] = w2;
664
        break;
665
    case PIX_FMT_YUV420P16LE:
666
    case PIX_FMT_YUV422P16LE:
667
    case PIX_FMT_YUV444P16LE:
668
    case PIX_FMT_YUV420P16BE:
669
    case PIX_FMT_YUV422P16BE:
670
    case PIX_FMT_YUV444P16BE:
671
        w2 = (width + (1 << pinfo->x_chroma_shift) - 1) >> pinfo->x_chroma_shift;
672
        picture->linesize[0] = 2*width;
673
        picture->linesize[1] = 2*w2;
674
        picture->linesize[2] = 2*w2;
675
        break;
676
    case PIX_FMT_YUVA420P:
677
        w2 = (width + (1 << pinfo->x_chroma_shift) - 1) >> pinfo->x_chroma_shift;
678
        picture->linesize[0] = width;
679
        picture->linesize[1] = w2;
680
        picture->linesize[2] = w2;
681
        picture->linesize[3] = width;
682
        break;
683
    case PIX_FMT_NV12:
684
    case PIX_FMT_NV21:
685
        w2 = (width + (1 << pinfo->x_chroma_shift) - 1) >> pinfo->x_chroma_shift;
686
        picture->linesize[0] = width;
687
        picture->linesize[1] = w2;
688
        break;
689
    case PIX_FMT_RGB24:
690
    case PIX_FMT_BGR24:
691
        picture->linesize[0] = width * 3;
692
        break;
693
    case PIX_FMT_ARGB:
694
    case PIX_FMT_ABGR:
695
    case PIX_FMT_RGBA:
696
    case PIX_FMT_BGRA:
697
        picture->linesize[0] = width * 4;
698
        break;
699
    case PIX_FMT_RGB48BE:
700
    case PIX_FMT_RGB48LE:
701
        picture->linesize[0] = width * 6;
702
        break;
703
    case PIX_FMT_GRAY16BE:
704
    case PIX_FMT_GRAY16LE:
705
    case PIX_FMT_BGR555BE:
706
    case PIX_FMT_BGR555LE:
707
    case PIX_FMT_BGR565BE:
708
    case PIX_FMT_BGR565LE:
709
    case PIX_FMT_RGB555BE:
710
    case PIX_FMT_RGB555LE:
711
    case PIX_FMT_RGB565BE:
712
    case PIX_FMT_RGB565LE:
713
    case PIX_FMT_YUYV422:
714
        picture->linesize[0] = width * 2;
715
        break;
716
    case PIX_FMT_UYVY422:
717
        picture->linesize[0] = width * 2;
718
        break;
719
    case PIX_FMT_UYYVYY411:
720
        picture->linesize[0] = width + width/2;
721
        break;
722
    case PIX_FMT_RGB4:
723
    case PIX_FMT_BGR4:
724
        picture->linesize[0] = width / 2;
725
        break;
726
    case PIX_FMT_MONOWHITE:
727
    case PIX_FMT_MONOBLACK:
728
        picture->linesize[0] = (width + 7) >> 3;
729
        break;
730
    case PIX_FMT_PAL8:
731
    case PIX_FMT_RGB8:
732
    case PIX_FMT_BGR8:
733
    case PIX_FMT_RGB4_BYTE:
734
    case PIX_FMT_BGR4_BYTE:
735
    case PIX_FMT_GRAY8:
736
        picture->linesize[0] = width;
737
        break;
738
    default:
739
        return -1;
740
    }
741
    return 0;
742
}
743

    
744
int ff_fill_pointer(AVPicture *picture, uint8_t *ptr, enum PixelFormat pix_fmt,
745
                    int height)
746
{
747
    int size, h2, size2;
748
    const PixFmtInfo *pinfo;
749

    
750
    pinfo = &pix_fmt_info[pix_fmt];
751
    size = picture->linesize[0] * height;
752
    switch(pix_fmt) {
753
    case PIX_FMT_YUV420P:
754
    case PIX_FMT_YUV422P:
755
    case PIX_FMT_YUV444P:
756
    case PIX_FMT_YUV410P:
757
    case PIX_FMT_YUV411P:
758
    case PIX_FMT_YUV440P:
759
    case PIX_FMT_YUVJ420P:
760
    case PIX_FMT_YUVJ422P:
761
    case PIX_FMT_YUVJ444P:
762
    case PIX_FMT_YUVJ440P:
763
    case PIX_FMT_YUV420P16LE:
764
    case PIX_FMT_YUV422P16LE:
765
    case PIX_FMT_YUV444P16LE:
766
    case PIX_FMT_YUV420P16BE:
767
    case PIX_FMT_YUV422P16BE:
768
    case PIX_FMT_YUV444P16BE:
769
        h2 = (height + (1 << pinfo->y_chroma_shift) - 1) >> pinfo->y_chroma_shift;
770
        size2 = picture->linesize[1] * h2;
771
        picture->data[0] = ptr;
772
        picture->data[1] = picture->data[0] + size;
773
        picture->data[2] = picture->data[1] + size2;
774
        picture->data[3] = NULL;
775
        return size + 2 * size2;
776
    case PIX_FMT_YUVA420P:
777
        h2 = (height + (1 << pinfo->y_chroma_shift) - 1) >> pinfo->y_chroma_shift;
778
        size2 = picture->linesize[1] * h2;
779
        picture->data[0] = ptr;
780
        picture->data[1] = picture->data[0] + size;
781
        picture->data[2] = picture->data[1] + size2;
782
        picture->data[3] = picture->data[1] + size2 + size2;
783
        return 2 * size + 2 * size2;
784
    case PIX_FMT_NV12:
785
    case PIX_FMT_NV21:
786
        h2 = (height + (1 << pinfo->y_chroma_shift) - 1) >> pinfo->y_chroma_shift;
787
        size2 = picture->linesize[1] * h2 * 2;
788
        picture->data[0] = ptr;
789
        picture->data[1] = picture->data[0] + size;
790
        picture->data[2] = NULL;
791
        picture->data[3] = NULL;
792
        return size + 2 * size2;
793
    case PIX_FMT_RGB24:
794
    case PIX_FMT_BGR24:
795
    case PIX_FMT_ARGB:
796
    case PIX_FMT_ABGR:
797
    case PIX_FMT_RGBA:
798
    case PIX_FMT_BGRA:
799
    case PIX_FMT_RGB48BE:
800
    case PIX_FMT_RGB48LE:
801
    case PIX_FMT_GRAY16BE:
802
    case PIX_FMT_GRAY16LE:
803
    case PIX_FMT_BGR555BE:
804
    case PIX_FMT_BGR555LE:
805
    case PIX_FMT_BGR565BE:
806
    case PIX_FMT_BGR565LE:
807
    case PIX_FMT_RGB555BE:
808
    case PIX_FMT_RGB555LE:
809
    case PIX_FMT_RGB565BE:
810
    case PIX_FMT_RGB565LE:
811
    case PIX_FMT_YUYV422:
812
    case PIX_FMT_UYVY422:
813
    case PIX_FMT_UYYVYY411:
814
    case PIX_FMT_RGB4:
815
    case PIX_FMT_BGR4:
816
    case PIX_FMT_MONOWHITE:
817
    case PIX_FMT_MONOBLACK:
818
        picture->data[0] = ptr;
819
        picture->data[1] = NULL;
820
        picture->data[2] = NULL;
821
        picture->data[3] = NULL;
822
        return size;
823
    case PIX_FMT_PAL8:
824
    case PIX_FMT_RGB8:
825
    case PIX_FMT_BGR8:
826
    case PIX_FMT_RGB4_BYTE:
827
    case PIX_FMT_BGR4_BYTE:
828
    case PIX_FMT_GRAY8:
829
        size2 = (size + 3) & ~3;
830
        picture->data[0] = ptr;
831
        picture->data[1] = ptr + size2; /* palette is stored here as 256 32 bit words */
832
        picture->data[2] = NULL;
833
        picture->data[3] = NULL;
834
        return size2 + 256 * 4;
835
    default:
836
        picture->data[0] = NULL;
837
        picture->data[1] = NULL;
838
        picture->data[2] = NULL;
839
        picture->data[3] = NULL;
840
        return -1;
841
    }
842
}
843

    
844
int avpicture_fill(AVPicture *picture, uint8_t *ptr,
845
                   enum PixelFormat pix_fmt, int width, int height)
846
{
847

    
848
    if(avcodec_check_dimensions(NULL, width, height))
849
        return -1;
850

    
851
    if (ff_fill_linesize(picture, pix_fmt, width))
852
        return -1;
853

    
854
    return ff_fill_pointer(picture, ptr, pix_fmt, height);
855
}
856

    
857
int avpicture_layout(const AVPicture* src, enum PixelFormat pix_fmt, int width, int height,
858
                     unsigned char *dest, int dest_size)
859
{
860
    const PixFmtInfo* pf = &pix_fmt_info[pix_fmt];
861
    int i, j, w, ow, h, oh, data_planes;
862
    const unsigned char* s;
863
    int size = avpicture_get_size(pix_fmt, width, height);
864

    
865
    if (size > dest_size || size < 0)
866
        return -1;
867

    
868
    if (pf->pixel_type == FF_PIXEL_PACKED || pf->pixel_type == FF_PIXEL_PALETTE) {
869
        if (pix_fmt == PIX_FMT_YUYV422 ||
870
            pix_fmt == PIX_FMT_UYVY422 ||
871
            pix_fmt == PIX_FMT_BGR565BE ||
872
            pix_fmt == PIX_FMT_BGR565LE ||
873
            pix_fmt == PIX_FMT_BGR555BE ||
874
            pix_fmt == PIX_FMT_BGR555LE ||
875
            pix_fmt == PIX_FMT_RGB565BE ||
876
            pix_fmt == PIX_FMT_RGB565LE ||
877
            pix_fmt == PIX_FMT_RGB555BE ||
878
            pix_fmt == PIX_FMT_RGB555LE)
879
            w = width * 2;
880
        else if (pix_fmt == PIX_FMT_UYYVYY411)
881
          w = width + width/2;
882
        else if (pix_fmt == PIX_FMT_PAL8)
883
          w = width;
884
        else
885
          w = width * (pf->depth * pf->nb_channels / 8);
886

    
887
        data_planes = 1;
888
        h = height;
889
    } else {
890
        data_planes = pf->nb_channels;
891
        w = (width*pf->depth + 7)/8;
892
        h = height;
893
    }
894

    
895
    ow = w;
896
    oh = h;
897

    
898
    for (i=0; i<data_planes; i++) {
899
         if (i == 1) {
900
             w = width >> pf->x_chroma_shift;
901
             h = height >> pf->y_chroma_shift;
902
         } else if (i == 3) {
903
             w = ow;
904
             h = oh;
905
         }
906
         s = src->data[i];
907
         for(j=0; j<h; j++) {
908
             memcpy(dest, s, w);
909
             dest += w;
910
             s += src->linesize[i];
911
         }
912
    }
913

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

    
917
    return size;
918
}
919

    
920
int avpicture_get_size(enum PixelFormat pix_fmt, int width, int height)
921
{
922
    AVPicture dummy_pict;
923
    if(avcodec_check_dimensions(NULL, width, height))
924
        return -1;
925
    switch (pix_fmt) {
926
    case PIX_FMT_RGB8:
927
    case PIX_FMT_BGR8:
928
    case PIX_FMT_RGB4_BYTE:
929
    case PIX_FMT_BGR4_BYTE:
930
    case PIX_FMT_GRAY8:
931
        // do not include palette for these pseudo-paletted formats
932
        return width * height;
933
    }
934
    return avpicture_fill(&dummy_pict, NULL, pix_fmt, width, height);
935
}
936

    
937
int avcodec_get_pix_fmt_loss(enum PixelFormat dst_pix_fmt, enum PixelFormat src_pix_fmt,
938
                             int has_alpha)
939
{
940
    const PixFmtInfo *pf, *ps;
941
    int loss;
942

    
943
    ps = &pix_fmt_info[src_pix_fmt];
944

    
945
    /* compute loss */
946
    loss = 0;
947
    pf = &pix_fmt_info[dst_pix_fmt];
948
    if (pf->depth < ps->depth ||
949
        ((dst_pix_fmt == PIX_FMT_RGB555BE || dst_pix_fmt == PIX_FMT_RGB555LE) &&
950
         (src_pix_fmt == PIX_FMT_RGB565BE || src_pix_fmt == PIX_FMT_RGB565LE)))
951
        loss |= FF_LOSS_DEPTH;
952
    if (pf->x_chroma_shift > ps->x_chroma_shift ||
953
        pf->y_chroma_shift > ps->y_chroma_shift)
954
        loss |= FF_LOSS_RESOLUTION;
955
    switch(pf->color_type) {
956
    case FF_COLOR_RGB:
957
        if (ps->color_type != FF_COLOR_RGB &&
958
            ps->color_type != FF_COLOR_GRAY)
959
            loss |= FF_LOSS_COLORSPACE;
960
        break;
961
    case FF_COLOR_GRAY:
962
        if (ps->color_type != FF_COLOR_GRAY)
963
            loss |= FF_LOSS_COLORSPACE;
964
        break;
965
    case FF_COLOR_YUV:
966
        if (ps->color_type != FF_COLOR_YUV)
967
            loss |= FF_LOSS_COLORSPACE;
968
        break;
969
    case FF_COLOR_YUV_JPEG:
970
        if (ps->color_type != FF_COLOR_YUV_JPEG &&
971
            ps->color_type != FF_COLOR_YUV &&
972
            ps->color_type != FF_COLOR_GRAY)
973
            loss |= FF_LOSS_COLORSPACE;
974
        break;
975
    default:
976
        /* fail safe test */
977
        if (ps->color_type != pf->color_type)
978
            loss |= FF_LOSS_COLORSPACE;
979
        break;
980
    }
981
    if (pf->color_type == FF_COLOR_GRAY &&
982
        ps->color_type != FF_COLOR_GRAY)
983
        loss |= FF_LOSS_CHROMA;
984
    if (!pf->is_alpha && (ps->is_alpha && has_alpha))
985
        loss |= FF_LOSS_ALPHA;
986
    if (pf->pixel_type == FF_PIXEL_PALETTE &&
987
        (ps->pixel_type != FF_PIXEL_PALETTE && ps->color_type != FF_COLOR_GRAY))
988
        loss |= FF_LOSS_COLORQUANT;
989
    return loss;
990
}
991

    
992
static int avg_bits_per_pixel(enum PixelFormat pix_fmt)
993
{
994
    int bits;
995
    const PixFmtInfo *pf;
996

    
997
    pf = &pix_fmt_info[pix_fmt];
998
    switch(pf->pixel_type) {
999
    case FF_PIXEL_PACKED:
1000
        switch(pix_fmt) {
1001
        case PIX_FMT_YUYV422:
1002
        case PIX_FMT_UYVY422:
1003
        case PIX_FMT_RGB565BE:
1004
        case PIX_FMT_RGB565LE:
1005
        case PIX_FMT_RGB555BE:
1006
        case PIX_FMT_RGB555LE:
1007
        case PIX_FMT_BGR565BE:
1008
        case PIX_FMT_BGR565LE:
1009
        case PIX_FMT_BGR555BE:
1010
        case PIX_FMT_BGR555LE:
1011
            bits = 16;
1012
            break;
1013
        case PIX_FMT_UYYVYY411:
1014
            bits = 12;
1015
            break;
1016
        default:
1017
            bits = pf->depth * pf->nb_channels;
1018
            break;
1019
        }
1020
        break;
1021
    case FF_PIXEL_PLANAR:
1022
        if (pf->x_chroma_shift == 0 && pf->y_chroma_shift == 0) {
1023
            bits = pf->depth * pf->nb_channels;
1024
        } else {
1025
            bits = pf->depth + ((2 * pf->depth) >>
1026
                                (pf->x_chroma_shift + pf->y_chroma_shift));
1027
        }
1028
        break;
1029
    case FF_PIXEL_PALETTE:
1030
        bits = 8;
1031
        break;
1032
    default:
1033
        bits = -1;
1034
        break;
1035
    }
1036
    return bits;
1037
}
1038

    
1039
static enum PixelFormat avcodec_find_best_pix_fmt1(int64_t pix_fmt_mask,
1040
                                      enum PixelFormat src_pix_fmt,
1041
                                      int has_alpha,
1042
                                      int loss_mask)
1043
{
1044
    int dist, i, loss, min_dist;
1045
    enum PixelFormat dst_pix_fmt;
1046

    
1047
    /* find exact color match with smallest size */
1048
    dst_pix_fmt = -1;
1049
    min_dist = 0x7fffffff;
1050
    for(i = 0;i < PIX_FMT_NB; i++) {
1051
        if (pix_fmt_mask & (1ULL << i)) {
1052
            loss = avcodec_get_pix_fmt_loss(i, src_pix_fmt, has_alpha) & loss_mask;
1053
            if (loss == 0) {
1054
                dist = avg_bits_per_pixel(i);
1055
                if (dist < min_dist) {
1056
                    min_dist = dist;
1057
                    dst_pix_fmt = i;
1058
                }
1059
            }
1060
        }
1061
    }
1062
    return dst_pix_fmt;
1063
}
1064

    
1065
enum PixelFormat avcodec_find_best_pix_fmt(int64_t pix_fmt_mask, enum PixelFormat src_pix_fmt,
1066
                              int has_alpha, int *loss_ptr)
1067
{
1068
    enum PixelFormat dst_pix_fmt;
1069
    int loss_mask, i;
1070
    static const int loss_mask_order[] = {
1071
        ~0, /* no loss first */
1072
        ~FF_LOSS_ALPHA,
1073
        ~FF_LOSS_RESOLUTION,
1074
        ~(FF_LOSS_COLORSPACE | FF_LOSS_RESOLUTION),
1075
        ~FF_LOSS_COLORQUANT,
1076
        ~FF_LOSS_DEPTH,
1077
        0,
1078
    };
1079

    
1080
    /* try with successive loss */
1081
    i = 0;
1082
    for(;;) {
1083
        loss_mask = loss_mask_order[i++];
1084
        dst_pix_fmt = avcodec_find_best_pix_fmt1(pix_fmt_mask, src_pix_fmt,
1085
                                                 has_alpha, loss_mask);
1086
        if (dst_pix_fmt >= 0)
1087
            goto found;
1088
        if (loss_mask == 0)
1089
            break;
1090
    }
1091
    return -1;
1092
 found:
1093
    if (loss_ptr)
1094
        *loss_ptr = avcodec_get_pix_fmt_loss(dst_pix_fmt, src_pix_fmt, has_alpha);
1095
    return dst_pix_fmt;
1096
}
1097

    
1098
void ff_img_copy_plane(uint8_t *dst, int dst_wrap,
1099
                           const uint8_t *src, int src_wrap,
1100
                           int width, int height)
1101
{
1102
    if((!dst) || (!src))
1103
        return;
1104
    for(;height > 0; height--) {
1105
        memcpy(dst, src, width);
1106
        dst += dst_wrap;
1107
        src += src_wrap;
1108
    }
1109
}
1110

    
1111
int ff_get_plane_bytewidth(enum PixelFormat pix_fmt, int width, int plane)
1112
{
1113
    int bits;
1114
    const PixFmtInfo *pf = &pix_fmt_info[pix_fmt];
1115

    
1116
    pf = &pix_fmt_info[pix_fmt];
1117
    switch(pf->pixel_type) {
1118
    case FF_PIXEL_PACKED:
1119
        switch(pix_fmt) {
1120
        case PIX_FMT_YUYV422:
1121
        case PIX_FMT_UYVY422:
1122
        case PIX_FMT_RGB565BE:
1123
        case PIX_FMT_RGB565LE:
1124
        case PIX_FMT_RGB555BE:
1125
        case PIX_FMT_RGB555LE:
1126
        case PIX_FMT_BGR565BE:
1127
        case PIX_FMT_BGR565LE:
1128
        case PIX_FMT_BGR555BE:
1129
        case PIX_FMT_BGR555LE:
1130
            bits = 16;
1131
            break;
1132
        case PIX_FMT_UYYVYY411:
1133
            bits = 12;
1134
            break;
1135
        default:
1136
            bits = pf->depth * pf->nb_channels;
1137
            break;
1138
        }
1139
        return (width * bits + 7) >> 3;
1140
        break;
1141
    case FF_PIXEL_PLANAR:
1142
            if (plane == 1 || plane == 2)
1143
                width= -((-width)>>pf->x_chroma_shift);
1144

    
1145
            return (width * pf->depth + 7) >> 3;
1146
        break;
1147
    case FF_PIXEL_PALETTE:
1148
        if (plane == 0)
1149
            return width;
1150
        break;
1151
    }
1152

    
1153
    return -1;
1154
}
1155

    
1156
void av_picture_copy(AVPicture *dst, const AVPicture *src,
1157
                     enum PixelFormat pix_fmt, int width, int height)
1158
{
1159
    int i;
1160
    const PixFmtInfo *pf = &pix_fmt_info[pix_fmt];
1161

    
1162
    switch(pf->pixel_type) {
1163
    case FF_PIXEL_PACKED:
1164
    case FF_PIXEL_PLANAR:
1165
        for(i = 0; i < pf->nb_channels; i++) {
1166
            int h;
1167
            int bwidth = ff_get_plane_bytewidth(pix_fmt, width, i);
1168
            h = height;
1169
            if (i == 1 || i == 2) {
1170
                h= -((-height)>>pf->y_chroma_shift);
1171
            }
1172
            ff_img_copy_plane(dst->data[i], dst->linesize[i],
1173
                           src->data[i], src->linesize[i],
1174
                           bwidth, h);
1175
        }
1176
        break;
1177
    case FF_PIXEL_PALETTE:
1178
        ff_img_copy_plane(dst->data[0], dst->linesize[0],
1179
                       src->data[0], src->linesize[0],
1180
                       width, height);
1181
        /* copy the palette */
1182
        ff_img_copy_plane(dst->data[1], dst->linesize[1],
1183
                       src->data[1], src->linesize[1],
1184
                       4, 256);
1185
        break;
1186
    }
1187
}
1188

    
1189
/* 2x2 -> 1x1 */
1190
void ff_shrink22(uint8_t *dst, int dst_wrap,
1191
                     const uint8_t *src, int src_wrap,
1192
                     int width, int height)
1193
{
1194
    int w;
1195
    const uint8_t *s1, *s2;
1196
    uint8_t *d;
1197

    
1198
    for(;height > 0; height--) {
1199
        s1 = src;
1200
        s2 = s1 + src_wrap;
1201
        d = dst;
1202
        for(w = width;w >= 4; w-=4) {
1203
            d[0] = (s1[0] + s1[1] + s2[0] + s2[1] + 2) >> 2;
1204
            d[1] = (s1[2] + s1[3] + s2[2] + s2[3] + 2) >> 2;
1205
            d[2] = (s1[4] + s1[5] + s2[4] + s2[5] + 2) >> 2;
1206
            d[3] = (s1[6] + s1[7] + s2[6] + s2[7] + 2) >> 2;
1207
            s1 += 8;
1208
            s2 += 8;
1209
            d += 4;
1210
        }
1211
        for(;w > 0; w--) {
1212
            d[0] = (s1[0] + s1[1] + s2[0] + s2[1] + 2) >> 2;
1213
            s1 += 2;
1214
            s2 += 2;
1215
            d++;
1216
        }
1217
        src += 2 * src_wrap;
1218
        dst += dst_wrap;
1219
    }
1220
}
1221

    
1222
/* 4x4 -> 1x1 */
1223
void ff_shrink44(uint8_t *dst, int dst_wrap,
1224
                     const uint8_t *src, int src_wrap,
1225
                     int width, int height)
1226
{
1227
    int w;
1228
    const uint8_t *s1, *s2, *s3, *s4;
1229
    uint8_t *d;
1230

    
1231
    for(;height > 0; height--) {
1232
        s1 = src;
1233
        s2 = s1 + src_wrap;
1234
        s3 = s2 + src_wrap;
1235
        s4 = s3 + src_wrap;
1236
        d = dst;
1237
        for(w = width;w > 0; w--) {
1238
            d[0] = (s1[0] + s1[1] + s1[2] + s1[3] +
1239
                    s2[0] + s2[1] + s2[2] + s2[3] +
1240
                    s3[0] + s3[1] + s3[2] + s3[3] +
1241
                    s4[0] + s4[1] + s4[2] + s4[3] + 8) >> 4;
1242
            s1 += 4;
1243
            s2 += 4;
1244
            s3 += 4;
1245
            s4 += 4;
1246
            d++;
1247
        }
1248
        src += 4 * src_wrap;
1249
        dst += dst_wrap;
1250
    }
1251
}
1252

    
1253
/* 8x8 -> 1x1 */
1254
void ff_shrink88(uint8_t *dst, int dst_wrap,
1255
                     const uint8_t *src, int src_wrap,
1256
                     int width, int height)
1257
{
1258
    int w, i;
1259

    
1260
    for(;height > 0; height--) {
1261
        for(w = width;w > 0; w--) {
1262
            int tmp=0;
1263
            for(i=0; i<8; i++){
1264
                tmp += src[0] + src[1] + src[2] + src[3] + src[4] + src[5] + src[6] + src[7];
1265
                src += src_wrap;
1266
            }
1267
            *(dst++) = (tmp + 32)>>6;
1268
            src += 8 - 8*src_wrap;
1269
        }
1270
        src += 8*src_wrap - 8*width;
1271
        dst += dst_wrap - width;
1272
    }
1273
}
1274

    
1275

    
1276
int avpicture_alloc(AVPicture *picture,
1277
                    enum PixelFormat pix_fmt, int width, int height)
1278
{
1279
    int size;
1280
    void *ptr;
1281

    
1282
    size = avpicture_fill(picture, NULL, pix_fmt, width, height);
1283
    if(size<0)
1284
        goto fail;
1285
    ptr = av_malloc(size);
1286
    if (!ptr)
1287
        goto fail;
1288
    avpicture_fill(picture, ptr, pix_fmt, width, height);
1289
    if(picture->data[1] && !picture->data[2])
1290
        ff_set_systematic_pal((uint32_t*)picture->data[1], pix_fmt);
1291

    
1292
    return 0;
1293
 fail:
1294
    memset(picture, 0, sizeof(AVPicture));
1295
    return -1;
1296
}
1297

    
1298
void avpicture_free(AVPicture *picture)
1299
{
1300
    av_free(picture->data[0]);
1301
}
1302

    
1303
/* return true if yuv planar */
1304
static inline int is_yuv_planar(const PixFmtInfo *ps)
1305
{
1306
    return (ps->color_type == FF_COLOR_YUV ||
1307
            ps->color_type == FF_COLOR_YUV_JPEG) &&
1308
        ps->pixel_type == FF_PIXEL_PLANAR;
1309
}
1310

    
1311
int av_picture_crop(AVPicture *dst, const AVPicture *src,
1312
                    enum PixelFormat pix_fmt, int top_band, int left_band)
1313
{
1314
    int y_shift;
1315
    int x_shift;
1316

    
1317
    if (pix_fmt < 0 || pix_fmt >= PIX_FMT_NB || !is_yuv_planar(&pix_fmt_info[pix_fmt]))
1318
        return -1;
1319

    
1320
    y_shift = pix_fmt_info[pix_fmt].y_chroma_shift;
1321
    x_shift = pix_fmt_info[pix_fmt].x_chroma_shift;
1322

    
1323
    dst->data[0] = src->data[0] + (top_band * src->linesize[0]) + left_band;
1324
    dst->data[1] = src->data[1] + ((top_band >> y_shift) * src->linesize[1]) + (left_band >> x_shift);
1325
    dst->data[2] = src->data[2] + ((top_band >> y_shift) * src->linesize[2]) + (left_band >> x_shift);
1326

    
1327
    dst->linesize[0] = src->linesize[0];
1328
    dst->linesize[1] = src->linesize[1];
1329
    dst->linesize[2] = src->linesize[2];
1330
    return 0;
1331
}
1332

    
1333
int av_picture_pad(AVPicture *dst, const AVPicture *src, int height, int width,
1334
                   enum PixelFormat pix_fmt, int padtop, int padbottom, int padleft, int padright,
1335
            int *color)
1336
{
1337
    uint8_t *optr;
1338
    int y_shift;
1339
    int x_shift;
1340
    int yheight;
1341
    int i, y;
1342

    
1343
    if (pix_fmt < 0 || pix_fmt >= PIX_FMT_NB ||
1344
        !is_yuv_planar(&pix_fmt_info[pix_fmt])) return -1;
1345

    
1346
    for (i = 0; i < 3; i++) {
1347
        x_shift = i ? pix_fmt_info[pix_fmt].x_chroma_shift : 0;
1348
        y_shift = i ? pix_fmt_info[pix_fmt].y_chroma_shift : 0;
1349

    
1350
        if (padtop || padleft) {
1351
            memset(dst->data[i], color[i],
1352
                dst->linesize[i] * (padtop >> y_shift) + (padleft >> x_shift));
1353
        }
1354

    
1355
        if (padleft || padright) {
1356
            optr = dst->data[i] + dst->linesize[i] * (padtop >> y_shift) +
1357
                (dst->linesize[i] - (padright >> x_shift));
1358
            yheight = (height - 1 - (padtop + padbottom)) >> y_shift;
1359
            for (y = 0; y < yheight; y++) {
1360
                memset(optr, color[i], (padleft + padright) >> x_shift);
1361
                optr += dst->linesize[i];
1362
            }
1363
        }
1364

    
1365
        if (src) { /* first line */
1366
            uint8_t *iptr = src->data[i];
1367
            optr = dst->data[i] + dst->linesize[i] * (padtop >> y_shift) +
1368
                    (padleft >> x_shift);
1369
            memcpy(optr, iptr, (width - padleft - padright) >> x_shift);
1370
            iptr += src->linesize[i];
1371
            optr = dst->data[i] + dst->linesize[i] * (padtop >> y_shift) +
1372
                (dst->linesize[i] - (padright >> x_shift));
1373
            yheight = (height - 1 - (padtop + padbottom)) >> y_shift;
1374
            for (y = 0; y < yheight; y++) {
1375
                memset(optr, color[i], (padleft + padright) >> x_shift);
1376
                memcpy(optr + ((padleft + padright) >> x_shift), iptr,
1377
                       (width - padleft - padright) >> x_shift);
1378
                iptr += src->linesize[i];
1379
                optr += dst->linesize[i];
1380
            }
1381
        }
1382

    
1383
        if (padbottom || padright) {
1384
            optr = dst->data[i] + dst->linesize[i] *
1385
                ((height - padbottom) >> y_shift) - (padright >> x_shift);
1386
            memset(optr, color[i],dst->linesize[i] *
1387
                (padbottom >> y_shift) + (padright >> x_shift));
1388
        }
1389
    }
1390
    return 0;
1391
}
1392

    
1393
/* NOTE: we scan all the pixels to have an exact information */
1394
static int get_alpha_info_pal8(const AVPicture *src, int width, int height)
1395
{
1396
    const unsigned char *p;
1397
    int src_wrap, ret, x, y;
1398
    unsigned int a;
1399
    uint32_t *palette = (uint32_t *)src->data[1];
1400

    
1401
    p = src->data[0];
1402
    src_wrap = src->linesize[0] - width;
1403
    ret = 0;
1404
    for(y=0;y<height;y++) {
1405
        for(x=0;x<width;x++) {
1406
            a = palette[p[0]] >> 24;
1407
            if (a == 0x00) {
1408
                ret |= FF_ALPHA_TRANSP;
1409
            } else if (a != 0xff) {
1410
                ret |= FF_ALPHA_SEMI_TRANSP;
1411
            }
1412
            p++;
1413
        }
1414
        p += src_wrap;
1415
    }
1416
    return ret;
1417
}
1418

    
1419
int img_get_alpha_info(const AVPicture *src,
1420
                       enum PixelFormat pix_fmt, int width, int height)
1421
{
1422
    const PixFmtInfo *pf = &pix_fmt_info[pix_fmt];
1423
    int ret;
1424

    
1425
    /* no alpha can be represented in format */
1426
    if (!pf->is_alpha)
1427
        return 0;
1428
    switch(pix_fmt) {
1429
    case PIX_FMT_PAL8:
1430
        ret = get_alpha_info_pal8(src, width, height);
1431
        break;
1432
    default:
1433
        /* we do not know, so everything is indicated */
1434
        ret = FF_ALPHA_TRANSP | FF_ALPHA_SEMI_TRANSP;
1435
        break;
1436
    }
1437
    return ret;
1438
}
1439

    
1440
#if HAVE_MMX
1441
#define DEINT_INPLACE_LINE_LUM \
1442
                    movd_m2r(lum_m4[0],mm0);\
1443
                    movd_m2r(lum_m3[0],mm1);\
1444
                    movd_m2r(lum_m2[0],mm2);\
1445
                    movd_m2r(lum_m1[0],mm3);\
1446
                    movd_m2r(lum[0],mm4);\
1447
                    punpcklbw_r2r(mm7,mm0);\
1448
                    movd_r2m(mm2,lum_m4[0]);\
1449
                    punpcklbw_r2r(mm7,mm1);\
1450
                    punpcklbw_r2r(mm7,mm2);\
1451
                    punpcklbw_r2r(mm7,mm3);\
1452
                    punpcklbw_r2r(mm7,mm4);\
1453
                    paddw_r2r(mm3,mm1);\
1454
                    psllw_i2r(1,mm2);\
1455
                    paddw_r2r(mm4,mm0);\
1456
                    psllw_i2r(2,mm1);\
1457
                    paddw_r2r(mm6,mm2);\
1458
                    paddw_r2r(mm2,mm1);\
1459
                    psubusw_r2r(mm0,mm1);\
1460
                    psrlw_i2r(3,mm1);\
1461
                    packuswb_r2r(mm7,mm1);\
1462
                    movd_r2m(mm1,lum_m2[0]);
1463

    
1464
#define DEINT_LINE_LUM \
1465
                    movd_m2r(lum_m4[0],mm0);\
1466
                    movd_m2r(lum_m3[0],mm1);\
1467
                    movd_m2r(lum_m2[0],mm2);\
1468
                    movd_m2r(lum_m1[0],mm3);\
1469
                    movd_m2r(lum[0],mm4);\
1470
                    punpcklbw_r2r(mm7,mm0);\
1471
                    punpcklbw_r2r(mm7,mm1);\
1472
                    punpcklbw_r2r(mm7,mm2);\
1473
                    punpcklbw_r2r(mm7,mm3);\
1474
                    punpcklbw_r2r(mm7,mm4);\
1475
                    paddw_r2r(mm3,mm1);\
1476
                    psllw_i2r(1,mm2);\
1477
                    paddw_r2r(mm4,mm0);\
1478
                    psllw_i2r(2,mm1);\
1479
                    paddw_r2r(mm6,mm2);\
1480
                    paddw_r2r(mm2,mm1);\
1481
                    psubusw_r2r(mm0,mm1);\
1482
                    psrlw_i2r(3,mm1);\
1483
                    packuswb_r2r(mm7,mm1);\
1484
                    movd_r2m(mm1,dst[0]);
1485
#endif
1486

    
1487
/* filter parameters: [-1 4 2 4 -1] // 8 */
1488
static void deinterlace_line(uint8_t *dst,
1489
                             const uint8_t *lum_m4, const uint8_t *lum_m3,
1490
                             const uint8_t *lum_m2, const uint8_t *lum_m1,
1491
                             const uint8_t *lum,
1492
                             int size)
1493
{
1494
#if !HAVE_MMX
1495
    uint8_t *cm = ff_cropTbl + MAX_NEG_CROP;
1496
    int sum;
1497

    
1498
    for(;size > 0;size--) {
1499
        sum = -lum_m4[0];
1500
        sum += lum_m3[0] << 2;
1501
        sum += lum_m2[0] << 1;
1502
        sum += lum_m1[0] << 2;
1503
        sum += -lum[0];
1504
        dst[0] = cm[(sum + 4) >> 3];
1505
        lum_m4++;
1506
        lum_m3++;
1507
        lum_m2++;
1508
        lum_m1++;
1509
        lum++;
1510
        dst++;
1511
    }
1512
#else
1513

    
1514
    {
1515
        pxor_r2r(mm7,mm7);
1516
        movq_m2r(ff_pw_4,mm6);
1517
    }
1518
    for (;size > 3; size-=4) {
1519
        DEINT_LINE_LUM
1520
        lum_m4+=4;
1521
        lum_m3+=4;
1522
        lum_m2+=4;
1523
        lum_m1+=4;
1524
        lum+=4;
1525
        dst+=4;
1526
    }
1527
#endif
1528
}
1529
static void deinterlace_line_inplace(uint8_t *lum_m4, uint8_t *lum_m3, uint8_t *lum_m2, uint8_t *lum_m1, uint8_t *lum,
1530
                             int size)
1531
{
1532
#if !HAVE_MMX
1533
    uint8_t *cm = ff_cropTbl + MAX_NEG_CROP;
1534
    int sum;
1535

    
1536
    for(;size > 0;size--) {
1537
        sum = -lum_m4[0];
1538
        sum += lum_m3[0] << 2;
1539
        sum += lum_m2[0] << 1;
1540
        lum_m4[0]=lum_m2[0];
1541
        sum += lum_m1[0] << 2;
1542
        sum += -lum[0];
1543
        lum_m2[0] = cm[(sum + 4) >> 3];
1544
        lum_m4++;
1545
        lum_m3++;
1546
        lum_m2++;
1547
        lum_m1++;
1548
        lum++;
1549
    }
1550
#else
1551

    
1552
    {
1553
        pxor_r2r(mm7,mm7);
1554
        movq_m2r(ff_pw_4,mm6);
1555
    }
1556
    for (;size > 3; size-=4) {
1557
        DEINT_INPLACE_LINE_LUM
1558
        lum_m4+=4;
1559
        lum_m3+=4;
1560
        lum_m2+=4;
1561
        lum_m1+=4;
1562
        lum+=4;
1563
    }
1564
#endif
1565
}
1566

    
1567
/* deinterlacing : 2 temporal taps, 3 spatial taps linear filter. The
1568
   top field is copied as is, but the bottom field is deinterlaced
1569
   against the top field. */
1570
static void deinterlace_bottom_field(uint8_t *dst, int dst_wrap,
1571
                                    const uint8_t *src1, int src_wrap,
1572
                                    int width, int height)
1573
{
1574
    const uint8_t *src_m2, *src_m1, *src_0, *src_p1, *src_p2;
1575
    int y;
1576

    
1577
    src_m2 = src1;
1578
    src_m1 = src1;
1579
    src_0=&src_m1[src_wrap];
1580
    src_p1=&src_0[src_wrap];
1581
    src_p2=&src_p1[src_wrap];
1582
    for(y=0;y<(height-2);y+=2) {
1583
        memcpy(dst,src_m1,width);
1584
        dst += dst_wrap;
1585
        deinterlace_line(dst,src_m2,src_m1,src_0,src_p1,src_p2,width);
1586
        src_m2 = src_0;
1587
        src_m1 = src_p1;
1588
        src_0 = src_p2;
1589
        src_p1 += 2*src_wrap;
1590
        src_p2 += 2*src_wrap;
1591
        dst += dst_wrap;
1592
    }
1593
    memcpy(dst,src_m1,width);
1594
    dst += dst_wrap;
1595
    /* do last line */
1596
    deinterlace_line(dst,src_m2,src_m1,src_0,src_0,src_0,width);
1597
}
1598

    
1599
static void deinterlace_bottom_field_inplace(uint8_t *src1, int src_wrap,
1600
                                             int width, int height)
1601
{
1602
    uint8_t *src_m1, *src_0, *src_p1, *src_p2;
1603
    int y;
1604
    uint8_t *buf;
1605
    buf = (uint8_t*)av_malloc(width);
1606

    
1607
    src_m1 = src1;
1608
    memcpy(buf,src_m1,width);
1609
    src_0=&src_m1[src_wrap];
1610
    src_p1=&src_0[src_wrap];
1611
    src_p2=&src_p1[src_wrap];
1612
    for(y=0;y<(height-2);y+=2) {
1613
        deinterlace_line_inplace(buf,src_m1,src_0,src_p1,src_p2,width);
1614
        src_m1 = src_p1;
1615
        src_0 = src_p2;
1616
        src_p1 += 2*src_wrap;
1617
        src_p2 += 2*src_wrap;
1618
    }
1619
    /* do last line */
1620
    deinterlace_line_inplace(buf,src_m1,src_0,src_0,src_0,width);
1621
    av_free(buf);
1622
}
1623

    
1624
int avpicture_deinterlace(AVPicture *dst, const AVPicture *src,
1625
                          enum PixelFormat pix_fmt, int width, int height)
1626
{
1627
    int i;
1628

    
1629
    if (pix_fmt != PIX_FMT_YUV420P &&
1630
        pix_fmt != PIX_FMT_YUV422P &&
1631
        pix_fmt != PIX_FMT_YUV444P &&
1632
        pix_fmt != PIX_FMT_YUV411P &&
1633
        pix_fmt != PIX_FMT_GRAY8)
1634
        return -1;
1635
    if ((width & 3) != 0 || (height & 3) != 0)
1636
        return -1;
1637

    
1638
    for(i=0;i<3;i++) {
1639
        if (i == 1) {
1640
            switch(pix_fmt) {
1641
            case PIX_FMT_YUV420P:
1642
                width >>= 1;
1643
                height >>= 1;
1644
                break;
1645
            case PIX_FMT_YUV422P:
1646
                width >>= 1;
1647
                break;
1648
            case PIX_FMT_YUV411P:
1649
                width >>= 2;
1650
                break;
1651
            default:
1652
                break;
1653
            }
1654
            if (pix_fmt == PIX_FMT_GRAY8) {
1655
                break;
1656
            }
1657
        }
1658
        if (src == dst) {
1659
            deinterlace_bottom_field_inplace(dst->data[i], dst->linesize[i],
1660
                                 width, height);
1661
        } else {
1662
            deinterlace_bottom_field(dst->data[i],dst->linesize[i],
1663
                                        src->data[i], src->linesize[i],
1664
                                        width, height);
1665
        }
1666
    }
1667
    emms_c();
1668
    return 0;
1669
}
1670