Statistics
| Branch: | Revision:

ffmpeg / libavcodec / imgconvert.c @ 80a07f6e

History | View | Annotate | Download (42.6 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
    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 depth;           /**< bit depth of the color components */
61
} PixFmtInfo;
62

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

    
151

    
152
    /* YUV formats with alpha plane */
153
    [PIX_FMT_YUVA420P] = {
154
        .nb_channels = 4,
155
        .color_type = FF_COLOR_YUV,
156
        .pixel_type = FF_PIXEL_PLANAR,
157
        .depth = 8,
158
    },
159

    
160
    /* JPEG YUV */
161
    [PIX_FMT_YUVJ420P] = {
162
        .nb_channels = 3,
163
        .color_type = FF_COLOR_YUV_JPEG,
164
        .pixel_type = FF_PIXEL_PLANAR,
165
        .depth = 8,
166
    },
167
    [PIX_FMT_YUVJ422P] = {
168
        .nb_channels = 3,
169
        .color_type = FF_COLOR_YUV_JPEG,
170
        .pixel_type = FF_PIXEL_PLANAR,
171
        .depth = 8,
172
    },
173
    [PIX_FMT_YUVJ444P] = {
174
        .nb_channels = 3,
175
        .color_type = FF_COLOR_YUV_JPEG,
176
        .pixel_type = FF_PIXEL_PLANAR,
177
        .depth = 8,
178
    },
179
    [PIX_FMT_YUVJ440P] = {
180
        .nb_channels = 3,
181
        .color_type = FF_COLOR_YUV_JPEG,
182
        .pixel_type = FF_PIXEL_PLANAR,
183
        .depth = 8,
184
    },
185

    
186
    /* RGB formats */
187
    [PIX_FMT_RGB24] = {
188
        .nb_channels = 3,
189
        .color_type = FF_COLOR_RGB,
190
        .pixel_type = FF_PIXEL_PACKED,
191
        .depth = 8,
192
    },
193
    [PIX_FMT_BGR24] = {
194
        .nb_channels = 3,
195
        .color_type = FF_COLOR_RGB,
196
        .pixel_type = FF_PIXEL_PACKED,
197
        .depth = 8,
198
    },
199
    [PIX_FMT_ARGB] = {
200
        .nb_channels = 4, .is_alpha = 1,
201
        .color_type = FF_COLOR_RGB,
202
        .pixel_type = FF_PIXEL_PACKED,
203
        .depth = 8,
204
    },
205
    [PIX_FMT_RGB48BE] = {
206
        .nb_channels = 3,
207
        .color_type = FF_COLOR_RGB,
208
        .pixel_type = FF_PIXEL_PACKED,
209
        .depth = 16,
210
    },
211
    [PIX_FMT_RGB48LE] = {
212
        .nb_channels = 3,
213
        .color_type = FF_COLOR_RGB,
214
        .pixel_type = FF_PIXEL_PACKED,
215
        .depth = 16,
216
    },
217
    [PIX_FMT_RGB565BE] = {
218
        .nb_channels = 3,
219
        .color_type = FF_COLOR_RGB,
220
        .pixel_type = FF_PIXEL_PACKED,
221
        .depth = 5,
222
    },
223
    [PIX_FMT_RGB565LE] = {
224
        .nb_channels = 3,
225
        .color_type = FF_COLOR_RGB,
226
        .pixel_type = FF_PIXEL_PACKED,
227
        .depth = 5,
228
    },
229
    [PIX_FMT_RGB555BE] = {
230
        .nb_channels = 3,
231
        .color_type = FF_COLOR_RGB,
232
        .pixel_type = FF_PIXEL_PACKED,
233
        .depth = 5,
234
    },
235
    [PIX_FMT_RGB555LE] = {
236
        .nb_channels = 3,
237
        .color_type = FF_COLOR_RGB,
238
        .pixel_type = FF_PIXEL_PACKED,
239
        .depth = 5,
240
    },
241

    
242
    /* gray / mono formats */
243
    [PIX_FMT_GRAY16BE] = {
244
        .nb_channels = 1,
245
        .color_type = FF_COLOR_GRAY,
246
        .pixel_type = FF_PIXEL_PLANAR,
247
        .depth = 16,
248
    },
249
    [PIX_FMT_GRAY16LE] = {
250
        .nb_channels = 1,
251
        .color_type = FF_COLOR_GRAY,
252
        .pixel_type = FF_PIXEL_PLANAR,
253
        .depth = 16,
254
    },
255
    [PIX_FMT_GRAY8] = {
256
        .nb_channels = 1,
257
        .color_type = FF_COLOR_GRAY,
258
        .pixel_type = FF_PIXEL_PLANAR,
259
        .depth = 8,
260
    },
261
    [PIX_FMT_MONOWHITE] = {
262
        .nb_channels = 1,
263
        .color_type = FF_COLOR_GRAY,
264
        .pixel_type = FF_PIXEL_PLANAR,
265
        .depth = 1,
266
    },
267
    [PIX_FMT_MONOBLACK] = {
268
        .nb_channels = 1,
269
        .color_type = FF_COLOR_GRAY,
270
        .pixel_type = FF_PIXEL_PLANAR,
271
        .depth = 1,
272
    },
273

    
274
    /* paletted formats */
275
    [PIX_FMT_PAL8] = {
276
        .nb_channels = 4, .is_alpha = 1,
277
        .color_type = FF_COLOR_RGB,
278
        .pixel_type = FF_PIXEL_PALETTE,
279
        .depth = 8,
280
    },
281
    [PIX_FMT_UYYVYY411] = {
282
        .nb_channels = 1,
283
        .color_type = FF_COLOR_YUV,
284
        .pixel_type = FF_PIXEL_PACKED,
285
        .depth = 8,
286
    },
287
    [PIX_FMT_ABGR] = {
288
        .nb_channels = 4, .is_alpha = 1,
289
        .color_type = FF_COLOR_RGB,
290
        .pixel_type = FF_PIXEL_PACKED,
291
        .depth = 8,
292
    },
293
    [PIX_FMT_BGR565BE] = {
294
        .nb_channels = 3,
295
        .color_type = FF_COLOR_RGB,
296
        .pixel_type = FF_PIXEL_PACKED,
297
        .depth = 5,
298
    },
299
    [PIX_FMT_BGR565LE] = {
300
        .nb_channels = 3,
301
        .color_type = FF_COLOR_RGB,
302
        .pixel_type = FF_PIXEL_PACKED,
303
        .depth = 5,
304
    },
305
    [PIX_FMT_BGR555BE] = {
306
        .nb_channels = 3,
307
        .color_type = FF_COLOR_RGB,
308
        .pixel_type = FF_PIXEL_PACKED,
309
        .depth = 5,
310
    },
311
    [PIX_FMT_BGR555LE] = {
312
        .nb_channels = 3,
313
        .color_type = FF_COLOR_RGB,
314
        .pixel_type = FF_PIXEL_PACKED,
315
        .depth = 5,
316
    },
317
    [PIX_FMT_RGB8] = {
318
        .nb_channels = 1,
319
        .color_type = FF_COLOR_RGB,
320
        .pixel_type = FF_PIXEL_PACKED,
321
        .depth = 8,
322
    },
