Statistics
| Branch: | Revision:

ffmpeg / libavcodec / imgconvert.c @ 0d8ee24c

History | View | Annotate | Download (80.2 KB)

1
/*
2
 * Misc image conversion routines
3
 * Copyright (c) 2001, 2002, 2003 Fabrice Bellard
4
 *
5
 * This file is part of FFmpeg.
6
 *
7
 * FFmpeg is free software; you can redistribute it and/or
8
 * modify it under the terms of the GNU Lesser General Public
9
 * License as published by the Free Software Foundation; either
10
 * version 2.1 of the License, or (at your option) any later version.
11
 *
12
 * FFmpeg is distributed in the hope that it will be useful,
13
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15
 * Lesser General Public License for more details.
16
 *
17
 * You should have received a copy of the GNU Lesser General Public
18
 * License along with FFmpeg; if not, write to the Free Software
19
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20
 */
21

    
22
/**
23
 * @file libavcodec/imgconvert.c
24
 * misc image conversion routines
25
 */
26

    
27
/* TODO:
28
 * - write 'ffimg' program to test all the image related stuff
29
 * - move all api to slice based system
30
 * - integrate deinterlacing, postprocessing and scaling in the conversion process
31
 */
32

    
33
#include "avcodec.h"
34
#include "dsputil.h"
35
#include "colorspace.h"
36

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

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

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

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

    
54
typedef struct PixFmtInfo {
55
    const char *name;
56
    uint8_t nb_channels;     /**< number of channels (including alpha) */
57
    uint8_t color_type;      /**< color type (see FF_COLOR_xxx constants) */
58
    uint8_t pixel_type;      /**< pixel storage type (see FF_PIXEL_xxx constants) */
59
    uint8_t is_alpha : 1;    /**< true if alpha can be specified */
60
    uint8_t is_hwaccel : 1;  /**< true if this is an HW accelerated format */
61
    uint8_t x_chroma_shift;  /**< X chroma subsampling factor is 2 ^ shift */
62
    uint8_t y_chroma_shift;  /**< Y chroma subsampling factor is 2 ^ shift */
63
    uint8_t depth;           /**< bit depth of the color components */
64
} PixFmtInfo;
65

    
66
/* this table gives more information about formats */
67
static const PixFmtInfo pix_fmt_info[PIX_FMT_NB] = {
68
    /* YUV formats */
69
    [PIX_FMT_YUV420P] = {
70
        .name = "yuv420p",
71
        .nb_channels = 3,
72
        .color_type = FF_COLOR_YUV,
73
        .pixel_type = FF_PIXEL_PLANAR,
74
        .depth = 8,
75
        .x_chroma_shift = 1, .y_chroma_shift = 1,
76
    },
77
    [PIX_FMT_YUV422P] = {
78
        .name = "yuv422p",
79
        .nb_channels = 3,
80
        .color_type = FF_COLOR_YUV,
81
        .pixel_type = FF_PIXEL_PLANAR,
82
        .depth = 8,
83
        .x_chroma_shift = 1, .y_chroma_shift = 0,
84
    },
85
    [PIX_FMT_YUV444P] = {
86
        .name = "yuv444p",
87
        .nb_channels = 3,
88
        .color_type = FF_COLOR_YUV,
89
        .pixel_type = FF_PIXEL_PLANAR,
90
        .depth = 8,
91
        .x_chroma_shift = 0, .y_chroma_shift = 0,
92
    },
93
    [PIX_FMT_YUYV422] = {
94
        .name = "yuyv422",
95
        .nb_channels = 1,
96
        .color_type = FF_COLOR_YUV,
97
        .pixel_type = FF_PIXEL_PACKED,
98
        .depth = 8,
99
        .x_chroma_shift = 1, .y_chroma_shift = 0,
100
    },
101
    [PIX_FMT_UYVY422] = {
102
        .name = "uyvy422",
103
        .nb_channels = 1,
104
        .color_type = FF_COLOR_YUV,
105
        .pixel_type = FF_PIXEL_PACKED,
106
        .depth = 8,
107
        .x_chroma_shift = 1, .y_chroma_shift = 0,
108
    },
109
    [PIX_FMT_YUV410P] = {
110
        .name = "yuv410p",
111
        .nb_channels = 3,
112
        .color_type = FF_COLOR_YUV,
113
        .pixel_type = FF_PIXEL_PLANAR,
114
        .depth = 8,
115
        .x_chroma_shift = 2, .y_chroma_shift = 2,
116
    },
117
    [PIX_FMT_YUV411P] = {
118
        .name = "yuv411p",
119
        .nb_channels = 3,
120
        .color_type = FF_COLOR_YUV,
121
        .pixel_type = FF_PIXEL_PLANAR,
122
        .depth = 8,
123
        .x_chroma_shift = 2, .y_chroma_shift = 0,
124
    },
125
    [PIX_FMT_YUV440P] = {
126
        .name = "yuv440p",
127
        .nb_channels = 3,
128
        .color_type = FF_COLOR_YUV,
129
        .pixel_type = FF_PIXEL_PLANAR,
130
        .depth = 8,
131
        .x_chroma_shift = 0, .y_chroma_shift = 1,
132
    },
133

    
134
    /* YUV formats with alpha plane */
135
    [PIX_FMT_YUVA420P] = {
136
        .name = "yuva420p",
137
        .nb_channels = 4,
138
        .color_type = FF_COLOR_YUV,
139
        .pixel_type = FF_PIXEL_PLANAR,
140
        .depth = 8,
141
        .x_chroma_shift = 1, .y_chroma_shift = 1,
142
    },
143

    
144
    /* JPEG YUV */
145
    [PIX_FMT_YUVJ420P] = {
146
        .name = "yuvj420p",
147
        .nb_channels = 3,
148
        .color_type = FF_COLOR_YUV_JPEG,
149
        .pixel_type = FF_PIXEL_PLANAR,
150
        .depth = 8,
151
        .x_chroma_shift = 1, .y_chroma_shift = 1,
152
    },
153
    [PIX_FMT_YUVJ422P] = {
154
        .name = "yuvj422p",
155
        .nb_channels = 3,
156
        .color_type = FF_COLOR_YUV_JPEG,
157
        .pixel_type = FF_PIXEL_PLANAR,
158
        .depth = 8,
159
        .x_chroma_shift = 1, .y_chroma_shift = 0,
160
    },
161
    [PIX_FMT_YUVJ444P] = {
162
        .name = "yuvj444p",
163
        .nb_channels = 3,
164
        .color_type = FF_COLOR_YUV_JPEG,
165
        .pixel_type = FF_PIXEL_PLANAR,
166
        .depth = 8,
167
        .x_chroma_shift = 0, .y_chroma_shift = 0,
168
    },
169
    [PIX_FMT_YUVJ440P] = {
170
        .name = "yuvj440p",
171
        .nb_channels = 3,
172
        .color_type = FF_COLOR_YUV_JPEG,
173
        .pixel_type = FF_PIXEL_PLANAR,
174
        .depth = 8,
175
        .x_chroma_shift = 0, .y_chroma_shift = 1,
176
    },
177

    
178
    /* RGB formats */
179
    [PIX_FMT_RGB24] = {
180
        .name = "rgb24",
181
        .nb_channels = 3,
182
        .color_type = FF_COLOR_RGB,
183
        .pixel_type = FF_PIXEL_PACKED,
184
        .depth = 8,
185
        .x_chroma_shift = 0, .y_chroma_shift = 0,
186
    },
187
    [PIX_FMT_BGR24] = {
188
        .name = "bgr24",
189
        .nb_channels = 3,
190
        .color_type = FF_COLOR_RGB,
191
        .pixel_type = FF_PIXEL_PACKED,
192
        .depth = 8,
193
        .x_chroma_shift = 0, .y_chroma_shift = 0,
194
    },
195
    [PIX_FMT_RGB32] = {
196
        .name = "rgb32",
197
        .nb_channels = 4, .is_alpha = 1,
198
        .color_type = FF_COLOR_RGB,
199
        .pixel_type = FF_PIXEL_PACKED,
200
        .depth = 8,
201
        .x_chroma_shift = 0, .y_chroma_shift = 0,
202
    },
203
    [PIX_FMT_RGB48BE] = {
204
        .name = "rgb48be",
205
        .nb_channels = 3,
206
        .color_type = FF_COLOR_RGB,
207
        .pixel_type = FF_PIXEL_PACKED,
208
        .depth = 16,
209
        .x_chroma_shift = 0, .y_chroma_shift = 0,
210
    },
211
    [PIX_FMT_RGB48LE] = {
212
        .name = "rgb48le",
213
        .nb_channels = 3,
214
        .color_type = FF_COLOR_RGB,
215
        .pixel_type = FF_PIXEL_PACKED,
216
        .depth = 16,
217
        .x_chroma_shift = 0, .y_chroma_shift = 0,
218
    },
219
    [PIX_FMT_RGB565] = {
220
        .name = "rgb565",
221
        .nb_channels = 3,
222
        .color_type = FF_COLOR_RGB,
223
        .pixel_type = FF_PIXEL_PACKED,
224
        .depth = 5,
225
        .x_chroma_shift = 0, .y_chroma_shift = 0,
226
    },
227
    [PIX_FMT_RGB555] = {
228
        .name = "rgb555",
229
        .nb_channels = 3,
230
        .color_type = FF_COLOR_RGB,
231
        .pixel_type = FF_PIXEL_PACKED,
232
        .depth = 5,
233
        .x_chroma_shift = 0, .y_chroma_shift = 0,
234
    },
235

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

    
273
    /* paletted formats */
274
    [PIX_FMT_PAL8] = {
275
        .name = "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_XVMC_MPEG2_MC] = {
282
        .name = "xvmcmc",
283
        .is_hwaccel = 1,
284
    },
285
    [PIX_FMT_XVMC_MPEG2_IDCT] = {
286
        .name = "xvmcidct",
287
        .is_hwaccel = 1,
288
    },
289
    [PIX_FMT_VDPAU_MPEG1] = {
290
        .name = "vdpau_mpeg1",
291
        .is_hwaccel = 1,
292
        .x_chroma_shift = 1, .y_chroma_shift = 1,
293
    },
294
    [PIX_FMT_VDPAU_MPEG2] = {
295
        .name = "vdpau_mpeg2",
296
        .is_hwaccel = 1,
297
        .x_chroma_shift = 1, .y_chroma_shift = 1,
298
    },
299
    [PIX_FMT_VDPAU_H264] = {
300
        .name = "vdpau_h264",
301
        .is_hwaccel = 1,
302
        .x_chroma_shift = 1, .y_chroma_shift = 1,
303
    },
304
    [PIX_FMT_VDPAU_WMV3] = {
305
        .name = "vdpau_wmv3",
306
        .is_hwaccel = 1,
307
        .x_chroma_shift = 1, .y_chroma_shift = 1,
308
    },
309
    [PIX_FMT_VDPAU_VC1] = {
310
        .name = "vdpau_vc1",
311
        .is_hwaccel = 1,
312
        .x_chroma_shift = 1, .y_chroma_shift = 1,
313
    },
314
    [PIX_FMT_UYYVYY411] = {
315
        .name = "uyyvyy411",
316
        .nb_channels = 1,
317
        .color_type = FF_COLOR_YUV,
318
        .pixel_type = FF_PIXEL_PACKED,
319
        .depth = 8,
320
        .x_chroma_shift = 2, .y_chroma_shift = 0,
321
    },
322
    [PIX_FMT_BGR32] = {
323
        .name = "bgr32",
324
        .nb_channels = 4, .is_alpha = 1,
325
        .color_type = FF_COLOR_RGB,
326
        .pixel_type = FF_PIXEL_PACKED,
327
        .depth = 8,
328
        .x_chroma_shift = 0, .y_chroma_shift = 0,
329
    },
330
    [PIX_FMT_BGR565] = {
331
        .name = "bgr565",
332
        .nb_channels = 3,
333
        .color_type = FF_COLOR_RGB,
334
        .pixel_type = FF_PIXEL_PACKED,
335
        .depth = 5,
336
        .x_chroma_shift = 0, .y_chroma_shift = 0,
337
    },
338
    [PIX_FMT_BGR555] = {
339
        .name = "bgr555",
340
        .nb_channels = 3,
341
        .color_type = FF_COLOR_RGB,
342
        .pixel_type = FF_PIXEL_PACKED,
343
        .depth = 5,
344
        .x_chroma_shift = 0, .y_chroma_shift = 0,
345
    },
346
    [PIX_FMT_RGB8] = {
347
        .name = "rgb8",
348
        .nb_channels = 1,
349
        .color_type = FF_COLOR_RGB,
350
        .pixel_type = FF_PIXEL_PACKED,
351
        .depth = 8,
352
        .x_chroma_shift = 0, .y_chroma_shift = 0,
353
    },
354
    [PIX_FMT_RGB4] = {
355
        .name = "rgb4",
356
        .nb_channels = 1,
357
        .color_type = FF_COLOR_RGB,
358
        .pixel_type = FF_PIXEL_PACKED,
359
        .depth = 4,
360
        .x_chroma_shift = 0, .y_chroma_shift = 0,
361
    },
362
    [PIX_FMT_RGB4_BYTE] = {
363
        .name = "rgb4_byte",
364
        .nb_channels = 1,
365
        .color_type = FF_COLOR_RGB,
366
        .pixel_type = FF_PIXEL_PACKED,
367
        .depth = 8,
368
        .x_chroma_shift = 0, .y_chroma_shift = 0,
369
    },
370
    [PIX_FMT_BGR8] = {
371
        .name = "bgr8",
372
        .nb_channels = 1,
373
        .color_type = FF_COLOR_RGB,
374
        .pixel_type = FF_PIXEL_PACKED,
375
        .depth = 8,
376
        .x_chroma_shift = 0, .y_chroma_shift = 0,
377
    },
378
    [PIX_FMT_BGR4] = {
379
        .name = "bgr4",
380
        .nb_channels = 1,
381
        .color_type = FF_COLOR_RGB,
382
        .pixel_type = FF_PIXEL_PACKED,
383
        .depth = 4,
384
        .x_chroma_shift = 0, .y_chroma_shift = 0,
385
    },
386
    [PIX_FMT_BGR4_BYTE] = {
387
        .name = "bgr4_byte",
388
        .nb_channels = 1,
389
        .color_type = FF_COLOR_RGB,
390
        .pixel_type = FF_PIXEL_PACKED,
391
        .depth = 8,
392
        .x_chroma_shift = 0, .y_chroma_shift = 0,
393
    },
394
    [PIX_FMT_NV12] = {
395
        .name = "nv12",
396
        .nb_channels = 2,
397
        .color_type = FF_COLOR_YUV,
398
        .pixel_type = FF_PIXEL_PLANAR,
399
        .depth = 8,
400
        .x_chroma_shift = 1, .y_chroma_shift = 1,
401
    },
402
    [PIX_FMT_NV21] = {
403
        .name = "nv12",
404
        .nb_channels = 2,
405
        .color_type = FF_COLOR_YUV,
406
        .pixel_type = FF_PIXEL_PLANAR,
407
        .depth = 8,
408
        .x_chroma_shift = 1, .y_chroma_shift = 1,
409
    },
410

    
411
    [PIX_FMT_BGR32_1] = {
412
        .name = "bgr32_1",
413
        .nb_channels = 4, .is_alpha = 1,
414
        .color_type = FF_COLOR_RGB,
415
        .pixel_type = FF_PIXEL_PACKED,
416
        .depth = 8,
417
        .x_chroma_shift = 0, .y_chroma_shift = 0,
418
    },
419
    [PIX_FMT_RGB32_1] = {
420
        .name = "rgb32_1",
421
        .nb_channels = 4, .is_alpha = 1,
422
        .color_type = FF_COLOR_RGB,
423
        .pixel_type = FF_PIXEL_PACKED,
424
        .depth = 8,
425
        .x_chroma_shift = 0, .y_chroma_shift = 0,
426
    },
427

    
428
    /* VA API formats */
429
    [PIX_FMT_VAAPI_MOCO] = {
430
        .name = "vaapi_moco",
431
        .is_hwaccel = 1,
432
        .x_chroma_shift = 1, .y_chroma_shift = 1,
433
    },
434
    [PIX_FMT_VAAPI_IDCT] = {
435
        .name = "vaapi_idct",
436
        .is_hwaccel = 1,
437
        .x_chroma_shift = 1, .y_chroma_shift = 1,
438
    },
439
    [PIX_FMT_VAAPI_VLD] = {
440
        .name = "vaapi_vld",
441
        .is_hwaccel = 1,
442
        .x_chroma_shift = 1, .y_chroma_shift = 1,
443
    },
444
};
445

    
446
void avcodec_get_chroma_sub_sample(int pix_fmt, int *h_shift, int *v_shift)
447
{
448
    *h_shift = pix_fmt_info[pix_fmt].x_chroma_shift;
449
    *v_shift = pix_fmt_info[pix_fmt].y_chroma_shift;
450
}
451

    
452
const char *avcodec_get_pix_fmt_name(int pix_fmt)
453
{
454
    if (pix_fmt < 0 || pix_fmt >= PIX_FMT_NB)
455
        return NULL;
456
    else
457
        return pix_fmt_info[pix_fmt].name;
458
}
459

    
460
enum PixelFormat avcodec_get_pix_fmt(const char* name)
461
{
462
    int i;
463

    
464
    for (i=0; i < PIX_FMT_NB; i++)
465
         if (!strcmp(pix_fmt_info[i].name, name))
466
             return i;
467
    return PIX_FMT_NONE;
468
}
469

    
470
void avcodec_pix_fmt_string (char *buf, int buf_size, int pix_fmt)
471
{
472
    /* print header */
473
    if (pix_fmt < 0)
474
        snprintf (buf, buf_size,
475
                  "name      " " nb_channels" " depth" " is_alpha"
476
            );
477
    else{
478
        PixFmtInfo info= pix_fmt_info[pix_fmt];
479

    
480
        char is_alpha_char= info.is_alpha ? 'y' : 'n';
481

    
482
        snprintf (buf, buf_size,
483
                  "%-10s" "      %1d     " "   %2d " "     %c   ",
484
                  info.name,
485
                  info.nb_channels,
486
                  info.depth,
487
                  is_alpha_char
488
            );
489
    }
490
}
491

    
492
int ff_is_hwaccel_pix_fmt(enum PixelFormat pix_fmt)
493
{
494
    return pix_fmt_info[pix_fmt].is_hwaccel;
495
}
496

    
497
int ff_set_systematic_pal(uint32_t pal[256], enum PixelFormat pix_fmt){
498
    int i;
499

    
500
    for(i=0; i<256; i++){
501
        int r,g,b;
502

    
503
        switch(pix_fmt) {
504
        case PIX_FMT_RGB8:
505
            r= (i>>5    )*36;
506
            g= ((i>>2)&7)*36;
507
            b= (i&3     )*85;
508
            break;
509
        case PIX_FMT_BGR8:
510
            b= (i>>6    )*85;
511
            g= ((i>>3)&7)*36;
512
            r= (i&7     )*36;
513
            break;
514
        case PIX_FMT_RGB4_BYTE:
515
            r= (i>>3    )*255;
516
            g= ((i>>1)&3)*85;
517
            b= (i&1     )*255;
518
            break;
519
        case PIX_FMT_BGR4_BYTE:
520
            b= (i>>3    )*255;
521
            g= ((i>>1)&3)*85;
522
            r= (i&1     )*255;
523
            break;
524
        case PIX_FMT_GRAY8:
525
            r=b=g= i;
526
            break;
527
        default:
528
            return -1;
529
        }
530
        pal[i] =  b + (g<<8) + (r<<16);
531
    }
532

    
533
    return 0;
534
}
535

    
536
int ff_fill_linesize(AVPicture *picture, int pix_fmt, int width)
537
{
538
    int w2;
539
    const PixFmtInfo *pinfo;
540

    
541
    memset(picture->linesize, 0, sizeof(picture->linesize));
542

    
543
    pinfo = &pix_fmt_info[pix_fmt];
544
    switch(pix_fmt) {
545
    case PIX_FMT_YUV420P:
546
    case PIX_FMT_YUV422P:
547
    case PIX_FMT_YUV444P:
548
    case PIX_FMT_YUV410P:
549
    case PIX_FMT_YUV411P:
550
    case PIX_FMT_YUV440P:
551
    case PIX_FMT_YUVJ420P:
552
    case PIX_FMT_YUVJ422P:
553
    case PIX_FMT_YUVJ444P:
554
    case PIX_FMT_YUVJ440P:
555
        w2 = (width + (1 << pinfo->x_chroma_shift) - 1) >> pinfo->x_chroma_shift;
556
        picture->linesize[0] = width;
557
        picture->linesize[1] = w2;
558
        picture->linesize[2] = w2;
559
        break;
560
    case PIX_FMT_YUVA420P:
561
        w2 = (width + (1 << pinfo->x_chroma_shift) - 1) >> pinfo->x_chroma_shift;
562
        picture->linesize[0] = width;
563
        picture->linesize[1] = w2;
564
        picture->linesize[2] = w2;
565
        picture->linesize[3] = width;
566
        break;
567
    case PIX_FMT_NV12:
568
    case PIX_FMT_NV21:
569
        w2 = (width + (1 << pinfo->x_chroma_shift) - 1) >> pinfo->x_chroma_shift;
570
        picture->linesize[0] = width;
571
        picture->linesize[1] = w2;
572
        break;
573
    case PIX_FMT_RGB24:
574
    case PIX_FMT_BGR24:
575
        picture->linesize[0] = width * 3;
576
        break;
577
    case PIX_FMT_RGB32:
578
    case PIX_FMT_BGR32:
579
    case PIX_FMT_RGB32_1:
580
    case PIX_FMT_BGR32_1:
581
        picture->linesize[0] = width * 4;
582
        break;
583
    case PIX_FMT_RGB48BE:
584
    case PIX_FMT_RGB48LE:
585
        picture->linesize[0] = width * 6;
586
        break;
587
    case PIX_FMT_GRAY16BE:
588
    case PIX_FMT_GRAY16LE:
589
    case PIX_FMT_BGR555:
590
    case PIX_FMT_BGR565:
591
    case PIX_FMT_RGB555:
592
    case PIX_FMT_RGB565:
593
    case PIX_FMT_YUYV422:
594
        picture->linesize[0] = width * 2;
595
        break;
596
    case PIX_FMT_UYVY422:
597
        picture->linesize[0] = width * 2;
598
        break;
599
    case PIX_FMT_UYYVYY411:
600
        picture->linesize[0] = width + width/2;
601
        break;
602
    case PIX_FMT_RGB4:
603
    case PIX_FMT_BGR4:
604
        picture->linesize[0] = width / 2;
605
        break;
606
    case PIX_FMT_MONOWHITE:
607
    case PIX_FMT_MONOBLACK:
608
        picture->linesize[0] = (width + 7) >> 3;
609
        break;
610
    case PIX_FMT_PAL8:
611
    case PIX_FMT_RGB8:
612
    case PIX_FMT_BGR8:
613
    case PIX_FMT_RGB4_BYTE:
614
    case PIX_FMT_BGR4_BYTE:
615
    case PIX_FMT_GRAY8:
616
        picture->linesize[0] = width;
617
        picture->linesize[1] = 4;
618
        break;
619
    default:
620
        return -1;
621
    }
622
    return 0;
623
}
624

    
625
int ff_fill_pointer(AVPicture *picture, uint8_t *ptr, int pix_fmt,
626
                    int height)
