Statistics
| Branch: | Revision:

ffmpeg / libavcodec / imgconvert.c @ 4ef82b17

History | View | Annotate | Download (42.8 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 "internal.h"
37
#include "imgconvert.h"
38
#include "libavutil/pixdesc.h"
39

    
40
#if HAVE_MMX
41
#include "x86/mmx.h"
42
#include "x86/dsputil_mmx.h"
43
#endif
44

    
45
#define xglue(x, y) x ## y
46
#define glue(x, y) xglue(x, y)
47

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

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

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

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

    
153

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

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

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

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

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

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

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

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

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

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

    
413
        char is_alpha_char= info.is_alpha ? 'y' : 'n';
414

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

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

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

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

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

    
466
    return 0;
467
}
468

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

    
474
    memset(picture->linesize, 0, sizeof(picture->linesize));
475

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

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

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

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

    
674
    if(avcodec_check_dimensions(NULL, width, height))
675
        return -1;
676

    
677
    if (ff_fill_linesize(picture, pix_fmt, width))
678
        return -1;
679

    
680
    return ff_fill_pointer(picture, ptr, pix_fmt, height);
681
}
682

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

    
692
    if (size > dest_size || size < 0)
693
        return -1;
694

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

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

    
722
    ow = w;
723
    oh = h;
724

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

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

    
746
    return size;
747
}
748

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

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

    
774
    ps = &pix_fmt_info[src_pix_fmt];
775

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

    
825
static int avg_bits_per_pixel(enum PixelFormat pix_fmt)
826
{
827
    int bits;
828
    const PixFmtInfo *pf;
829
    const AVPixFmtDescriptor *desc = &av_pix_fmt_descriptors[pix_fmt];
830

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

    
873
static enum PixelFormat avcodec_find_best_pix_fmt1(int64_t pix_fmt_mask,
874
                                      enum PixelFormat src_pix_fmt,
875
                                      int has_alpha,
876
                                      int loss_mask)
877
{
878
    int dist, i, loss, min_dist;
879
    enum PixelFormat dst_pix_fmt;
880

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

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

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

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

    
945
int ff_get_plane_bytewidth(enum PixelFormat pix_fmt, int width, int plane)
946
{
947
    int bits;
948
    const PixFmtInfo *pf = &pix_fmt_info[pix_fmt];
949
    const AVPixFmtDescriptor *desc = &av_pix_fmt_descriptors[pix_fmt];
950

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

    
980
            return (width * pf->depth + 7) >> 3;
981
        break;
982
    case FF_PIXEL_PALETTE:
983
        if (plane == 0)
984
            return width;
985
        break;
986
    }
987

    
988
    return -1;
989
}
990

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

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

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

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

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

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

    
1087
/* 8x8 -> 1x1 */
1088
void ff_shrink88(uint8_t *dst, int dst_wrap,
1089
                     const uint8_t *src, int src_wrap,
1090
                     int width, int height)
1091
{
1092
    int w, i;
1093

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

    
1109

    
1110
int avpicture_alloc(AVPicture *picture,
1111
                    enum PixelFormat pix_fmt, int width, int height)
1112
{
1113
    int size;
1114
    void *ptr;
1115

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

    
1126
    return 0;
1127
 fail:
1128
    memset(picture, 0, sizeof(AVPicture));
1129
    return -1;
1130
}
1131

    
1132
void avpicture_free(AVPicture *picture)
1133
{
1134
    av_free(picture->data[0]);
1135
}
1136

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

    
1145
int av_picture_crop(AVPicture *dst, const AVPicture *src,
1146
                    enum PixelFormat pix_fmt, int top_band, int left_band)
1147
{
1148
    int y_shift;
1149
    int x_shift;
1150

    
1151
    if (pix_fmt < 0 || pix_fmt >= PIX_FMT_NB || !is_yuv_planar(&pix_fmt_info[pix_fmt]))
1152
        return -1;
1153

    
1154
    y_shift = av_pix_fmt_descriptors[pix_fmt].log2_chroma_h;
1155
    x_shift = av_pix_fmt_descriptors[pix_fmt].log2_chroma_w;
1156

    
1157
    dst->data[0] = src->data[0] + (top_band * src->linesize[0]) + left_band;
1158
    dst->data[1] = src->data[1] + ((top_band >> y_shift) * src->linesize[1]) + (left_band >> x_shift);
1159
    dst->data[2] = src->data[2] + ((top_band >> y_shift) * src->linesize[2]) + (left_band >> x_shift);
1160

    
1161
    dst->linesize[0] = src->linesize[0];
1162
    dst->linesize[1] = src->linesize[1];
1163
    dst->linesize[2] = src->linesize[2];
1164
    return 0;
1165
}
1166

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

    
1177
    if (pix_fmt < 0 || pix_fmt >= PIX_FMT_NB ||
1178
        !is_yuv_planar(&pix_fmt_info[pix_fmt])) return -1;
1179

    
1180
    for (i = 0; i < 3; i++) {
1181
        x_shift = i ? av_pix_fmt_descriptors[pix_fmt].log2_chroma_w : 0;
1182
        y_shift = i ? av_pix_fmt_descriptors[pix_fmt].log2_chroma_h : 0;
1183

    
1184
        if (padtop || padleft) {
1185
            memset(dst->data[i], color[i],
1186
                dst->linesize[i] * (padtop >> y_shift) + (padleft >> x_shift));
1187
        }
1188

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

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

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

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

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

    
1253
int img_get_alpha_info(const AVPicture *src,
1254
                       enum PixelFormat pix_fmt, int width, int height)
1255
{
1256
    const PixFmtInfo *pf = &pix_fmt_info[pix_fmt];
1257
    int ret;
1258

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

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

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

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

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

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

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

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

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

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

    
1433
static void deinterlace_bottom_field_inplace(uint8_t *src1, int src_wrap,
1434
                                             int width, int height)
1435
{
1436
    uint8_t *src_m1, *src_0, *src_p1, *src_p2;
1437
    int y;
1438
    uint8_t *buf;
1439
    buf = (uint8_t*)av_malloc(width);
1440

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

    
1458
int avpicture_deinterlace(AVPicture *dst, const AVPicture *src,
1459
                          enum PixelFormat pix_fmt, int width, int height)
1460
{
1461
    int i;
1462

    
1463
    if (pix_fmt != PIX_FMT_YUV420P &&
1464
        pix_fmt != PIX_FMT_YUV422P &&
1465
        pix_fmt != PIX_FMT_YUV444P &&
1466
        pix_fmt != PIX_FMT_YUV411P &&
1467
        pix_fmt != PIX_FMT_GRAY8)
1468
        return -1;
1469
    if ((width & 3) != 0 || (height & 3) != 0)
1470
        return -1;
1471

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