323
    [PIX_FMT_RGB4] = {
324
        .nb_channels = 1,
325
        .color_type = FF_COLOR_RGB,
326
        .pixel_type = FF_PIXEL_PACKED,
327
        .depth = 4,
328
    },
329
    [PIX_FMT_RGB4_BYTE] = {
330
        .nb_channels = 1,
331
        .color_type = FF_COLOR_RGB,
332
        .pixel_type = FF_PIXEL_PACKED,
333
        .depth = 8,
334
    },
335
    [PIX_FMT_BGR8] = {
336
        .nb_channels = 1,
337
        .color_type = FF_COLOR_RGB,
338
        .pixel_type = FF_PIXEL_PACKED,
339
        .depth = 8,
340
    },
341
    [PIX_FMT_BGR4] = {
342
        .nb_channels = 1,
343
        .color_type = FF_COLOR_RGB,
344
        .pixel_type = FF_PIXEL_PACKED,
345
        .depth = 4,
346
    },
347
    [PIX_FMT_BGR4_BYTE] = {
348
        .nb_channels = 1,
349
        .color_type = FF_COLOR_RGB,
350
        .pixel_type = FF_PIXEL_PACKED,
351
        .depth = 8,
352
    },
353
    [PIX_FMT_NV12] = {
354
        .nb_channels = 2,
355
        .color_type = FF_COLOR_YUV,
356
        .pixel_type = FF_PIXEL_PLANAR,
357
        .depth = 8,
358
    },
359
    [PIX_FMT_NV21] = {
360
        .nb_channels = 2,
361
        .color_type = FF_COLOR_YUV,
362
        .pixel_type = FF_PIXEL_PLANAR,
363
        .depth = 8,
364
    },
365

    
366
    [PIX_FMT_BGRA] = {
367
        .nb_channels = 4, .is_alpha = 1,
368
        .color_type = FF_COLOR_RGB,
369
        .pixel_type = FF_PIXEL_PACKED,
370
        .depth = 8,
371
    },
372
    [PIX_FMT_RGBA] = {
373
        .nb_channels = 4, .is_alpha = 1,
374
        .color_type = FF_COLOR_RGB,
375
        .pixel_type = FF_PIXEL_PACKED,
376
        .depth = 8,
377
    },
378
};
379

    
380
void avcodec_get_chroma_sub_sample(enum PixelFormat pix_fmt, int *h_shift, int *v_shift)
381
{
382
    *h_shift = av_pix_fmt_descriptors[pix_fmt].log2_chroma_w;
383
    *v_shift = av_pix_fmt_descriptors[pix_fmt].log2_chroma_h;
384
}
385

    
386
const char *avcodec_get_pix_fmt_name(enum PixelFormat pix_fmt)
387
{
388
    if (pix_fmt < 0 || pix_fmt >= PIX_FMT_NB)
389
        return NULL;
390
    else
391
        return av_pix_fmt_descriptors[pix_fmt].name;
392
}
393

    
394
#if LIBAVCODEC_VERSION_MAJOR < 53
395
enum PixelFormat avcodec_get_pix_fmt(const char *name)
396
{
397
    return av_get_pix_fmt(name);
398
}
399
#endif
400

    
401
void avcodec_pix_fmt_string (char *buf, int buf_size, enum PixelFormat pix_fmt)
402
{
403
    /* print header */
404
    if (pix_fmt < 0)
405
        snprintf (buf, buf_size,
406
                  "name      " " nb_channels" " depth" " is_alpha"
407
            );
408
    else{
409
        PixFmtInfo info= pix_fmt_info[pix_fmt];
410

    
411
        char is_alpha_char= info.is_alpha ? 'y' : 'n';
412

    
413
        snprintf (buf, buf_size,
414
                  "%-11s %5d %9d %6c",
415
                  av_pix_fmt_descriptors[pix_fmt].name,
416
                  info.nb_channels,
417
                  info.depth,
418
                  is_alpha_char
419
            );
420
    }
421
}
422

    
423
int ff_is_hwaccel_pix_fmt(enum PixelFormat pix_fmt)
424
{
425
    return av_pix_fmt_descriptors[pix_fmt].flags & PIX_FMT_HWACCEL;
426
}
427

    
428
int ff_set_systematic_pal(uint32_t pal[256], enum PixelFormat pix_fmt){
429
    int i;
430

    
431
    for(i=0; i<256; i++){
432
        int r,g,b;
433

    
434
        switch(pix_fmt) {
435
        case PIX_FMT_RGB8:
436
            r= (i>>5    )*36;
437
            g= ((i>>2)&7)*36;
438
            b= (i&3     )*85;
439
            break;
440
        case PIX_FMT_BGR8:
441
            b= (i>>6    )*85;
442
            g= ((i>>3)&7)*36;
443
            r= (i&7     )*36;
444
            break;
445
        case PIX_FMT_RGB4_BYTE:
446
            r= (i>>3    )*255;
447
            g= ((i>>1)&3)*85;
448
            b= (i&1     )*255;
449
            break;
450
        case PIX_FMT_BGR4_BYTE:
451
            b= (i>>3    )*255;
452
            g= ((i>>1)&3)*85;
453
            r= (i&1     )*255;
454
            break;
455
        case PIX_FMT_GRAY8:
456
            r=b=g= i;
457
            break;
458
        default:
459
            return -1;
460
        }
461
        pal[i] =  b + (g<<8) + (r<<16);
462
    }
463

    
464
    return 0;
465
}
466

    
467
int ff_fill_linesize(AVPicture *picture, enum PixelFormat pix_fmt, int width)
468
{
469
    int w2;
470
    const AVPixFmtDescriptor *desc = &av_pix_fmt_descriptors[pix_fmt];
471

    
472
    memset(picture->linesize, 0, sizeof(picture->linesize));
473

    
474
    switch(pix_fmt) {
475
    case PIX_FMT_YUV420P:
476
    case PIX_FMT_YUV422P:
477
    case PIX_FMT_YUV444P:
478
    case PIX_FMT_YUV410P:
479
    case PIX_FMT_YUV411P:
480
    case PIX_FMT_YUV440P:
481
    case PIX_FMT_YUVJ420P:
482
    case PIX_FMT_YUVJ422P:
483
    case PIX_FMT_YUVJ444P:
484
    case PIX_FMT_YUVJ440P:
485
        w2 = (width + (1 << desc->log2_chroma_w) - 1) >> desc->log2_chroma_w;
486
        picture->linesize[0] = width;
487
        picture->linesize[1] = w2;
488
        picture->linesize[2] = w2;
489
        break;
490
    case PIX_FMT_YUV420P16LE:
491
    case PIX_FMT_YUV422P16LE:
492
    case PIX_FMT_YUV444P16LE:
493
    case PIX_FMT_YUV420P16BE:
494
    case PIX_FMT_YUV422P16BE:
495
    case PIX_FMT_YUV444P16BE:
496
        w2 = (width + (1 << desc->log2_chroma_w) - 1) >> desc->log2_chroma_w;
497
        picture->linesize[0] = 2*width;
498
        picture->linesize[1] = 2*w2;
499
        picture->linesize[2] = 2*w2;
500
        break;
501
    case PIX_FMT_YUVA420P:
502
        w2 = (width + (1 << desc->log2_chroma_w) - 1) >> desc->log2_chroma_w;
503
        picture->linesize[0] = width;
504
        picture->linesize[1] = w2;
505
        picture->linesize[2] = w2;
506
        picture->linesize[3] = width;
507
        break;
508
    case PIX_FMT_NV12:
509
    case PIX_FMT_NV21:
510
        w2 = (width + (1 << desc->log2_chroma_w) - 1) >> desc->log2_chroma_w;
511
        picture->linesize[0] = width;
512
        picture->linesize[1] = 2 * w2;
513
        break;
514
    case PIX_FMT_RGB24:
515
    case PIX_FMT_BGR24:
516
        picture->linesize[0] = width * 3;
517
        break;
518
    case PIX_FMT_ARGB:
519
    case PIX_FMT_ABGR:
520
    case PIX_FMT_RGBA:
521
    case PIX_FMT_BGRA:
522
        picture->linesize[0] = width * 4;
523
        break;
524
    case PIX_FMT_RGB48BE:
525
    case PIX_FMT_RGB48LE:
526
        picture->linesize[0] = width * 6;
527
        break;
528
    case PIX_FMT_GRAY16BE:
529
    case PIX_FMT_GRAY16LE:
530
    case PIX_FMT_BGR555BE:
531
    case PIX_FMT_BGR555LE:
532
    case PIX_FMT_BGR565BE:
533
    case PIX_FMT_BGR565LE:
534
    case PIX_FMT_RGB555BE:
535
    case PIX_FMT_RGB555LE:
536
    case PIX_FMT_RGB565BE:
537
    case PIX_FMT_RGB565LE:
538
    case PIX_FMT_YUYV422:
539
        picture->linesize[0] = width * 2;
540
        break;
541
    case PIX_FMT_UYVY422:
542
        picture->linesize[0] = width * 2;
543
        break;
544
    case PIX_FMT_UYYVYY411:
545
        picture->linesize[0] = width + width/2;
546
        break;
547
    case PIX_FMT_RGB4:
548
    case PIX_FMT_BGR4:
549
        picture->linesize[0] = width / 2;
550
        break;
551
    case PIX_FMT_MONOWHITE:
552
    case PIX_FMT_MONOBLACK:
553
        picture->linesize[0] = (width + 7) >> 3;
554
        break;
555
    case PIX_FMT_PAL8:
556
    case PIX_FMT_RGB8:
557
    case PIX_FMT_BGR8:
558
    case PIX_FMT_RGB4_BYTE:
559
    case PIX_FMT_BGR4_BYTE:
560
    case PIX_FMT_GRAY8:
561
        picture->linesize[0] = width;
562
        break;
563
    default:
564
        return -1;
565
    }
566
    return 0;
567
}
568

    
569
int ff_fill_pointer(AVPicture *picture, uint8_t *ptr, enum PixelFormat pix_fmt,
570
                    int height)