627
{
628
    int size, h2, size2;
629
    const PixFmtInfo *pinfo;
630

    
631
    pinfo = &pix_fmt_info[pix_fmt];
632
    size = picture->linesize[0] * height;
633
    switch(pix_fmt) {
634
    case PIX_FMT_YUV420P:
635
    case PIX_FMT_YUV422P:
636
    case PIX_FMT_YUV444P:
637
    case PIX_FMT_YUV410P:
638
    case PIX_FMT_YUV411P:
639
    case PIX_FMT_YUV440P:
640
    case PIX_FMT_YUVJ420P:
641
    case PIX_FMT_YUVJ422P:
642
    case PIX_FMT_YUVJ444P:
643
    case PIX_FMT_YUVJ440P:
644
        h2 = (height + (1 << pinfo->y_chroma_shift) - 1) >> pinfo->y_chroma_shift;
645
        size2 = picture->linesize[1] * h2;
646
        picture->data[0] = ptr;
647
        picture->data[1] = picture->data[0] + size;
648
        picture->data[2] = picture->data[1] + size2;
649
        picture->data[3] = NULL;
650
        return size + 2 * size2;
651
    case PIX_FMT_YUVA420P:
652
        h2 = (height + (1 << pinfo->y_chroma_shift) - 1) >> pinfo->y_chroma_shift;
653
        size2 = picture->linesize[1] * h2;
654
        picture->data[0] = ptr;
655
        picture->data[1] = picture->data[0] + size;
656
        picture->data[2] = picture->data[1] + size2;
657
        picture->data[3] = picture->data[1] + size2 + size2;
658
        return 2 * size + 2 * size2;
659
    case PIX_FMT_NV12:
660
    case PIX_FMT_NV21:
661
        h2 = (height + (1 << pinfo->y_chroma_shift) - 1) >> pinfo->y_chroma_shift;
662
        size2 = picture->linesize[1] * h2 * 2;
663
        picture->data[0] = ptr;
664
        picture->data[1] = picture->data[0] + size;
665
        picture->data[2] = NULL;
666
        picture->data[3] = NULL;
667
        return size + 2 * size2;
668
    case PIX_FMT_RGB24:
669
    case PIX_FMT_BGR24:
670
    case PIX_FMT_RGB32:
671
    case PIX_FMT_BGR32:
672
    case PIX_FMT_RGB32_1:
673
    case PIX_FMT_BGR32_1:
674
    case PIX_FMT_RGB48BE:
675
    case PIX_FMT_RGB48LE:
676
    case PIX_FMT_GRAY16BE:
677
    case PIX_FMT_GRAY16LE:
678
    case PIX_FMT_BGR555:
679
    case PIX_FMT_BGR565:
680
    case PIX_FMT_RGB555:
681
    case PIX_FMT_RGB565:
682
    case PIX_FMT_YUYV422:
683
    case PIX_FMT_UYVY422:
684
    case PIX_FMT_UYYVYY411:
685
    case PIX_FMT_RGB4:
686
    case PIX_FMT_BGR4:
687
    case PIX_FMT_MONOWHITE:
688
    case PIX_FMT_MONOBLACK:
689
        picture->data[0] = ptr;
690
        picture->data[1] = NULL;
691
        picture->data[2] = NULL;
692
        picture->data[3] = NULL;
693
        return size;
694
    case PIX_FMT_PAL8:
695
    case PIX_FMT_RGB8:
696
    case PIX_FMT_BGR8:
697
    case PIX_FMT_RGB4_BYTE:
698
    case PIX_FMT_BGR4_BYTE:
699
    case PIX_FMT_GRAY8:
700
        size2 = (size + 3) & ~3;
701
        picture->data[0] = ptr;
702
        picture->data[1] = ptr + size2; /* palette is stored here as 256 32 bit words */
703
        picture->data[2] = NULL;
704
        picture->data[3] = NULL;
705
        return size2 + 256 * 4;
706
    default:
707
        picture->data[0] = NULL;
708
        picture->data[1] = NULL;
709
        picture->data[2] = NULL;
710
        picture->data[3] = NULL;
711
        return -1;
712
    }
713
}
714

    
715
int avpicture_fill(AVPicture *picture, uint8_t *ptr,
716
                   int pix_fmt, int width, int height)
717
{
718

    
719
    if(avcodec_check_dimensions(NULL, width, height))
720
        return -1;
721

    
722
    if (ff_fill_linesize(picture, pix_fmt, width))
723
        return -1;
724

    
725
    return ff_fill_pointer(picture, ptr, pix_fmt, height);
726
}
727

    
728
int avpicture_layout(const AVPicture* src, int pix_fmt, int width, int height,
729
                     unsigned char *dest, int dest_size)
