Statistics
| Branch: | Revision:

ffmpeg / libavcodec / imgconvert.c @ 70e0c871

History | View | Annotate | Download (47.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_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_VDPAU_MPEG4] = {
380
        .name = "vdpau_mpeg4",
381
        .is_hwaccel = 1,
382
        .x_chroma_shift = 1, .y_chroma_shift = 1,
383
    },
384
    [PIX_FMT_UYYVYY411] = {
385
        .name = "uyyvyy411",
386
        .nb_channels = 1,
387
        .color_type = FF_COLOR_YUV,
388
        .pixel_type = FF_PIXEL_PACKED,
389
        .depth = 8,
390
        .x_chroma_shift = 2, .y_chroma_shift = 0,
391
    },
392
    [PIX_FMT_ABGR] = {
393
        .name = "abgr",
394
        .nb_channels = 4, .is_alpha = 1,
395
        .color_type = FF_COLOR_RGB,
396
        .pixel_type = FF_PIXEL_PACKED,
397
        .depth = 8,
398
        .x_chroma_shift = 0, .y_chroma_shift = 0,
399
    },
400
    [PIX_FMT_BGR565BE] = {
401
        .name = "bgr565be",
402
        .nb_channels = 3,
403
        .color_type = FF_COLOR_RGB,
404
        .pixel_type = FF_PIXEL_PACKED,
405
        .depth = 5,
406
        .x_chroma_shift = 0, .y_chroma_shift = 0,
407
    },
408
    [PIX_FMT_BGR565LE] = {
409
        .name = "bgr565le",
410
        .nb_channels = 3,
411
        .color_type = FF_COLOR_RGB,
412
        .pixel_type = FF_PIXEL_PACKED,
413
        .depth = 5,
414
        .x_chroma_shift = 0, .y_chroma_shift = 0,
415
    },
416
    [PIX_FMT_BGR555BE] = {
417
        .name = "bgr555be",
418
        .nb_channels = 3,
419
        .color_type = FF_COLOR_RGB,
420
        .pixel_type = FF_PIXEL_PACKED,
421
        .depth = 5,
422
        .x_chroma_shift = 0, .y_chroma_shift = 0,
423
    },
424
    [PIX_FMT_BGR555LE] = {
425
        .name = "bgr555le",
426
        .nb_channels = 3,
427
        .color_type = FF_COLOR_RGB,
428
        .pixel_type = FF_PIXEL_PACKED,
429
        .depth = 5,
430
        .x_chroma_shift = 0, .y_chroma_shift = 0,
431
    },
432
    [PIX_FMT_RGB8] = {
433
        .name = "rgb8",
434
        .nb_channels = 1,
435
        .color_type = FF_COLOR_RGB,
436
        .pixel_type = FF_PIXEL_PACKED,
437
        .depth = 8,
438
        .x_chroma_shift = 0, .y_chroma_shift = 0,
439
    },
440
    [PIX_FMT_RGB4] = {
441
        .name = "rgb4",
442
        .nb_channels = 1,
443
        .color_type = FF_COLOR_RGB,
444
        .pixel_type = FF_PIXEL_PACKED,
445
        .depth = 4,
446
        .x_chroma_shift = 0, .y_chroma_shift = 0,
447
    },
448
    [PIX_FMT_RGB4_BYTE] = {
449
        .name = "rgb4_byte",
450
        .nb_channels = 1,
451
        .color_type = FF_COLOR_RGB,
452
        .pixel_type = FF_PIXEL_PACKED,
453
        .depth = 8,
454
        .x_chroma_shift = 0, .y_chroma_shift = 0,
455
    },
456
    [PIX_FMT_BGR8] = {
457
        .name = "bgr8",
458
        .nb_channels = 1,
459
        .color_type = FF_COLOR_RGB,
460
        .pixel_type = FF_PIXEL_PACKED,
461
        .depth = 8,
462
        .x_chroma_shift = 0, .y_chroma_shift = 0,
463
    },
464
    [PIX_FMT_BGR4] = {
465
        .name = "bgr4",
466
        .nb_channels = 1,
467
        .color_type = FF_COLOR_RGB,
468
        .pixel_type = FF_PIXEL_PACKED,
469
        .depth = 4,
470
        .x_chroma_shift = 0, .y_chroma_shift = 0,
471
    },