571
{
572
    int size, h2, size2;
573
    const AVPixFmtDescriptor *desc = &av_pix_fmt_descriptors[pix_fmt];
574

    
575
    size = picture->linesize[0] * height;
576
    switch(pix_fmt) {
577
    case PIX_FMT_YUV420P:
578
    case PIX_FMT_YUV422P:
579
    case PIX_FMT_YUV444P:
580
    case PIX_FMT_YUV410P:
581
    case PIX_FMT_YUV411P:
582
    case PIX_FMT_YUV440P:
583
    case PIX_FMT_YUVJ420P:
584
    case PIX_FMT_YUVJ422P:
585
    case PIX_FMT_YUVJ444P:
586
    case PIX_FMT_YUVJ440P:
587
    case PIX_FMT_YUV420P16LE:
588
    case PIX_FMT_YUV422P16LE:
589
    case PIX_FMT_YUV444P16LE:
590
    case PIX_FMT_YUV420P16BE:
591
    case PIX_FMT_YUV422P16BE:
592
    case PIX_FMT_YUV444P16BE:
593
        h2 = (height + (1 << desc->log2_chroma_h) - 1) >> desc->log2_chroma_h;
594
        size2 = picture->linesize[1] * h2;
595
        picture->data[0] = ptr;
596
        picture->data[1] = picture->data[0] + size;
597
        picture->data[2] = picture->data[1] + size2;
598
        picture->data[3] = NULL;
599
        return size + 2 * size2;
600
    case PIX_FMT_YUVA420P:
601
        h2 = (height + (1 << desc->log2_chroma_h) - 1) >> desc->log2_chroma_h;
602
        size2 = picture->linesize[1] * h2;
603
        picture->data[0] = ptr;
604
        picture->data[1] = picture->data[0] + size;
605
        picture->data[2] = picture->data[1] + size2;
606
        picture->data[3] = picture->data[1] + size2 + size2;
607
        return 2 * size + 2 * size2;
608
    case PIX_FMT_NV12:
609
    case PIX_FMT_NV21:
610
        h2 = (height + (1 << desc->log2_chroma_h) - 1) >> desc->log2_chroma_h;
611
        size2 = picture->linesize[1] * h2;
612
        picture->data[0] = ptr;
613
        picture->data[1] = picture->data[0] + size;
614
        picture->data[2] = NULL;
615
        picture->data[3] = NULL;
616
        return size + size2;
617
    case PIX_FMT_RGB24:
618
    case PIX_FMT_BGR24:
619
    case PIX_FMT_ARGB:
620
    case PIX_FMT_ABGR:
621
    case PIX_FMT_RGBA:
622
    case PIX_FMT_BGRA:
623
    case PIX_FMT_RGB48BE:
624
    case PIX_FMT_RGB48LE:
625
    case PIX_FMT_GRAY16BE:
626
    case PIX_FMT_GRAY16LE:
627
    case PIX_FMT_BGR555BE:
628
    case PIX_FMT_BGR555LE:
629
    case PIX_FMT_BGR565BE:
630
    case PIX_FMT_BGR565LE:
631
    case PIX_FMT_RGB555BE:
632
    case PIX_FMT_RGB555LE:
633
    case PIX_FMT_RGB565BE:
634
    case PIX_FMT_RGB565LE:
635
    case PIX_FMT_YUYV422:
636
    case PIX_FMT_UYVY422:
637
    case PIX_FMT_UYYVYY411:
638
    case PIX_FMT_RGB4:
639
    case PIX_FMT_BGR4:
640
    case PIX_FMT_MONOWHITE:
641
    case PIX_FMT_MONOBLACK:
642
        picture->data[0] = ptr;
643
        picture->data[1] = NULL;
644
        picture->data[2] = NULL;
645
        picture->data[3] = NULL;
646
        return size;
647
    case PIX_FMT_PAL8:
648
    case PIX_FMT_RGB8:
649
    case PIX_FMT_BGR8:
650
    case PIX_FMT_RGB4_BYTE:
651
    case PIX_FMT_BGR4_BYTE:
652
    case PIX_FMT_GRAY8:
653
        size2 = (size + 3) & ~3;
654
        picture->data[0] = ptr;
655
        picture->data[1] = ptr + size2; /* palette is stored here as 256 32 bit words */
656
        picture->data[2] = NULL;
657
        picture->data[3] = NULL;
658
        return size2 + 256 * 4;
659
    default:
660
        picture->data[0] = NULL;
661
        picture->data[1] = NULL;
662
        picture->data[2] = NULL;
663
        picture->data[3] = NULL;
664
        return -1;
665
    }
666
}
667

    
668
int avpicture_fill(AVPicture *picture, uint8_t *ptr,
669
                   enum PixelFormat pix_fmt, int width, int height)