730
{
731
    const PixFmtInfo* pf = &pix_fmt_info[pix_fmt];
732
    int i, j, w, ow, h, oh, data_planes;
733
    const unsigned char* s;
734
    int size = avpicture_get_size(pix_fmt, width, height);
735

    
736
    if (size > dest_size || size < 0)
737
        return -1;
738

    
739
    if (pf->pixel_type == FF_PIXEL_PACKED || pf->pixel_type == FF_PIXEL_PALETTE) {
740
        if (pix_fmt == PIX_FMT_YUYV422 ||
741
            pix_fmt == PIX_FMT_UYVY422 ||
742
            pix_fmt == PIX_FMT_BGR565 ||
743
            pix_fmt == PIX_FMT_BGR555 ||
744
            pix_fmt == PIX_FMT_RGB565 ||
745
            pix_fmt == PIX_FMT_RGB555)
746
            w = width * 2;
747
        else if (pix_fmt == PIX_FMT_UYYVYY411)
748
          w = width + width/2;
749
        else if (pix_fmt == PIX_FMT_PAL8)
750
          w = width;
751
        else
752
          w = width * (pf->depth * pf->nb_channels / 8);
753

    
754
        data_planes = 1;
755
        h = height;
756
    } else {
757
        data_planes = pf->nb_channels;
758
        w = (width*pf->depth + 7)/8;
759
        h = height;
760
    }
761

    
762
    ow = w;
763
    oh = h;
764

    
765
    for (i=0; i<data_planes; i++) {
766
         if (i == 1) {
767
             w = width >> pf->x_chroma_shift;
768
             h = height >> pf->y_chroma_shift;
769
         } else if (i == 3) {
770
             w = ow;
771
             h = oh;
772
         }
773
         s = src->data[i];
774
         for(j=0; j<h; j++) {
775
             memcpy(dest, s, w);
776
             dest += w;
777
             s += src->linesize[i];
778
         }
779
    }
780

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

    
784
    return size;
785
}
786

    
787
int avpicture_get_size(int pix_fmt, int width, int height)
788
{
789
    AVPicture dummy_pict;
790
    return avpicture_fill(&dummy_pict, NULL, pix_fmt, width, height);
791
}
792

    
793
int avcodec_get_pix_fmt_loss(int dst_pix_fmt, int src_pix_fmt,
794
                             int has_alpha)
795
{
796
    const PixFmtInfo *pf, *ps;
797
    int loss;
798

    
799
    ps = &pix_fmt_info[src_pix_fmt];
800
    pf = &pix_fmt_info[dst_pix_fmt];
801

    
802
    /* compute loss */
803
    loss = 0;
804
    pf = &pix_fmt_info[dst_pix_fmt];
805
    if (pf->depth < ps->depth ||
806
        (dst_pix_fmt == PIX_FMT_RGB555 && src_pix_fmt == PIX_FMT_RGB565))
807
        loss |= FF_LOSS_DEPTH;
808
    if (pf->x_chroma_shift > ps->x_chroma_shift ||
809
        pf->y_chroma_shift > ps->y_chroma_shift)
810
        loss |= FF_LOSS_RESOLUTION;
811
    switch(pf->color_type) {
812
    case FF_COLOR_RGB:
813
        if (ps->color_type != FF_COLOR_RGB &&
814
            ps->color_type != FF_COLOR_GRAY)
815
            loss |= FF_LOSS_COLORSPACE;
816
        break;
817
    case FF_COLOR_GRAY:
818
        if (ps->color_type != FF_COLOR_GRAY)
819
            loss |= FF_LOSS_COLORSPACE;
820
        break;
821
    case FF_COLOR_YUV:
822
        if (ps->color_type != FF_COLOR_YUV)
823
            loss |= FF_LOSS_COLORSPACE;
824
        break;
825
    case FF_COLOR_YUV_JPEG:
826
        if (ps->color_type != FF_COLOR_YUV_JPEG &&
827
            ps->color_type != FF_COLOR_YUV &&
828
            ps->color_type != FF_COLOR_GRAY)
829
            loss |= FF_LOSS_COLORSPACE;
830
        break;
831
    default:
832
        /* fail safe test */
833
        if (ps->color_type != pf->color_type)
834
            loss |= FF_LOSS_COLORSPACE;
835
        break;
836
    }
837
    if (pf->color_type == FF_COLOR_GRAY &&
838
        ps->color_type != FF_COLOR_GRAY)
839
        loss |= FF_LOSS_CHROMA;
840
    if (!pf->is_alpha && (ps->is_alpha && has_alpha))
841
        loss |= FF_LOSS_ALPHA;
842
    if (pf->pixel_type == FF_PIXEL_PALETTE &&
843
        (ps->pixel_type != FF_PIXEL_PALETTE && ps->color_type != FF_COLOR_GRAY))
844
        loss |= FF_LOSS_COLORQUANT;
845
    return loss;
846
}
847

    
848
static int avg_bits_per_pixel(int pix_fmt)
849
{
850
    int bits;
851
    const PixFmtInfo *pf;
852

    
853
    pf = &pix_fmt_info[pix_fmt];
854
    switch(pf->pixel_type) {
855
    case FF_PIXEL_PACKED:
856
        switch(pix_fmt) {
857
        case PIX_FMT_YUYV422:
858
        case PIX_FMT_UYVY422:
859
        case PIX_FMT_RGB565:
860
        case PIX_FMT_RGB555:
861
        case PIX_FMT_BGR565:
862
        case PIX_FMT_BGR555:
863
            bits = 16;
864
            break;
865
        case PIX_FMT_UYYVYY411:
866
            bits = 12;
867
            break;
868
        default:
869
            bits = pf->depth * pf->nb_channels;
870
            break;
871
        }
872
        break;
873
    case FF_PIXEL_PLANAR:
874
        if (pf->x_chroma_shift == 0 && pf->y_chroma_shift == 0) {
875
            bits = pf->depth * pf->nb_channels;
876
        } else {
877
            bits = pf->depth + ((2 * pf->depth) >>
878
                                (pf->x_chroma_shift + pf->y_chroma_shift));
879
        }
880
        break;
881
    case FF_PIXEL_PALETTE:
882
        bits = 8;
883
        break;
884
    default:
885
        bits = -1;
886
        break;
887
    }
888
    return bits;
889
}
890

    
891
static int avcodec_find_best_pix_fmt1(int64_t pix_fmt_mask,
892
                                      int src_pix_fmt,
893
                                      int has_alpha,
894
                                      int loss_mask)
895
{
896
    int dist, i, loss, min_dist, dst_pix_fmt;
897

    
898
    /* find exact color match with smallest size */
899
    dst_pix_fmt = -1;
900
    min_dist = 0x7fffffff;
901
    for(i = 0;i < PIX_FMT_NB; i++) {
902
        if (pix_fmt_mask & (1ULL << i)) {
903
            loss = avcodec_get_pix_fmt_loss(i, src_pix_fmt, has_alpha) & loss_mask;
904
            if (loss == 0) {
905
                dist = avg_bits_per_pixel(i);
906
                if (dist < min_dist) {
907
                    min_dist = dist;
908
                    dst_pix_fmt = i;
909
                }
910
            }
911
        }
912
    }
913
    return dst_pix_fmt;
914
}
915

    
916
int avcodec_find_best_pix_fmt(int64_t pix_fmt_mask, int src_pix_fmt,
917
                              int has_alpha, int *loss_ptr)
918
{
919
    int dst_pix_fmt, loss_mask, i;
920
    static const int loss_mask_order[] = {
921
        ~0, /* no loss first */
922
        ~FF_LOSS_ALPHA,
923
        ~FF_LOSS_RESOLUTION,
924
        ~(FF_LOSS_COLORSPACE | FF_LOSS_RESOLUTION),
925
        ~FF_LOSS_COLORQUANT,
926
        ~FF_LOSS_DEPTH,
927
        0,
928
    };
929

    
930
    /* try with successive loss */
931
    i = 0;
932
    for(;;) {
933
        loss_mask = loss_mask_order[i++];
934
        dst_pix_fmt = avcodec_find_best_pix_fmt1(pix_fmt_mask, src_pix_fmt,
935
                                                 has_alpha, loss_mask);
936
        if (dst_pix_fmt >= 0)
937
            goto found;
938
        if (loss_mask == 0)
939
            break;
940
    }
941
    return -1;
942
 found:
943
    if (loss_ptr)
944
        *loss_ptr = avcodec_get_pix_fmt_loss(dst_pix_fmt, src_pix_fmt, has_alpha);
945
    return dst_pix_fmt;
946
}
947

    
948
void ff_img_copy_plane(uint8_t *dst, int dst_wrap,
949
                           const uint8_t *src, int src_wrap,
950
                           int width, int height)
951
{
952
    if((!dst) || (!src))
953
        return;
954
    for(;height > 0; height--) {
955
        memcpy(dst, src, width);
956
        dst += dst_wrap;
957
        src += src_wrap;
958
    }
959
}
960

    
961
int ff_get_plane_bytewidth(enum PixelFormat pix_fmt, int width, int plane)
962
{
963
    int bits;
964
    const PixFmtInfo *pf = &pix_fmt_info[pix_fmt];
965

    
966
    pf = &pix_fmt_info[pix_fmt];
967
    switch(pf->pixel_type) {
968
    case FF_PIXEL_PACKED:
969
        switch(pix_fmt) {
970
        case PIX_FMT_YUYV422:
971
        case PIX_FMT_UYVY422:
972
        case PIX_FMT_RGB565:
973
        case PIX_FMT_RGB555:
974
        case PIX_FMT_BGR565:
975
        case PIX_FMT_BGR555:
976
            bits = 16;
977
            break;
978
        case PIX_FMT_UYYVYY411:
979
            bits = 12;
980
            break;
981
        default:
982
            bits = pf->depth * pf->nb_channels;
983
            break;
984
        }
985
        return (width * bits + 7) >> 3;
986
        break;
987
    case FF_PIXEL_PLANAR:
988
            if (plane == 1 || plane == 2)
989
                width= -((-width)>>pf->x_chroma_shift);
990

    
991
            return (width * pf->depth + 7) >> 3;
992
        break;
993
    case FF_PIXEL_PALETTE:
994
        if (plane == 0)
995
            return width;
996
        break;
997
    }
998

    
999
    return -1;
1000
}
1001

    
1002
void av_picture_copy(AVPicture *dst, const AVPicture *src,
1003
              int pix_fmt, int width, int height)
1004
{
1005
    int i;
1006
    const PixFmtInfo *pf = &pix_fmt_info[pix_fmt];
1007

    
1008
    pf = &pix_fmt_info[pix_fmt];
1009
    switch(pf->pixel_type) {
1010
    case FF_PIXEL_PACKED:
1011
    case FF_PIXEL_PLANAR:
1012
        for(i = 0; i < pf->nb_channels; i++) {
1013
            int h;
1014
            int bwidth = ff_get_plane_bytewidth(pix_fmt, width, i);
1015
            h = height;
1016
            if (i == 1 || i == 2) {
1017
                h= -((-height)>>pf->y_chroma_shift);
1018
            }
1019
            ff_img_copy_plane(dst->data[i], dst->linesize[i],
1020
                           src->data[i], src->linesize[i],
1021
                           bwidth, h);
1022
        }
1023
        break;
1024
    case FF_PIXEL_PALETTE:
1025
        ff_img_copy_plane(dst->data[0], dst->linesize[0],
1026
                       src->data[0], src->linesize[0],
1027
                       width, height);
1028
        /* copy the palette */
1029
        ff_img_copy_plane(dst->data[1], dst->linesize[1],
1030
                       src->data[1], src->linesize[1],
1031
                       4, 256);
1032
        break;
1033
    }
1034
}
1035

    
1036
/* XXX: totally non optimized */
1037

    
1038
static void yuyv422_to_yuv420p(AVPicture *dst, const AVPicture *src,
1039
                              int width, int height)
1040
{
1041
    const uint8_t *p, *p1;
1042
    uint8_t *lum, *cr, *cb, *lum1, *cr1, *cb1;
1043
    int w;
1044

    
1045
    p1 = src->data[0];
1046
    lum1 = dst->data[0];
1047
    cb1 = dst->data[1];
1048
    cr1 = dst->data[2];
1049

    
1050
    for(;height >= 1; height -= 2) {
1051
        p = p1;
1052
        lum = lum1;
1053
        cb = cb1;
1054
        cr = cr1;
1055
        for(w = width; w >= 2; w -= 2) {
1056
            lum[0] = p[0];
1057
            cb[0] = p[1];
1058
            lum[1] = p[2];
1059
            cr[0] = p[3];
1060
            p += 4;
1061
            lum += 2;
1062
            cb++;
1063
            cr++;
1064
        }
1065
        if (w) {
1066
            lum[0] = p[0];
1067
            cb[0] = p[1];
1068
            cr[0] = p[3];
1069
            cb++;
1070
            cr++;
1071
        }
1072
        p1 += src->linesize[0];
1073
        lum1 += dst->linesize[0];
1074
        if (height>1) {
1075
            p = p1;
1076
            lum = lum1;
1077
            for(w = width; w >= 2; w -= 2) {
1078
                lum[0] = p[0];
1079
                lum[1] = p[2];
1080
                p += 4;
1081
                lum += 2;
1082
            }
1083
            if (w) {
1084
                lum[0] = p[0];
1085
            }
1086
            p1 += src->linesize[0];
1087
            lum1 += dst->linesize[0];
1088
        }
1089
        cb1 += dst->linesize[1];
1090
        cr1 += dst->linesize[2];
1091
    }
1092
}
1093

    
1094
static void uyvy422_to_yuv420p(AVPicture *dst, const AVPicture *src,
1095
                              int width, int height)
1096
{
1097
    const uint8_t *p, *p1;
1098
    uint8_t *lum, *cr, *cb, *lum1, *cr1, *cb1;
1099
    int w;
1100

    
1101
    p1 = src->data[0];
1102

    
1103
    lum1 = dst->data[0];
1104
    cb1 = dst->data[1];
1105
    cr1 = dst->data[2];
1106

    
1107
    for(;height >= 1; height -= 2) {
1108
        p = p1;
1109
        lum = lum1;
1110
        cb = cb1;
1111
        cr = cr1;
1112
        for(w = width; w >= 2; w -= 2) {
1113
            lum[0] = p[1];
1114
            cb[0] = p[0];
1115
            lum[1] = p[3];
1116
            cr[0] = p[2];
1117
            p += 4;
1118
            lum += 2;
1119
            cb++;
1120
            cr++;
1121
        }
1122
        if (w) {
1123
            lum[0] = p[1];
1124
            cb[0] = p[0];
1125
            cr[0] = p[2];
1126
            cb++;
1127
            cr++;
1128
        }
1129
        p1 += src->linesize[0];
1130
        lum1 += dst->linesize[0];
1131
        if (height>1) {
1132
            p = p1;
1133
            lum = lum1;
1134
            for(w = width; w >= 2; w -= 2) {
1135
                lum[0] = p[1];
1136
                lum[1] = p[3];
1137
                p += 4;
1138
                lum += 2;
1139
            }
1140
            if (w) {
1141
                lum[0] = p[1];
1142
            }
1143
            p1 += src->linesize[0];
1144
            lum1 += dst->linesize[0];
1145
        }
1146
        cb1 += dst->linesize[1];
1147
        cr1 += dst->linesize[2];
1148
    }
1149
}
1150

    
1151

    
1152
static void uyvy422_to_yuv422p(AVPicture *dst, const AVPicture *src,
1153
                              int width, int height)