472
    [PIX_FMT_BGR4_BYTE] = {
473
        .name = "bgr4_byte",
474
        .nb_channels = 1,
475
        .color_type = FF_COLOR_RGB,
476
        .pixel_type = FF_PIXEL_PACKED,
477
        .depth = 8,
478
        .x_chroma_shift = 0, .y_chroma_shift = 0,
479
    },
480
    [PIX_FMT_NV12] = {
481
        .name = "nv12",
482
        .nb_channels = 2,
483
        .color_type = FF_COLOR_YUV,
484
        .pixel_type = FF_PIXEL_PLANAR,
485
        .depth = 8,
486
        .x_chroma_shift = 1, .y_chroma_shift = 1,
487
    },
488
    [PIX_FMT_NV21] = {
489
        .name = "nv12",
490
        .nb_channels = 2,
491
        .color_type = FF_COLOR_YUV,
492
        .pixel_type = FF_PIXEL_PLANAR,
493
        .depth = 8,
494
        .x_chroma_shift = 1, .y_chroma_shift = 1,
495
    },
496

    
497
    [PIX_FMT_BGRA] = {
498
        .name = "bgra",
499
        .nb_channels = 4, .is_alpha = 1,
500
        .color_type = FF_COLOR_RGB,
501
        .pixel_type = FF_PIXEL_PACKED,
502
        .depth = 8,
503
        .x_chroma_shift = 0, .y_chroma_shift = 0,
504
    },
505
    [PIX_FMT_RGBA] = {
506
        .name = "rgba",
507
        .nb_channels = 4, .is_alpha = 1,
508
        .color_type = FF_COLOR_RGB,
509
        .pixel_type = FF_PIXEL_PACKED,
510
        .depth = 8,
511
        .x_chroma_shift = 0, .y_chroma_shift = 0,
512
    },
513

    
514
    /* VA API formats */
515
    [PIX_FMT_VAAPI_MOCO] = {
516
        .name = "vaapi_moco",
517
        .is_hwaccel = 1,
518
        .x_chroma_shift = 1, .y_chroma_shift = 1,
519
    },
520
    [PIX_FMT_VAAPI_IDCT] = {
521
        .name = "vaapi_idct",
522
        .is_hwaccel = 1,
523
        .x_chroma_shift = 1, .y_chroma_shift = 1,
524
    },
525
    [PIX_FMT_VAAPI_VLD] = {
526
        .name = "vaapi_vld",
527
        .is_hwaccel = 1,
528
        .x_chroma_shift = 1, .y_chroma_shift = 1,
529
    },