670
{
671

    
672
    if(avcodec_check_dimensions(NULL, width, height))
673
        return -1;
674

    
675
    if (ff_fill_linesize(picture, pix_fmt, width))
676
        return -1;
677

    
678
    return ff_fill_pointer(picture, ptr, pix_fmt, height);
679
}
680

    
681
int avpicture_layout(const AVPicture* src, enum PixelFormat pix_fmt, int width, int height,
682
                     unsigned char *dest, int dest_size)
683
{
684
    const PixFmtInfo* pf = &pix_fmt_info[pix_fmt];
685
    const AVPixFmtDescriptor *desc = &av_pix_fmt_descriptors[pix_fmt];
686
    int i, j, w, ow, h, oh, data_planes;
687
    const unsigned char* s;
688
    int size = avpicture_get_size(pix_fmt, width, height);
689

    
690
    if (size > dest_size || size < 0)
691
        return -1;
692

    
693
    if (pf->pixel_type == FF_PIXEL_PACKED || pf->pixel_type == FF_PIXEL_PALETTE) {
694
        if (pix_fmt == PIX_FMT_YUYV422 ||
695
            pix_fmt == PIX_FMT_UYVY422 ||
696
            pix_fmt == PIX_FMT_BGR565BE ||
697
            pix_fmt == PIX_FMT_BGR565LE ||
698
            pix_fmt == PIX_FMT_BGR555BE ||
699
            pix_fmt == PIX_FMT_BGR555LE ||
700
            pix_fmt == PIX_FMT_RGB565BE ||
701
            pix_fmt == PIX_FMT_RGB565LE ||
702
            pix_fmt == PIX_FMT_RGB555BE ||
703
            pix_fmt == PIX_FMT_RGB555LE)
704
            w = width * 2;
705
        else if (pix_fmt == PIX_FMT_UYYVYY411)
706
            w = width + width/2;
707
        else if (pix_fmt == PIX_FMT_PAL8)
708
            w = width;
709
        else
710
            w = width * (pf->depth * pf->nb_channels / 8);
711

    
712
        data_planes = 1;
713
        h = height;
714
    } else {
715
        data_planes = pf->nb_channels;
716
        w = (width*pf->depth + 7)/8;
717
        h = height;
718
    }
719

    
720
    ow = w;
721
    oh = h;
722

    
723
    for (i=0; i<data_planes; i++) {
724
        if (i == 1) {
725
            w = ((width >> desc->log2_chroma_w) * pf->depth + 7) / 8;
726
            h = height >> desc->log2_chroma_h;
727
            if (pix_fmt == PIX_FMT_NV12 || pix_fmt == PIX_FMT_NV21)
728
                w <<= 1;
729
        } else if (i == 3) {
730
            w = ow;
731
            h = oh;
732
        }
733
        s = src->data[i];
734
        for(j=0; j<h; j++) {
735
            memcpy(dest, s, w);
736
            dest += w;
737
            s += src->linesize[i];
738
        }
739
    }
740

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

    
744
    return size;
745
}
746

    
747
int avpicture_get_size(enum PixelFormat pix_fmt, int width, int height)
748
{
749
    AVPicture dummy_pict;
750
    if(avcodec_check_dimensions(NULL, width, height))
751
        return -1;
752
    switch (pix_fmt) {
753
    case PIX_FMT_RGB8:
754
    case PIX_FMT_BGR8:
755
    case PIX_FMT_RGB4_BYTE:
756
    case PIX_FMT_BGR4_BYTE:
757
    case PIX_FMT_GRAY8:
758
        // do not include palette for these pseudo-paletted formats
759
        return width * height;
760
    }
761
    return avpicture_fill(&dummy_pict, NULL, pix_fmt, width, height);
762
}
763

    
764
int avcodec_get_pix_fmt_loss(enum PixelFormat dst_pix_fmt, enum PixelFormat src_pix_fmt,
765
                             int has_alpha)
766
{
767
    const PixFmtInfo *pf, *ps;
768
    const AVPixFmtDescriptor *src_desc = &av_pix_fmt_descriptors[src_pix_fmt];
769
    const AVPixFmtDescriptor *dst_desc = &av_pix_fmt_descriptors[dst_pix_fmt];
770
    int loss;
771

    
772
    ps = &pix_fmt_info[src_pix_fmt];
773

    
774
    /* compute loss */
775
    loss = 0;
776
    pf = &pix_fmt_info[dst_pix_fmt];
777
    if (pf->depth < ps->depth ||
778
        ((dst_pix_fmt == PIX_FMT_RGB555BE || dst_pix_fmt == PIX_FMT_RGB555LE) &&
779
         (src_pix_fmt == PIX_FMT_RGB565BE || src_pix_fmt == PIX_FMT_RGB565LE)))
780
        loss |= FF_LOSS_DEPTH;
781
    if (dst_desc->log2_chroma_w > src_desc->log2_chroma_w ||
782
        dst_desc->log2_chroma_h > src_desc->log2_chroma_h)
783
        loss |= FF_LOSS_RESOLUTION;
784
    switch(pf->color_type) {
785
    case FF_COLOR_RGB:
786
        if (ps->color_type != FF_COLOR_RGB &&
787
            ps->color_type != FF_COLOR_GRAY)
788
            loss |= FF_LOSS_COLORSPACE;
789
        break;
790
    case FF_COLOR_GRAY:
791
        if (ps->color_type != FF_COLOR_GRAY)
792
            loss |= FF_LOSS_COLORSPACE;
793
        break;
794
    case FF_COLOR_YUV:
795
        if (ps->color_type != FF_COLOR_YUV)
796
            loss |= FF_LOSS_COLORSPACE;
797
        break;
798
    case FF_COLOR_YUV_JPEG:
799
        if (ps->color_type != FF_COLOR_YUV_JPEG &&
800
            ps->color_type != FF_COLOR_YUV &&
801
            ps->color_type != FF_COLOR_GRAY)
802
            loss |= FF_LOSS_COLORSPACE;
803
        break;
804
    default:
805
        /* fail safe test */
806
        if (ps->color_type != pf->color_type)
807
            loss |= FF_LOSS_COLORSPACE;
808
        break;
809
    }
810
    if (pf->color_type == FF_COLOR_GRAY &&
811
        ps->color_type != FF_COLOR_GRAY)
812
        loss |= FF_LOSS_CHROMA;
813
    if (!pf->is_alpha && (ps->is_alpha && has_alpha))
814
        loss |= FF_LOSS_ALPHA;
815
    if (pf->pixel_type == FF_PIXEL_PALETTE &&
816
        (ps->pixel_type != FF_PIXEL_PALETTE && ps->color_type != FF_COLOR_GRAY))
817
        loss |= FF_LOSS_COLORQUANT;
818
    return loss;
819
}
820

    
821
static int avg_bits_per_pixel(enum PixelFormat pix_fmt)
822
{
823
    int bits;
824
    const PixFmtInfo *pf;
825
    const AVPixFmtDescriptor *desc = &av_pix_fmt_descriptors[pix_fmt];
826

    
827
    pf = &pix_fmt_info[pix_fmt];
828
    switch(pf->pixel_type) {
829
    case FF_PIXEL_PACKED:
830
        switch(pix_fmt) {
831
        case PIX_FMT_YUYV422:
832
        case PIX_FMT_UYVY422:
833
        case PIX_FMT_RGB565BE:
834
        case PIX_FMT_RGB565LE:
835
        case PIX_FMT_RGB555BE:
836
        case PIX_FMT_RGB555LE:
837
        case PIX_FMT_BGR565BE:
838
        case PIX_FMT_BGR565LE:
839
        case PIX_FMT_BGR555BE:
840
        case PIX_FMT_BGR555LE:
841
            bits = 16;
842
            break;
843
        case PIX_FMT_UYYVYY411:
844
            bits = 12;
845
            break;
846
        default:
847
            bits = pf->depth * pf->nb_channels;
848
            break;
849
        }
850
        break;
851
    case FF_PIXEL_PLANAR:
852
        if (desc->log2_chroma_w == 0 && desc->log2_chroma_h == 0) {
853
            bits = pf->depth * pf->nb_channels;
854
        } else {
855
            bits = pf->depth + ((2 * pf->depth) >>
856
                                (desc->log2_chroma_w + desc->log2_chroma_h));
857
        }
858
        break;
859
    case FF_PIXEL_PALETTE:
860
        bits = 8;
861
        break;
862
    default:
863
        bits = -1;
864
        break;
865
    }
866
    return bits;
867
}
868

    
869
static enum PixelFormat avcodec_find_best_pix_fmt1(int64_t pix_fmt_mask,
870
                                      enum PixelFormat src_pix_fmt,
871
                                      int has_alpha,
872
                                      int loss_mask)