1154
{
1155
    const uint8_t *p, *p1;
1156
    uint8_t *lum, *cr, *cb, *lum1, *cr1, *cb1;
1157
    int w;
1158

    
1159
    p1 = src->data[0];
1160
    lum1 = dst->data[0];
1161
    cb1 = dst->data[1];
1162
    cr1 = dst->data[2];
1163
    for(;height > 0; height--) {
1164
        p = p1;
1165
        lum = lum1;
1166
        cb = cb1;
1167
        cr = cr1;
1168
        for(w = width; w >= 2; w -= 2) {
1169
            lum[0] = p[1];
1170
            cb[0] = p[0];
1171
            lum[1] = p[3];
1172
            cr[0] = p[2];
1173
            p += 4;
1174
            lum += 2;
1175
            cb++;
1176
            cr++;
1177
        }
1178
        p1 += src->linesize[0];
1179
        lum1 += dst->linesize[0];
1180
        cb1 += dst->linesize[1];
1181
        cr1 += dst->linesize[2];
1182
    }
1183
}
1184

    
1185

    
1186
static void yuyv422_to_yuv422p(AVPicture *dst, const AVPicture *src,
1187
                              int width, int height)
1188
{
1189
    const uint8_t *p, *p1;
1190
    uint8_t *lum, *cr, *cb, *lum1, *cr1, *cb1;
1191
    int w;
1192

    
1193
    p1 = src->data[0];
1194
    lum1 = dst->data[0];
1195
    cb1 = dst->data[1];
1196
    cr1 = dst->data[2];
1197
    for(;height > 0; height--) {
1198
        p = p1;
1199
        lum = lum1;
1200
        cb = cb1;
1201
        cr = cr1;
1202
        for(w = width; w >= 2; w -= 2) {
1203
            lum[0] = p[0];
1204
            cb[0] = p[1];
1205
            lum[1] = p[2];
1206
            cr[0] = p[3];
1207
            p += 4;
1208
            lum += 2;
1209
            cb++;
1210
            cr++;
1211
        }
1212
        p1 += src->linesize[0];
1213
        lum1 += dst->linesize[0];
1214
        cb1 += dst->linesize[1];
1215
        cr1 += dst->linesize[2];
1216
    }
1217
}
1218

    
1219
static void yuv422p_to_yuyv422(AVPicture *dst, const AVPicture *src,
1220
                              int width, int height)
1221
{
1222
    uint8_t *p, *p1;
1223
    const uint8_t *lum, *cr, *cb, *lum1, *cr1, *cb1;
1224
    int w;
1225

    
1226
    p1 = dst->data[0];
1227
    lum1 = src->data[0];
1228
    cb1 = src->data[1];
1229
    cr1 = src->data[2];
1230
    for(;height > 0; height--) {
1231
        p = p1;
1232
        lum = lum1;
1233
        cb = cb1;
1234
        cr = cr1;
1235
        for(w = width; w >= 2; w -= 2) {
1236
            p[0] = lum[0];
1237
            p[1] = cb[0];
1238
            p[2] = lum[1];
1239
            p[3] = cr[0];
1240
            p += 4;
1241
            lum += 2;
1242
            cb++;
1243
            cr++;
1244
        }
1245
        p1 += dst->linesize[0];
1246
        lum1 += src->linesize[0];
1247
        cb1 += src->linesize[1];
1248
        cr1 += src->linesize[2];
1249
    }
1250
}
1251

    
1252
static void yuv422p_to_uyvy422(AVPicture *dst, const AVPicture *src,
1253
                              int width, int height)
1254
{
1255
    uint8_t *p, *p1;
1256
    const uint8_t *lum, *cr, *cb, *lum1, *cr1, *cb1;
1257
    int w;
1258

    
1259
    p1 = dst->data[0];
1260
    lum1 = src->data[0];
1261
    cb1 = src->data[1];
1262
    cr1 = src->data[2];
1263
    for(;height > 0; height--) {
1264
        p = p1;
1265
        lum = lum1;
1266
        cb = cb1;
1267
        cr = cr1;
1268
        for(w = width; w >= 2; w -= 2) {
1269
            p[1] = lum[0];
1270
            p[0] = cb[0];
1271
            p[3] = lum[1];
1272
            p[2] = cr[0];
1273
            p += 4;
1274
            lum += 2;
1275
            cb++;
1276
            cr++;
1277
        }
1278
        p1 += dst->linesize[0];
1279
        lum1 += src->linesize[0];
1280
        cb1 += src->linesize[1];
1281
        cr1 += src->linesize[2];
1282
    }
1283
}
1284

    
1285
static void uyyvyy411_to_yuv411p(AVPicture *dst, const AVPicture *src,
1286
                              int width, int height)
1287
{
1288
    const uint8_t *p, *p1;
1289
    uint8_t *lum, *cr, *cb, *lum1, *cr1, *cb1;
1290
    int w;
1291

    
1292
    p1 = src->data[0];
1293
    lum1 = dst->data[0];
1294
    cb1 = dst->data[1];
1295
    cr1 = dst->data[2];
1296
    for(;height > 0; height--) {
1297
        p = p1;
1298
        lum = lum1;
1299
        cb = cb1;
1300
        cr = cr1;
1301
        for(w = width; w >= 4; w -= 4) {
1302
            cb[0] = p[0];
1303
            lum[0] = p[1];
1304
            lum[1] = p[2];
1305
            cr[0] = p[3];
1306
            lum[2] = p[4];
1307
            lum[3] = p[5];
1308
            p += 6;
1309
            lum += 4;
1310
            cb++;
1311
            cr++;
1312
        }
1313
        p1 += src->linesize[0];
1314
        lum1 += dst->linesize[0];
1315
        cb1 += dst->linesize[1];
1316
        cr1 += dst->linesize[2];
1317
    }
1318
}
1319

    
1320

    
1321
static void yuv420p_to_yuyv422(AVPicture *dst, const AVPicture *src,
1322
                              int width, int height)
1323
{
1324
    int w, h;
1325
    uint8_t *line1, *line2, *linesrc = dst->data[0];
1326
    uint8_t *lum1, *lum2, *lumsrc = src->data[0];
1327
    uint8_t *cb1, *cb2 = src->data[1];
1328
    uint8_t *cr1, *cr2 = src->data[2];
1329

    
1330
    for(h = height / 2; h--;) {
1331
        line1 = linesrc;
1332
        line2 = linesrc + dst->linesize[0];
1333

    
1334
        lum1 = lumsrc;
1335
        lum2 = lumsrc + src->linesize[0];
1336

    
1337
        cb1 = cb2;
1338
        cr1 = cr2;
1339

    
1340
        for(w = width / 2; w--;) {
1341
                *line1++ = *lum1++; *line2++ = *lum2++;
1342
                *line1++ =          *line2++ = *cb1++;
1343
                *line1++ = *lum1++; *line2++ = *lum2++;
1344
                *line1++ =          *line2++ = *cr1++;
1345
        }
1346

    
1347
        linesrc += dst->linesize[0] * 2;
1348
        lumsrc += src->linesize[0] * 2;
1349
        cb2 += src->linesize[1];
1350
        cr2 += src->linesize[2];
1351
    }
1352
}
1353

    
1354
static void yuv420p_to_uyvy422(AVPicture *dst, const AVPicture *src,
1355
                              int width, int height)
1356
{
1357
    int w, h;
1358
    uint8_t *line1, *line2, *linesrc = dst->data[0];
1359
    uint8_t *lum1, *lum2, *lumsrc = src->data[0];
1360
    uint8_t *cb1, *cb2 = src->data[1];
1361
    uint8_t *cr1, *cr2 = src->data[2];
1362

    
1363
    for(h = height / 2; h--;) {
1364
        line1 = linesrc;
1365
        line2 = linesrc + dst->linesize[0];
1366

    
1367
        lum1 = lumsrc;
1368
        lum2 = lumsrc + src->linesize[0];
1369

    
1370
        cb1 = cb2;
1371
        cr1 = cr2;
1372

    
1373
        for(w = width / 2; w--;) {
1374
                *line1++ =          *line2++ = *cb1++;
1375
                *line1++ = *lum1++; *line2++ = *lum2++;
1376
                *line1++ =          *line2++ = *cr1++;
1377
                *line1++ = *lum1++; *line2++ = *lum2++;
1378
        }
1379

    
1380
        linesrc += dst->linesize[0] * 2;
1381
        lumsrc += src->linesize[0] * 2;
1382
        cb2 += src->linesize[1];
1383
        cr2 += src->linesize[2];
1384
    }
1385
}
1386

    
1387
/* 2x2 -> 1x1 */
1388
void ff_shrink22(uint8_t *dst, int dst_wrap,
1389
                     const uint8_t *src, int src_wrap,
1390
                     int width, int height)
1391
{
1392
    int w;
1393
    const uint8_t *s1, *s2;
1394
    uint8_t *d;
1395

    
1396
    for(;height > 0; height--) {
1397
        s1 = src;
1398
        s2 = s1 + src_wrap;
1399
        d = dst;
1400
        for(w = width;w >= 4; w-=4) {
1401
            d[0] = (s1[0] + s1[1] + s2[0] + s2[1] + 2) >> 2;
1402
            d[1] = (s1[2] + s1[3] + s2[2] + s2[3] + 2) >> 2;
1403
            d[2] = (s1[4] + s1[5] + s2[4] + s2[5] + 2) >> 2;
1404
            d[3] = (s1[6] + s1[7] + s2[6] + s2[7] + 2) >> 2;
1405
            s1 += 8;
1406
            s2 += 8;
1407
            d += 4;
1408
        }
1409
        for(;w > 0; w--) {
1410
            d[0] = (s1[0] + s1[1] + s2[0] + s2[1] + 2) >> 2;
1411
            s1 += 2;
1412
            s2 += 2;
1413
            d++;
1414
        }
1415
        src += 2 * src_wrap;
1416
        dst += dst_wrap;
1417
    }
1418
}
1419

    
1420
/* 4x4 -> 1x1 */
1421
void ff_shrink44(uint8_t *dst, int dst_wrap,
1422
                     const uint8_t *src, int src_wrap,
1423
                     int width, int height)
1424
{
1425
    int w;
1426
    const uint8_t *s1, *s2, *s3, *s4;
1427
    uint8_t *d;
1428

    
1429
    for(;height > 0; height--) {
1430
        s1 = src;
1431
        s2 = s1 + src_wrap;
1432
        s3 = s2 + src_wrap;
1433
        s4 = s3 + src_wrap;
1434
        d = dst;
1435
        for(w = width;w > 0; w--) {
1436
            d[0] = (s1[0] + s1[1] + s1[2] + s1[3] +
1437
                    s2[0] + s2[1] + s2[2] + s2[3] +
1438
                    s3[0] + s3[1] + s3[2] + s3[3] +
1439
                    s4[0] + s4[1] + s4[2] + s4[3] + 8) >> 4;
1440
            s1 += 4;
1441
            s2 += 4;
1442
            s3 += 4;
1443
            s4 += 4;
1444
            d++;
1445
        }
1446
        src += 4 * src_wrap;
1447
        dst += dst_wrap;
1448
    }
1449
}
1450

    
1451
/* 8x8 -> 1x1 */
1452
void ff_shrink88(uint8_t *dst, int dst_wrap,
1453
                     const uint8_t *src, int src_wrap,
1454
                     int width, int height)
