Statistics
| Branch: | Revision:

ffmpeg / libavcodec / imgconvert.c @ f72d40b0

History | View | Annotate | Download (45.3 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
#include "libavutil/pixdesc.h"
37

    
38
#if HAVE_MMX
39
#include "x86/mmx.h"
40
#include "x86/dsputil_mmx.h"
41
#endif
42

    
43
#define xglue(x, y) x ## y
44
#define glue(x, y) xglue(x, y)
45

    
46
#define FF_COLOR_RGB      0 /**< RGB color space */
47
#define FF_COLOR_GRAY     1 /**< gray color space */
48
#define FF_COLOR_YUV      2 /**< YUV color space. 16 <= Y <= 235, 16 <= U, V <= 240 */
49
#define FF_COLOR_YUV_JPEG 3 /**< YUV color space. 0 <= Y <= 255, 0 <= U, V <= 255 */
50

    
51
#define FF_PIXEL_PLANAR   0 /**< each channel has one component in AVPicture */
52
#define FF_PIXEL_PACKED   1 /**< only one components containing all the channels */
53
#define FF_PIXEL_PALETTE  2  /**< one components containing indexes for a palette */
54

    
55
typedef struct PixFmtInfo {
56
    const char *name;
57
    uint8_t nb_channels;     /**< number of channels (including alpha) */
58
    uint8_t color_type;      /**< color type (see FF_COLOR_xxx constants) */
59
    uint8_t pixel_type;      /**< pixel storage type (see FF_PIXEL_xxx constants) */
60
    uint8_t is_alpha : 1;    /**< true if alpha can be specified */
61
    uint8_t depth;           /**< bit depth of the color components */
62
} PixFmtInfo;
63

    
64
/* this table gives more information about formats */
65
static const PixFmtInfo pix_fmt_info[PIX_FMT_NB] = {
66
    /* YUV formats */
67
    [PIX_FMT_YUV420P] = {
68
        .name = "yuv420p",
69
        .nb_channels = 3,
70
        .color_type = FF_COLOR_YUV,
71
        .pixel_type = FF_PIXEL_PLANAR,
72
        .depth = 8,
73
    },
74
    [PIX_FMT_YUV422P] = {
75
        .name = "yuv422p",
76
        .nb_channels = 3,
77
        .color_type = FF_COLOR_YUV,
78
        .pixel_type = FF_PIXEL_PLANAR,
79
        .depth = 8,
80
    },
81
    [PIX_FMT_YUV444P] = {
82
        .name = "yuv444p",
83
        .nb_channels = 3,
84
        .color_type = FF_COLOR_YUV,
85
        .pixel_type = FF_PIXEL_PLANAR,
86
        .depth = 8,
87
    },
88
    [PIX_FMT_YUYV422] = {
89
        .name = "yuyv422",
90
        .nb_channels = 1,
91
        .color_type = FF_COLOR_YUV,
92
        .pixel_type = FF_PIXEL_PACKED,
93
        .depth = 8,
94
    },
95
    [PIX_FMT_UYVY422] = {
96
        .name = "uyvy422",
97
        .nb_channels = 1,
98
        .color_type = FF_COLOR_YUV,
99
        .pixel_type = FF_PIXEL_PACKED,
100
        .depth = 8,
101
    },
102
    [PIX_FMT_YUV410P] = {
103
        .name = "yuv410p",
104
        .nb_channels = 3,
105
        .color_type = FF_COLOR_YUV,
106
        .pixel_type = FF_PIXEL_PLANAR,
107
        .depth = 8,
108
    },
109
    [PIX_FMT_YUV411P] = {
110
        .name = "yuv411p",
111
        .nb_channels = 3,
112
        .color_type = FF_COLOR_YUV,
113
        .pixel_type = FF_PIXEL_PLANAR,
114
        .depth = 8,
115
    },
116
    [PIX_FMT_YUV440P] = {
117
        .name = "yuv440p",
118
        .nb_channels = 3,
119
        .color_type = FF_COLOR_YUV,
120
        .pixel_type = FF_PIXEL_PLANAR,
121
        .depth = 8,
122
    },
123
    [PIX_FMT_YUV420P16LE] = {
124
        .name = "yuv420p16le",
125
        .nb_channels = 3,
126
        .color_type = FF_COLOR_YUV,
127
        .pixel_type = FF_PIXEL_PLANAR,
128
        .depth = 16,
129
    },
130
    [PIX_FMT_YUV422P16LE] = {
131
        .name = "yuv422p16le",
132
        .nb_channels = 3,
133
        .color_type = FF_COLOR_YUV,
134
        .pixel_type = FF_PIXEL_PLANAR,
135
        .depth = 16,
136
    },
137
    [PIX_FMT_YUV444P16LE] = {
138
        .name = "yuv444p16le",
139
        .nb_channels = 3,
140
        .color_type = FF_COLOR_YUV,
141
        .pixel_type = FF_PIXEL_PLANAR,
142
        .depth = 16,
143
    },
144
    [PIX_FMT_YUV420P16BE] = {
145
        .name = "yuv420p16be",
146
        .nb_channels = 3,
147
        .color_type = FF_COLOR_YUV,
148
        .pixel_type = FF_PIXEL_PLANAR,
149
        .depth = 16,
150
    },
151
    [PIX_FMT_YUV422P16BE] = {
152
        .name = "yuv422p16be",
153
        .nb_channels = 3,
154
        .color_type = FF_COLOR_YUV,
155
        .pixel_type = FF_PIXEL_PLANAR,
156
        .depth = 16,
157
    },
158
    [PIX_FMT_YUV444P16BE] = {
159
        .name = "yuv444p16be",
160
        .nb_channels = 3,
161
        .color_type = FF_COLOR_YUV,
162
        .pixel_type = FF_PIXEL_PLANAR,
163
        .depth = 16,
164
    },
165

    
166

    
167
    /* YUV formats with alpha plane */
168
    [PIX_FMT_YUVA420P] = {
169
        .name = "yuva420p",
170
        .nb_channels = 4,
171
        .color_type = FF_COLOR_YUV,
172
        .pixel_type = FF_PIXEL_PLANAR,
173
        .depth = 8,
174
    },
175

    
176
    /* JPEG YUV */
177
    [PIX_FMT_YUVJ420P] = {
178
        .name = "yuvj420p",
179
        .nb_channels = 3,
180
        .color_type = FF_COLOR_YUV_JPEG,
181
        .pixel_type = FF_PIXEL_PLANAR,
182
        .depth = 8,
183
    },
184
    [PIX_FMT_YUVJ422P] = {
185
        .name = "yuvj422p",
186
        .nb_channels = 3,
187
        .color_type = FF_COLOR_YUV_JPEG,
188
        .pixel_type = FF_PIXEL_PLANAR,
189
        .depth = 8,
190
    },
191
    [PIX_FMT_YUVJ444P] = {
192
        .name = "yuvj444p",
193
        .nb_channels = 3,
194
        .color_type = FF_COLOR_YUV_JPEG,
195
        .pixel_type = FF_PIXEL_PLANAR,
196
        .depth = 8,
197
    },
198
    [PIX_FMT_YUVJ440P] = {
199
        .name = "yuvj440p",
200
        .nb_channels = 3,
201
        .color_type = FF_COLOR_YUV_JPEG,
202
        .pixel_type = FF_PIXEL_PLANAR,
203
        .depth = 8,
204
    },
205

    
206
    /* RGB formats */
207
    [PIX_FMT_RGB24] = {
208
        .name = "rgb24",
209
        .nb_channels = 3,
210
        .color_type = FF_COLOR_RGB,
211
        .pixel_type = FF_PIXEL_PACKED,
212
        .depth = 8,
213
    },
214
    [PIX_FMT_BGR24] = {
215
        .name = "bgr24",
216
        .nb_channels = 3,
217
        .color_type = FF_COLOR_RGB,
218
        .pixel_type = FF_PIXEL_PACKED,
219
        .depth = 8,
220
    },
221
    [PIX_FMT_ARGB] = {
222
        .name = "argb",
223
        .nb_channels = 4, .is_alpha = 1,
224
        .color_type = FF_COLOR_RGB,
225
        .pixel_type = FF_PIXEL_PACKED,
226
        .depth = 8,
227
    },
228
    [PIX_FMT_RGB48BE] = {
229
        .name = "rgb48be",
230
        .nb_channels = 3,
231
        .color_type = FF_COLOR_RGB,
232
        .pixel_type = FF_PIXEL_PACKED,
233
        .depth = 16,
234
    },
235
    [PIX_FMT_RGB48LE] = {
236
        .name = "rgb48le",
237
        .nb_channels = 3,
238
        .color_type = FF_COLOR_RGB,
239
        .pixel_type = FF_PIXEL_PACKED,
240
        .depth = 16,
241
    },
242
    [PIX_FMT_RGB565BE] = {
243
        .name = "rgb565be",
244
        .nb_channels = 3,
245
        .color_type = FF_COLOR_RGB,
246
        .pixel_type = FF_PIXEL_PACKED,
247
        .depth = 5,
248
    },
249
    [PIX_FMT_RGB565LE] = {
250
        .name = "rgb565le",
251
        .nb_channels = 3,
252
        .color_type = FF_COLOR_RGB,
253
        .pixel_type = FF_PIXEL_PACKED,
254
        .depth = 5,
255
    },
256
    [PIX_FMT_RGB555BE] = {
257
        .name = "rgb555be",
258
        .nb_channels = 3,
259
        .color_type = FF_COLOR_RGB,
260
        .pixel_type = FF_PIXEL_PACKED,
261
        .depth = 5,
262
    },
263
    [PIX_FMT_RGB555LE] = {
264
        .name = "rgb555le",
265
        .nb_channels = 3,
266
        .color_type = FF_COLOR_RGB,
267
        .pixel_type = FF_PIXEL_PACKED,
268
        .depth = 5,
269
    },
270

    
271
    /* gray / mono formats */
272
    [PIX_FMT_GRAY16BE] = {
273
        .name = "gray16be",
274
        .nb_channels = 1,
275
        .color_type = FF_COLOR_GRAY,
276
        .pixel_type = FF_PIXEL_PLANAR,
277
        .depth = 16,
278
    },
279
    [PIX_FMT_GRAY16LE] = {
280
        .name = "gray16le",
281
        .nb_channels = 1,
282
        .color_type = FF_COLOR_GRAY,
283
        .pixel_type = FF_PIXEL_PLANAR,
284
        .depth = 16,
285
    },
286
    [PIX_FMT_GRAY8] = {
287
        .name = "gray",
288
        .nb_channels = 1,
289
        .color_type = FF_COLOR_GRAY,
290
        .pixel_type = FF_PIXEL_PLANAR,
291
        .depth = 8,
292
    },
293
    [PIX_FMT_MONOWHITE] = {
294
        .name = "monow",
295
        .nb_channels = 1,
296
        .color_type = FF_COLOR_GRAY,
297
        .pixel_type = FF_PIXEL_PLANAR,
298
        .depth = 1,
299
    },
300
    [PIX_FMT_MONOBLACK] = {
301
        .name = "monob",
302
        .nb_channels = 1,
303
        .color_type = FF_COLOR_GRAY,
304
        .pixel_type = FF_PIXEL_PLANAR,
305
        .depth = 1,
306
    },
307

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

    
439
    [PIX_FMT_BGRA] = {
440
        .name = "bgra",
441
        .nb_channels = 4, .is_alpha = 1,
442
        .color_type = FF_COLOR_RGB,
443
        .pixel_type = FF_PIXEL_PACKED,
444
        .depth = 8,
445
    },
446
    [PIX_FMT_RGBA] = {
447
        .name = "rgba",
448
        .nb_channels = 4, .is_alpha = 1,
449
        .color_type = FF_COLOR_RGB,
450
        .pixel_type = FF_PIXEL_PACKED,
451
        .depth = 8,
452
    },
453

    
454
    /* VA API formats */
455
    [PIX_FMT_VAAPI_MOCO] = {
456
        .name = "vaapi_moco",
457
    },
458
    [PIX_FMT_VAAPI_IDCT] = {
459
        .name = "vaapi_idct",
460
    },
461
    [PIX_FMT_VAAPI_VLD] = {
462
        .name = "vaapi_vld",
463
    },
464
};
465

    
466
void avcodec_get_chroma_sub_sample(enum PixelFormat pix_fmt, int *h_shift, int *v_shift)
467
{
468
    *h_shift = av_pix_fmt_descriptors[pix_fmt].log2_chroma_w;
469
    *v_shift = av_pix_fmt_descriptors[pix_fmt].log2_chroma_h;
470
}
471

    
472
const char *avcodec_get_pix_fmt_name(enum PixelFormat pix_fmt)
473
{
474
    if (pix_fmt < 0 || pix_fmt >= PIX_FMT_NB)
475
        return NULL;
476
    else
477
        return av_pix_fmt_descriptors[pix_fmt].name;
478
}
479

    
480
static enum PixelFormat avcodec_get_pix_fmt_internal(const char *name)
481
{
482
    int i;
483

    
484
    for (i=0; i < PIX_FMT_NB; i++)
485
        if (pix_fmt_info[i].name && !strcmp(pix_fmt_info[i].name, name))
486
            return i;
487
    return PIX_FMT_NONE;
488
}
489

    
490
#if HAVE_BIGENDIAN
491
#   define X_NE(be, le) be
492
#else
493
#   define X_NE(be, le) le
494
#endif
495

    
496
enum PixelFormat avcodec_get_pix_fmt(const char *name)
497
{
498
    enum PixelFormat pix_fmt;
499

    
500
    if (!strcmp(name, "rgb32"))
501
        name = X_NE("argb", "bgra");
502
    else if (!strcmp(name, "bgr32"))
503
        name = X_NE("abgr", "rgba");
504

    
505
    pix_fmt = avcodec_get_pix_fmt_internal(name);
506
    if (pix_fmt == PIX_FMT_NONE) {
507
        char name2[32];
508
        snprintf(name2, sizeof(name2), "%s%s", name, X_NE("be", "le"));
509
        pix_fmt = avcodec_get_pix_fmt_internal(name2);
510
    }
511
    return pix_fmt;
512
}
513

    
514
void avcodec_pix_fmt_string (char *buf, int buf_size, enum PixelFormat pix_fmt)
515
{
516
    /* print header */
517
    if (pix_fmt < 0)
518
        snprintf (buf, buf_size,
519
                  "name      " " nb_channels" " depth" " is_alpha"
520
            );
521
    else{
522
        PixFmtInfo info= pix_fmt_info[pix_fmt];
523

    
524
        char is_alpha_char= info.is_alpha ? 'y' : 'n';
525

    
526
        snprintf (buf, buf_size,
527
                  "%-11s %5d %9d %6c",
528
                  info.name,
529
                  info.nb_channels,
530
                  info.depth,
531
                  is_alpha_char
532
            );
533
    }
534
}
535

    
536
int ff_is_hwaccel_pix_fmt(enum PixelFormat pix_fmt)
537
{
538
    return av_pix_fmt_descriptors[pix_fmt].flags & PIX_FMT_HWACCEL;
539
}
540

    
541
int ff_set_systematic_pal(uint32_t pal[256], enum PixelFormat pix_fmt){
542
    int i;
543

    
544
    for(i=0; i<256; i++){
545
        int r,g,b;
546

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

    
577
    return 0;
578
}
579

    
580
int ff_fill_linesize(AVPicture *picture, enum PixelFormat pix_fmt, int width)
581
{
582
    int w2;
583
    const AVPixFmtDescriptor *desc = &av_pix_fmt_descriptors[pix_fmt];
584

    
585
    memset(picture->linesize, 0, sizeof(picture->linesize));
586

    
587
    switch(pix_fmt) {
588
    case PIX_FMT_YUV420P:
589
    case PIX_FMT_YUV422P:
590
    case PIX_FMT_YUV444P:
591
    case PIX_FMT_YUV410P:
592
    case PIX_FMT_YUV411P:
593
    case PIX_FMT_YUV440P:
594
    case PIX_FMT_YUVJ420P:
595
    case PIX_FMT_YUVJ422P:
596
    case PIX_FMT_YUVJ444P:
597
    case PIX_FMT_YUVJ440P:
598
        w2 = (width + (1 << desc->log2_chroma_w) - 1) >> desc->log2_chroma_w;
599
        picture->linesize[0] = width;
600
        picture->linesize[1] = w2;
601
        picture->linesize[2] = w2;
602
        break;
603
    case PIX_FMT_YUV420P16LE:
604
    case PIX_FMT_YUV422P16LE:
605
    case PIX_FMT_YUV444P16LE:
606
    case PIX_FMT_YUV420P16BE:
607
    case PIX_FMT_YUV422P16BE:
608
    case PIX_FMT_YUV444P16BE:
609
        w2 = (width + (1 << desc->log2_chroma_w) - 1) >> desc->log2_chroma_w;
610
        picture->linesize[0] = 2*width;
611
        picture->linesize[1] = 2*w2;
612
        picture->linesize[2] = 2*w2;
613
        break;
614
    case PIX_FMT_YUVA420P:
615
        w2 = (width + (1 << desc->log2_chroma_w) - 1) >> desc->log2_chroma_w;
616
        picture->linesize[0] = width;
617
        picture->linesize[1] = w2;
618
        picture->linesize[2] = w2;
619
        picture->linesize[3] = width;
620
        break;
621
    case PIX_FMT_NV12:
622
    case PIX_FMT_NV21:
623
        w2 = (width + (1 << desc->log2_chroma_w) - 1) >> desc->log2_chroma_w;
624
        picture->linesize[0] = width;
625
        picture->linesize[1] = 2 * w2;
626
        break;
627
    case PIX_FMT_RGB24:
628
    case PIX_FMT_BGR24:
629
        picture->linesize[0] = width * 3;
630
        break;
631
    case PIX_FMT_ARGB:
632
    case PIX_FMT_ABGR:
633
    case PIX_FMT_RGBA:
634
    case PIX_FMT_BGRA:
635
        picture->linesize[0] = width * 4;
636
        break;
637
    case PIX_FMT_RGB48BE:
638
    case PIX_FMT_RGB48LE:
639
        picture->linesize[0] = width * 6;
640
        break;
641
    case PIX_FMT_GRAY16BE:
642
    case PIX_FMT_GRAY16LE:
643
    case PIX_FMT_BGR555BE:
644
    case PIX_FMT_BGR555LE:
645
    case PIX_FMT_BGR565BE:
646
    case PIX_FMT_BGR565LE:
647
    case PIX_FMT_RGB555BE:
648
    case PIX_FMT_RGB555LE:
649
    case PIX_FMT_RGB565BE:
650
    case PIX_FMT_RGB565LE:
651
    case PIX_FMT_YUYV422:
652
        picture->linesize[0] = width * 2;
653
        break;
654
    case PIX_FMT_UYVY422:
655
        picture->linesize[0] = width * 2;
656
        break;
657
    case PIX_FMT_UYYVYY411:
658
        picture->linesize[0] = width + width/2;
659
        break;
660
    case PIX_FMT_RGB4:
661
    case PIX_FMT_BGR4:
662
        picture->linesize[0] = width / 2;
663
        break;
664
    case PIX_FMT_MONOWHITE:
665
    case PIX_FMT_MONOBLACK:
666
        picture->linesize[0] = (width + 7) >> 3;
667
        break;
668
    case PIX_FMT_PAL8:
669
    case PIX_FMT_RGB8:
670
    case PIX_FMT_BGR8:
671
    case PIX_FMT_RGB4_BYTE:
672
    case PIX_FMT_BGR4_BYTE:
673
    case PIX_FMT_GRAY8:
674
        picture->linesize[0] = width;
675
        break;
676
    default:
677
        return -1;
678
    }
679
    return 0;
680
}
681

    
682
int ff_fill_pointer(AVPicture *picture, uint8_t *ptr, enum PixelFormat pix_fmt,
683
                    int height)
684
{
685
    int size, h2, size2;
686
    const AVPixFmtDescriptor *desc = &av_pix_fmt_descriptors[pix_fmt];
687

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

    
781
int avpicture_fill(AVPicture *picture, uint8_t *ptr,
782
                   enum PixelFormat pix_fmt, int width, int height)
783
{
784

    
785
    if(avcodec_check_dimensions(NULL, width, height))
786
        return -1;
787

    
788
    if (ff_fill_linesize(picture, pix_fmt, width))
789
        return -1;
790

    
791
    return ff_fill_pointer(picture, ptr, pix_fmt, height);
792
}
793

    
794
int avpicture_layout(const AVPicture* src, enum PixelFormat pix_fmt, int width, int height,
795
                     unsigned char *dest, int dest_size)
796
{
797
    const PixFmtInfo* pf = &pix_fmt_info[pix_fmt];
798
    const AVPixFmtDescriptor *desc = &av_pix_fmt_descriptors[pix_fmt];
799
    int i, j, w, ow, h, oh, data_planes;
800
    const unsigned char* s;
801
    int size = avpicture_get_size(pix_fmt, width, height);
802

    
803
    if (size > dest_size || size < 0)
804
        return -1;
805

    
806
    if (pf->pixel_type == FF_PIXEL_PACKED || pf->pixel_type == FF_PIXEL_PALETTE) {
807
        if (pix_fmt == PIX_FMT_YUYV422 ||
808
            pix_fmt == PIX_FMT_UYVY422 ||
809
            pix_fmt == PIX_FMT_BGR565BE ||
810
            pix_fmt == PIX_FMT_BGR565LE ||
811
            pix_fmt == PIX_FMT_BGR555BE ||
812
            pix_fmt == PIX_FMT_BGR555LE ||
813
            pix_fmt == PIX_FMT_RGB565BE ||
814
            pix_fmt == PIX_FMT_RGB565LE ||
815
            pix_fmt == PIX_FMT_RGB555BE ||
816
            pix_fmt == PIX_FMT_RGB555LE)
817
            w = width * 2;
818
        else if (pix_fmt == PIX_FMT_UYYVYY411)
819
            w = width + width/2;
820
        else if (pix_fmt == PIX_FMT_PAL8)
821
            w = width;
822
        else
823
            w = width * (pf->depth * pf->nb_channels / 8);
824

    
825
        data_planes = 1;
826
        h = height;
827
    } else {
828
        data_planes = pf->nb_channels;
829
        w = (width*pf->depth + 7)/8;
830
        h = height;
831
    }
832

    
833
    ow = w;
834
    oh = h;
835

    
836
    for (i=0; i<data_planes; i++) {
837
        if (i == 1) {
838
            w = ((width >> desc->log2_chroma_w) * pf->depth + 7) / 8;
839
            h = height >> desc->log2_chroma_h;
840
            if (pix_fmt == PIX_FMT_NV12 || pix_fmt == PIX_FMT_NV21)
841
                w <<= 1;
842
        } else if (i == 3) {
843
            w = ow;
844
            h = oh;
845
        }
846
        s = src->data[i];
847
        for(j=0; j<h; j++) {
848
            memcpy(dest, s, w);
849
            dest += w;
850
            s += src->linesize[i];
851
        }
852
    }
853

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

    
857
    return size;
858
}
859

    
860
int avpicture_get_size(enum PixelFormat pix_fmt, int width, int height)
861
{
862
    AVPicture dummy_pict;
863
    if(avcodec_check_dimensions(NULL, width, height))
864
        return -1;
865
    switch (pix_fmt) {
866
    case PIX_FMT_RGB8:
867
    case PIX_FMT_BGR8:
868
    case PIX_FMT_RGB4_BYTE:
869
    case PIX_FMT_BGR4_BYTE:
870
    case PIX_FMT_GRAY8:
871
        // do not include palette for these pseudo-paletted formats
872
        return width * height;
873
    }
874
    return avpicture_fill(&dummy_pict, NULL, pix_fmt, width, height);
875
}
876

    
877
int avcodec_get_pix_fmt_loss(enum PixelFormat dst_pix_fmt, enum PixelFormat src_pix_fmt,
878
                             int has_alpha)
879
{
880
    const PixFmtInfo *pf, *ps;
881
    const AVPixFmtDescriptor *src_desc = &av_pix_fmt_descriptors[src_pix_fmt];
882
    const AVPixFmtDescriptor *dst_desc = &av_pix_fmt_descriptors[dst_pix_fmt];
883
    int loss;
884

    
885
    ps = &pix_fmt_info[src_pix_fmt];
886

    
887
    /* compute loss */
888
    loss = 0;
889
    pf = &pix_fmt_info[dst_pix_fmt];
890
    if (pf->depth < ps->depth ||
891
        ((dst_pix_fmt == PIX_FMT_RGB555BE || dst_pix_fmt == PIX_FMT_RGB555LE) &&
892
         (src_pix_fmt == PIX_FMT_RGB565BE || src_pix_fmt == PIX_FMT_RGB565LE)))
893
        loss |= FF_LOSS_DEPTH;
894
    if (dst_desc->log2_chroma_w > src_desc->log2_chroma_w ||
895
        dst_desc->log2_chroma_h > src_desc->log2_chroma_h)
896
        loss |= FF_LOSS_RESOLUTION;
897
    switch(pf->color_type) {
898
    case FF_COLOR_RGB:
899
        if (ps->color_type != FF_COLOR_RGB &&
900
            ps->color_type != FF_COLOR_GRAY)
901
            loss |= FF_LOSS_COLORSPACE;
902
        break;
903
    case FF_COLOR_GRAY:
904
        if (ps->color_type != FF_COLOR_GRAY)
905
            loss |= FF_LOSS_COLORSPACE;
906
        break;
907
    case FF_COLOR_YUV:
908
        if (ps->color_type != FF_COLOR_YUV)
909
            loss |= FF_LOSS_COLORSPACE;
910
        break;
911
    case FF_COLOR_YUV_JPEG:
912
        if (ps->color_type != FF_COLOR_YUV_JPEG &&
913
            ps->color_type != FF_COLOR_YUV &&
914
            ps->color_type != FF_COLOR_GRAY)
915
            loss |= FF_LOSS_COLORSPACE;
916
        break;
917
    default:
918
        /* fail safe test */
919
        if (ps->color_type != pf->color_type)
920
            loss |= FF_LOSS_COLORSPACE;
921
        break;
922
    }
923
    if (pf->color_type == FF_COLOR_GRAY &&
924
        ps->color_type != FF_COLOR_GRAY)
925
        loss |= FF_LOSS_CHROMA;
926
    if (!pf->is_alpha && (ps->is_alpha && has_alpha))
927
        loss |= FF_LOSS_ALPHA;
928
    if (pf->pixel_type == FF_PIXEL_PALETTE &&
929
        (ps->pixel_type != FF_PIXEL_PALETTE && ps->color_type != FF_COLOR_GRAY))
930
        loss |= FF_LOSS_COLORQUANT;
931
    return loss;
932
}
933

    
934
static int avg_bits_per_pixel(enum PixelFormat pix_fmt)
935
{
936
    int bits;
937
    const PixFmtInfo *pf;
938
    const AVPixFmtDescriptor *desc = &av_pix_fmt_descriptors[pix_fmt];
939

    
940
    pf = &pix_fmt_info[pix_fmt];
941
    switch(pf->pixel_type) {
942
    case FF_PIXEL_PACKED:
943
        switch(pix_fmt) {
944
        case PIX_FMT_YUYV422:
945
        case PIX_FMT_UYVY422:
946
        case PIX_FMT_RGB565BE:
947
        case PIX_FMT_RGB565LE:
948
        case PIX_FMT_RGB555BE:
949
        case PIX_FMT_RGB555LE:
950
        case PIX_FMT_BGR565BE:
951
        case PIX_FMT_BGR565LE:
952
        case PIX_FMT_BGR555BE:
953
        case PIX_FMT_BGR555LE:
954
            bits = 16;
955
            break;
956
        case PIX_FMT_UYYVYY411:
957
            bits = 12;
958
            break;
959
        default:
960
            bits = pf->depth * pf->nb_channels;
961
            break;
962
        }
963
        break;
964
    case FF_PIXEL_PLANAR:
965
        if (desc->log2_chroma_w == 0 && desc->log2_chroma_h == 0) {
966
            bits = pf->depth * pf->nb_channels;
967
        } else {
968
            bits = pf->depth + ((2 * pf->depth) >>
969
                                (desc->log2_chroma_w + desc->log2_chroma_h));
970
        }
971
        break;
972
    case FF_PIXEL_PALETTE:
973
        bits = 8;
974
        break;
975
    default:
976
        bits = -1;
977
        break;
978
    }
979
    return bits;
980
}
981

    
982
static enum PixelFormat avcodec_find_best_pix_fmt1(int64_t pix_fmt_mask,
983
                                      enum PixelFormat src_pix_fmt,
984
                                      int has_alpha,
985
                                      int loss_mask)
986
{
987
    int dist, i, loss, min_dist;
988
    enum PixelFormat dst_pix_fmt;
989

    
990
    /* find exact color match with smallest size */
991
    dst_pix_fmt = -1;
992
    min_dist = 0x7fffffff;
993
    for(i = 0;i < PIX_FMT_NB; i++) {
994
        if (pix_fmt_mask & (1ULL << i)) {
995
            loss = avcodec_get_pix_fmt_loss(i, src_pix_fmt, has_alpha) & loss_mask;
996
            if (loss == 0) {
997
                dist = avg_bits_per_pixel(i);
998
                if (dist < min_dist) {
999
                    min_dist = dist;
1000
                    dst_pix_fmt = i;
1001
                }
1002
            }
1003
        }
1004
    }
1005
    return dst_pix_fmt;
1006
}
1007

    
1008
enum PixelFormat avcodec_find_best_pix_fmt(int64_t pix_fmt_mask, enum PixelFormat src_pix_fmt,
1009
                              int has_alpha, int *loss_ptr)
1010
{
1011
    enum PixelFormat dst_pix_fmt;
1012
    int loss_mask, i;
1013
    static const int loss_mask_order[] = {
1014
        ~0, /* no loss first */
1015
        ~FF_LOSS_ALPHA,
1016
        ~FF_LOSS_RESOLUTION,
1017
        ~(FF_LOSS_COLORSPACE | FF_LOSS_RESOLUTION),
1018
        ~FF_LOSS_COLORQUANT,
1019
        ~FF_LOSS_DEPTH,
1020
        0,
1021
    };
1022

    
1023
    /* try with successive loss */
1024
    i = 0;
1025
    for(;;) {
1026
        loss_mask = loss_mask_order[i++];
1027
        dst_pix_fmt = avcodec_find_best_pix_fmt1(pix_fmt_mask, src_pix_fmt,
1028
                                                 has_alpha, loss_mask);
1029
        if (dst_pix_fmt >= 0)
1030
            goto found;
1031
        if (loss_mask == 0)
1032
            break;
1033
    }
1034
    return -1;
1035
 found:
1036
    if (loss_ptr)
1037
        *loss_ptr = avcodec_get_pix_fmt_loss(dst_pix_fmt, src_pix_fmt, has_alpha);
1038
    return dst_pix_fmt;
1039
}
1040

    
1041
void ff_img_copy_plane(uint8_t *dst, int dst_wrap,
1042
                           const uint8_t *src, int src_wrap,
1043
                           int width, int height)
1044
{
1045
    if((!dst) || (!src))
1046
        return;
1047
    for(;height > 0; height--) {
1048
        memcpy(dst, src, width);
1049
        dst += dst_wrap;
1050
        src += src_wrap;
1051
    }
1052
}
1053

    
1054
int ff_get_plane_bytewidth(enum PixelFormat pix_fmt, int width, int plane)
1055
{
1056
    int bits;
1057
    const PixFmtInfo *pf = &pix_fmt_info[pix_fmt];
1058
    const AVPixFmtDescriptor *desc = &av_pix_fmt_descriptors[pix_fmt];
1059

    
1060
    pf = &pix_fmt_info[pix_fmt];
1061
    switch(pf->pixel_type) {
1062
    case FF_PIXEL_PACKED:
1063
        switch(pix_fmt) {
1064
        case PIX_FMT_YUYV422:
1065
        case PIX_FMT_UYVY422:
1066
        case PIX_FMT_RGB565BE:
1067
        case PIX_FMT_RGB565LE:
1068
        case PIX_FMT_RGB555BE:
1069
        case PIX_FMT_RGB555LE:
1070
        case PIX_FMT_BGR565BE:
1071
        case PIX_FMT_BGR565LE:
1072
        case PIX_FMT_BGR555BE:
1073
        case PIX_FMT_BGR555LE:
1074
            bits = 16;
1075
            break;
1076
        case PIX_FMT_UYYVYY411:
1077
            bits = 12;
1078
            break;
1079
        default:
1080
            bits = pf->depth * pf->nb_channels;
1081
            break;
1082
        }
1083
        return (width * bits + 7) >> 3;
1084
        break;
1085
    case FF_PIXEL_PLANAR:
1086
            if (plane == 1 || plane == 2)
1087
                width= -((-width)>>desc->log2_chroma_w);
1088

    
1089
            return (width * pf->depth + 7) >> 3;
1090
        break;
1091
    case FF_PIXEL_PALETTE:
1092
        if (plane == 0)
1093
            return width;
1094
        break;
1095
    }
1096

    
1097
    return -1;
1098
}
1099

    
1100
void av_picture_copy(AVPicture *dst, const AVPicture *src,
1101
                     enum PixelFormat pix_fmt, int width, int height)
1102
{
1103
    int i;
1104
    const PixFmtInfo *pf = &pix_fmt_info[pix_fmt];
1105
    const AVPixFmtDescriptor *desc = &av_pix_fmt_descriptors[pix_fmt];
1106

    
1107
    switch(pf->pixel_type) {
1108
    case FF_PIXEL_PACKED:
1109
    case FF_PIXEL_PLANAR:
1110
        for(i = 0; i < pf->nb_channels; i++) {
1111
            int h;
1112
            int bwidth = ff_get_plane_bytewidth(pix_fmt, width, i);
1113
            h = height;
1114
            if (i == 1 || i == 2) {
1115
                h= -((-height)>>desc->log2_chroma_h);
1116
            }
1117
            ff_img_copy_plane(dst->data[i], dst->linesize[i],
1118
                           src->data[i], src->linesize[i],
1119
                           bwidth, h);
1120
        }
1121
        break;
1122
    case FF_PIXEL_PALETTE:
1123
        ff_img_copy_plane(dst->data[0], dst->linesize[0],
1124
                       src->data[0], src->linesize[0],
1125
                       width, height);
1126
        /* copy the palette */
1127
        memcpy(dst->data[1], src->data[1], 4*256);
1128
        break;
1129
    }
1130
}
1131

    
1132
/* 2x2 -> 1x1 */
1133
void ff_shrink22(uint8_t *dst, int dst_wrap,
1134
                     const uint8_t *src, int src_wrap,
1135
                     int width, int height)
1136
{
1137
    int w;
1138
    const uint8_t *s1, *s2;
1139
    uint8_t *d;
1140

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

    
1165
/* 4x4 -> 1x1 */
1166
void ff_shrink44(uint8_t *dst, int dst_wrap,
1167
                     const uint8_t *src, int src_wrap,
1168
                     int width, int height)
1169
{
1170
    int w;
1171
    const uint8_t *s1, *s2, *s3, *s4;
1172
    uint8_t *d;
1173

    
1174
    for(;height > 0; height--) {
1175
        s1 = src;
1176
        s2 = s1 + src_wrap;
1177
        s3 = s2 + src_wrap;
1178
        s4 = s3 + src_wrap;
1179
        d = dst;
1180
        for(w = width;w > 0; w--) {
1181
            d[0] = (s1[0] + s1[1] + s1[2] + s1[3] +
1182
                    s2[0] + s2[1] + s2[2] + s2[3] +
1183
                    s3[0] + s3[1] + s3[2] + s3[3] +
1184
                    s4[0] + s4[1] + s4[2] + s4[3] + 8) >> 4;
1185
            s1 += 4;
1186
            s2 += 4;
1187
            s3 += 4;
1188
            s4 += 4;
1189
            d++;
1190
        }
1191
        src += 4 * src_wrap;
1192
        dst += dst_wrap;
1193
    }
1194
}
1195

    
1196
/* 8x8 -> 1x1 */
1197
void ff_shrink88(uint8_t *dst, int dst_wrap,
1198
                     const uint8_t *src, int src_wrap,
1199
                     int width, int height)
1200
{
1201
    int w, i;
1202

    
1203
    for(;height > 0; height--) {
1204
        for(w = width;w > 0; w--) {
1205
            int tmp=0;
1206
            for(i=0; i<8; i++){
1207
                tmp += src[0] + src[1] + src[2] + src[3] + src[4] + src[5] + src[6] + src[7];
1208
                src += src_wrap;
1209
            }
1210
            *(dst++) = (tmp + 32)>>6;
1211
            src += 8 - 8*src_wrap;
1212
        }
1213
        src += 8*src_wrap - 8*width;
1214
        dst += dst_wrap - width;
1215
    }
1216
}
1217

    
1218

    
1219
int avpicture_alloc(AVPicture *picture,
1220
                    enum PixelFormat pix_fmt, int width, int height)
1221
{
1222
    int size;
1223
    void *ptr;
1224

    
1225
    size = avpicture_fill(picture, NULL, pix_fmt, width, height);
1226
    if(size<0)
1227
        goto fail;
1228
    ptr = av_malloc(size);
1229
    if (!ptr)
1230
        goto fail;
1231
    avpicture_fill(picture, ptr, pix_fmt, width, height);
1232
    if(picture->data[1] && !picture->data[2])
1233
        ff_set_systematic_pal((uint32_t*)picture->data[1], pix_fmt);
1234

    
1235
    return 0;
1236
 fail:
1237
    memset(picture, 0, sizeof(AVPicture));
1238
    return -1;
1239
}
1240

    
1241
void avpicture_free(AVPicture *picture)
1242
{
1243
    av_free(picture->data[0]);
1244
}
1245

    
1246
/* return true if yuv planar */
1247
static inline int is_yuv_planar(const PixFmtInfo *ps)
1248
{
1249
    return (ps->color_type == FF_COLOR_YUV ||
1250
            ps->color_type == FF_COLOR_YUV_JPEG) &&
1251
        ps->pixel_type == FF_PIXEL_PLANAR;
1252
}
1253

    
1254
int av_picture_crop(AVPicture *dst, const AVPicture *src,
1255
                    enum PixelFormat pix_fmt, int top_band, int left_band)
1256
{
1257
    int y_shift;
1258
    int x_shift;
1259

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

    
1263
    y_shift = av_pix_fmt_descriptors[pix_fmt].log2_chroma_h;
1264
    x_shift = av_pix_fmt_descriptors[pix_fmt].log2_chroma_w;
1265

    
1266
    dst->data[0] = src->data[0] + (top_band * src->linesize[0]) + left_band;
1267
    dst->data[1] = src->data[1] + ((top_band >> y_shift) * src->linesize[1]) + (left_band >> x_shift);
1268
    dst->data[2] = src->data[2] + ((top_band >> y_shift) * src->linesize[2]) + (left_band >> x_shift);
1269

    
1270
    dst->linesize[0] = src->linesize[0];
1271
    dst->linesize[1] = src->linesize[1];
1272
    dst->linesize[2] = src->linesize[2];
1273
    return 0;
1274
}
1275

    
1276
int av_picture_pad(AVPicture *dst, const AVPicture *src, int height, int width,
1277
                   enum PixelFormat pix_fmt, int padtop, int padbottom, int padleft, int padright,
1278
            int *color)
1279
{
1280
    uint8_t *optr;
1281
    int y_shift;
1282
    int x_shift;
1283
    int yheight;
1284
    int i, y;
1285

    
1286
    if (pix_fmt < 0 || pix_fmt >= PIX_FMT_NB ||
1287
        !is_yuv_planar(&pix_fmt_info[pix_fmt])) return -1;
1288

    
1289
    for (i = 0; i < 3; i++) {
1290
        x_shift = i ? av_pix_fmt_descriptors[pix_fmt].log2_chroma_w : 0;
1291
        y_shift = i ? av_pix_fmt_descriptors[pix_fmt].log2_chroma_h : 0;
1292

    
1293
        if (padtop || padleft) {
1294
            memset(dst->data[i], color[i],
1295
                dst->linesize[i] * (padtop >> y_shift) + (padleft >> x_shift));
1296
        }
1297

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

    
1308
        if (src) { /* first line */
1309
            uint8_t *iptr = src->data[i];
1310
            optr = dst->data[i] + dst->linesize[i] * (padtop >> y_shift) +
1311
                    (padleft >> x_shift);
1312
            memcpy(optr, iptr, (width - padleft - padright) >> x_shift);
1313
            iptr += src->linesize[i];
1314
            optr = dst->data[i] + dst->linesize[i] * (padtop >> y_shift) +
1315
                (dst->linesize[i] - (padright >> x_shift));
1316
            yheight = (height - 1 - (padtop + padbottom)) >> y_shift;
1317
            for (y = 0; y < yheight; y++) {
1318
                memset(optr, color[i], (padleft + padright) >> x_shift);
1319
                memcpy(optr + ((padleft + padright) >> x_shift), iptr,
1320
                       (width - padleft - padright) >> x_shift);
1321
                iptr += src->linesize[i];
1322
                optr += dst->linesize[i];
1323
            }
1324
        }
1325

    
1326
        if (padbottom || padright) {
1327
            optr = dst->data[i] + dst->linesize[i] *
1328
                ((height - padbottom) >> y_shift) - (padright >> x_shift);
1329
            memset(optr, color[i],dst->linesize[i] *
1330
                (padbottom >> y_shift) + (padright >> x_shift));
1331
        }
1332
    }
1333
    return 0;
1334
}
1335

    
1336
/* NOTE: we scan all the pixels to have an exact information */
1337
static int get_alpha_info_pal8(const AVPicture *src, int width, int height)
1338
{
1339
    const unsigned char *p;
1340
    int src_wrap, ret, x, y;
1341
    unsigned int a;
1342
    uint32_t *palette = (uint32_t *)src->data[1];
1343

    
1344
    p = src->data[0];
1345
    src_wrap = src->linesize[0] - width;
1346
    ret = 0;
1347
    for(y=0;y<height;y++) {
1348
        for(x=0;x<width;x++) {
1349
            a = palette[p[0]] >> 24;
1350
            if (a == 0x00) {
1351
                ret |= FF_ALPHA_TRANSP;
1352
            } else if (a != 0xff) {
1353
                ret |= FF_ALPHA_SEMI_TRANSP;
1354
            }
1355
            p++;
1356
        }
1357
        p += src_wrap;
1358
    }
1359
    return ret;
1360
}
1361

    
1362
int img_get_alpha_info(const AVPicture *src,
1363
                       enum PixelFormat pix_fmt, int width, int height)
1364
{
1365
    const PixFmtInfo *pf = &pix_fmt_info[pix_fmt];
1366
    int ret;
1367

    
1368
    /* no alpha can be represented in format */
1369
    if (!pf->is_alpha)
1370
        return 0;
1371
    switch(pix_fmt) {
1372
    case PIX_FMT_PAL8:
1373
        ret = get_alpha_info_pal8(src, width, height);
1374
        break;
1375
    default:
1376
        /* we do not know, so everything is indicated */
1377
        ret = FF_ALPHA_TRANSP | FF_ALPHA_SEMI_TRANSP;
1378
        break;
1379
    }
1380
    return ret;
1381
}
1382

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

    
1407
#define DEINT_LINE_LUM \
1408
                    movd_m2r(lum_m4[0],mm0);\
1409
                    movd_m2r(lum_m3[0],mm1);\
1410
                    movd_m2r(lum_m2[0],mm2);\
1411
                    movd_m2r(lum_m1[0],mm3);\
1412
                    movd_m2r(lum[0],mm4);\
1413
                    punpcklbw_r2r(mm7,mm0);\
1414
                    punpcklbw_r2r(mm7,mm1);\
1415
                    punpcklbw_r2r(mm7,mm2);\
1416
                    punpcklbw_r2r(mm7,mm3);\
1417
                    punpcklbw_r2r(mm7,mm4);\
1418
                    paddw_r2r(mm3,mm1);\
1419
                    psllw_i2r(1,mm2);\
1420
                    paddw_r2r(mm4,mm0);\
1421
                    psllw_i2r(2,mm1);\
1422
                    paddw_r2r(mm6,mm2);\
1423
                    paddw_r2r(mm2,mm1);\
1424
                    psubusw_r2r(mm0,mm1);\
1425
                    psrlw_i2r(3,mm1);\
1426
                    packuswb_r2r(mm7,mm1);\
1427
                    movd_r2m(mm1,dst[0]);
1428
#endif
1429

    
1430
/* filter parameters: [-1 4 2 4 -1] // 8 */
1431
static void deinterlace_line(uint8_t *dst,
1432
                             const uint8_t *lum_m4, const uint8_t *lum_m3,
1433
                             const uint8_t *lum_m2, const uint8_t *lum_m1,
1434
                             const uint8_t *lum,
1435
                             int size)
1436
{
1437
#if !HAVE_MMX
1438
    uint8_t *cm = ff_cropTbl + MAX_NEG_CROP;
1439
    int sum;
1440

    
1441
    for(;size > 0;size--) {
1442
        sum = -lum_m4[0];
1443
        sum += lum_m3[0] << 2;
1444
        sum += lum_m2[0] << 1;
1445
        sum += lum_m1[0] << 2;
1446
        sum += -lum[0];
1447
        dst[0] = cm[(sum + 4) >> 3];
1448
        lum_m4++;
1449
        lum_m3++;
1450
        lum_m2++;
1451
        lum_m1++;
1452
        lum++;
1453
        dst++;
1454
    }
1455
#else
1456

    
1457
    {
1458
        pxor_r2r(mm7,mm7);
1459
        movq_m2r(ff_pw_4,mm6);
1460
    }
1461
    for (;size > 3; size-=4) {
1462
        DEINT_LINE_LUM
1463
        lum_m4+=4;
1464
        lum_m3+=4;
1465
        lum_m2+=4;
1466
        lum_m1+=4;
1467
        lum+=4;
1468
        dst+=4;
1469
    }
1470
#endif
1471
}
1472
static void deinterlace_line_inplace(uint8_t *lum_m4, uint8_t *lum_m3, uint8_t *lum_m2, uint8_t *lum_m1, uint8_t *lum,
1473
                             int size)
1474
{
1475
#if !HAVE_MMX
1476
    uint8_t *cm = ff_cropTbl + MAX_NEG_CROP;
1477
    int sum;
1478

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

    
1495
    {
1496
        pxor_r2r(mm7,mm7);
1497
        movq_m2r(ff_pw_4,mm6);
1498
    }
1499
    for (;size > 3; size-=4) {
1500
        DEINT_INPLACE_LINE_LUM
1501
        lum_m4+=4;
1502
        lum_m3+=4;
1503
        lum_m2+=4;
1504
        lum_m1+=4;
1505
        lum+=4;
1506
    }
1507
#endif
1508
}
1509

    
1510
/* deinterlacing : 2 temporal taps, 3 spatial taps linear filter. The
1511
   top field is copied as is, but the bottom field is deinterlaced
1512
   against the top field. */
1513
static void deinterlace_bottom_field(uint8_t *dst, int dst_wrap,
1514
                                    const uint8_t *src1, int src_wrap,
1515
                                    int width, int height)
1516
{
1517
    const uint8_t *src_m2, *src_m1, *src_0, *src_p1, *src_p2;
1518
    int y;
1519

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

    
1542
static void deinterlace_bottom_field_inplace(uint8_t *src1, int src_wrap,
1543
                                             int width, int height)
1544
{
1545
    uint8_t *src_m1, *src_0, *src_p1, *src_p2;
1546
    int y;
1547
    uint8_t *buf;
1548
    buf = (uint8_t*)av_malloc(width);
1549

    
1550
    src_m1 = src1;
1551
    memcpy(buf,src_m1,width);
1552
    src_0=&src_m1[src_wrap];
1553
    src_p1=&src_0[src_wrap];
1554
    src_p2=&src_p1[src_wrap];
1555
    for(y=0;y<(height-2);y+=2) {
1556
        deinterlace_line_inplace(buf,src_m1,src_0,src_p1,src_p2,width);
1557
        src_m1 = src_p1;
1558
        src_0 = src_p2;
1559
        src_p1 += 2*src_wrap;
1560
        src_p2 += 2*src_wrap;
1561
    }
1562
    /* do last line */
1563
    deinterlace_line_inplace(buf,src_m1,src_0,src_0,src_0,width);
1564
    av_free(buf);
1565
}
1566

    
1567
int avpicture_deinterlace(AVPicture *dst, const AVPicture *src,
1568
                          enum PixelFormat pix_fmt, int width, int height)
1569
{
1570
    int i;
1571

    
1572
    if (pix_fmt != PIX_FMT_YUV420P &&
1573
        pix_fmt != PIX_FMT_YUV422P &&
1574
        pix_fmt != PIX_FMT_YUV444P &&
1575
        pix_fmt != PIX_FMT_YUV411P &&
1576
        pix_fmt != PIX_FMT_GRAY8)
1577
        return -1;
1578
    if ((width & 3) != 0 || (height & 3) != 0)
1579
        return -1;
1580

    
1581
    for(i=0;i<3;i++) {
1582
        if (i == 1) {
1583
            switch(pix_fmt) {
1584
            case PIX_FMT_YUV420P:
1585
                width >>= 1;
1586
                height >>= 1;
1587
                break;
1588
            case PIX_FMT_YUV422P:
1589
                width >>= 1;
1590
                break;
1591
            case PIX_FMT_YUV411P:
1592
                width >>= 2;
1593
                break;
1594
            default:
1595
                break;
1596
            }
1597
            if (pix_fmt == PIX_FMT_GRAY8) {
1598
                break;
1599
            }
1600
        }
1601
        if (src == dst) {
1602
            deinterlace_bottom_field_inplace(dst->data[i], dst->linesize[i],
1603
                                 width, height);
1604
        } else {
1605
            deinterlace_bottom_field(dst->data[i],dst->linesize[i],
1606
                                        src->data[i], src->linesize[i],
1607
                                        width, height);
1608
        }
1609
    }
1610
    emms_c();
1611
    return 0;
1612
}
1613