873
{
874
    int dist, i, loss, min_dist;
875
    enum PixelFormat dst_pix_fmt;
876

    
877
    /* find exact color match with smallest size */
878
    dst_pix_fmt = PIX_FMT_NONE;
879
    min_dist = 0x7fffffff;
880
    for(i = 0;i < PIX_FMT_NB; i++) {
881
        if (pix_fmt_mask & (1ULL << i)) {
882
            loss = avcodec_get_pix_fmt_loss(i, src_pix_fmt, has_alpha) & loss_mask;
883
            if (loss == 0) {
884
                dist = avg_bits_per_pixel(i);
885
                if (dist < min_dist) {
886
                    min_dist = dist;
887
                    dst_pix_fmt = i;
888
                }
889
            }
890
        }
891
    }
892
    return dst_pix_fmt;
893
}
894

    
895
enum PixelFormat avcodec_find_best_pix_fmt(int64_t pix_fmt_mask, enum PixelFormat src_pix_fmt,
896
                              int has_alpha, int *loss_ptr)
897
{
898
    enum PixelFormat dst_pix_fmt;
899
    int loss_mask, i;
900
    static const int loss_mask_order[] = {
901
        ~0, /* no loss first */
902
        ~FF_LOSS_ALPHA,
903
        ~FF_LOSS_RESOLUTION,
904
        ~(FF_LOSS_COLORSPACE | FF_LOSS_RESOLUTION),
905
        ~FF_LOSS_COLORQUANT,
906
        ~FF_LOSS_DEPTH,
907
        0,
908
    };
909

    
910
    /* try with successive loss */
911
    i = 0;
912
    for(;;) {
913
        loss_mask = loss_mask_order[i++];
914
        dst_pix_fmt = avcodec_find_best_pix_fmt1(pix_fmt_mask, src_pix_fmt,
915
                                                 has_alpha, loss_mask);
916
        if (dst_pix_fmt >= 0)
917
            goto found;
918
        if (loss_mask == 0)
919
            break;
920
    }
921
    return PIX_FMT_NONE;
922
 found:
923
    if (loss_ptr)
924
        *loss_ptr = avcodec_get_pix_fmt_loss(dst_pix_fmt, src_pix_fmt, has_alpha);
925
    return dst_pix_fmt;
926
}
927

    
928
void ff_img_copy_plane(uint8_t *dst, int dst_wrap,
929
                           const uint8_t *src, int src_wrap,
930
                           int width, int height)
931
{
932
    if((!dst) || (!src))
933
        return;
934
    for(;height > 0; height--) {
935
        memcpy(dst, src, width);
936
        dst += dst_wrap;
937
        src += src_wrap;
938
    }
939
}
940

    
941
int ff_get_plane_bytewidth(enum PixelFormat pix_fmt, int width, int plane)
942
{
943
    int bits;
944
    const PixFmtInfo *pf = &pix_fmt_info[pix_fmt];
945
    const AVPixFmtDescriptor *desc = &av_pix_fmt_descriptors[pix_fmt];
946

    
947
    pf = &pix_fmt_info[pix_fmt];
948
    switch(pf->pixel_type) {
949
    case FF_PIXEL_PACKED:
950
        switch(pix_fmt) {
951
        case PIX_FMT_YUYV422:
952
        case PIX_FMT_UYVY422:
953
        case PIX_FMT_RGB565BE:
954
        case PIX_FMT_RGB565LE:
955
        case PIX_FMT_RGB555BE:
956
        case PIX_FMT_RGB555LE:
957
        case PIX_FMT_BGR565BE:
958
        case PIX_FMT_BGR565LE:
959
        case PIX_FMT_BGR555BE:
960
        case PIX_FMT_BGR555LE:
961
            bits = 16;
962
            break;
963
        case PIX_FMT_UYYVYY411:
964
            bits = 12;
965
            break;
966
        default:
967
            bits = pf->depth * pf->nb_channels;
968
            break;
969
        }
970
        return (width * bits + 7) >> 3;
971
        break;
972
    case FF_PIXEL_PLANAR:
973
            if (plane == 1 || plane == 2)
974
                width= -((-width)>>desc->log2_chroma_w);
975

    
976
            return (width * pf->depth + 7) >> 3;
977
        break;
978
    case FF_PIXEL_PALETTE:
979
        if (plane == 0)
980
            return width;
981
        break;
982
    }
983

    
984
    return -1;
985
}
986

    
987
void av_picture_copy(AVPicture *dst, const AVPicture *src,
988
                     enum PixelFormat pix_fmt, int width, int height)