1455
{
1456
    int w, i;
1457

    
1458
    for(;height > 0; height--) {
1459
        for(w = width;w > 0; w--) {
1460
            int tmp=0;
1461
            for(i=0; i<8; i++){
1462
                tmp += src[0] + src[1] + src[2] + src[3] + src[4] + src[5] + src[6] + src[7];
1463
                src += src_wrap;
1464
            }
1465
            *(dst++) = (tmp + 32)>>6;
1466
            src += 8 - 8*src_wrap;
1467
        }
1468
        src += 8*src_wrap - 8*width;
1469
        dst += dst_wrap - width;
1470
    }
1471
}
1472

    
1473
/* XXX: add jpeg quantize code */
1474

    
1475
#define TRANSP_INDEX (6*6*6)
1476

    
1477
/* this is maybe slow, but allows for extensions */
1478
static inline unsigned char gif_clut_index(uint8_t r, uint8_t g, uint8_t b)
1479
{
1480
    return (((r) / 47) % 6) * 6 * 6 + (((g) / 47) % 6) * 6 + (((b) / 47) % 6);
1481
}
1482

    
1483
static void build_rgb_palette(uint8_t *palette, int has_alpha)
1484
{
1485
    uint32_t *pal;
1486
    static const uint8_t pal_value[6] = { 0x00, 0x33, 0x66, 0x99, 0xcc, 0xff };
1487
    int i, r, g, b;
1488

    
1489
    pal = (uint32_t *)palette;
1490
    i = 0;
1491
    for(r = 0; r < 6; r++) {
1492
        for(g = 0; g < 6; g++) {
1493
            for(b = 0; b < 6; b++) {
1494
                pal[i++] = (0xff << 24) | (pal_value[r] << 16) |
1495
                    (pal_value[g] << 8) | pal_value[b];
1496
            }
1497
        }
1498
    }
1499
    if (has_alpha)
1500
        pal[i++] = 0;
1501
    while (i < 256)
1502
        pal[i++] = 0xff000000;
1503
}
1504

    
1505
/* copy bit n to bits 0 ... n - 1 */
1506
static inline unsigned int bitcopy_n(unsigned int a, int n)
1507
{
1508
    int mask;
1509
    mask = (1 << n) - 1;
1510
    return (a & (0xff & ~mask)) | ((-((a >> n) & 1)) & mask);
1511
}
1512

    
1513
/* rgb555 handling */
1514

    
1515
#define RGB_NAME rgb555
1516

    
1517
#define RGB_IN(r, g, b, s)\
1518
{\
1519
    unsigned int v = ((const uint16_t *)(s))[0];\
1520
    r = bitcopy_n(v >> (10 - 3), 3);\
1521
    g = bitcopy_n(v >> (5 - 3), 3);\
1522
    b = bitcopy_n(v << 3, 3);\
1523
}
1524

    
1525

    
1526
#define RGB_OUT(d, r, g, b)\
1527
{\
1528
    ((uint16_t *)(d))[0] = ((r >> 3) << 10) | ((g >> 3) << 5) | (b >> 3);\
1529
}
1530

    
1531
#define BPP 2
1532

    
1533
#include "imgconvert_template.c"
1534

    
1535
/* rgb565 handling */
1536

    
1537
#define RGB_NAME rgb565
1538

    
1539
#define RGB_IN(r, g, b, s)\
1540
{\
1541
    unsigned int v = ((const uint16_t *)(s))[0];\
1542
    r = bitcopy_n(v >> (11 - 3), 3);\
1543
    g = bitcopy_n(v >> (5 - 2), 2);\
1544
    b = bitcopy_n(v << 3, 3);\
1545
}
1546

    
1547
#define RGB_OUT(d, r, g, b)\
1548
{\
1549
    ((uint16_t *)(d))[0] = ((r >> 3) << 11) | ((g >> 2) << 5) | (b >> 3);\
1550
}
1551

    
1552
#define BPP 2
1553

    
1554
#include "imgconvert_template.c"
1555

    
1556
/* bgr24 handling */
1557

    
1558
#define RGB_NAME bgr24
1559

    
1560
#define RGB_IN(r, g, b, s)\
1561
{\
1562
    b = (s)[0];\
1563
    g = (s)[1];\
1564
    r = (s)[2];\
1565
}
1566

    
1567
#define RGB_OUT(d, r, g, b)\
1568
{\
1569
    (d)[0] = b;\
1570
    (d)[1] = g;\
1571
    (d)[2] = r;\
1572
}
1573

    
1574
#define BPP 3
1575

    
1576
#include "imgconvert_template.c"
1577

    
1578
#undef RGB_IN
1579
#undef RGB_OUT
1580
#undef BPP
1581

    
1582
/* rgb24 handling */
1583

    
1584
#define RGB_NAME rgb24
1585
#define FMT_RGB24
1586

    
1587
#define RGB_IN(r, g, b, s)\
1588
{\
1589
    r = (s)[0];\
1590
    g = (s)[1];\
1591
    b = (s)[2];\
1592
}
1593

    
1594
#define RGB_OUT(d, r, g, b)\
1595
{\
1596
    (d)[0] = r;\
1597
    (d)[1] = g;\
1598
    (d)[2] = b;\
1599
}
1600

    
1601
#define BPP 3
1602

    
1603
#include "imgconvert_template.c"
1604

    
1605
/* rgb32 handling */
1606

    
1607
#define RGB_NAME rgb32
1608
#define FMT_RGB32
1609

    
1610
#define RGB_IN(r, g, b, s)\
1611
{\
1612
    unsigned int v = ((const uint32_t *)(s))[0];\
1613
    r = (v >> 16) & 0xff;\
1614
    g = (v >> 8) & 0xff;\
1615
    b = v & 0xff;\
1616
}
1617

    
1618
#define RGBA_IN(r, g, b, a, s)\
1619
{\
1620
    unsigned int v = ((const uint32_t *)(s))[0];\
1621
    a = (v >> 24) & 0xff;\
1622
    r = (v >> 16) & 0xff;\
1623
    g = (v >> 8) & 0xff;\
1624
    b = v & 0xff;\
1625
}
1626

    
1627
#define RGBA_OUT(d, r, g, b, a)\
1628
{\
1629
    ((uint32_t *)(d))[0] = (a << 24) | (r << 16) | (g << 8) | b;\
1630
}
1631

    
1632
#define BPP 4
1633

    
1634
#include "imgconvert_template.c"
1635

    
1636
static void mono_to_gray(AVPicture *dst, const AVPicture *src,
1637
                         int width, int height, int xor_mask)
1638
{
1639
    const unsigned char *p;
1640
    unsigned char *q;
1641
    int v, dst_wrap, src_wrap;
1642
    int y, w;
1643

    
1644
    p = src->data[0];
1645
    src_wrap = src->linesize[0] - ((width + 7) >> 3);
1646

    
1647
    q = dst->data[0];
1648
    dst_wrap = dst->linesize[0] - width;
1649
    for(y=0;y<height;y++) {
1650
        w = width;
1651
        while (w >= 8) {
1652
            v = *p++ ^ xor_mask;
1653
            q[0] = -(v >> 7);
1654
            q[1] = -((v >> 6) & 1);
1655
            q[2] = -((v >> 5) & 1);
1656
            q[3] = -((v >> 4) & 1);
1657
            q[4] = -((v >> 3) & 1);
1658
            q[5] = -((v >> 2) & 1);
1659
            q[6] = -((v >> 1) & 1);
1660
            q[7] = -((v >> 0) & 1);
1661
            w -= 8;
1662
            q += 8;
1663
        }
1664
        if (w > 0) {
1665
            v = *p++ ^ xor_mask;
1666
            do {
1667
                q[0] = -((v >> 7) & 1);
1668
                q++;
1669
                v <<= 1;
1670
            } while (--w);
1671
        }
1672
        p += src_wrap;
1673
        q += dst_wrap;
1674
    }
1675
}
1676

    
1677
static void monowhite_to_gray(AVPicture *dst, const AVPicture *src,
1678
                               int width, int height)
1679
{
1680
    mono_to_gray(dst, src, width, height, 0xff);
1681
}
1682

    
1683
static void monoblack_to_gray(AVPicture *dst, const AVPicture *src,
1684
                               int width, int height)
1685
{
1686
    mono_to_gray(dst, src, width, height, 0x00);
1687
}
1688

    
1689
static void gray_to_mono(AVPicture *dst, const AVPicture *src,
1690
                         int width, int height, int xor_mask)
1691
{
1692
    int n;
1693
    const uint8_t *s;
1694
    uint8_t *d;
1695
    int j, b, v, n1, src_wrap, dst_wrap, y;
1696

    
1697
    s = src->data[0];
1698
    src_wrap = src->linesize[0] - width;
1699

    
1700
    d = dst->data[0];
1701
    dst_wrap = dst->linesize[0] - ((width + 7) >> 3);
1702

    
1703
    for(y=0;y<height;y++) {
1704
        n = width;
1705
        while (n >= 8) {
1706
            v = 0;
1707
            for(j=0;j<8;j++) {
1708
                b = s[0];
1709
                s++;
1710
                v = (v << 1) | (b >> 7);
1711
            }
1712
            d[0] = v ^ xor_mask;
1713
            d++;
1714
            n -= 8;
1715
        }
1716
        if (n > 0) {
1717
            n1 = n;
1718
            v = 0;
1719
            while (n > 0) {
1720
                b = s[0];
1721
                s++;
1722
                v = (v << 1) | (b >> 7);
1723
                n--;
1724
            }
1725
            d[0] = (v << (8 - (n1 & 7))) ^ xor_mask;
1726
            d++;
1727
        }
1728
        s += src_wrap;
1729
        d += dst_wrap;
1730
    }
1731
}
1732

    
1733
static void gray_to_monowhite(AVPicture *dst, const AVPicture *src,
1734
                              int width, int height)
1735
{
1736
    gray_to_mono(dst, src, width, height, 0xff);
1737
}
1738

    
1739
static void gray_to_monoblack(AVPicture *dst, const AVPicture *src,
1740
                              int width, int height)
1741
{
1742
    gray_to_mono(dst, src, width, height, 0x00);
1743
}
1744

    
1745
static void gray_to_gray16(AVPicture *dst, const AVPicture *src,
1746
                              int width, int height)
1747
{
1748
    int x, y, src_wrap, dst_wrap;
1749
    uint8_t *s, *d;
1750
    s = src->data[0];
1751
    src_wrap = src->linesize[0] - width;
1752
    d = dst->data[0];
1753
    dst_wrap = dst->linesize[0] - width * 2;
1754
    for(y=0; y<height; y++){
1755
        for(x=0; x<width; x++){
1756
            *d++ = *s;
1757
            *d++ = *s++;
1758
        }
1759
        s += src_wrap;
1760
        d += dst_wrap;
1761
    }
1762
}
1763

    
1764
static void gray16_to_gray(AVPicture *dst, const AVPicture *src,
1765
                              int width, int height)
1766
{
1767
    int x, y, src_wrap, dst_wrap;
1768
    uint8_t *s, *d;
1769
    s = src->data[0];
1770
    src_wrap = src->linesize[0] - width * 2;
1771
    d = dst->data[0];
1772
    dst_wrap = dst->linesize[0] - width;
1773
    for(y=0; y<height; y++){
1774
        for(x=0; x<width; x++){
1775
            *d++ = *s;
1776
            s += 2;
1777
        }
1778
        s += src_wrap;
1779
        d += dst_wrap;
1780
    }
1781
}
1782

    
1783
static void gray16be_to_gray(AVPicture *dst, const AVPicture *src,
1784
                              int width, int height)
1785
{
1786
    gray16_to_gray(dst, src, width, height);
1787
}
1788

    
1789
static void gray16le_to_gray(AVPicture *dst, const AVPicture *src,
1790
                              int width, int height)
1791
{
1792
    AVPicture tmpsrc = *src;
1793
    tmpsrc.data[0]++;
1794
    gray16_to_gray(dst, &tmpsrc, width, height);
1795
}
1796

    
1797
static void gray16_to_gray16(AVPicture *dst, const AVPicture *src,
1798
                              int width, int height)
