Statistics
| Branch: | Revision:

ffmpeg / libavcodec / imgconvert.c @ 63613fe6

History | View | Annotate | Download (46.9 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_YUV420PLE] = {
134
        .name = "yuv420ple",
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_YUV422PLE] = {
142
        .name = "yuv422ple",
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_YUV444PLE] = {
150
        .name = "yuv444ple",
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_YUV420PBE] = {
158
        .name = "yuv420pbe",
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_YUV422PBE] = {
166
        .name = "yuv422pbe",
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_YUV444PBE] = {
174
        .name = "yuv444pbe",
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_YUV420PLE:
666
    case PIX_FMT_YUV422PLE:
667
    case PIX_FMT_YUV444PLE:
668
    case PIX_FMT_YUV420PBE:
669
    case PIX_FMT_YUV422PBE:
670
    case PIX_FMT_YUV444PBE:
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_BGR555:
706
    case PIX_FMT_BGR565:
707
    case PIX_FMT_RGB555:
708
    case PIX_FMT_RGB565:
709
    case PIX_FMT_YUYV422:
710
        picture->linesize[0] = width * 2;
711
        break;
712
    case PIX_FMT_UYVY422:
713
        picture->linesize[0] = width * 2;
714
        break;
715
    case PIX_FMT_UYYVYY411:
716
        picture->linesize[0] = width + width/2;
717
        break;
718
    case PIX_FMT_RGB4:
719
    case PIX_FMT_BGR4:
720
        picture->linesize[0] = width / 2;
721
        break;
722
    case PIX_FMT_MONOWHITE:
723
    case PIX_FMT_MONOBLACK:
724
        picture->linesize[0] = (width + 7) >> 3;
725
        break;
726
    case PIX_FMT_PAL8:
727
    case PIX_FMT_RGB8:
728
    case PIX_FMT_BGR8:
729
    case PIX_FMT_RGB4_BYTE:
730
    case PIX_FMT_BGR4_BYTE:
731
    case PIX_FMT_GRAY8:
732
        picture->linesize[0] = width;
733
        break;
734
    default:
735
        return -1;
736
    }
737
    return 0;
738
}
739

    
740
int ff_fill_pointer(AVPicture *picture, uint8_t *ptr, enum PixelFormat pix_fmt,
741
                    int height)