989
{
990
    int i;
991
    const PixFmtInfo *pf = &pix_fmt_info[pix_fmt];
992
    const AVPixFmtDescriptor *desc = &av_pix_fmt_descriptors[pix_fmt];
993

    
994
    switch(pf->pixel_type) {
995
    case FF_PIXEL_PACKED:
996
    case FF_PIXEL_PLANAR:
997
        for(i = 0; i < pf->nb_channels; i++) {
998
            int h;
999
            int bwidth = ff_get_plane_bytewidth(pix_fmt, width, i);
1000
            h = height;
1001
            if (i == 1 || i == 2) {
1002
                h= -((-height)>>desc->log2_chroma_h);
1003
            }
1004
            ff_img_copy_plane(dst->data[i], dst->linesize[i],
1005
                           src->data[i], src->linesize[i],
1006
                           bwidth, h);
1007
        }
1008
        break;
1009
    case FF_PIXEL_PALETTE:
1010
        ff_img_copy_plane(dst->data[0], dst->linesize[0],
1011
                       src->data[0], src->linesize[0],
1012
                       width, height);
1013
        /* copy the palette */
1014
        memcpy(dst->data[1], src->data[1], 4*256);
1015
        break;
1016
    }
1017
}
1018

    
1019
/* 2x2 -> 1x1 */
1020
void ff_shrink22(uint8_t *dst, int dst_wrap,
1021
                     const uint8_t *src, int src_wrap,
1022
                     int width, int height)
1023
{
1024
    int w;
1025
    const uint8_t *s1, *s2;
1026
    uint8_t *d;
1027

    
1028
    for(;height > 0; height--) {
1029
        s1 = src;
1030
        s2 = s1 + src_wrap;
1031
        d = dst;
1032
        for(w = width;w >= 4; w-=4) {
1033
            d[0] = (s1[0] + s1[1] + s2[0] + s2[1] + 2) >> 2;
1034
            d[1] = (s1[2] + s1[3] + s2[2] + s2[3] + 2) >> 2;
1035
            d[2] = (s1[4] + s1[5] + s2[4] + s2[5] + 2) >> 2;
1036
            d[3] = (s1[6] + s1[7] + s2[6] + s2[7] + 2) >> 2;
1037
            s1 += 8;
1038
            s2 += 8;
1039
            d += 4;
1040
        }
1041
        for(;w > 0; w--) {
1042
            d[0] = (s1[0] + s1[1] + s2[0] + s2[1] + 2) >> 2;
1043
            s1 += 2;
1044
            s2 += 2;
1045
            d++;
1046
        }
1047
        src += 2 * src_wrap;
1048
        dst += dst_wrap;
1049
    }
1050
}
1051

    
1052
/* 4x4 -> 1x1 */
1053
void ff_shrink44(uint8_t *dst, int dst_wrap,
1054
                     const uint8_t *src, int src_wrap,
1055
                     int width, int height)
1056
{
1057
    int w;
1058
    const uint8_t *s1, *s2, *s3, *s4;
1059
    uint8_t *d;
1060

    
1061
    for(;height > 0; height--) {
1062
        s1 = src;
1063
        s2 = s1 + src_wrap;
1064
        s3 = s2 + src_wrap;
1065
        s4 = s3 + src_wrap;
1066
        d = dst;
1067
        for(w = width;w > 0; w--) {
1068
            d[0] = (s1[0] + s1[1] + s1[2] + s1[3] +
1069
                    s2[0] + s2[1] + s2[2] + s2[3] +
1070
                    s3[0] + s3[1] + s3[2] + s3[3] +
1071
                    s4[0] + s4[1] + s4[2] + s4[3] + 8) >> 4;
1072
            s1 += 4;
1073
            s2 += 4;
1074
            s3 += 4;
1075
            s4 += 4;
1076
            d++;
1077
        }
1078
        src += 4 * src_wrap;
1079
        dst += dst_wrap;
1080
    }
1081
}
1082

    
1083
/* 8x8 -> 1x1 */
1084
void ff_shrink88(uint8_t *dst, int dst_wrap,
1085
                     const uint8_t *src, int src_wrap,
1086
                     int width, int height)
1087
{
1088
    int w, i;
1089

    
1090
    for(;height > 0; height--) {
1091
        for(w = width;w > 0; w--) {
1092
            int tmp=0;
1093
            for(i=0; i<8; i++){
1094
                tmp += src[0] + src[1] + src[2] + src[3] + src[4] + src[5] + src[6] + src[7];
1095
                src += src_wrap;
1096
            }
1097
            *(dst++) = (tmp + 32)>>6;
1098
            src += 8 - 8*src_wrap;
1099
        }
1100
        src += 8*src_wrap - 8*width;
1101
        dst += dst_wrap - width;
1102
    }
1103
}
1104

    
1105

    
1106
int avpicture_alloc(AVPicture *picture,
1107
                    enum PixelFormat pix_fmt, int width, int height)
1108
{
1109
    int size;
1110
    void *ptr;
1111

    
1112
    size = avpicture_fill(picture, NULL, pix_fmt, width, height);
1113
    if(size<0)
1114
        goto fail;
1115
    ptr = av_malloc(size);
1116
    if (!ptr)
1117
        goto fail;
1118
    avpicture_fill(picture, ptr, pix_fmt, width, height);
1119
    if(picture->data[1] && !picture->data[2])
1120
        ff_set_systematic_pal((uint32_t*)picture->data[1], pix_fmt);
1121

    
1122
    return 0;
1123
 fail:
1124
    memset(picture, 0, sizeof(AVPicture));
1125
    return -1;
1126
}
1127

    
1128
void avpicture_free(AVPicture *picture)
1129
{
1130
    av_free(picture->data[0]);
1131
}
1132

    
1133
/* return true if yuv planar */
1134
static inline int is_yuv_planar(const PixFmtInfo *ps)
1135
{
1136
    return (ps->color_type == FF_COLOR_YUV ||
1137
            ps->color_type == FF_COLOR_YUV_JPEG) &&
1138
        ps->pixel_type == FF_PIXEL_PLANAR;
1139
}
1140

    
1141
int av_picture_crop(AVPicture *dst, const AVPicture *src,
1142
                    enum PixelFormat pix_fmt, int top_band, int left_band)
1143
{
1144
    int y_shift;
1145
    int x_shift;
1146

    
1147
    if (pix_fmt < 0 || pix_fmt >= PIX_FMT_NB || !is_yuv_planar(&pix_fmt_info[pix_fmt]))
1148
        return -1;
1149

    
1150
    y_shift = av_pix_fmt_descriptors[pix_fmt].log2_chroma_h;
1151
    x_shift = av_pix_fmt_descriptors[pix_fmt].log2_chroma_w;
1152

    
1153
    dst->data[0] = src->data[0] + (top_band * src->linesize[0]) + left_band;
1154
    dst->data[1] = src->data[1] + ((top_band >> y_shift) * src->linesize[1]) + (left_band >> x_shift);
1155
    dst->data[2] = src->data[2] + ((top_band >> y_shift) * src->linesize[2]) + (left_band >> x_shift);
1156

    
1157
    dst->linesize[0] = src->linesize[0];
1158
    dst->linesize[1] = src->linesize[1];
1159
    dst->linesize[2] = src->linesize[2];
1160
    return 0;
1161
}
1162

    
1163
int av_picture_pad(AVPicture *dst, const AVPicture *src, int height, int width,
1164
                   enum PixelFormat pix_fmt, int padtop, int padbottom, int padleft, int padright,
1165
            int *color)