1799
{
1800
    int x, y, src_wrap, dst_wrap;
1801
    uint16_t *s, *d;
1802
    s = (uint16_t*)src->data[0];
1803
    src_wrap = (src->linesize[0] - width * 2)/2;
1804
    d = (uint16_t*)dst->data[0];
1805
    dst_wrap = (dst->linesize[0] - width * 2)/2;
1806
    for(y=0; y<height; y++){
1807
        for(x=0; x<width; x++){
1808
            *d++ = bswap_16(*s++);
1809
        }
1810
        s += src_wrap;
1811
        d += dst_wrap;
1812
    }
1813
}
1814

    
1815

    
1816
typedef struct ConvertEntry {
1817
    void (*convert)(AVPicture *dst,
1818
                    const AVPicture *src, int width, int height);
1819
} ConvertEntry;
1820

    
1821
/* Add each new conversion function in this table. In order to be able
1822
   to convert from any format to any format, the following constraints
1823
   must be satisfied:
1824

1825
   - all FF_COLOR_RGB formats must convert to and from PIX_FMT_RGB24
1826

1827
   - all FF_COLOR_GRAY formats must convert to and from PIX_FMT_GRAY8
1828

1829
   - all FF_COLOR_RGB formats with alpha must convert to and from PIX_FMT_RGB32
1830

1831
   - PIX_FMT_YUV444P and PIX_FMT_YUVJ444P must convert to and from
1832
     PIX_FMT_RGB24.
1833

1834
   - PIX_FMT_422 must convert to and from PIX_FMT_422P.
1835

1836
   The other conversion functions are just optimizations for common cases.
1837
*/
1838
static const ConvertEntry convert_table[PIX_FMT_NB][PIX_FMT_NB] = {
1839
    [PIX_FMT_YUV420P] = {
1840
        [PIX_FMT_YUYV422] = {
1841
            .convert = yuv420p_to_yuyv422,
1842
        },
1843
        [PIX_FMT_RGB555] = {
1844
            .convert = yuv420p_to_rgb555
1845
        },
1846
        [PIX_FMT_RGB565] = {
1847
            .convert = yuv420p_to_rgb565
1848
        },
1849
        [PIX_FMT_BGR24] = {
1850
            .convert = yuv420p_to_bgr24
1851
        },
1852
        [PIX_FMT_RGB24] = {
1853
            .convert = yuv420p_to_rgb24
1854
        },
1855
        [PIX_FMT_RGB32] = {
1856
            .convert = yuv420p_to_rgb32
1857
        },
1858
        [PIX_FMT_UYVY422] = {
1859
            .convert = yuv420p_to_uyvy422,
1860
        },
1861
    },
1862
    [PIX_FMT_YUV422P] = {
1863
        [PIX_FMT_YUYV422] = {
1864
            .convert = yuv422p_to_yuyv422,
1865
        },
1866
        [PIX_FMT_UYVY422] = {
1867
            .convert = yuv422p_to_uyvy422,
1868
        },
1869
    },
1870
    [PIX_FMT_YUV444P] = {
1871
        [PIX_FMT_RGB24] = {
1872
            .convert = yuv444p_to_rgb24
1873
        },
1874
    },
1875
    [PIX_FMT_YUVJ420P] = {
1876
        [PIX_FMT_RGB555] = {
1877
            .convert = yuvj420p_to_rgb555
1878
        },
1879
        [PIX_FMT_RGB565] = {
1880
            .convert = yuvj420p_to_rgb565
1881
        },
1882
        [PIX_FMT_BGR24] = {
1883
            .convert = yuvj420p_to_bgr24
1884
        },
1885
        [PIX_FMT_RGB24] = {
1886
            .convert = yuvj420p_to_rgb24
1887
        },
1888
        [PIX_FMT_RGB32] = {
1889
            .convert = yuvj420p_to_rgb32
1890
        },
1891
    },
1892
    [PIX_FMT_YUVJ444P] = {
1893
        [PIX_FMT_RGB24] = {
1894
            .convert = yuvj444p_to_rgb24
1895
        },
1896
    },
1897
    [PIX_FMT_YUYV422] = {
1898
        [PIX_FMT_YUV420P] = {
1899
            .convert = yuyv422_to_yuv420p,
1900
        },
1901
        [PIX_FMT_YUV422P] = {
1902
            .convert = yuyv422_to_yuv422p,
1903
        },
1904
    },
1905
    [PIX_FMT_UYVY422] = {
1906
        [PIX_FMT_YUV420P] = {
1907
            .convert = uyvy422_to_yuv420p,
1908
        },
1909
        [PIX_FMT_YUV422P] = {
1910
            .convert = uyvy422_to_yuv422p,
1911
        },
1912
    },
1913
    [PIX_FMT_RGB24] = {
1914
        [PIX_FMT_YUV420P] = {
1915
            .convert = rgb24_to_yuv420p
1916
        },
1917
        [PIX_FMT_RGB565] = {
1918
            .convert = rgb24_to_rgb565
1919
        },
1920
        [PIX_FMT_RGB555] = {
1921
            .convert = rgb24_to_rgb555
1922
        },
1923
        [PIX_FMT_RGB32] = {
1924
            .convert = rgb24_to_rgb32
1925
        },
1926
        [PIX_FMT_BGR24] = {
1927
            .convert = rgb24_to_bgr24
1928
        },
1929
        [PIX_FMT_GRAY8] = {
1930
            .convert = rgb24_to_gray
1931
        },
1932
        [PIX_FMT_PAL8] = {
1933
            .convert = rgb24_to_pal8
1934
        },
1935
        [PIX_FMT_YUV444P] = {
1936
            .convert = rgb24_to_yuv444p
1937
        },
1938
        [PIX_FMT_YUVJ420P] = {
1939
            .convert = rgb24_to_yuvj420p
1940
        },
1941
        [PIX_FMT_YUVJ444P] = {
1942
            .convert = rgb24_to_yuvj444p
1943
        },
1944
    },
1945
    [PIX_FMT_RGB32] = {
1946
        [PIX_FMT_RGB24] = {
1947
            .convert = rgb32_to_rgb24
1948
        },
1949
        [PIX_FMT_BGR24] = {
1950
            .convert = rgb32_to_bgr24
1951
        },
1952
        [PIX_FMT_RGB565] = {
1953
            .convert = rgb32_to_rgb565
1954
        },
1955
        [PIX_FMT_RGB555] = {
1956
            .convert = rgb32_to_rgb555
1957
        },
1958
        [PIX_FMT_PAL8] = {
1959
            .convert = rgb32_to_pal8
1960
        },
1961
        [PIX_FMT_YUV420P] = {
1962
            .convert = rgb32_to_yuv420p
1963
        },
1964
        [PIX_FMT_GRAY8] = {
1965
            .convert = rgb32_to_gray
1966
        },
1967
    },
1968
    [PIX_FMT_BGR24] = {
1969
        [PIX_FMT_RGB32] = {
1970
            .convert = bgr24_to_rgb32
1971
        },
1972
        [PIX_FMT_RGB24] = {
1973
            .convert = bgr24_to_rgb24
1974
        },
1975
        [PIX_FMT_YUV420P] = {
1976
            .convert = bgr24_to_yuv420p
1977
        },
1978
        [PIX_FMT_GRAY8] = {
1979
            .convert = bgr24_to_gray
1980
        },
1981
    },
1982
    [PIX_FMT_RGB555] = {
1983
        [PIX_FMT_RGB24] = {
1984
            .convert = rgb555_to_rgb24
1985
        },
1986
        [PIX_FMT_RGB32] = {
1987
            .convert = rgb555_to_rgb32
1988
        },
1989
        [PIX_FMT_YUV420P] = {
1990
            .convert = rgb555_to_yuv420p
1991
        },
1992
        [PIX_FMT_GRAY8] = {
1993
            .convert = rgb555_to_gray
1994
        },
1995
    },
1996
    [PIX_FMT_RGB565] = {
1997
        [PIX_FMT_RGB32] = {
1998
            .convert = rgb565_to_rgb32
1999
        },
2000
        [PIX_FMT_RGB24] = {
2001
            .convert = rgb565_to_rgb24
2002
        },
2003
        [PIX_FMT_YUV420P] = {
2004
            .convert = rgb565_to_yuv420p
2005
        },
2006
        [PIX_FMT_GRAY8] = {
2007
            .convert = rgb565_to_gray
2008
        },
2009
    },
2010
    [PIX_FMT_GRAY16BE] = {
2011
        [PIX_FMT_GRAY8] = {
2012
            .convert = gray16be_to_gray
2013
        },
2014
        [PIX_FMT_GRAY16LE] = {
2015
            .convert = gray16_to_gray16
2016
        },
2017
    },
2018
    [PIX_FMT_GRAY16LE] = {
2019
        [PIX_FMT_GRAY8] = {
2020
            .convert = gray16le_to_gray
2021
        },
2022
        [PIX_FMT_GRAY16BE] = {
2023
            .convert = gray16_to_gray16
2024
        },
2025
    },
2026
    [PIX_FMT_GRAY8] = {
2027
        [PIX_FMT_RGB555] = {
2028
            .convert = gray_to_rgb555
2029
        },
2030
        [PIX_FMT_RGB565] = {
2031
            .convert = gray_to_rgb565
2032
        },
2033
        [PIX_FMT_RGB24] = {
2034
            .convert = gray_to_rgb24
2035
        },
2036
        [PIX_FMT_BGR24] = {
2037
            .convert = gray_to_bgr24
2038
        },
2039
        [PIX_FMT_RGB32] = {
2040
            .convert = gray_to_rgb32
2041
        },
2042
        [PIX_FMT_MONOWHITE] = {
2043
            .convert = gray_to_monowhite
2044
        },
2045
        [PIX_FMT_MONOBLACK] = {
2046
            .convert = gray_to_monoblack
2047
        },
2048
        [PIX_FMT_GRAY16LE] = {
2049
            .convert = gray_to_gray16
2050
        },
2051
        [PIX_FMT_GRAY16BE] = {
2052
            .convert = gray_to_gray16
2053
        },
2054
    },
2055
    [PIX_FMT_MONOWHITE] = {
2056
        [PIX_FMT_GRAY8] = {
2057
            .convert = monowhite_to_gray
2058
        },
2059
    },
2060
    [PIX_FMT_MONOBLACK] = {
2061
        [PIX_FMT_GRAY8] = {
2062
            .convert = monoblack_to_gray
2063
        },
2064
    },
2065
    [PIX_FMT_PAL8] = {
2066
        [PIX_FMT_RGB555] = {
2067
            .convert = pal8_to_rgb555
2068
        },
2069
        [PIX_FMT_RGB565] = {
2070
            .convert = pal8_to_rgb565
2071
        },
2072
        [PIX_FMT_BGR24] = {
2073
            .convert = pal8_to_bgr24
2074
        },
2075
        [PIX_FMT_RGB24] = {
2076
            .convert = pal8_to_rgb24
2077
        },
2078
        [PIX_FMT_RGB32] = {
2079
            .convert = pal8_to_rgb32
2080
        },
2081
    },
2082
    [PIX_FMT_UYYVYY411] = {
2083
        [PIX_FMT_YUV411P] = {
2084
            .convert = uyyvyy411_to_yuv411p,
2085
        },
2086
    },
2087

    
2088
};
2089

    
2090
int avpicture_alloc(AVPicture *picture,
2091
                           int pix_fmt, int width, int height)
2092
{
2093
    int size;
2094
    void *ptr;
2095

    
2096
    size = avpicture_get_size(pix_fmt, width, height);
2097
    if(size<0)
2098
        goto fail;
2099
    ptr = av_malloc(size);
2100
    if (!ptr)
2101
        goto fail;
2102
    avpicture_fill(picture, ptr, pix_fmt, width, height);
2103
    if(picture->data[1] && !picture->data[2])
2104
        ff_set_systematic_pal((uint32_t*)picture->data[1], pix_fmt);
2105

    
2106
    return 0;
2107
 fail:
2108
    memset(picture, 0, sizeof(AVPicture));
2109
    return -1;
2110
}
2111

    
2112
void avpicture_free(AVPicture *picture)
2113
{
2114
    av_free(picture->data[0]);
2115
}
2116

    
2117
/* return true if yuv planar */
2118
static inline int is_yuv_planar(const PixFmtInfo *ps)
2119
{
2120
    return (ps->color_type == FF_COLOR_YUV ||
2121
            ps->color_type == FF_COLOR_YUV_JPEG) &&
2122
        ps->pixel_type == FF_PIXEL_PLANAR;
2123
}
2124

    
2125
int av_picture_crop(AVPicture *dst, const AVPicture *src,
2126
              int pix_fmt, int top_band, int left_band)
2127
{
2128
    int y_shift;
2129
    int x_shift;
2130

    
2131
    if (pix_fmt < 0 || pix_fmt >= PIX_FMT_NB || !is_yuv_planar(&pix_fmt_info[pix_fmt]))
2132
        return -1;
2133

    
2134
    y_shift = pix_fmt_info[pix_fmt].y_chroma_shift;
2135
    x_shift = pix_fmt_info[pix_fmt].x_chroma_shift;
2136

    
2137
    dst->data[0] = src->data[0] + (top_band * src->linesize[0]) + left_band;
2138
    dst->data[1] = src->data[1] + ((top_band >> y_shift) * src->linesize[1]) + (left_band >> x_shift);
2139
    dst->data[2] = src->data[2] + ((top_band >> y_shift) * src->linesize[2]) + (left_band >> x_shift);
2140

    
2141
    dst->linesize[0] = src->linesize[0];
2142
    dst->linesize[1] = src->linesize[1];
2143
    dst->linesize[2] = src->linesize[2];
2144
    return 0;
2145
}
2146

    
2147
int av_picture_pad(AVPicture *dst, const AVPicture *src, int height, int width,
2148
            int pix_fmt, int padtop, int padbottom, int padleft, int padright,
2149
            int *color)
2150
{
2151
    uint8_t *optr;
2152
    int y_shift;
2153
    int x_shift;
2154
    int yheight;
2155
    int i, y;
2156

    
2157
    if (pix_fmt < 0 || pix_fmt >= PIX_FMT_NB ||
2158
        !is_yuv_planar(&pix_fmt_info[pix_fmt])) return -1;
2159

    
2160
    for (i = 0; i < 3; i++) {
2161
        x_shift = i ? pix_fmt_info[pix_fmt].x_chroma_shift : 0;
2162
        y_shift = i ? pix_fmt_info[pix_fmt].y_chroma_shift : 0;
2163

    
2164
        if (padtop || padleft) {
2165
            memset(dst->data[i], color[i],
2166
                dst->linesize[i] * (padtop >> y_shift) + (padleft >> x_shift));
2167
        }
2168

    
2169
        if (padleft || padright) {
2170
            optr = dst->data[i] + dst->linesize[i] * (padtop >> y_shift) +
2171
                (dst->linesize[i] - (padright >> x_shift));
2172
            yheight = (height - 1 - (padtop + padbottom)) >> y_shift;
2173
            for (y = 0; y < yheight; y++) {
2174
                memset(optr, color[i], (padleft + padright) >> x_shift);
2175
                optr += dst->linesize[i];
2176
            }
2177
        }
2178

    
2179
        if (src) { /* first line */
2180
            uint8_t *iptr = src->data[i];
2181
            optr = dst->data[i] + dst->linesize[i] * (padtop >> y_shift) +
2182
                    (padleft >> x_shift);
2183
            memcpy(optr, iptr, (width - padleft - padright) >> x_shift);
2184
            iptr += src->linesize[i];
2185
            optr = dst->data[i] + dst->linesize[i] * (padtop >> y_shift) +
2186
                (dst->linesize[i] - (padright >> x_shift));
2187
            yheight = (height - 1 - (padtop + padbottom)) >> y_shift;
2188
            for (y = 0; y < yheight; y++) {
2189
                memset(optr, color[i], (padleft + padright) >> x_shift);
2190
                memcpy(optr + ((padleft + padright) >> x_shift), iptr,
2191
                       (width - padleft - padright) >> x_shift);
2192
                iptr += src->linesize[i];
2193
                optr += dst->linesize[i];
2194
            }
2195
        }
2196

    
2197
        if (padbottom || padright) {
2198
            optr = dst->data[i] + dst->linesize[i] *
2199
                ((height - padbottom) >> y_shift) - (padright >> x_shift);
2200
            memset(optr, color[i],dst->linesize[i] *
2201
                (padbottom >> y_shift) + (padright >> x_shift));
2202
        }
2203
    }
2204
    return 0;
2205
}
2206

    
2207
#if !CONFIG_SWSCALE
2208
static uint8_t y_ccir_to_jpeg[256];
2209
static uint8_t y_jpeg_to_ccir[256];
2210
static uint8_t c_ccir_to_jpeg[256];
2211
static uint8_t c_jpeg_to_ccir[256];
2212

    
2213
/* init various conversion tables */
2214
static av_cold void img_convert_init(void)
2215
{
2216
    int i;
2217
    uint8_t *cm = ff_cropTbl + MAX_NEG_CROP;
2218

    
2219
    for(i = 0;i < 256; i++) {
2220
        y_ccir_to_jpeg[i] = Y_CCIR_TO_JPEG(i);
2221
        y_jpeg_to_ccir[i] = Y_JPEG_TO_CCIR(i);
2222
        c_ccir_to_jpeg[i] = C_CCIR_TO_JPEG(i);
2223
        c_jpeg_to_ccir[i] = C_JPEG_TO_CCIR(i);
2224
    }
2225
}
2226

    
2227
/* apply to each pixel the given table */
2228
static void img_apply_table(uint8_t *dst, int dst_wrap,
2229
                            const uint8_t *src, int src_wrap,
2230
                            int width, int height, const uint8_t *table1)
2231
{
2232
    int n;
2233
    const uint8_t *s;
2234
    uint8_t *d;
2235
    const uint8_t *table;
2236

    
2237
    table = table1;
2238
    for(;height > 0; height--) {
2239
        s = src;
2240
        d = dst;
2241
        n = width;
2242
        while (n >= 4) {
2243
            d[0] = table[s[0]];
2244
            d[1] = table[s[1]];
2245
            d[2] = table[s[2]];
2246
            d[3] = table[s[3]];
2247
            d += 4;
2248
            s += 4;
2249
            n -= 4;
2250
        }
2251
        while (n > 0) {
2252
            d[0] = table[s[0]];
2253
            d++;
2254
            s++;
2255
            n--;
2256
        }
2257
        dst += dst_wrap;
2258
        src += src_wrap;
2259
    }
2260
}
2261

    
2262
/* XXX: use generic filter ? */
2263
/* XXX: in most cases, the sampling position is incorrect */
2264

    
2265
/* 4x1 -> 1x1 */
2266
static void shrink41(uint8_t *dst, int dst_wrap,
2267
                     const uint8_t *src, int src_wrap,
2268
                     int width, int height)
2269
{
2270
    int w;
2271
    const uint8_t *s;
2272
    uint8_t *d;
2273

    
2274
    for(;height > 0; height--) {
2275
        s = src;
2276
        d = dst;
2277
        for(w = width;w > 0; w--) {
2278
            d[0] = (s[0] + s[1] + s[2] + s[3] + 2) >> 2;
2279
            s += 4;
2280
            d++;
2281
        }
2282
        src += src_wrap;
2283
        dst += dst_wrap;
2284
    }
2285
}
2286

    
2287
/* 2x1 -> 1x1 */
2288
static void shrink21(uint8_t *dst, int dst_wrap,
2289
                     const uint8_t *src, int src_wrap,
2290
                     int width, int height)