530
};
531

    
532
void avcodec_get_chroma_sub_sample(enum PixelFormat pix_fmt, int *h_shift, int *v_shift)
533
{
534
    *h_shift = pix_fmt_info[pix_fmt].x_chroma_shift;
535
    *v_shift = pix_fmt_info[pix_fmt].y_chroma_shift;
536
}
537

    
538
const char *avcodec_get_pix_fmt_name(enum PixelFormat pix_fmt)
539
{
540
    if (pix_fmt < 0 || pix_fmt >= PIX_FMT_NB)
541
        return NULL;
542
    else
543
        return pix_fmt_info[pix_fmt].name;
544
}
545

    
546
static enum PixelFormat avcodec_get_pix_fmt_internal(const char *name)
547
{
548
    int i;
549

    
550
    for (i=0; i < PIX_FMT_NB; i++)
551
        if (pix_fmt_info[i].name && !strcmp(pix_fmt_info[i].name, name))
552
            return i;
553
    return PIX_FMT_NONE;
554
}
555

    
556
#if HAVE_BIGENDIAN
557
#   define X_NE(be, le) be
558
#else
559
#   define X_NE(be, le) le
560
#endif
561

    
562
enum PixelFormat avcodec_get_pix_fmt(const char *name)
563
{
564
    enum PixelFormat pix_fmt;
565

    
566
    if (!strcmp(name, "rgb32"))
567
        name = X_NE("argb", "bgra");
568
    else if (!strcmp(name, "bgr32"))
569
        name = X_NE("abgr", "rgba");
570

    
571
    pix_fmt = avcodec_get_pix_fmt_internal(name);
572
    if (pix_fmt == PIX_FMT_NONE) {
573
        char name2[32];
574
        snprintf(name2, sizeof(name2), "%s%s", name, X_NE("be", "le"));
575
        pix_fmt = avcodec_get_pix_fmt_internal(name2);
576
    }
577
    return pix_fmt;
578
}
579

    
580
void avcodec_pix_fmt_string (char *buf, int buf_size, enum PixelFormat pix_fmt)
581
{
582
    /* print header */
583
    if (pix_fmt < 0)
584
        snprintf (buf, buf_size,
585
                  "name      " " nb_channels" " depth" " is_alpha"
586
            );
587
    else{
588
        PixFmtInfo info= pix_fmt_info[pix_fmt];
589

    
590
        char is_alpha_char= info.is_alpha ? 'y' : 'n';
591

    
592
        snprintf (buf, buf_size,
593
                  "%-11s %5d %9d %6c",
594
                  info.name,
595
                  info.nb_channels,
596
                  info.depth,
597
                  is_alpha_char
598
            );
599
    }
600
}
601

    
602
int ff_is_hwaccel_pix_fmt(enum PixelFormat pix_fmt)
603
{
604
    return pix_fmt_info[pix_fmt].is_hwaccel;
605
}
606

    
607
int ff_set_systematic_pal(uint32_t pal[256], enum PixelFormat pix_fmt){
608
    int i;
609

    
610
    for(i=0; i<256; i++){
611
        int r,g,b;
612

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

    
643
    return 0;
644
}
645

    
646
int ff_fill_linesize(AVPicture *picture, enum PixelFormat pix_fmt, int width)
647
{
648
    int w2;
649
    const PixFmtInfo *pinfo;
650

    
651
    memset(picture->linesize, 0, sizeof(picture->linesize));
652

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

    
749
int ff_fill_pointer(AVPicture *picture, uint8_t *ptr, enum PixelFormat pix_fmt,
750
                    int height)
751
{
752
    int size, h2, size2;
753
    const PixFmtInfo *pinfo;
754

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

    
849
int avpicture_fill(AVPicture *picture, uint8_t *ptr,
850
                   enum PixelFormat pix_fmt, int width, int height)
851
{
852

    
853
    if(avcodec_check_dimensions(NULL, width, height))
854
        return -1;
855

    
856
    if (ff_fill_linesize(picture, pix_fmt, width))
857
        return -1;
858

    
859
    return ff_fill_pointer(picture, ptr, pix_fmt, height);
860
}
861

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

    
870
    if (size > dest_size || size < 0)
871
        return -1;
872

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

    
892
        data_planes = 1;
893
        h = height;
894
    } else {
895
        data_planes = pf->nb_channels;
896
        w = (width*pf->depth + 7)/8;
897
        h = height;
898
    }
899

    
900
    ow = w;
901
    oh = h;
902

    
903
    for (i=0; i<data_planes; i++) {
904
         if (i == 1) {
905
             w = ((width >> pf->x_chroma_shift) * pf->depth + 7) / 8;
906
             h = height >> pf->y_chroma_shift;
907
         } else if (i == 3) {
908
             w = ow;
909
             h = oh;
910
         }
911
         s = src->data[i];
912
         for(j=0; j<h; j++) {
913
             memcpy(dest, s, w);
914
             dest += w;
915
             s += src->linesize[i];
916
         }
917
    }
918

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

    
922
    return size;
923
}
924

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

    
942
int avcodec_get_pix_fmt_loss(enum PixelFormat dst_pix_fmt, enum PixelFormat src_pix_fmt,
943
                             int has_alpha)
944
{
945
    const PixFmtInfo *pf, *ps;
946
    int loss;
947

    
948
    ps = &pix_fmt_info[src_pix_fmt];
949

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

    
997
static int avg_bits_per_pixel(enum PixelFormat pix_fmt)
998
{
999
    int bits;
1000
    const PixFmtInfo *pf;
1001

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

    
1044
static enum PixelFormat avcodec_find_best_pix_fmt1(int64_t pix_fmt_mask,
1045
                                      enum PixelFormat src_pix_fmt,
1046
                                      int has_alpha,
1047
                                      int loss_mask)
1048
{
1049
    int dist, i, loss, min_dist;
1050
    enum PixelFormat dst_pix_fmt;
1051

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

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

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

    
1103
void ff_img_copy_plane(uint8_t *dst, int dst_wrap,
1104
                           const uint8_t *src, int src_wrap,
1105
                           int width, int height)
1106
{
1107
    if((!dst) || (!src))
1108
        return;
1109
    for(;height > 0; height--) {
1110
        memcpy(dst, src, width);
1111
        dst += dst_wrap;
1112
        src += src_wrap;
1113
    }
1114
}
1115

    
1116
int ff_get_plane_bytewidth(enum PixelFormat pix_fmt, int width, int plane)
1117
{
1118
    int bits;
1119
    const PixFmtInfo *pf = &pix_fmt_info[pix_fmt];
1120

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

    
1150
            return (width * pf->depth + 7) >> 3;
1151
        break;
1152
    case FF_PIXEL_PALETTE:
1153
        if (plane == 0)
1154
            return width;
1155
        break;
1156
    }
1157

    
1158
    return -1;
1159
}
1160

    
1161
void av_picture_copy(AVPicture *dst, const AVPicture *src,
1162
                     enum PixelFormat pix_fmt, int width, int height)
1163
{
1164
    int i;
1165
    const PixFmtInfo *pf = &pix_fmt_info[pix_fmt];
1166

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

    
1194
/* 2x2 -> 1x1 */
1195
void ff_shrink22(uint8_t *dst, int dst_wrap,
1196
                     const uint8_t *src, int src_wrap,
1197
                     int width, int height)
1198
{
1199
    int w;
1200
    const uint8_t *s1, *s2;
1201
    uint8_t *d;
1202

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

    
1227
/* 4x4 -> 1x1 */
1228
void ff_shrink44(uint8_t *dst, int dst_wrap,
1229
                     const uint8_t *src, int src_wrap,
1230
                     int width, int height)
1231
{
1232
    int w;
1233
    const uint8_t *s1, *s2, *s3, *s4;
1234
    uint8_t *d;
1235

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

    
1258
/* 8x8 -> 1x1 */
1259
void ff_shrink88(uint8_t *dst, int dst_wrap,
1260
                     const uint8_t *src, int src_wrap,
1261
                     int width, int height)
1262
{
1263
    int w, i;
1264

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

    
1280

    
1281
int avpicture_alloc(AVPicture *picture,
1282
                    enum PixelFormat pix_fmt, int width, int height)
1283
{
1284
    int size;
1285
    void *ptr;
1286

    
1287
    size = avpicture_fill(picture, NULL, pix_fmt, width, height);
1288
    if(size<0)
1289
        goto fail;
1290
    ptr = av_malloc(size);
1291
    if (!ptr)
1292
        goto fail;
1293
    avpicture_fill(picture, ptr, pix_fmt, width, height);
1294
    if(picture->data[1] && !picture->data[2])
1295
        ff_set_systematic_pal((uint32_t*)picture->data[1], pix_fmt);
1296

    
1297
    return 0;
1298
 fail:
1299
    memset(picture, 0, sizeof(AVPicture));
1300
    return -1;
1301
}
1302

    
1303
void avpicture_free(AVPicture *picture)
1304
{
1305
    av_free(picture->data[0]);
1306
}
1307

    
1308
/* return true if yuv planar */
1309
static inline int is_yuv_planar(const PixFmtInfo *ps)
1310
{
1311
    return (ps->color_type == FF_COLOR_YUV ||
1312
            ps->color_type == FF_COLOR_YUV_JPEG) &&
1313
        ps->pixel_type == FF_PIXEL_PLANAR;
1314
}
1315

    
1316
int av_picture_crop(AVPicture *dst, const AVPicture *src,
1317
                    enum PixelFormat pix_fmt, int top_band, int left_band)
1318
{
1319
    int y_shift;
1320
    int x_shift;
1321

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

    
1325
    y_shift = pix_fmt_info[pix_fmt].y_chroma_shift;
1326
    x_shift = pix_fmt_info[pix_fmt].x_chroma_shift;
1327

    
1328
    dst->data[0] = src->data[0] + (top_band * src->linesize[0]) + left_band;
1329
    dst->data[1] = src->data[1] + ((top_band >> y_shift) * src->linesize[1]) + (left_band >> x_shift);
1330
    dst->data[2] = src->data[2] + ((top_band >> y_shift) * src->linesize[2]) + (left_band >> x_shift);
1331

    
1332
    dst->linesize[0] = src->linesize[0];
1333
    dst->linesize[1] = src->linesize[1];
1334
    dst->linesize[2] = src->linesize[2];
1335
    return 0;
1336
}
1337

    
1338
int av_picture_pad(AVPicture *dst, const AVPicture *src, int height, int width,
1339
                   enum PixelFormat pix_fmt, int padtop, int padbottom, int padleft, int padright,
1340
            int *color)
1341
{
1342
    uint8_t *optr;
1343
    int y_shift;
1344
    int x_shift;
1345
    int yheight;
1346
    int i, y;
1347

    
1348
    if (pix_fmt < 0 || pix_fmt >= PIX_FMT_NB ||
1349
        !is_yuv_planar(&pix_fmt_info[pix_fmt])) return -1;
1350

    
1351
    for (i = 0; i < 3; i++) {
1352
        x_shift = i ? pix_fmt_info[pix_fmt].x_chroma_shift : 0;
1353
        y_shift = i ? pix_fmt_info[pix_fmt].y_chroma_shift : 0;
1354

    
1355
        if (padtop || padleft) {
1356
            memset(dst->data[i], color[i],
1357
                dst->linesize[i] * (padtop >> y_shift) + (padleft >> x_shift));
1358
        }
1359

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

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

    
1388
        if (padbottom || padright) {
1389
            optr = dst->data[i] + dst->linesize[i] *
1390
                ((height - padbottom) >> y_shift) - (padright >> x_shift);
1391
            memset(optr, color[i],dst->linesize[i] *
1392
                (padbottom >> y_shift) + (padright >> x_shift));
1393
        }
1394
    }
1395
    return 0;
1396
}
1397

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

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

    
1424
int img_get_alpha_info(const AVPicture *src,
1425
                       enum PixelFormat pix_fmt, int width, int height)
1426
{
1427
    const PixFmtInfo *pf = &pix_fmt_info[pix_fmt];
1428
    int ret;
1429

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

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

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

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

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

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

    
1541
    for(;size > 0;size--) {
1542
        sum = -lum_m4[0];
1543
        sum += lum_m3[0] << 2;
1544
        sum += lum_m2[0] << 1;
1545
        lum_m4[0]=lum_m2[0];
1546
        sum += lum_m1[0] << 2;
1547
        sum += -lum[0];
1548
        lum_m2[0] = cm[(sum + 4) >> 3];
1549
        lum_m4++;
1550
        lum_m3++;
1551
        lum_m2++;
1552
        lum_m1++;
1553
        lum++;
1554
    }
1555
#else
1556

    
1557
    {
1558
        pxor_r2r(mm7,mm7);
1559
        movq_m2r(ff_pw_4,mm6);
1560
    }
1561
    for (;size > 3; size-=4) {
1562
        DEINT_INPLACE_LINE_LUM
1563
        lum_m4+=4;
1564
        lum_m3+=4;
1565
        lum_m2+=4;
1566
        lum_m1+=4;
1567
        lum+=4;
1568
    }
1569
#endif
1570
}
1571

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

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

    
1604
static void deinterlace_bottom_field_inplace(uint8_t *src1, int src_wrap,
1605
                                             int width, int height)
1606
{
1607
    uint8_t *src_m1, *src_0, *src_p1, *src_p2;
1608
    int y;
1609
    uint8_t *buf;
1610
    buf = (uint8_t*)av_malloc(width);
1611

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

    
1629
int avpicture_deinterlace(AVPicture *dst, const AVPicture *src,
1630
                          enum PixelFormat pix_fmt, int width, int height)
1631
{
1632
    int i;
1633

    
1634
    if (pix_fmt != PIX_FMT_YUV420P &&
1635
        pix_fmt != PIX_FMT_YUV422P &&
1636
        pix_fmt != PIX_FMT_YUV444P &&
1637
        pix_fmt != PIX_FMT_YUV411P &&
1638
        pix_fmt != PIX_FMT_GRAY8)
1639
        return -1;
1640
    if ((width & 3) != 0 || (height & 3) != 0)
1641
        return -1;
1642

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