1166
{
1167
    uint8_t *optr;
1168
    int y_shift;
1169
    int x_shift;
1170
    int yheight;
1171
    int i, y;
1172

    
1173
    if (pix_fmt < 0 || pix_fmt >= PIX_FMT_NB ||
1174
        !is_yuv_planar(&pix_fmt_info[pix_fmt])) return -1;
1175

    
1176
    for (i = 0; i < 3; i++) {
1177
        x_shift = i ? av_pix_fmt_descriptors[pix_fmt].log2_chroma_w : 0;
1178
        y_shift = i ? av_pix_fmt_descriptors[pix_fmt].log2_chroma_h : 0;
1179

    
1180
        if (padtop || padleft) {
1181
            memset(dst->data[i], color[i],
1182
                dst->linesize[i] * (padtop >> y_shift) + (padleft >> x_shift));
1183
        }
1184

    
1185
        if (padleft || padright) {
1186
            optr = dst->data[i] + dst->linesize[i] * (padtop >> y_shift) +
1187
                (dst->linesize[i] - (padright >> x_shift));
1188
            yheight = (height - 1 - (padtop + padbottom)) >> y_shift;
1189
            for (y = 0; y < yheight; y++) {
1190
                memset(optr, color[i], (padleft + padright) >> x_shift);
1191
                optr += dst->linesize[i];
1192
            }
1193
        }
1194

    
1195
        if (src) { /* first line */
1196
            uint8_t *iptr = src->data[i];
1197
            optr = dst->data[i] + dst->linesize[i] * (padtop >> y_shift) +
1198
                    (padleft >> x_shift);
1199
            memcpy(optr, iptr, (width - padleft - padright) >> x_shift);
1200
            iptr += src->linesize[i];
1201
            optr = dst->data[i] + dst->linesize[i] * (padtop >> y_shift) +
1202
                (dst->linesize[i] - (padright >> x_shift));
1203
            yheight = (height - 1 - (padtop + padbottom)) >> y_shift;
1204
            for (y = 0; y < yheight; y++) {
1205
                memset(optr, color[i], (padleft + padright) >> x_shift);
1206
                memcpy(optr + ((padleft + padright) >> x_shift), iptr,
1207
                       (width - padleft - padright) >> x_shift);
1208
                iptr += src->linesize[i];
1209
                optr += dst->linesize[i];
1210
            }
1211
        }
1212

    
1213
        if (padbottom || padright) {
1214
            optr = dst->data[i] + dst->linesize[i] *
1215
                ((height - padbottom) >> y_shift) - (padright >> x_shift);
1216
            memset(optr, color[i],dst->linesize[i] *
1217
                (padbottom >> y_shift) + (padright >> x_shift));
1218
        }
1219
    }
1220
    return 0;
1221
}
1222

    
1223
/* NOTE: we scan all the pixels to have an exact information */
1224
static int get_alpha_info_pal8(const AVPicture *src, int width, int height)
1225
{
1226
    const unsigned char *p;
1227
    int src_wrap, ret, x, y;
1228
    unsigned int a;
1229
    uint32_t *palette = (uint32_t *)src->data[1];
1230

    
1231
    p = src->data[0];
1232
    src_wrap = src->linesize[0] - width;
1233
    ret = 0;
1234
    for(y=0;y<height;y++) {
1235
        for(x=0;x<width;x++) {
1236
            a = palette[p[0]] >> 24;
1237
            if (a == 0x00) {
1238
                ret |= FF_ALPHA_TRANSP;
1239
            } else if (a != 0xff) {
1240
                ret |= FF_ALPHA_SEMI_TRANSP;
1241
            }
1242
            p++;
1243
        }
1244
        p += src_wrap;
1245
    }
1246
    return ret;
1247
}
1248

    
1249
int img_get_alpha_info(const AVPicture *src,
1250
                       enum PixelFormat pix_fmt, int width, int height)
1251
{
1252
    const PixFmtInfo *pf = &pix_fmt_info[pix_fmt];
1253
    int ret;
1254

    
1255
    /* no alpha can be represented in format */
1256
    if (!pf->is_alpha)
1257
        return 0;
1258
    switch(pix_fmt) {
1259
    case PIX_FMT_PAL8:
1260
        ret = get_alpha_info_pal8(src, width, height);
1261
        break;
1262
    default:
1263
        /* we do not know, so everything is indicated */
1264
        ret = FF_ALPHA_TRANSP | FF_ALPHA_SEMI_TRANSP;
1265
        break;
1266
    }
1267
    return ret;
1268
}
1269

    
1270
#if HAVE_MMX
1271
#define DEINT_INPLACE_LINE_LUM \
1272
                    movd_m2r(lum_m4[0],mm0);\
1273
                    movd_m2r(lum_m3[0],mm1);\
1274
                    movd_m2r(lum_m2[0],mm2);\
1275
                    movd_m2r(lum_m1[0],mm3);\
1276
                    movd_m2r(lum[0],mm4);\
1277
                    punpcklbw_r2r(mm7,mm0);\
1278
                    movd_r2m(mm2,lum_m4[0]);\
1279
                    punpcklbw_r2r(mm7,mm1);\
1280
                    punpcklbw_r2r(mm7,mm2);\
1281
                    punpcklbw_r2r(mm7,mm3);\
1282
                    punpcklbw_r2r(mm7,mm4);\
1283
                    paddw_r2r(mm3,mm1);\
1284
                    psllw_i2r(1,mm2);\
1285
                    paddw_r2r(mm4,mm0);\
1286
                    psllw_i2r(2,mm1);\
1287
                    paddw_r2r(mm6,mm2);\
1288
                    paddw_r2r(mm2,mm1);\
1289
                    psubusw_r2r(mm0,mm1);\
1290
                    psrlw_i2r(3,mm1);\
1291
                    packuswb_r2r(mm7,mm1);\
1292
                    movd_r2m(mm1,lum_m2[0]);
1293

    
1294
#define DEINT_LINE_LUM \
1295
                    movd_m2r(lum_m4[0],mm0);\
1296
                    movd_m2r(lum_m3[0],mm1);\
1297
                    movd_m2r(lum_m2[0],mm2);\
1298
                    movd_m2r(lum_m1[0],mm3);\
1299
                    movd_m2r(lum[0],mm4);\
1300
                    punpcklbw_r2r(mm7,mm0);\
1301
                    punpcklbw_r2r(mm7,mm1);\
1302
                    punpcklbw_r2r(mm7,mm2);\
1303
                    punpcklbw_r2r(mm7,mm3);\
1304
                    punpcklbw_r2r(mm7,mm4);\
1305
                    paddw_r2r(mm3,mm1);\
1306
                    psllw_i2r(1,mm2);\
1307
                    paddw_r2r(mm4,mm0);\
1308
                    psllw_i2r(2,mm1);\
1309
                    paddw_r2r(mm6,mm2);\
1310
                    paddw_r2r(mm2,mm1);\
1311
                    psubusw_r2r(mm0,mm1);\
1312
                    psrlw_i2r(3,mm1);\
1313
                    packuswb_r2r(mm7,mm1);\
1314
                    movd_r2m(mm1,dst[0]);