2291
{
2292
    int w;
2293
    const uint8_t *s;
2294
    uint8_t *d;
2295

    
2296
    for(;height > 0; height--) {
2297
        s = src;
2298
        d = dst;
2299
        for(w = width;w > 0; w--) {
2300
            d[0] = (s[0] + s[1]) >> 1;
2301
            s += 2;
2302
            d++;
2303
        }
2304
        src += src_wrap;
2305
        dst += dst_wrap;
2306
    }
2307
}
2308

    
2309
/* 1x2 -> 1x1 */
2310
static void shrink12(uint8_t *dst, int dst_wrap,
2311
                     const uint8_t *src, int src_wrap,
2312
                     int width, int height)
2313
{
2314
    int w;
2315
    uint8_t *d;
2316
    const uint8_t *s1, *s2;
2317

    
2318
    for(;height > 0; height--) {
2319
        s1 = src;
2320
        s2 = s1 + src_wrap;
2321
        d = dst;
2322
        for(w = width;w >= 4; w-=4) {
2323
            d[0] = (s1[0] + s2[0]) >> 1;
2324
            d[1] = (s1[1] + s2[1]) >> 1;
2325
            d[2] = (s1[2] + s2[2]) >> 1;
2326
            d[3] = (s1[3] + s2[3]) >> 1;
2327
            s1 += 4;
2328
            s2 += 4;
2329
            d += 4;
2330
        }
2331
        for(;w > 0; w--) {
2332
            d[0] = (s1[0] + s2[0]) >> 1;
2333
            s1++;
2334
            s2++;
2335
            d++;
2336
        }
2337
        src += 2 * src_wrap;
2338
        dst += dst_wrap;
2339
    }
2340
}
2341

    
2342
static void grow21_line(uint8_t *dst, const uint8_t *src,
2343
                        int width)
2344
{
2345
    int w;
2346
    const uint8_t *s1;
2347
    uint8_t *d;
2348

    
2349
    s1 = src;
2350
    d = dst;
2351
    for(w = width;w >= 4; w-=4) {
2352
        d[1] = d[0] = s1[0];
2353
        d[3] = d[2] = s1[1];
2354
        s1 += 2;
2355
        d += 4;
2356
    }
2357
    for(;w >= 2; w -= 2) {
2358
        d[1] = d[0] = s1[0];
2359
        s1 ++;
2360
        d += 2;
2361
    }
2362
    /* only needed if width is not a multiple of two */
2363
    /* XXX: veryfy that */
2364
    if (w) {
2365
        d[0] = s1[0];
2366
    }
2367
}
2368

    
2369
static void grow41_line(uint8_t *dst, const uint8_t *src,
2370
                        int width)
2371
{
2372
    int w, v;
2373
    const uint8_t *s1;
2374
    uint8_t *d;
2375

    
2376
    s1 = src;
2377
    d = dst;
2378
    for(w = width;w >= 4; w-=4) {
2379
        v = s1[0];
2380
        d[0] = v;
2381
        d[1] = v;
2382
        d[2] = v;
2383
        d[3] = v;
2384
        s1 ++;
2385
        d += 4;
2386
    }
2387
}
2388

    
2389
/* 1x1 -> 2x1 */
2390
static void grow21(uint8_t *dst, int dst_wrap,
2391
                   const uint8_t *src, int src_wrap,
2392
                   int width, int height)
2393
{
2394
    for(;height > 0; height--) {
2395
        grow21_line(dst, src, width);
2396
        src += src_wrap;
2397
        dst += dst_wrap;
2398
    }
2399
}
2400

    
2401
/* 1x1 -> 1x2 */
2402
static void grow12(uint8_t *dst, int dst_wrap,
2403
                   const uint8_t *src, int src_wrap,
2404
                   int width, int height)
2405
{
2406
    for(;height > 0; height-=2) {
2407
        memcpy(dst, src, width);
2408
        dst += dst_wrap;
2409
        memcpy(dst, src, width);
2410
        dst += dst_wrap;
2411
        src += src_wrap;
2412
    }
2413
}
2414

    
2415
/* 1x1 -> 2x2 */
2416
static void grow22(uint8_t *dst, int dst_wrap,
2417
                   const uint8_t *src, int src_wrap,
2418
                   int width, int height)
2419
{
2420
    for(;height > 0; height--) {
2421
        grow21_line(dst, src, width);
2422
        if (height%2)
2423
            src += src_wrap;
2424
        dst += dst_wrap;
2425
    }
2426
}
2427

    
2428
/* 1x1 -> 4x1 */
2429
static void grow41(uint8_t *dst, int dst_wrap,
2430
                   const uint8_t *src, int src_wrap,
2431
                   int width, int height)
2432
{
2433
    for(;height > 0; height--) {
2434
        grow41_line(dst, src, width);
2435
        src += src_wrap;
2436
        dst += dst_wrap;
2437
    }
2438
}
2439

    
2440
/* 1x1 -> 4x4 */
2441
static void grow44(uint8_t *dst, int dst_wrap,
2442
                   const uint8_t *src, int src_wrap,
2443
                   int width, int height)
2444
{
2445
    for(;height > 0; height--) {
2446
        grow41_line(dst, src, width);
2447
        if ((height & 3) == 1)
2448
            src += src_wrap;
2449
        dst += dst_wrap;
2450
    }
2451
}
2452

    
2453
/* 1x2 -> 2x1 */
2454
static void conv411(uint8_t *dst, int dst_wrap,
2455
                    const uint8_t *src, int src_wrap,
2456
                    int width, int height)
2457
{
2458
    int w, c;
2459
    const uint8_t *s1, *s2;
2460
    uint8_t *d;
2461

    
2462
    width>>=1;
2463

    
2464
    for(;height > 0; height--) {
2465
        s1 = src;
2466
        s2 = src + src_wrap;
2467
        d = dst;
2468
        for(w = width;w > 0; w--) {
2469
            c = (s1[0] + s2[0]) >> 1;
2470
            d[0] = c;
2471
            d[1] = c;
2472
            s1++;
2473
            s2++;
2474
            d += 2;
2475
        }
2476
        src += src_wrap * 2;
2477
        dst += dst_wrap;
2478
    }
2479
}
2480

    
2481
/* XXX: always use linesize. Return -1 if not supported */
2482
int img_convert(AVPicture *dst, int dst_pix_fmt,
2483
                const AVPicture *src, int src_pix_fmt,
2484
                int src_width, int src_height)
2485
{
2486
    static int initialized;
2487
    int i, ret, dst_width, dst_height, int_pix_fmt;
2488
    const PixFmtInfo *src_pix, *dst_pix;
2489
    const ConvertEntry *ce;
2490
    AVPicture tmp1, *tmp = &tmp1;
2491

    
2492
    if (src_pix_fmt < 0 || src_pix_fmt >= PIX_FMT_NB ||
2493
        dst_pix_fmt < 0 || dst_pix_fmt >= PIX_FMT_NB)
2494
        return -1;
2495
    if (src_width <= 0 || src_height <= 0)
2496
        return 0;
2497

    
2498
    if (!initialized) {
2499
        initialized = 1;
2500
        img_convert_init();
2501
    }
2502

    
2503
    dst_width = src_width;
2504
    dst_height = src_height;
2505

    
2506
    dst_pix = &pix_fmt_info[dst_pix_fmt];
2507
    src_pix = &pix_fmt_info[src_pix_fmt];
2508
    if (src_pix_fmt == dst_pix_fmt) {
2509
        /* no conversion needed: just copy */
2510
        av_picture_copy(dst, src, dst_pix_fmt, dst_width, dst_height);
2511
        return 0;
2512
    }
2513

    
2514
    ce = &convert_table[src_pix_fmt][dst_pix_fmt];
2515
    if (ce->convert) {
2516
        /* specific conversion routine */
2517
        ce->convert(dst, src, dst_width, dst_height);
2518
        return 0;
2519
    }
2520

    
2521
    /* gray to YUV */
2522
    if (is_yuv_planar(dst_pix) &&
2523
        src_pix_fmt == PIX_FMT_GRAY8) {
2524
        int w, h, y;
2525
        uint8_t *d;
2526

    
2527
        if (dst_pix->color_type == FF_COLOR_YUV_JPEG) {
2528
            ff_img_copy_plane(dst->data[0], dst->linesize[0],
2529
                     src->data[0], src->linesize[0],
2530
                     dst_width, dst_height);
2531
        } else {
2532
            img_apply_table(dst->data[0], dst->linesize[0],
2533
                            src->data[0], src->linesize[0],
2534
                            dst_width, dst_height,
2535
                            y_jpeg_to_ccir);
2536
        }
2537
        /* fill U and V with 128 */
2538
        w = dst_width;
2539
        h = dst_height;
2540
        w >>= dst_pix->x_chroma_shift;
2541
        h >>= dst_pix->y_chroma_shift;
2542
        for(i = 1; i <= 2; i++) {
2543
            d = dst->data[i];
2544
            for(y = 0; y< h; y++) {
2545
                memset(d, 128, w);
2546
                d += dst->linesize[i];
2547
            }
2548
        }
2549
        return 0;
2550
    }
2551

    
2552
    /* YUV to gray */
2553
    if (is_yuv_planar(src_pix) &&
2554
        dst_pix_fmt == PIX_FMT_GRAY8) {
2555
        if (src_pix->color_type == FF_COLOR_YUV_JPEG) {
2556
            ff_img_copy_plane(dst->data[0], dst->linesize[0],
2557
                     src->data[0], src->linesize[0],
2558
                     dst_width, dst_height);
2559
        } else {
2560
            img_apply_table(dst->data[0], dst->linesize[0],
2561
                            src->data[0], src->linesize[0],
2562
                            dst_width, dst_height,
2563
                            y_ccir_to_jpeg);
2564
        }
2565
        return 0;
2566
    }
2567

    
2568
    /* YUV to YUV planar */
2569
    if (is_yuv_planar(dst_pix) && is_yuv_planar(src_pix)) {
2570
        int x_shift, y_shift, w, h, xy_shift;
2571
        void (*resize_func)(uint8_t *dst, int dst_wrap,
2572
                            const uint8_t *src, int src_wrap,
2573
                            int width, int height);
2574

    
2575
        /* compute chroma size of the smallest dimensions */
2576
        w = dst_width;
2577
        h = dst_height;
2578
        if (dst_pix->x_chroma_shift >= src_pix->x_chroma_shift)
2579
            w >>= dst_pix->x_chroma_shift;
2580
        else
2581
            w >>= src_pix->x_chroma_shift;
2582
        if (dst_pix->y_chroma_shift >= src_pix->y_chroma_shift)
2583
            h >>= dst_pix->y_chroma_shift;
2584
        else
2585
            h >>= src_pix->y_chroma_shift;
2586

    
2587
        x_shift = (dst_pix->x_chroma_shift - src_pix->x_chroma_shift);
2588
        y_shift = (dst_pix->y_chroma_shift - src_pix->y_chroma_shift);
2589
        xy_shift = ((x_shift & 0xf) << 4) | (y_shift & 0xf);
2590
        /* there must be filters for conversion at least from and to
2591
           YUV444 format */
2592
        switch(xy_shift) {
2593
        case 0x00:
2594
            resize_func = ff_img_copy_plane;
2595
            break;
2596
        case 0x10:
2597
            resize_func = shrink21;
2598
            break;
2599
        case 0x20:
2600
            resize_func = shrink41;
2601
            break;
2602
        case 0x01:
2603
            resize_func = shrink12;
2604
            break;
2605
        case 0x11:
2606
            resize_func = ff_shrink22;
2607
            break;
2608
        case 0x22:
2609
            resize_func = ff_shrink44;
2610
            break;
2611
        case 0xf0:
2612
            resize_func = grow21;
2613
            break;
2614
        case 0x0f:
2615
            resize_func = grow12;
2616
            break;
2617
        case 0xe0:
2618
            resize_func = grow41;
2619
            break;
2620
        case 0xff:
2621
            resize_func = grow22;
2622
            break;
2623
        case 0xee:
2624
            resize_func = grow44;
2625
            break;
2626
        case 0xf1:
2627
            resize_func = conv411;
2628
            break;
2629
        default:
2630
            /* currently not handled */
2631
            goto no_chroma_filter;
2632
        }
2633

    
2634
        ff_img_copy_plane(dst->data[0], dst->linesize[0],
2635
                       src->data[0], src->linesize[0],
2636
                       dst_width, dst_height);
2637

    
2638
        for(i = 1;i <= 2; i++)
2639
            resize_func(dst->data[i], dst->linesize[i],
2640
                        src->data[i], src->linesize[i],
2641
                        dst_width>>dst_pix->x_chroma_shift, dst_height>>dst_pix->y_chroma_shift);
2642
        /* if yuv color space conversion is needed, we do it here on
2643
           the destination image */
2644
        if (dst_pix->color_type != src_pix->color_type) {
2645
            const uint8_t *y_table, *c_table;
2646
            if (dst_pix->color_type == FF_COLOR_YUV) {
2647
                y_table = y_jpeg_to_ccir;
2648
                c_table = c_jpeg_to_ccir;
2649
            } else {
2650
                y_table = y_ccir_to_jpeg;
2651
                c_table = c_ccir_to_jpeg;
2652
            }
2653
            img_apply_table(dst->data[0], dst->linesize[0],
2654
                            dst->data[0], dst->linesize[0],
2655
                            dst_width, dst_height,
2656
                            y_table);
2657

    
2658
            for(i = 1;i <= 2; i++)
2659
                img_apply_table(dst->data[i], dst->linesize[i],
2660
                                dst->data[i], dst->linesize[i],
2661
                                dst_width>>dst_pix->x_chroma_shift,
2662
                                dst_height>>dst_pix->y_chroma_shift,
2663
                                c_table);
2664
        }
2665
        return 0;
2666
    }
2667
 no_chroma_filter:
2668

    
2669
    /* try to use an intermediate format */
2670
    if (src_pix_fmt == PIX_FMT_YUYV422 ||
2671
        dst_pix_fmt == PIX_FMT_YUYV422) {
2672
        /* specific case: convert to YUV422P first */
2673
        int_pix_fmt = PIX_FMT_YUV422P;
2674
    } else if (src_pix_fmt == PIX_FMT_UYVY422 ||
2675
        dst_pix_fmt == PIX_FMT_UYVY422) {
2676
        /* specific case: convert to YUV422P first */
2677
        int_pix_fmt = PIX_FMT_YUV422P;
2678
    } else if (src_pix_fmt == PIX_FMT_UYYVYY411 ||
2679
        dst_pix_fmt == PIX_FMT_UYYVYY411) {
2680
        /* specific case: convert to YUV411P first */
2681
        int_pix_fmt = PIX_FMT_YUV411P;
2682
    } else if ((src_pix->color_type == FF_COLOR_GRAY &&
2683
                src_pix_fmt != PIX_FMT_GRAY8) ||
2684
               (dst_pix->color_type == FF_COLOR_GRAY &&
2685
                dst_pix_fmt != PIX_FMT_GRAY8)) {
2686
        /* gray8 is the normalized format */
2687
        int_pix_fmt = PIX_FMT_GRAY8;
2688
    } else if ((is_yuv_planar(src_pix) &&
2689
                src_pix_fmt != PIX_FMT_YUV444P &&
2690
                src_pix_fmt != PIX_FMT_YUVJ444P)) {
2691
        /* yuv444 is the normalized format */
2692
        if (src_pix->color_type == FF_COLOR_YUV_JPEG)
2693
            int_pix_fmt = PIX_FMT_YUVJ444P;
2694
        else
2695
            int_pix_fmt = PIX_FMT_YUV444P;
2696
    } else if ((is_yuv_planar(dst_pix) &&
2697
                dst_pix_fmt != PIX_FMT_YUV444P &&
2698
                dst_pix_fmt != PIX_FMT_YUVJ444P)) {
2699
        /* yuv444 is the normalized format */
2700
        if (dst_pix->color_type == FF_COLOR_YUV_JPEG)
2701
            int_pix_fmt = PIX_FMT_YUVJ444P;
2702
        else
2703
            int_pix_fmt = PIX_FMT_YUV444P;
2704
    } else {
2705
        /* the two formats are rgb or gray8 or yuv[j]444p */
2706
        if (src_pix->is_alpha && dst_pix->is_alpha)
2707
            int_pix_fmt = PIX_FMT_RGB32;
2708
        else
2709
            int_pix_fmt = PIX_FMT_RGB24;
2710
    }
2711
    if (src_pix_fmt == int_pix_fmt)
2712
        return -1;
2713
    if (avpicture_alloc(tmp, int_pix_fmt, dst_width, dst_height) < 0)
2714
        return -1;
2715
    ret = -1;
2716
    if (img_convert(tmp, int_pix_fmt,
2717
                    src, src_pix_fmt, src_width, src_height) < 0)
2718
        goto fail1;
2719
    if (img_convert(dst, dst_pix_fmt,
2720
                    tmp, int_pix_fmt, dst_width, dst_height) < 0)
2721
        goto fail1;
2722
    ret = 0;
2723
 fail1:
2724
    avpicture_free(tmp);
2725
    return ret;
2726
}
2727
#endif
2728

    
2729
/* NOTE: we scan all the pixels to have an exact information */
2730
static int get_alpha_info_pal8(const AVPicture *src, int width, int height)
2731
{
2732
    const unsigned char *p;
2733
    int src_wrap, ret, x, y;
2734
    unsigned int a;
2735
    uint32_t *palette = (uint32_t *)src->data[1];
2736

    
2737
    p = src->data[0];
2738
    src_wrap = src->linesize[0] - width;
2739
    ret = 0;
2740
    for(y=0;y<height;y++) {
2741
        for(x=0;x<width;x++) {
2742
            a = palette[p[0]] >> 24;
2743
            if (a == 0x00) {
2744
                ret |= FF_ALPHA_TRANSP;
2745
            } else if (a != 0xff) {
2746
                ret |= FF_ALPHA_SEMI_TRANSP;
2747
            }
2748
            p++;
2749
        }
2750
        p += src_wrap;
2751
    }
2752
    return ret;
2753
}
2754

    
2755
int img_get_alpha_info(const AVPicture *src,
2756
                       int pix_fmt, int width, int height)