742
{
743
    int size, h2, size2;
744
    const PixFmtInfo *pinfo;
745

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

    
836
int avpicture_fill(AVPicture *picture, uint8_t *ptr,
837
                   enum PixelFormat pix_fmt, int width, int height)
838
{
839

    
840
    if(avcodec_check_dimensions(NULL, width, height))
841
        return -1;
842

    
843
    if (ff_fill_linesize(picture, pix_fmt, width))
844
        return -1;
845

    
846
    return ff_fill_pointer(picture, ptr, pix_fmt, height);
847
}
848

    
849
int avpicture_layout(const AVPicture* src, enum PixelFormat pix_fmt, int width, int height,
850
                     unsigned char *dest, int dest_size)
851
{
852
    const PixFmtInfo* pf = &pix_fmt_info[pix_fmt];
853
    int i, j, w, ow, h, oh, data_planes;
854
    const unsigned char* s;
855
    int size = avpicture_get_size(pix_fmt, width, height);
856

    
857
    if (size > dest_size || size < 0)
858
        return -1;
859

    
860
    if (pf->pixel_type == FF_PIXEL_PACKED || pf->pixel_type == FF_PIXEL_PALETTE) {
861
        if (pix_fmt == PIX_FMT_YUYV422 ||
862
            pix_fmt == PIX_FMT_UYVY422 ||
863
            pix_fmt == PIX_FMT_BGR565 ||
864
            pix_fmt == PIX_FMT_BGR555 ||
865
            pix_fmt == PIX_FMT_RGB565 ||
866
            pix_fmt == PIX_FMT_RGB555)
867
            w = width * 2;
868
        else if (pix_fmt == PIX_FMT_UYYVYY411)
869
          w = width + width/2;
870
        else if (pix_fmt == PIX_FMT_PAL8)
871
          w = width;
872
        else
873
          w = width * (pf->depth * pf->nb_channels / 8);
874

    
875
        data_planes = 1;
876
        h = height;
877
    } else {
878
        data_planes = pf->nb_channels;
879
        w = (width*pf->depth + 7)/8;
880
        h = height;
881
    }
882

    
883
    ow = w;
884
    oh = h;
885

    
886
    for (i=0; i<data_planes; i++) {
887
         if (i == 1) {
888
             w = width >> pf->x_chroma_shift;
889
             h = height >> pf->y_chroma_shift;
890
         } else if (i == 3) {
891
             w = ow;
892
             h = oh;
893
         }
894
         s = src->data[i];
895
         for(j=0; j<h; j++) {
896
             memcpy(dest, s, w);
897
             dest += w;
898
             s += src->linesize[i];
899
         }
900
    }
901

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

    
905
    return size;
906
}
907

    
908
int avpicture_get_size(enum PixelFormat pix_fmt, int width, int height)
909
{
910
    AVPicture dummy_pict;
911
    if(avcodec_check_dimensions(NULL, width, height))
912
        return -1;
913
    switch (pix_fmt) {
914
    case PIX_FMT_RGB8:
915
    case PIX_FMT_BGR8:
916
    case PIX_FMT_RGB4_BYTE:
917
    case PIX_FMT_BGR4_BYTE:
918
    case PIX_FMT_GRAY8:
919
        // do not include palette for these pseudo-paletted formats
920
        return width * height;
921
    }
922
    return avpicture_fill(&dummy_pict, NULL, pix_fmt, width, height);
923
}
924

    
925
int avcodec_get_pix_fmt_loss(enum PixelFormat dst_pix_fmt, enum PixelFormat src_pix_fmt,
926
                             int has_alpha)
927
{
928
    const PixFmtInfo *pf, *ps;
929
    int loss;
930

    
931
    ps = &pix_fmt_info[src_pix_fmt];
932

    
933
    /* compute loss */
934
    loss = 0;
935
    pf = &pix_fmt_info[dst_pix_fmt];
936
    if (pf->depth < ps->depth ||
937
        (dst_pix_fmt == PIX_FMT_RGB555 && src_pix_fmt == PIX_FMT_RGB565))
938
        loss |= FF_LOSS_DEPTH;
939
    if (pf->x_chroma_shift > ps->x_chroma_shift ||
940
        pf->y_chroma_shift > ps->y_chroma_shift)
941
        loss |= FF_LOSS_RESOLUTION;
942
    switch(pf->color_type) {
943
    case FF_COLOR_RGB:
944
        if (ps->color_type != FF_COLOR_RGB &&
945
            ps->color_type != FF_COLOR_GRAY)
946
            loss |= FF_LOSS_COLORSPACE;
947
        break;
948
    case FF_COLOR_GRAY:
949
        if (ps->color_type != FF_COLOR_GRAY)
950
            loss |= FF_LOSS_COLORSPACE;
951
        break;
952
    case FF_COLOR_YUV:
953
        if (ps->color_type != FF_COLOR_YUV)
954
            loss |= FF_LOSS_COLORSPACE;
955
        break;
956
    case FF_COLOR_YUV_JPEG:
957
        if (ps->color_type != FF_COLOR_YUV_JPEG &&
958
            ps->color_type != FF_COLOR_YUV &&
959
            ps->color_type != FF_COLOR_GRAY)
960
            loss |= FF_LOSS_COLORSPACE;
961
        break;
962
    default:
963
        /* fail safe test */
964
        if (ps->color_type != pf->color_type)
965
            loss |= FF_LOSS_COLORSPACE;
966
        break;
967
    }
968
    if (pf->color_type == FF_COLOR_GRAY &&
969
        ps->color_type != FF_COLOR_GRAY)
970
        loss |= FF_LOSS_CHROMA;
971
    if (!pf->is_alpha && (ps->is_alpha && has_alpha))
972
        loss |= FF_LOSS_ALPHA;
973
    if (pf->pixel_type == FF_PIXEL_PALETTE &&
974
        (ps->pixel_type != FF_PIXEL_PALETTE && ps->color_type != FF_COLOR_GRAY))
975
        loss |= FF_LOSS_COLORQUANT;
976
    return loss;
977
}
978

    
979
static int avg_bits_per_pixel(enum PixelFormat pix_fmt)
980
{
981
    int bits;
982
    const PixFmtInfo *pf;
983

    
984
    pf = &pix_fmt_info[pix_fmt];
985
    switch(pf->pixel_type) {
986
    case FF_PIXEL_PACKED:
987
        switch(pix_fmt) {
988
        case PIX_FMT_YUYV422:
989
        case PIX_FMT_UYVY422:
990
        case PIX_FMT_RGB565:
991
        case PIX_FMT_RGB555:
992
        case PIX_FMT_BGR565:
993
        case PIX_FMT_BGR555:
994
            bits = 16;
995
            break;
996
        case PIX_FMT_UYYVYY411:
997
            bits = 12;
998
            break;
999
        default:
1000
            bits = pf->depth * pf->nb_channels;
1001
            break;
1002
        }
1003
        break;
1004
    case FF_PIXEL_PLANAR:
1005
        if (pf->x_chroma_shift == 0 && pf->y_chroma_shift == 0) {
1006
            bits = pf->depth * pf->nb_channels;
1007
        } else {
1008
            bits = pf->depth + ((2 * pf->depth) >>
1009
                                (pf->x_chroma_shift + pf->y_chroma_shift));
1010
        }
1011
        break;
1012
    case FF_PIXEL_PALETTE:
1013
        bits = 8;
1014
        break;
1015
    default:
1016
        bits = -1;
1017
        break;
1018
    }
1019
    return bits;
1020
}
1021

    
1022
static enum PixelFormat avcodec_find_best_pix_fmt1(int64_t pix_fmt_mask,
1023
                                      enum PixelFormat src_pix_fmt,
1024
                                      int has_alpha,
1025
                                      int loss_mask)
1026
{
1027
    int dist, i, loss, min_dist;
1028
    enum PixelFormat dst_pix_fmt;
1029

    
1030
    /* find exact color match with smallest size */
1031
    dst_pix_fmt = -1;
1032
    min_dist = 0x7fffffff;
1033
    for(i = 0;i < PIX_FMT_NB; i++) {
1034
        if (pix_fmt_mask & (1ULL << i)) {
1035
            loss = avcodec_get_pix_fmt_loss(i, src_pix_fmt, has_alpha) & loss_mask;
1036
            if (loss == 0) {
1037
                dist = avg_bits_per_pixel(i);
1038
                if (dist < min_dist) {
1039
                    min_dist = dist;
1040
                    dst_pix_fmt = i;
1041
                }
1042
            }
1043
        }
1044
    }
1045
    return dst_pix_fmt;
1046
}
1047

    
1048
enum PixelFormat avcodec_find_best_pix_fmt(int64_t pix_fmt_mask, enum PixelFormat src_pix_fmt,
1049
                              int has_alpha, int *loss_ptr)
1050
{
1051
    enum PixelFormat dst_pix_fmt;
1052
    int loss_mask, i;
1053
    static const int loss_mask_order[] = {
1054
        ~0, /* no loss first */
1055
        ~FF_LOSS_ALPHA,
1056
        ~FF_LOSS_RESOLUTION,
1057
        ~(FF_LOSS_COLORSPACE | FF_LOSS_RESOLUTION),
1058
        ~FF_LOSS_COLORQUANT,
1059
        ~FF_LOSS_DEPTH,
1060
        0,
1061
    };
1062

    
1063
    /* try with successive loss */
1064
    i = 0;
1065
    for(;;) {
1066
        loss_mask = loss_mask_order[i++];
1067
        dst_pix_fmt = avcodec_find_best_pix_fmt1(pix_fmt_mask, src_pix_fmt,
1068
                                                 has_alpha, loss_mask);
1069
        if (dst_pix_fmt >= 0)
1070
            goto found;
1071
        if (loss_mask == 0)
1072
            break;
1073
    }
1074
    return -1;
1075
 found:
1076
    if (loss_ptr)
1077
        *loss_ptr = avcodec_get_pix_fmt_loss(dst_pix_fmt, src_pix_fmt, has_alpha);
1078
    return dst_pix_fmt;
1079
}
1080

    
1081
void ff_img_copy_plane(uint8_t *dst, int dst_wrap,
1082
                           const uint8_t *src, int src_wrap,
1083
                           int width, int height)
1084
{
1085
    if((!dst) || (!src))
1086
        return;
1087
    for(;height > 0; height--) {
1088
        memcpy(dst, src, width);
1089
        dst += dst_wrap;
1090
        src += src_wrap;
1091
    }
1092
}
1093

    
1094
int ff_get_plane_bytewidth(enum PixelFormat pix_fmt, int width, int plane)
1095
{
1096
    int bits;
1097
    const PixFmtInfo *pf = &pix_fmt_info[pix_fmt];
1098

    
1099
    pf = &pix_fmt_info[pix_fmt];
1100
    switch(pf->pixel_type) {
1101
    case FF_PIXEL_PACKED:
1102
        switch(pix_fmt) {
1103
        case PIX_FMT_YUYV422:
1104
        case PIX_FMT_UYVY422:
1105
        case PIX_FMT_RGB565:
1106
        case PIX_FMT_RGB555:
1107
        case PIX_FMT_BGR565:
1108
        case PIX_FMT_BGR555:
1109
            bits = 16;
1110
            break;
1111
        case PIX_FMT_UYYVYY411:
1112
            bits = 12;
1113
            break;
1114
        default:
1115
            bits = pf->depth * pf->nb_channels;
1116
            break;
1117
        }
1118
        return (width * bits + 7) >> 3;
1119
        break;
1120
    case FF_PIXEL_PLANAR:
1121
            if (plane == 1 || plane == 2)
1122
                width= -((-width)>>pf->x_chroma_shift);
1123

    
1124
            return (width * pf->depth + 7) >> 3;
1125
        break;
1126
    case FF_PIXEL_PALETTE:
1127
        if (plane == 0)
1128
            return width;
1129
        break;
1130
    }
1131

    
1132
    return -1;
1133
}
1134

    
1135
void av_picture_copy(AVPicture *dst, const AVPicture *src,
1136
                     enum PixelFormat pix_fmt, int width, int height)
1137
{
1138
    int i;
1139
    const PixFmtInfo *pf = &pix_fmt_info[pix_fmt];
1140

    
1141
    switch(pf->pixel_type) {
1142
    case FF_PIXEL_PACKED:
1143
    case FF_PIXEL_PLANAR:
1144
        for(i = 0; i < pf->nb_channels; i++) {
1145
            int h;
1146
            int bwidth = ff_get_plane_bytewidth(pix_fmt, width, i);
1147
            h = height;
1148
            if (i == 1 || i == 2) {
1149
                h= -((-height)>>pf->y_chroma_shift);
1150
            }
1151
            ff_img_copy_plane(dst->data[i], dst->linesize[i],
1152
                           src->data[i], src->linesize[i],
1153
                           bwidth, h);
1154
        }
1155
        break;
1156
    case FF_PIXEL_PALETTE:
1157
        ff_img_copy_plane(dst->data[0], dst->linesize[0],
1158
                       src->data[0], src->linesize[0],
1159
                       width, height);
1160
        /* copy the palette */
1161
        ff_img_copy_plane(dst->data[1], dst->linesize[1],
1162
                       src->data[1], src->linesize[1],
1163
                       4, 256);
1164
        break;
1165
    }
1166
}
1167

    
1168
/* 2x2 -> 1x1 */
1169
void ff_shrink22(uint8_t *dst, int dst_wrap,
1170
                     const uint8_t *src, int src_wrap,
1171
                     int width, int height)
1172
{
1173
    int w;
1174
    const uint8_t *s1, *s2;
1175
    uint8_t *d;
1176

    
1177
    for(;height > 0; height--) {
1178
        s1 = src;
1179
        s2 = s1 + src_wrap;
1180
        d = dst;
1181
        for(w = width;w >= 4; w-=4) {
1182
            d[0] = (s1[0] + s1[1] + s2[0] + s2[1] + 2) >> 2;
1183
            d[1] = (s1[2] + s1[3] + s2[2] + s2[3] + 2) >> 2;
1184
            d[2] = (s1[4] + s1[5] + s2[4] + s2[5] + 2) >> 2;
1185
            d[3] = (s1[6] + s1[7] + s2[6] + s2[7] + 2) >> 2;
1186
            s1 += 8;
1187
            s2 += 8;
1188
            d += 4;
1189
        }
1190
        for(;w > 0; w--) {
1191
            d[0] = (s1[0] + s1[1] + s2[0] + s2[1] + 2) >> 2;
1192
            s1 += 2;
1193
            s2 += 2;
1194
            d++;
1195
        }
1196
        src += 2 * src_wrap;
1197
        dst += dst_wrap;
1198
    }
1199
}
1200

    
1201
/* 4x4 -> 1x1 */
1202
void ff_shrink44(uint8_t *dst, int dst_wrap,
1203
                     const uint8_t *src, int src_wrap,
1204
                     int width, int height)
1205
{
1206
    int w;
1207
    const uint8_t *s1, *s2, *s3, *s4;
1208
    uint8_t *d;
1209

    
1210
    for(;height > 0; height--) {
1211
        s1 = src;
1212
        s2 = s1 + src_wrap;
1213
        s3 = s2 + src_wrap;
1214
        s4 = s3 + src_wrap;
1215
        d = dst;
1216
        for(w = width;w > 0; w--) {
1217
            d[0] = (s1[0] + s1[1] + s1[2] + s1[3] +
1218
                    s2[0] + s2[1] + s2[2] + s2[3] +
1219
                    s3[0] + s3[1] + s3[2] + s3[3] +
1220
                    s4[0] + s4[1] + s4[2] + s4[3] + 8) >> 4;
1221
            s1 += 4;
1222
            s2 += 4;
1223
            s3 += 4;
1224
            s4 += 4;
1225
            d++;
1226
        }
1227
        src += 4 * src_wrap;
1228
        dst += dst_wrap;
1229
    }
1230
}
1231

    
1232
/* 8x8 -> 1x1 */
1233
void ff_shrink88(uint8_t *dst, int dst_wrap,
1234
                     const uint8_t *src, int src_wrap,
1235
                     int width, int height)
1236
{
1237
    int w, i;
1238

    
1239
    for(;height > 0; height--) {
1240
        for(w = width;w > 0; w--) {
1241
            int tmp=0;
1242
            for(i=0; i<8; i++){
1243
                tmp += src[0] + src[1] + src[2] + src[3] + src[4] + src[5] + src[6] + src[7];
1244
                src += src_wrap;
1245
            }
1246
            *(dst++) = (tmp + 32)>>6;
1247
            src += 8 - 8*src_wrap;
1248
        }
1249
        src += 8*src_wrap - 8*width;
1250
        dst += dst_wrap - width;
1251
    }
1252
}
1253

    
1254

    
1255
int avpicture_alloc(AVPicture *picture,
1256
                    enum PixelFormat pix_fmt, int width, int height)
1257
{
1258
    int size;
1259
    void *ptr;
1260

    
1261
    size = avpicture_fill(picture, NULL, pix_fmt, width, height);
1262
    if(size<0)
1263
        goto fail;
1264
    ptr = av_malloc(size);
1265
    if (!ptr)
1266
        goto fail;
1267
    avpicture_fill(picture, ptr, pix_fmt, width, height);
1268
    if(picture->data[1] && !picture->data[2])
1269
        ff_set_systematic_pal((uint32_t*)picture->data[1], pix_fmt);
1270

    
1271
    return 0;
1272
 fail:
1273
    memset(picture, 0, sizeof(AVPicture));
1274
    return -1;
1275
}
1276

    
1277
void avpicture_free(AVPicture *picture)
1278
{
1279
    av_free(picture->data[0]);
1280
}
1281

    
1282
/* return true if yuv planar */
1283
static inline int is_yuv_planar(const PixFmtInfo *ps)
1284
{
1285
    return (ps->color_type == FF_COLOR_YUV ||
1286
            ps->color_type == FF_COLOR_YUV_JPEG) &&
1287
        ps->pixel_type == FF_PIXEL_PLANAR;
1288
}
1289

    
1290
int av_picture_crop(AVPicture *dst, const AVPicture *src,
1291
                    enum PixelFormat pix_fmt, int top_band, int left_band)
1292
{
1293
    int y_shift;
1294
    int x_shift;
1295

    
1296
    if (pix_fmt < 0 || pix_fmt >= PIX_FMT_NB || !is_yuv_planar(&pix_fmt_info[pix_fmt]))
1297
        return -1;
1298

    
1299
    y_shift = pix_fmt_info[pix_fmt].y_chroma_shift;
1300
    x_shift = pix_fmt_info[pix_fmt].x_chroma_shift;
1301

    
1302
    dst->data[0] = src->data[0] + (top_band * src->linesize[0]) + left_band;
1303
    dst->data[1] = src->data[1] + ((top_band >> y_shift) * src->linesize[1]) + (left_band >> x_shift);
1304
    dst->data[2] = src->data[2] + ((top_band >> y_shift) * src->linesize[2]) + (left_band >> x_shift);
1305

    
1306
    dst->linesize[0] = src->linesize[0];
1307
    dst->linesize[1] = src->linesize[1];
1308
    dst->linesize[2] = src->linesize[2];
1309
    return 0;
1310
}
1311

    
1312
int av_picture_pad(AVPicture *dst, const AVPicture *src, int height, int width,
1313
                   enum PixelFormat pix_fmt, int padtop, int padbottom, int padleft, int padright,
1314
            int *color)
1315
{
1316
    uint8_t *optr;
1317
    int y_shift;
1318
    int x_shift;
1319
    int yheight;
1320
    int i, y;
1321

    
1322
    if (pix_fmt < 0 || pix_fmt >= PIX_FMT_NB ||
1323
        !is_yuv_planar(&pix_fmt_info[pix_fmt])) return -1;
1324

    
1325
    for (i = 0; i < 3; i++) {
1326
        x_shift = i ? pix_fmt_info[pix_fmt].x_chroma_shift : 0;
1327
        y_shift = i ? pix_fmt_info[pix_fmt].y_chroma_shift : 0;
1328

    
1329
        if (padtop || padleft) {
1330
            memset(dst->data[i], color[i],
1331
                dst->linesize[i] * (padtop >> y_shift) + (padleft >> x_shift));
1332
        }
1333

    
1334
        if (padleft || padright) {
1335
            optr = dst->data[i] + dst->linesize[i] * (padtop >> y_shift) +
1336
                (dst->linesize[i] - (padright >> x_shift));
1337
            yheight = (height - 1 - (padtop + padbottom)) >> y_shift;
1338
            for (y = 0; y < yheight; y++) {
1339
                memset(optr, color[i], (padleft + padright) >> x_shift);
1340
                optr += dst->linesize[i];
1341
            }
1342
        }
1343

    
1344
        if (src) { /* first line */
1345
            uint8_t *iptr = src->data[i];
1346
            optr = dst->data[i] + dst->linesize[i] * (padtop >> y_shift) +
1347
                    (padleft >> x_shift);
1348
            memcpy(optr, iptr, (width - padleft - padright) >> x_shift);
1349
            iptr += src->linesize[i];
1350
            optr = dst->data[i] + dst->linesize[i] * (padtop >> y_shift) +
1351
                (dst->linesize[i] - (padright >> x_shift));
1352
            yheight = (height - 1 - (padtop + padbottom)) >> y_shift;
1353
            for (y = 0; y < yheight; y++) {
1354
                memset(optr, color[i], (padleft + padright) >> x_shift);
1355
                memcpy(optr + ((padleft + padright) >> x_shift), iptr,
1356
                       (width - padleft - padright) >> x_shift);
1357
                iptr += src->linesize[i];
1358
                optr += dst->linesize[i];
1359
            }
1360
        }
1361

    
1362
        if (padbottom || padright) {
1363
            optr = dst->data[i] + dst->linesize[i] *
1364
                ((height - padbottom) >> y_shift) - (padright >> x_shift);
1365
            memset(optr, color[i],dst->linesize[i] *
1366
                (padbottom >> y_shift) + (padright >> x_shift));
1367
        }
1368
    }
1369
    return 0;
1370
}
1371

    
1372
/* NOTE: we scan all the pixels to have an exact information */
1373
static int get_alpha_info_pal8(const AVPicture *src, int width, int height)
1374
{
1375
    const unsigned char *p;
1376
    int src_wrap, ret, x, y;
1377
    unsigned int a;
1378
    uint32_t *palette = (uint32_t *)src->data[1];
1379

    
1380
    p = src->data[0];
1381
    src_wrap = src->linesize[0] - width;
1382
    ret = 0;
1383
    for(y=0;y<height;y++) {
1384
        for(x=0;x<width;x++) {
1385
            a = palette[p[0]] >> 24;
1386
            if (a == 0x00) {
1387
                ret |= FF_ALPHA_TRANSP;
1388
            } else if (a != 0xff) {
1389
                ret |= FF_ALPHA_SEMI_TRANSP;
1390
            }
1391
            p++;
1392
        }
1393
        p += src_wrap;
1394
    }
1395
    return ret;
1396
}
1397

    
1398
int img_get_alpha_info(const AVPicture *src,
1399
                       enum PixelFormat pix_fmt, int width, int height)
1400
{
1401
    const PixFmtInfo *pf = &pix_fmt_info[pix_fmt];
1402
    int ret;
1403

    
1404
    /* no alpha can be represented in format */
1405
    if (!pf->is_alpha)
1406
        return 0;
1407
    switch(pix_fmt) {
1408
    case PIX_FMT_PAL8:
1409
        ret = get_alpha_info_pal8(src, width, height);
1410
        break;
1411
    default:
1412
        /* we do not know, so everything is indicated */
1413
        ret = FF_ALPHA_TRANSP | FF_ALPHA_SEMI_TRANSP;
1414
        break;
1415
    }
1416
    return ret;
1417
}
1418

    
1419
#if HAVE_MMX
1420
#define DEINT_INPLACE_LINE_LUM \
1421
                    movd_m2r(lum_m4[0],mm0);\
1422
                    movd_m2r(lum_m3[0],mm1);\
1423
                    movd_m2r(lum_m2[0],mm2);\
1424
                    movd_m2r(lum_m1[0],mm3);\
1425
                    movd_m2r(lum[0],mm4);\
1426
                    punpcklbw_r2r(mm7,mm0);\
1427
                    movd_r2m(mm2,lum_m4[0]);\
1428
                    punpcklbw_r2r(mm7,mm1);\
1429
                    punpcklbw_r2r(mm7,mm2);\
1430
                    punpcklbw_r2r(mm7,mm3);\
1431
                    punpcklbw_r2r(mm7,mm4);\
1432
                    paddw_r2r(mm3,mm1);\
1433
                    psllw_i2r(1,mm2);\
1434
                    paddw_r2r(mm4,mm0);\
1435
                    psllw_i2r(2,mm1);\
1436
                    paddw_r2r(mm6,mm2);\
1437
                    paddw_r2r(mm2,mm1);\
1438
                    psubusw_r2r(mm0,mm1);\
1439
                    psrlw_i2r(3,mm1);\
1440
                    packuswb_r2r(mm7,mm1);\
1441
                    movd_r2m(mm1,lum_m2[0]);
1442

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

    
1466
/* filter parameters: [-1 4 2 4 -1] // 8 */
1467
static void deinterlace_line(uint8_t *dst,
1468
                             const uint8_t *lum_m4, const uint8_t *lum_m3,
1469
                             const uint8_t *lum_m2, const uint8_t *lum_m1,
1470
                             const uint8_t *lum,
1471
                             int size)
1472
{
1473
#if !HAVE_MMX
1474
    uint8_t *cm = ff_cropTbl + MAX_NEG_CROP;
1475
    int sum;
1476

    
1477
    for(;size > 0;size--) {
1478
        sum = -lum_m4[0];
1479
        sum += lum_m3[0] << 2;
1480
        sum += lum_m2[0] << 1;
1481
        sum += lum_m1[0] << 2;
1482
        sum += -lum[0];
1483
        dst[0] = cm[(sum + 4) >> 3];
1484
        lum_m4++;
1485
        lum_m3++;
1486
        lum_m2++;
1487
        lum_m1++;
1488
        lum++;
1489
        dst++;
1490
    }
1491
#else
1492

    
1493
    {
1494
        pxor_r2r(mm7,mm7);
1495
        movq_m2r(ff_pw_4,mm6);
1496
    }
1497
    for (;size > 3; size-=4) {
1498
        DEINT_LINE_LUM
1499
        lum_m4+=4;
1500
        lum_m3+=4;
1501
        lum_m2+=4;
1502
        lum_m1+=4;
1503
        lum+=4;
1504
        dst+=4;
1505
    }
1506
#endif
1507
}
1508
static void deinterlace_line_inplace(uint8_t *lum_m4, uint8_t *lum_m3, uint8_t *lum_m2, uint8_t *lum_m1, uint8_t *lum,
1509
                             int size)
1510
{
1511
#if !HAVE_MMX
1512
    uint8_t *cm = ff_cropTbl + MAX_NEG_CROP;
1513
    int sum;
1514

    
1515
    for(;size > 0;size--) {
1516
        sum = -lum_m4[0];
1517
        sum += lum_m3[0] << 2;
1518
        sum += lum_m2[0] << 1;
1519
        lum_m4[0]=lum_m2[0];
1520
        sum += lum_m1[0] << 2;
1521
        sum += -lum[0];
1522
        lum_m2[0] = cm[(sum + 4) >> 3];
1523
        lum_m4++;
1524
        lum_m3++;
1525
        lum_m2++;
1526
        lum_m1++;
1527
        lum++;
1528
    }
1529
#else
1530

    
1531
    {
1532
        pxor_r2r(mm7,mm7);
1533
        movq_m2r(ff_pw_4,mm6);
1534
    }
1535
    for (;size > 3; size-=4) {
1536
        DEINT_INPLACE_LINE_LUM
1537
        lum_m4+=4;
1538
        lum_m3+=4;
1539
        lum_m2+=4;
1540
        lum_m1+=4;
1541
        lum+=4;
1542
    }
1543
#endif
1544
}
1545

    
1546
/* deinterlacing : 2 temporal taps, 3 spatial taps linear filter. The
1547
   top field is copied as is, but the bottom field is deinterlaced
1548
   against the top field. */
1549
static void deinterlace_bottom_field(uint8_t *dst, int dst_wrap,
1550
                                    const uint8_t *src1, int src_wrap,
1551
                                    int width, int height)
1552
{
1553
    const uint8_t *src_m2, *src_m1, *src_0, *src_p1, *src_p2;
1554
    int y;
1555

    
1556
    src_m2 = src1;
1557
    src_m1 = src1;
1558
    src_0=&src_m1[src_wrap];
1559
    src_p1=&src_0[src_wrap];
1560
    src_p2=&src_p1[src_wrap];
1561
    for(y=0;y<(height-2);y+=2) {
1562
        memcpy(dst,src_m1,width);
1563
        dst += dst_wrap;
1564
        deinterlace_line(dst,src_m2,src_m1,src_0,src_p1,src_p2,width);
1565
        src_m2 = src_0;
1566
        src_m1 = src_p1;
1567
        src_0 = src_p2;
1568
        src_p1 += 2*src_wrap;
1569
        src_p2 += 2*src_wrap;
1570
        dst += dst_wrap;
1571
    }
1572
    memcpy(dst,src_m1,width);
1573
    dst += dst_wrap;
1574
    /* do last line */
1575
    deinterlace_line(dst,src_m2,src_m1,src_0,src_0,src_0,width);
1576
}
1577

    
1578
static void deinterlace_bottom_field_inplace(uint8_t *src1, int src_wrap,
1579
                                             int width, int height)
1580
{
1581
    uint8_t *src_m1, *src_0, *src_p1, *src_p2;
1582
    int y;
1583
    uint8_t *buf;
1584
    buf = (uint8_t*)av_malloc(width);
1585

    
1586
    src_m1 = src1;
1587
    memcpy(buf,src_m1,width);
1588
    src_0=&src_m1[src_wrap];
1589
    src_p1=&src_0[src_wrap];
1590
    src_p2=&src_p1[src_wrap];
1591
    for(y=0;y<(height-2);y+=2) {
1592
        deinterlace_line_inplace(buf,src_m1,src_0,src_p1,src_p2,width);
1593
        src_m1 = src_p1;
1594
        src_0 = src_p2;
1595
        src_p1 += 2*src_wrap;
1596
        src_p2 += 2*src_wrap;
1597
    }
1598
    /* do last line */
1599
    deinterlace_line_inplace(buf,src_m1,src_0,src_0,src_0,width);
1600
    av_free(buf);
1601
}
1602

    
1603
int avpicture_deinterlace(AVPicture *dst, const AVPicture *src,
1604
                          enum PixelFormat pix_fmt, int width, int height)
1605
{
1606
    int i;
1607

    
1608
    if (pix_fmt != PIX_FMT_YUV420P &&
1609
        pix_fmt != PIX_FMT_YUV422P &&
1610
        pix_fmt != PIX_FMT_YUV444P &&
1611
        pix_fmt != PIX_FMT_YUV411P &&
1612
        pix_fmt != PIX_FMT_GRAY8)
1613
        return -1;
1614
    if ((width & 3) != 0 || (height & 3) != 0)
1615
        return -1;
1616

    
1617
    for(i=0;i<3;i++) {
1618
        if (i == 1) {
1619
            switch(pix_fmt) {
1620
            case PIX_FMT_YUV420P:
1621
                width >>= 1;
1622
                height >>= 1;
1623
                break;
1624
            case PIX_FMT_YUV422P:
1625
                width >>= 1;
1626
                break;
1627
            case PIX_FMT_YUV411P:
1628
                width >>= 2;
1629
                break;
1630
            default:
1631
                break;
1632
            }
1633
            if (pix_fmt == PIX_FMT_GRAY8) {
1634
                break;
1635
            }
1636
        }
1637
        if (src == dst) {
1638
            deinterlace_bottom_field_inplace(dst->data[i], dst->linesize[i],
1639
                                 width, height);
1640
        } else {
1641
            deinterlace_bottom_field(dst->data[i],dst->linesize[i],
1642
                                        src->data[i], src->linesize[i],
1643
                                        width, height);
1644
        }
1645
    }
1646
    emms_c();
1647
    return 0;
1648
}
1649