1315
#endif
1316

    
1317
/* filter parameters: [-1 4 2 4 -1] // 8 */
1318
static void deinterlace_line(uint8_t *dst,
1319
                             const uint8_t *lum_m4, const uint8_t *lum_m3,
1320
                             const uint8_t *lum_m2, const uint8_t *lum_m1,
1321
                             const uint8_t *lum,
1322
                             int size)
1323
{
1324
#if !HAVE_MMX
1325
    uint8_t *cm = ff_cropTbl + MAX_NEG_CROP;
1326
    int sum;
1327

    
1328
    for(;size > 0;size--) {
1329
        sum = -lum_m4[0];
1330
        sum += lum_m3[0] << 2;
1331
        sum += lum_m2[0] << 1;
1332
        sum += lum_m1[0] << 2;
1333
        sum += -lum[0];
1334
        dst[0] = cm[(sum + 4) >> 3];
1335
        lum_m4++;
1336
        lum_m3++;
1337
        lum_m2++;
1338
        lum_m1++;
1339
        lum++;
1340
        dst++;
1341
    }
1342
#else
1343

    
1344
    {
1345
        pxor_r2r(mm7,mm7);
1346
        movq_m2r(ff_pw_4,mm6);
1347
    }
1348
    for (;size > 3; size-=4) {
1349
        DEINT_LINE_LUM
1350
        lum_m4+=4;
1351
        lum_m3+=4;
1352
        lum_m2+=4;
1353
        lum_m1+=4;
1354
        lum+=4;
1355
        dst+=4;
1356
    }
1357
#endif
1358
}
1359
static void deinterlace_line_inplace(uint8_t *lum_m4, uint8_t *lum_m3, uint8_t *lum_m2, uint8_t *lum_m1, uint8_t *lum,
1360
                             int size)
1361
{
1362
#if !HAVE_MMX
1363
    uint8_t *cm = ff_cropTbl + MAX_NEG_CROP;
1364
    int sum;
1365

    
1366
    for(;size > 0;size--) {
1367
        sum = -lum_m4[0];
1368
        sum += lum_m3[0] << 2;
1369
        sum += lum_m2[0] << 1;
1370
        lum_m4[0]=lum_m2[0];
1371
        sum += lum_m1[0] << 2;
1372
        sum += -lum[0];
1373
        lum_m2[0] = cm[(sum + 4) >> 3];
1374
        lum_m4++;
1375
        lum_m3++;
1376
        lum_m2++;
1377
        lum_m1++;
1378
        lum++;
1379
    }
1380
#else
1381

    
1382
    {
1383
        pxor_r2r(mm7,mm7);
1384
        movq_m2r(ff_pw_4,mm6);
1385
    }
1386
    for (;size > 3; size-=4) {
1387
        DEINT_INPLACE_LINE_LUM
1388
        lum_m4+=4;
1389
        lum_m3+=4;
1390
        lum_m2+=4;
1391
        lum_m1+=4;
1392
        lum+=4;
1393
    }
1394
#endif
1395
}
1396

    
1397
/* deinterlacing : 2 temporal taps, 3 spatial taps linear filter. The
1398
   top field is copied as is, but the bottom field is deinterlaced
1399
   against the top field. */
1400
static void deinterlace_bottom_field(uint8_t *dst, int dst_wrap,
1401
                                    const uint8_t *src1, int src_wrap,
1402
                                    int width, int height)
1403
{
1404
    const uint8_t *src_m2, *src_m1, *src_0, *src_p1, *src_p2;
1405
    int y;
1406

    
1407
    src_m2 = src1;
1408
    src_m1 = src1;
1409
    src_0=&src_m1[src_wrap];
1410
    src_p1=&src_0[src_wrap];
1411
    src_p2=&src_p1[src_wrap];
1412
    for(y=0;y<(height-2);y+=2) {
1413
        memcpy(dst,src_m1,width);
1414
        dst += dst_wrap;
1415
        deinterlace_line(dst,src_m2,src_m1,src_0,src_p1,src_p2,width);
1416
        src_m2 = src_0;
1417
        src_m1 = src_p1;
1418
        src_0 = src_p2;
1419
        src_p1 += 2*src_wrap;
1420
        src_p2 += 2*src_wrap;
1421
        dst += dst_wrap;
1422
    }
1423
    memcpy(dst,src_m1,width);
1424
    dst += dst_wrap;
1425
    /* do last line */
1426
    deinterlace_line(dst,src_m2,src_m1,src_0,src_0,src_0,width);
1427
}
1428

    
1429
static void deinterlace_bottom_field_inplace(uint8_t *src1, int src_wrap,
1430
                                             int width, int height)
1431
{
1432
    uint8_t *src_m1, *src_0, *src_p1, *src_p2;
1433
    int y;
1434
    uint8_t *buf;
1435
    buf = (uint8_t*)av_malloc(width);
1436

    
1437
    src_m1 = src1;
1438
    memcpy(buf,src_m1,width);
1439
    src_0=&src_m1[src_wrap];
1440
    src_p1=&src_0[src_wrap];
1441
    src_p2=&src_p1[src_wrap];
1442
    for(y=0;y<(height-2);y+=2) {
1443
        deinterlace_line_inplace(buf,src_m1,src_0,src_p1,src_p2,width);
1444
        src_m1 = src_p1;
1445
        src_0 = src_p2;
1446
        src_p1 += 2*src_wrap;
1447
        src_p2 += 2*src_wrap;
1448
    }
1449
    /* do last line */
1450
    deinterlace_line_inplace(buf,src_m1,src_0,src_0,src_0,width);
1451
    av_free(buf);
1452
}
1453

    
1454
int avpicture_deinterlace(AVPicture *dst, const AVPicture *src,
1455
                          enum PixelFormat pix_fmt, int width, int height)
1456
{
1457
    int i;
1458

    
1459
    if (pix_fmt != PIX_FMT_YUV420P &&
1460
        pix_fmt != PIX_FMT_YUV422P &&
1461
        pix_fmt != PIX_FMT_YUV444P &&
1462
        pix_fmt != PIX_FMT_YUV411P &&
1463
        pix_fmt != PIX_FMT_GRAY8)
1464
        return -1;
1465
    if ((width & 3) != 0 || (height & 3) != 0)
1466
        return -1;
1467

    
1468
    for(i=0;i<3;i++) {
1469
        if (i == 1) {
1470
            switch(pix_fmt) {
1471
            case PIX_FMT_YUV420P:
1472
                width >>= 1;
1473
                height >>= 1;
1474
                break;
1475
            case PIX_FMT_YUV422P:
1476
                width >>= 1;
1477
                break;
1478
            case PIX_FMT_YUV411P:
1479
                width >>= 2;
1480
                break;
1481
            default:
1482
                break;
1483
            }
1484
            if (pix_fmt == PIX_FMT_GRAY8) {
1485
                break;
1486
            }
1487
        }
1488
        if (src == dst) {
1489
            deinterlace_bottom_field_inplace(dst->data[i], dst->linesize[i],
1490
                                 width, height);
1491
        } else {
1492
            deinterlace_bottom_field(dst->data[i],dst->linesize[i],
1493
                                        src->data[i], src->linesize[i],
1494
                                        width, height);
1495
        }
1496
    }
1497
    emms_c();
1498
    return 0;
1499
}
1500