2757
{
2758
    const PixFmtInfo *pf = &pix_fmt_info[pix_fmt];
2759
    int ret;
2760

    
2761
    pf = &pix_fmt_info[pix_fmt];
2762
    /* no alpha can be represented in format */
2763
    if (!pf->is_alpha)
2764
        return 0;
2765
    switch(pix_fmt) {
2766
    case PIX_FMT_RGB32:
2767
        ret = get_alpha_info_rgb32(src, width, height);
2768
        break;
2769
    case PIX_FMT_PAL8:
2770
        ret = get_alpha_info_pal8(src, width, height);
2771
        break;
2772
    default:
2773
        /* we do not know, so everything is indicated */
2774
        ret = FF_ALPHA_TRANSP | FF_ALPHA_SEMI_TRANSP;
2775
        break;
2776
    }
2777
    return ret;
2778
}
2779

    
2780
#if HAVE_MMX
2781
#define DEINT_INPLACE_LINE_LUM \
2782
                    movd_m2r(lum_m4[0],mm0);\
2783
                    movd_m2r(lum_m3[0],mm1);\
2784
                    movd_m2r(lum_m2[0],mm2);\
2785
                    movd_m2r(lum_m1[0],mm3);\
2786
                    movd_m2r(lum[0],mm4);\
2787
                    punpcklbw_r2r(mm7,mm0);\
2788
                    movd_r2m(mm2,lum_m4[0]);\
2789
                    punpcklbw_r2r(mm7,mm1);\
2790
                    punpcklbw_r2r(mm7,mm2);\
2791
                    punpcklbw_r2r(mm7,mm3);\
2792
                    punpcklbw_r2r(mm7,mm4);\
2793
                    paddw_r2r(mm3,mm1);\
2794
                    psllw_i2r(1,mm2);\
2795
                    paddw_r2r(mm4,mm0);\
2796
                    psllw_i2r(2,mm1);\
2797
                    paddw_r2r(mm6,mm2);\
2798
                    paddw_r2r(mm2,mm1);\
2799
                    psubusw_r2r(mm0,mm1);\
2800
                    psrlw_i2r(3,mm1);\
2801
                    packuswb_r2r(mm7,mm1);\
2802
                    movd_r2m(mm1,lum_m2[0]);
2803

    
2804
#define DEINT_LINE_LUM \
2805
                    movd_m2r(lum_m4[0],mm0);\
2806
                    movd_m2r(lum_m3[0],mm1);\
2807
                    movd_m2r(lum_m2[0],mm2);\
2808
                    movd_m2r(lum_m1[0],mm3);\
2809
                    movd_m2r(lum[0],mm4);\
2810
                    punpcklbw_r2r(mm7,mm0);\
2811
                    punpcklbw_r2r(mm7,mm1);\
2812
                    punpcklbw_r2r(mm7,mm2);\
2813
                    punpcklbw_r2r(mm7,mm3);\
2814
                    punpcklbw_r2r(mm7,mm4);\
2815
                    paddw_r2r(mm3,mm1);\
2816
                    psllw_i2r(1,mm2);\
2817
                    paddw_r2r(mm4,mm0);\
2818
                    psllw_i2r(2,mm1);\
2819
                    paddw_r2r(mm6,mm2);\
2820
                    paddw_r2r(mm2,mm1);\
2821
                    psubusw_r2r(mm0,mm1);\
2822
                    psrlw_i2r(3,mm1);\
2823
                    packuswb_r2r(mm7,mm1);\
2824
                    movd_r2m(mm1,dst[0]);
2825
#endif
2826

    
2827
/* filter parameters: [-1 4 2 4 -1] // 8 */
2828
static void deinterlace_line(uint8_t *dst,
2829
                             const uint8_t *lum_m4, const uint8_t *lum_m3,
2830
                             const uint8_t *lum_m2, const uint8_t *lum_m1,
2831
                             const uint8_t *lum,
2832
                             int size)
2833
{
2834
#if !HAVE_MMX
2835
    uint8_t *cm = ff_cropTbl + MAX_NEG_CROP;
2836
    int sum;
2837

    
2838
    for(;size > 0;size--) {
2839
        sum = -lum_m4[0];
2840
        sum += lum_m3[0] << 2;
2841
        sum += lum_m2[0] << 1;
2842
        sum += lum_m1[0] << 2;
2843
        sum += -lum[0];
2844
        dst[0] = cm[(sum + 4) >> 3];
2845
        lum_m4++;
2846
        lum_m3++;
2847
        lum_m2++;
2848
        lum_m1++;
2849
        lum++;
2850
        dst++;
2851
    }
2852
#else
2853

    
2854
    {
2855
        pxor_r2r(mm7,mm7);
2856
        movq_m2r(ff_pw_4,mm6);
2857
    }
2858
    for (;size > 3; size-=4) {
2859
        DEINT_LINE_LUM
2860
        lum_m4+=4;
2861
        lum_m3+=4;
2862
        lum_m2+=4;
2863
        lum_m1+=4;
2864
        lum+=4;
2865
        dst+=4;
2866
    }
2867
#endif
2868
}
2869
static void deinterlace_line_inplace(uint8_t *lum_m4, uint8_t *lum_m3, uint8_t *lum_m2, uint8_t *lum_m1, uint8_t *lum,
2870
                             int size)
2871
{
2872
#if !HAVE_MMX
2873
    uint8_t *cm = ff_cropTbl + MAX_NEG_CROP;
2874
    int sum;
2875

    
2876
    for(;size > 0;size--) {
2877
        sum = -lum_m4[0];
2878
        sum += lum_m3[0] << 2;
2879
        sum += lum_m2[0] << 1;
2880
        lum_m4[0]=lum_m2[0];
2881
        sum += lum_m1[0] << 2;
2882
        sum += -lum[0];
2883
        lum_m2[0] = cm[(sum + 4) >> 3];
2884
        lum_m4++;
2885
        lum_m3++;
2886
        lum_m2++;
2887
        lum_m1++;
2888
        lum++;
2889
    }
2890
#else
2891

    
2892
    {
2893
        pxor_r2r(mm7,mm7);
2894
        movq_m2r(ff_pw_4,mm6);
2895
    }
2896
    for (;size > 3; size-=4) {
2897
        DEINT_INPLACE_LINE_LUM
2898
        lum_m4+=4;
2899
        lum_m3+=4;
2900
        lum_m2+=4;
2901
        lum_m1+=4;
2902
        lum+=4;
2903
    }
2904
#endif
2905
}
2906

    
2907
/* deinterlacing : 2 temporal taps, 3 spatial taps linear filter. The
2908
   top field is copied as is, but the bottom field is deinterlaced
2909
   against the top field. */
2910
static void deinterlace_bottom_field(uint8_t *dst, int dst_wrap,
2911
                                    const uint8_t *src1, int src_wrap,
2912
                                    int width, int height)
2913
{
2914
    const uint8_t *src_m2, *src_m1, *src_0, *src_p1, *src_p2;
2915
    int y;
2916

    
2917
    src_m2 = src1;
2918
    src_m1 = src1;
2919
    src_0=&src_m1[src_wrap];
2920
    src_p1=&src_0[src_wrap];
2921
    src_p2=&src_p1[src_wrap];
2922
    for(y=0;y<(height-2);y+=2) {
2923
        memcpy(dst,src_m1,width);
2924
        dst += dst_wrap;
2925
        deinterlace_line(dst,src_m2,src_m1,src_0,src_p1,src_p2,width);
2926
        src_m2 = src_0;
2927
        src_m1 = src_p1;
2928
        src_0 = src_p2;
2929
        src_p1 += 2*src_wrap;
2930
        src_p2 += 2*src_wrap;
2931
        dst += dst_wrap;
2932
    }
2933
    memcpy(dst,src_m1,width);
2934
    dst += dst_wrap;
2935
    /* do last line */
2936
    deinterlace_line(dst,src_m2,src_m1,src_0,src_0,src_0,width);
2937
}
2938

    
2939
static void deinterlace_bottom_field_inplace(uint8_t *src1, int src_wrap,
2940
                                             int width, int height)
2941
{
2942
    uint8_t *src_m1, *src_0, *src_p1, *src_p2;
2943
    int y;
2944
    uint8_t *buf;
2945
    buf = (uint8_t*)av_malloc(width);
2946

    
2947
    src_m1 = src1;
2948
    memcpy(buf,src_m1,width);
2949
    src_0=&src_m1[src_wrap];
2950
    src_p1=&src_0[src_wrap];
2951
    src_p2=&src_p1[src_wrap];
2952
    for(y=0;y<(height-2);y+=2) {
2953
        deinterlace_line_inplace(buf,src_m1,src_0,src_p1,src_p2,width);
2954
        src_m1 = src_p1;
2955
        src_0 = src_p2;
2956
        src_p1 += 2*src_wrap;
2957
        src_p2 += 2*src_wrap;
2958
    }
2959
    /* do last line */
2960
    deinterlace_line_inplace(buf,src_m1,src_0,src_0,src_0,width);
2961
    av_free(buf);
2962
}
2963

    
2964
int avpicture_deinterlace(AVPicture *dst, const AVPicture *src,
2965
                          int pix_fmt, int width, int height)
2966
{
2967
    int i;
2968

    
2969
    if (pix_fmt != PIX_FMT_YUV420P &&
2970
        pix_fmt != PIX_FMT_YUV422P &&
2971
        pix_fmt != PIX_FMT_YUV444P &&
2972
        pix_fmt != PIX_FMT_YUV411P &&
2973
        pix_fmt != PIX_FMT_GRAY8)
2974
        return -1;
2975
    if ((width & 3) != 0 || (height & 3) != 0)
2976
        return -1;
2977

    
2978
    for(i=0;i<3;i++) {
2979
        if (i == 1) {
2980
            switch(pix_fmt) {
2981
            case PIX_FMT_YUV420P:
2982
                width >>= 1;
2983
                height >>= 1;
2984
                break;
2985
            case PIX_FMT_YUV422P:
2986
                width >>= 1;
2987
                break;
2988
            case PIX_FMT_YUV411P:
2989
                width >>= 2;
2990
                break;
2991
            default:
2992
                break;
2993
            }
2994
            if (pix_fmt == PIX_FMT_GRAY8) {
2995
                break;
2996
            }
2997
        }
2998
        if (src == dst) {
2999
            deinterlace_bottom_field_inplace(dst->data[i], dst->linesize[i],
3000
                                 width, height);
3001
        } else {
3002
            deinterlace_bottom_field(dst->data[i],dst->linesize[i],
3003
                                        src->data[i], src->linesize[i],
3004
                                        width, height);
3005
        }
3006
    }
3007
    emms_c();
3008
    return 0;
3009
}
3010