Statistics
| Branch: | Revision:

ffmpeg / libavcodec / imgconvert.c @ 80a07f6e

History | View | Annotate | Download (42.6 KB)

1 de6d9b64 Fabrice Bellard
/*
2 f1ea5c2a Diego Biurrun
 * Misc image conversion routines
3 406792e7 Diego Biurrun
 * Copyright (c) 2001, 2002, 2003 Fabrice Bellard
4 de6d9b64 Fabrice Bellard
 *
5 b78e7197 Diego Biurrun
 * This file is part of FFmpeg.
6
 *
7
 * FFmpeg is free software; you can redistribute it and/or
8 ff4ec49e Fabrice Bellard
 * modify it under the terms of the GNU Lesser General Public
9
 * License as published by the Free Software Foundation; either
10 b78e7197 Diego Biurrun
 * version 2.1 of the License, or (at your option) any later version.
11 de6d9b64 Fabrice Bellard
 *
12 b78e7197 Diego Biurrun
 * FFmpeg is distributed in the hope that it will be useful,
13 de6d9b64 Fabrice Bellard
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 ff4ec49e Fabrice Bellard
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15
 * Lesser General Public License for more details.
16 de6d9b64 Fabrice Bellard
 *
17 ff4ec49e Fabrice Bellard
 * You should have received a copy of the GNU Lesser General Public
18 b78e7197 Diego Biurrun
 * License along with FFmpeg; if not, write to the Free Software
19 5509bffa Diego Biurrun
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20 de6d9b64 Fabrice Bellard
 */
21 983e3246 Michael Niedermayer
22
/**
23 bad5537e Diego Biurrun
 * @file libavcodec/imgconvert.c
24 f1ea5c2a Diego Biurrun
 * misc image conversion routines
25 983e3246 Michael Niedermayer
 */
26
27 c50c0bc8 Fabrice Bellard
/* 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 983e3246 Michael Niedermayer
33 de6d9b64 Fabrice Bellard
#include "avcodec.h"
34 85c242d8 Fabrice Bellard
#include "dsputil.h"
35 04d2e45f Ian Caulfield
#include "colorspace.h"
36 8e861e1b Stefano Sabatini
#include "libavutil/pixdesc.h"
37 de6d9b64 Fabrice Bellard
38 b250f9c6 Aurelien Jacobs
#if HAVE_MMX
39 a6493a8f Diego Biurrun
#include "x86/mmx.h"
40
#include "x86/dsputil_mmx.h"
41 5981f4e6 Fred
#endif
42 524c6b63 Fabrice Bellard
43 7e7e5940 Fabrice Bellard
#define xglue(x, y) x ## y
44
#define glue(x, y) xglue(x, y)
45
46 bb0f999b Guillaume Poirier
#define FF_COLOR_RGB      0 /**< RGB color space */
47
#define FF_COLOR_GRAY     1 /**< gray color space */
48
#define FF_COLOR_YUV      2 /**< YUV color space. 16 <= Y <= 235, 16 <= U, V <= 240 */
49
#define FF_COLOR_YUV_JPEG 3 /**< YUV color space. 0 <= Y <= 255, 0 <= U, V <= 255 */
50 b6147995 Fabrice Bellard
51 bb0f999b Guillaume Poirier
#define FF_PIXEL_PLANAR   0 /**< each channel has one component in AVPicture */
52
#define FF_PIXEL_PACKED   1 /**< only one components containing all the channels */
53
#define FF_PIXEL_PALETTE  2  /**< one components containing indexes for a palette */
54 7e7e5940 Fabrice Bellard
55 524c6b63 Fabrice Bellard
typedef struct PixFmtInfo {
56 bb0f999b Guillaume Poirier
    uint8_t nb_channels;     /**< number of channels (including alpha) */
57
    uint8_t color_type;      /**< color type (see FF_COLOR_xxx constants) */
58
    uint8_t pixel_type;      /**< pixel storage type (see FF_PIXEL_xxx constants) */
59
    uint8_t is_alpha : 1;    /**< true if alpha can be specified */
60
    uint8_t depth;           /**< bit depth of the color components */
61 524c6b63 Fabrice Bellard
} PixFmtInfo;
62
63
/* this table gives more information about formats */
64 62a05b5b Stefan Huehner
static const PixFmtInfo pix_fmt_info[PIX_FMT_NB] = {
65 524c6b63 Fabrice Bellard
    /* YUV formats */
66
    [PIX_FMT_YUV420P] = {
67 7e7e5940 Fabrice Bellard
        .nb_channels = 3,
68 b6147995 Fabrice Bellard
        .color_type = FF_COLOR_YUV,
69 7e7e5940 Fabrice Bellard
        .pixel_type = FF_PIXEL_PLANAR,
70 b6147995 Fabrice Bellard
        .depth = 8,
71 524c6b63 Fabrice Bellard
    },
72
    [PIX_FMT_YUV422P] = {
73 7e7e5940 Fabrice Bellard
        .nb_channels = 3,
74 b6147995 Fabrice Bellard
        .color_type = FF_COLOR_YUV,
75 7e7e5940 Fabrice Bellard
        .pixel_type = FF_PIXEL_PLANAR,
76 b6147995 Fabrice Bellard
        .depth = 8,
77 524c6b63 Fabrice Bellard
    },
78
    [PIX_FMT_YUV444P] = {
79 7e7e5940 Fabrice Bellard
        .nb_channels = 3,
80 b6147995 Fabrice Bellard
        .color_type = FF_COLOR_YUV,
81 7e7e5940 Fabrice Bellard
        .pixel_type = FF_PIXEL_PLANAR,
82 b6147995 Fabrice Bellard
        .depth = 8,
83 524c6b63 Fabrice Bellard
    },
84 71e445fc Diego Biurrun
    [PIX_FMT_YUYV422] = {
85 7e7e5940 Fabrice Bellard
        .nb_channels = 1,
86 b6147995 Fabrice Bellard
        .color_type = FF_COLOR_YUV,
87 7e7e5940 Fabrice Bellard
        .pixel_type = FF_PIXEL_PACKED,
88 b6147995 Fabrice Bellard
        .depth = 8,
89 524c6b63 Fabrice Bellard
    },
90 ebb177dd Todd Kirby
    [PIX_FMT_UYVY422] = {
91
        .nb_channels = 1,
92
        .color_type = FF_COLOR_YUV,
93
        .pixel_type = FF_PIXEL_PACKED,
94
        .depth = 8,
95
    },
96 524c6b63 Fabrice Bellard
    [PIX_FMT_YUV410P] = {
97 7e7e5940 Fabrice Bellard
        .nb_channels = 3,
98 b6147995 Fabrice Bellard
        .color_type = FF_COLOR_YUV,
99 7e7e5940 Fabrice Bellard
        .pixel_type = FF_PIXEL_PLANAR,
100 b6147995 Fabrice Bellard
        .depth = 8,
101 524c6b63 Fabrice Bellard
    },
102
    [PIX_FMT_YUV411P] = {
103 7e7e5940 Fabrice Bellard
        .nb_channels = 3,
104 b6147995 Fabrice Bellard
        .color_type = FF_COLOR_YUV,
105 7e7e5940 Fabrice Bellard
        .pixel_type = FF_PIXEL_PLANAR,
106 b6147995 Fabrice Bellard
        .depth = 8,
107 524c6b63 Fabrice Bellard
    },
108 4196cfb7 Andreas Öman
    [PIX_FMT_YUV440P] = {
109
        .nb_channels = 3,
110
        .color_type = FF_COLOR_YUV,
111
        .pixel_type = FF_PIXEL_PLANAR,
112
        .depth = 8,
113
    },
114 35f6c154 Lars Täuber
    [PIX_FMT_YUV420P16LE] = {
115 6c2a8608 Michael Niedermayer
        .nb_channels = 3,
116
        .color_type = FF_COLOR_YUV,
117
        .pixel_type = FF_PIXEL_PLANAR,
118
        .depth = 16,
119
    },
120 35f6c154 Lars Täuber
    [PIX_FMT_YUV422P16LE] = {
121 6c2a8608 Michael Niedermayer
        .nb_channels = 3,
122
        .color_type = FF_COLOR_YUV,
123
        .pixel_type = FF_PIXEL_PLANAR,
124
        .depth = 16,
125
    },
126 35f6c154 Lars Täuber
    [PIX_FMT_YUV444P16LE] = {
127 6c2a8608 Michael Niedermayer
        .nb_channels = 3,
128
        .color_type = FF_COLOR_YUV,
129
        .pixel_type = FF_PIXEL_PLANAR,
130
        .depth = 16,
131
    },
132 35f6c154 Lars Täuber
    [PIX_FMT_YUV420P16BE] = {
133 6c2a8608 Michael Niedermayer
        .nb_channels = 3,
134
        .color_type = FF_COLOR_YUV,
135
        .pixel_type = FF_PIXEL_PLANAR,
136
        .depth = 16,
137
    },
138 35f6c154 Lars Täuber
    [PIX_FMT_YUV422P16BE] = {
139 6c2a8608 Michael Niedermayer
        .nb_channels = 3,
140
        .color_type = FF_COLOR_YUV,
141
        .pixel_type = FF_PIXEL_PLANAR,
142
        .depth = 16,
143
    },
144 35f6c154 Lars Täuber
    [PIX_FMT_YUV444P16BE] = {
145 6c2a8608 Michael Niedermayer
        .nb_channels = 3,
146
        .color_type = FF_COLOR_YUV,
147
        .pixel_type = FF_PIXEL_PLANAR,
148
        .depth = 16,
149
    },
150
151 524c6b63 Fabrice Bellard
152 b70335a2 Aurelien Jacobs
    /* YUV formats with alpha plane */
153
    [PIX_FMT_YUVA420P] = {
154
        .nb_channels = 4,
155
        .color_type = FF_COLOR_YUV,
156
        .pixel_type = FF_PIXEL_PLANAR,
157
        .depth = 8,
158
    },
159
160 b6147995 Fabrice Bellard
    /* JPEG YUV */
161
    [PIX_FMT_YUVJ420P] = {
162 7e7e5940 Fabrice Bellard
        .nb_channels = 3,
163 b6147995 Fabrice Bellard
        .color_type = FF_COLOR_YUV_JPEG,
164 7e7e5940 Fabrice Bellard
        .pixel_type = FF_PIXEL_PLANAR,
165 b6147995 Fabrice Bellard
        .depth = 8,
166
    },
167
    [PIX_FMT_YUVJ422P] = {
168 7e7e5940 Fabrice Bellard
        .nb_channels = 3,
169 b6147995 Fabrice Bellard
        .color_type = FF_COLOR_YUV_JPEG,
170 7e7e5940 Fabrice Bellard
        .pixel_type = FF_PIXEL_PLANAR,
171 b6147995 Fabrice Bellard
        .depth = 8,
172
    },
173
    [PIX_FMT_YUVJ444P] = {
174 7e7e5940 Fabrice Bellard
        .nb_channels = 3,
175 b6147995 Fabrice Bellard
        .color_type = FF_COLOR_YUV_JPEG,
176 7e7e5940 Fabrice Bellard
        .pixel_type = FF_PIXEL_PLANAR,
177 b6147995 Fabrice Bellard
        .depth = 8,
178
    },
179 4196cfb7 Andreas Öman
    [PIX_FMT_YUVJ440P] = {
180
        .nb_channels = 3,
181
        .color_type = FF_COLOR_YUV_JPEG,
182
        .pixel_type = FF_PIXEL_PLANAR,
183
        .depth = 8,
184
    },
185 b6147995 Fabrice Bellard
186 524c6b63 Fabrice Bellard
    /* RGB formats */
187
    [PIX_FMT_RGB24] = {
188 7e7e5940 Fabrice Bellard
        .nb_channels = 3,
189 b6147995 Fabrice Bellard
        .color_type = FF_COLOR_RGB,
190 7e7e5940 Fabrice Bellard
        .pixel_type = FF_PIXEL_PACKED,
191 b6147995 Fabrice Bellard
        .depth = 8,
192 524c6b63 Fabrice Bellard
    },
193
    [PIX_FMT_BGR24] = {
194 7e7e5940 Fabrice Bellard
        .nb_channels = 3,
195 b6147995 Fabrice Bellard
        .color_type = FF_COLOR_RGB,
196 7e7e5940 Fabrice Bellard
        .pixel_type = FF_PIXEL_PACKED,
197 b6147995 Fabrice Bellard
        .depth = 8,
198 524c6b63 Fabrice Bellard
    },
199 6e08ca9c Stefano Sabatini
    [PIX_FMT_ARGB] = {
200 7e7e5940 Fabrice Bellard
        .nb_channels = 4, .is_alpha = 1,
201 b6147995 Fabrice Bellard
        .color_type = FF_COLOR_RGB,
202 7e7e5940 Fabrice Bellard
        .pixel_type = FF_PIXEL_PACKED,
203 b6147995 Fabrice Bellard
        .depth = 8,
204 524c6b63 Fabrice Bellard
    },
205 88c21a6f Peter Ross
    [PIX_FMT_RGB48BE] = {
206
        .nb_channels = 3,
207
        .color_type = FF_COLOR_RGB,
208
        .pixel_type = FF_PIXEL_PACKED,
209
        .depth = 16,
210
    },
211
    [PIX_FMT_RGB48LE] = {
212
        .nb_channels = 3,
213
        .color_type = FF_COLOR_RGB,
214
        .pixel_type = FF_PIXEL_PACKED,
215
        .depth = 16,
216
    },
217 f82674e5 Stefano Sabatini
    [PIX_FMT_RGB565BE] = {
218 7e7e5940 Fabrice Bellard
        .nb_channels = 3,
219 b6147995 Fabrice Bellard
        .color_type = FF_COLOR_RGB,
220 7e7e5940 Fabrice Bellard
        .pixel_type = FF_PIXEL_PACKED,
221 b6147995 Fabrice Bellard
        .depth = 5,
222 524c6b63 Fabrice Bellard
    },
223 f82674e5 Stefano Sabatini
    [PIX_FMT_RGB565LE] = {
224
        .nb_channels = 3,
225
        .color_type = FF_COLOR_RGB,
226
        .pixel_type = FF_PIXEL_PACKED,
227
        .depth = 5,
228
    },
229
    [PIX_FMT_RGB555BE] = {
230
        .nb_channels = 3,
231
        .color_type = FF_COLOR_RGB,
232
        .pixel_type = FF_PIXEL_PACKED,
233
        .depth = 5,
234
    },
235
    [PIX_FMT_RGB555LE] = {
236 20d46c03 Alex Beregszaszi
        .nb_channels = 3,
237 b6147995 Fabrice Bellard
        .color_type = FF_COLOR_RGB,
238 7e7e5940 Fabrice Bellard
        .pixel_type = FF_PIXEL_PACKED,
239 b6147995 Fabrice Bellard
        .depth = 5,
240 524c6b63 Fabrice Bellard
    },
241
242
    /* gray / mono formats */
243 34380af0 Kostya Shishkov
    [PIX_FMT_GRAY16BE] = {
244
        .nb_channels = 1,
245
        .color_type = FF_COLOR_GRAY,
246
        .pixel_type = FF_PIXEL_PLANAR,
247
        .depth = 16,
248
    },
249
    [PIX_FMT_GRAY16LE] = {
250
        .nb_channels = 1,
251
        .color_type = FF_COLOR_GRAY,
252
        .pixel_type = FF_PIXEL_PLANAR,
253
        .depth = 16,
254
    },
255 524c6b63 Fabrice Bellard
    [PIX_FMT_GRAY8] = {
256 7e7e5940 Fabrice Bellard
        .nb_channels = 1,
257 b6147995 Fabrice Bellard
        .color_type = FF_COLOR_GRAY,
258 7e7e5940 Fabrice Bellard
        .pixel_type = FF_PIXEL_PLANAR,
259 b6147995 Fabrice Bellard
        .depth = 8,
260 524c6b63 Fabrice Bellard
    },
261
    [PIX_FMT_MONOWHITE] = {
262 7e7e5940 Fabrice Bellard
        .nb_channels = 1,
263 b6147995 Fabrice Bellard
        .color_type = FF_COLOR_GRAY,
264 7e7e5940 Fabrice Bellard
        .pixel_type = FF_PIXEL_PLANAR,
265 b6147995 Fabrice Bellard
        .depth = 1,
266 524c6b63 Fabrice Bellard
    },
267
    [PIX_FMT_MONOBLACK] = {
268 7e7e5940 Fabrice Bellard
        .nb_channels = 1,
269 b6147995 Fabrice Bellard
        .color_type = FF_COLOR_GRAY,
270 7e7e5940 Fabrice Bellard
        .pixel_type = FF_PIXEL_PLANAR,
271 b6147995 Fabrice Bellard
        .depth = 1,
272 524c6b63 Fabrice Bellard
    },
273 7e6d70d0 Fabrice Bellard
274
    /* paletted formats */
275
    [PIX_FMT_PAL8] = {
276 7e7e5940 Fabrice Bellard
        .nb_channels = 4, .is_alpha = 1,
277 b6147995 Fabrice Bellard
        .color_type = FF_COLOR_RGB,
278 7e7e5940 Fabrice Bellard
        .pixel_type = FF_PIXEL_PALETTE,
279 b6147995 Fabrice Bellard
        .depth = 8,
280 7e6d70d0 Fabrice Bellard
    },
281 71e445fc Diego Biurrun
    [PIX_FMT_UYYVYY411] = {
282 f02be79d Roman Shaposhnik
        .nb_channels = 1,
283
        .color_type = FF_COLOR_YUV,
284
        .pixel_type = FF_PIXEL_PACKED,
285
        .depth = 8,
286
    },
287 6e08ca9c Stefano Sabatini
    [PIX_FMT_ABGR] = {
288 00b2fa86 Luca Abeni
        .nb_channels = 4, .is_alpha = 1,
289
        .color_type = FF_COLOR_RGB,
290
        .pixel_type = FF_PIXEL_PACKED,
291
        .depth = 8,
292
    },
293 f82674e5 Stefano Sabatini
    [PIX_FMT_BGR565BE] = {
294
        .nb_channels = 3,
295
        .color_type = FF_COLOR_RGB,
296
        .pixel_type = FF_PIXEL_PACKED,
297
        .depth = 5,
298
    },
299
    [PIX_FMT_BGR565LE] = {
300
        .nb_channels = 3,
301
        .color_type = FF_COLOR_RGB,
302
        .pixel_type = FF_PIXEL_PACKED,
303
        .depth = 5,
304
    },
305
    [PIX_FMT_BGR555BE] = {
306 00b2fa86 Luca Abeni
        .nb_channels = 3,
307
        .color_type = FF_COLOR_RGB,
308
        .pixel_type = FF_PIXEL_PACKED,
309
        .depth = 5,
310
    },
311 f82674e5 Stefano Sabatini
    [PIX_FMT_BGR555LE] = {
312 08d23410 Alex Beregszaszi
        .nb_channels = 3,
313 00b2fa86 Luca Abeni
        .color_type = FF_COLOR_RGB,
314
        .pixel_type = FF_PIXEL_PACKED,
315
        .depth = 5,
316
    },
317
    [PIX_FMT_RGB8] = {
318
        .nb_channels = 1,
319
        .color_type = FF_COLOR_RGB,
320
        .pixel_type = FF_PIXEL_PACKED,
321
        .depth = 8,
322
    },
323
    [PIX_FMT_RGB4] = {
324
        .nb_channels = 1,
325
        .color_type = FF_COLOR_RGB,
326
        .pixel_type = FF_PIXEL_PACKED,
327
        .depth = 4,
328
    },
329
    [PIX_FMT_RGB4_BYTE] = {
330
        .nb_channels = 1,
331
        .color_type = FF_COLOR_RGB,
332
        .pixel_type = FF_PIXEL_PACKED,
333
        .depth = 8,
334
    },
335
    [PIX_FMT_BGR8] = {
336
        .nb_channels = 1,
337
        .color_type = FF_COLOR_RGB,
338
        .pixel_type = FF_PIXEL_PACKED,
339
        .depth = 8,
340
    },
341
    [PIX_FMT_BGR4] = {
342
        .nb_channels = 1,
343
        .color_type = FF_COLOR_RGB,
344
        .pixel_type = FF_PIXEL_PACKED,
345
        .depth = 4,
346
    },
347
    [PIX_FMT_BGR4_BYTE] = {
348
        .nb_channels = 1,
349
        .color_type = FF_COLOR_RGB,
350
        .pixel_type = FF_PIXEL_PACKED,
351
        .depth = 8,
352
    },
353
    [PIX_FMT_NV12] = {
354
        .nb_channels = 2,
355
        .color_type = FF_COLOR_YUV,
356
        .pixel_type = FF_PIXEL_PLANAR,
357
        .depth = 8,
358
    },
359
    [PIX_FMT_NV21] = {
360
        .nb_channels = 2,
361
        .color_type = FF_COLOR_YUV,
362
        .pixel_type = FF_PIXEL_PLANAR,
363
        .depth = 8,
364
    },
365
366 6e08ca9c Stefano Sabatini
    [PIX_FMT_BGRA] = {
367 00b2fa86 Luca Abeni
        .nb_channels = 4, .is_alpha = 1,
368
        .color_type = FF_COLOR_RGB,
369
        .pixel_type = FF_PIXEL_PACKED,
370
        .depth = 8,
371
    },
372 6e08ca9c Stefano Sabatini
    [PIX_FMT_RGBA] = {
373 00b2fa86 Luca Abeni
        .nb_channels = 4, .is_alpha = 1,
374
        .color_type = FF_COLOR_RGB,
375
        .pixel_type = FF_PIXEL_PACKED,
376
        .depth = 8,
377
    },
378 524c6b63 Fabrice Bellard
};
379
380 a61ec8e7 Stefano Sabatini
void avcodec_get_chroma_sub_sample(enum PixelFormat pix_fmt, int *h_shift, int *v_shift)
381 524c6b63 Fabrice Bellard
{
382 38264abb Stefano Sabatini
    *h_shift = av_pix_fmt_descriptors[pix_fmt].log2_chroma_w;
383
    *v_shift = av_pix_fmt_descriptors[pix_fmt].log2_chroma_h;
384 524c6b63 Fabrice Bellard
}
385
386 a61ec8e7 Stefano Sabatini
const char *avcodec_get_pix_fmt_name(enum PixelFormat pix_fmt)
387 524c6b63 Fabrice Bellard
{
388
    if (pix_fmt < 0 || pix_fmt >= PIX_FMT_NB)
389 42a45a03 Peter Ross
        return NULL;
390 524c6b63 Fabrice Bellard
    else
391 797229a6 Stefano Sabatini
        return av_pix_fmt_descriptors[pix_fmt].name;
392 524c6b63 Fabrice Bellard
}
393
394 80a07f6e Stefano Sabatini
#if LIBAVCODEC_VERSION_MAJOR < 53
395 d89f692f Stefano Sabatini
enum PixelFormat avcodec_get_pix_fmt(const char *name)
396
{
397 80a07f6e Stefano Sabatini
    return av_get_pix_fmt(name);
398 d89f692f Stefano Sabatini
}
399 80a07f6e Stefano Sabatini
#endif
400 d89f692f Stefano Sabatini
401 a61ec8e7 Stefano Sabatini
void avcodec_pix_fmt_string (char *buf, int buf_size, enum PixelFormat pix_fmt)
402 c3b95b1d Stefano Sabatini
{
403
    /* print header */
404
    if (pix_fmt < 0)
405
        snprintf (buf, buf_size,
406
                  "name      " " nb_channels" " depth" " is_alpha"
407
            );
408 8e6f8869 Michael Niedermayer
    else{
409
        PixFmtInfo info= pix_fmt_info[pix_fmt];
410
411
        char is_alpha_char= info.is_alpha ? 'y' : 'n';
412
413 c3b95b1d Stefano Sabatini
        snprintf (buf, buf_size,
414 65935bc7 Justin Ruggles
                  "%-11s %5d %9d %6c",
415 106c72fa Stefano Sabatini
                  av_pix_fmt_descriptors[pix_fmt].name,
416 c3b95b1d Stefano Sabatini
                  info.nb_channels,
417
                  info.depth,
418
                  is_alpha_char
419
            );
420 8e6f8869 Michael Niedermayer
    }
421 c3b95b1d Stefano Sabatini
}
422
423 c269cf68 Michael Niedermayer
int ff_is_hwaccel_pix_fmt(enum PixelFormat pix_fmt)
424
{
425 8e861e1b Stefano Sabatini
    return av_pix_fmt_descriptors[pix_fmt].flags & PIX_FMT_HWACCEL;
426 c269cf68 Michael Niedermayer
}
427
428 6337178b Michael Niedermayer
int ff_set_systematic_pal(uint32_t pal[256], enum PixelFormat pix_fmt){
429
    int i;
430
431
    for(i=0; i<256; i++){
432
        int r,g,b;
433
434
        switch(pix_fmt) {
435
        case PIX_FMT_RGB8:
436
            r= (i>>5    )*36;
437
            g= ((i>>2)&7)*36;
438
            b= (i&3     )*85;
439
            break;
440
        case PIX_FMT_BGR8:
441
            b= (i>>6    )*85;
442
            g= ((i>>3)&7)*36;
443
            r= (i&7     )*36;
444
            break;
445
        case PIX_FMT_RGB4_BYTE:
446
            r= (i>>3    )*255;
447
            g= ((i>>1)&3)*85;
448
            b= (i&1     )*255;
449
            break;
450
        case PIX_FMT_BGR4_BYTE:
451
            b= (i>>3    )*255;
452
            g= ((i>>1)&3)*85;
453
            r= (i&1     )*255;
454
            break;
455
        case PIX_FMT_GRAY8:
456
            r=b=g= i;
457
            break;
458 c7efffcb Patrik Kullman
        default:
459
            return -1;
460 6337178b Michael Niedermayer
        }
461
        pal[i] =  b + (g<<8) + (r<<16);
462
    }
463
464
    return 0;
465
}
466
467 a61ec8e7 Stefano Sabatini
int ff_fill_linesize(AVPicture *picture, enum PixelFormat pix_fmt, int width)
468 2a877875 Fabrice Bellard
{
469 cc9853d3 Vitor Sessak
    int w2;
470 14b903f3 Stefano Sabatini
    const AVPixFmtDescriptor *desc = &av_pix_fmt_descriptors[pix_fmt];
471 115329f1 Diego Biurrun
472 cc9853d3 Vitor Sessak
    memset(picture->linesize, 0, sizeof(picture->linesize));
473 0ecca7a4 Michael Niedermayer
474 2a877875 Fabrice Bellard
    switch(pix_fmt) {
475
    case PIX_FMT_YUV420P:
476 4c7e8619 Fabrice Bellard
    case PIX_FMT_YUV422P:
477
    case PIX_FMT_YUV444P:
478
    case PIX_FMT_YUV410P:
479
    case PIX_FMT_YUV411P:
480 4196cfb7 Andreas Öman
    case PIX_FMT_YUV440P:
481 c50c0bc8 Fabrice Bellard
    case PIX_FMT_YUVJ420P:
482
    case PIX_FMT_YUVJ422P:
483
    case PIX_FMT_YUVJ444P:
484 4196cfb7 Andreas Öman
    case PIX_FMT_YUVJ440P:
485 14b903f3 Stefano Sabatini
        w2 = (width + (1 << desc->log2_chroma_w) - 1) >> desc->log2_chroma_w;
486 2a877875 Fabrice Bellard
        picture->linesize[0] = width;
487 4c7e8619 Fabrice Bellard
        picture->linesize[1] = w2;
488
        picture->linesize[2] = w2;
489 cc9853d3 Vitor Sessak
        break;
490 35f6c154 Lars Täuber
    case PIX_FMT_YUV420P16LE:
491
    case PIX_FMT_YUV422P16LE:
492
    case PIX_FMT_YUV444P16LE:
493
    case PIX_FMT_YUV420P16BE:
494
    case PIX_FMT_YUV422P16BE:
495
    case PIX_FMT_YUV444P16BE:
496 14b903f3 Stefano Sabatini
        w2 = (width + (1 << desc->log2_chroma_w) - 1) >> desc->log2_chroma_w;
497 6c2a8608 Michael Niedermayer
        picture->linesize[0] = 2*width;
498
        picture->linesize[1] = 2*w2;
499
        picture->linesize[2] = 2*w2;
500
        break;
501 b70335a2 Aurelien Jacobs
    case PIX_FMT_YUVA420P:
502 14b903f3 Stefano Sabatini
        w2 = (width + (1 << desc->log2_chroma_w) - 1) >> desc->log2_chroma_w;
503 b70335a2 Aurelien Jacobs
        picture->linesize[0] = width;
504
        picture->linesize[1] = w2;
505
        picture->linesize[2] = w2;
506
        picture->linesize[3] = width;
507 cc9853d3 Vitor Sessak
        break;
508 00b2fa86 Luca Abeni
    case PIX_FMT_NV12:
509
    case PIX_FMT_NV21:
510 14b903f3 Stefano Sabatini
        w2 = (width + (1 << desc->log2_chroma_w) - 1) >> desc->log2_chroma_w;
511 00b2fa86 Luca Abeni
        picture->linesize[0] = width;
512 f2526204 Ramiro Polla
        picture->linesize[1] = 2 * w2;
513 cc9853d3 Vitor Sessak
        break;
514 2a877875 Fabrice Bellard
    case PIX_FMT_RGB24:
515
    case PIX_FMT_BGR24:
516
        picture->linesize[0] = width * 3;
517 cc9853d3 Vitor Sessak
        break;
518 6e08ca9c Stefano Sabatini
    case PIX_FMT_ARGB:
519
    case PIX_FMT_ABGR:
520
    case PIX_FMT_RGBA:
521
    case PIX_FMT_BGRA:
522 2a877875 Fabrice Bellard
        picture->linesize[0] = width * 4;
523 cc9853d3 Vitor Sessak
        break;
524 88c21a6f Peter Ross
    case PIX_FMT_RGB48BE:
525
    case PIX_FMT_RGB48LE:
526
        picture->linesize[0] = width * 6;
527
        break;
528 34380af0 Kostya Shishkov
    case PIX_FMT_GRAY16BE:
529
    case PIX_FMT_GRAY16LE:
530 ffd38d8b Alexis Ballier
    case PIX_FMT_BGR555BE:
531
    case PIX_FMT_BGR555LE:
532
    case PIX_FMT_BGR565BE:
533
    case PIX_FMT_BGR565LE:
534
    case PIX_FMT_RGB555BE:
535
    case PIX_FMT_RGB555LE:
536
    case PIX_FMT_RGB565BE:
537
    case PIX_FMT_RGB565LE:
538 71e445fc Diego Biurrun
    case PIX_FMT_YUYV422:
539 2a877875 Fabrice Bellard
        picture->linesize[0] = width * 2;
540 cc9853d3 Vitor Sessak
        break;
541 ebb177dd Todd Kirby
    case PIX_FMT_UYVY422:
542
        picture->linesize[0] = width * 2;
543 cc9853d3 Vitor Sessak
        break;
544 71e445fc Diego Biurrun
    case PIX_FMT_UYYVYY411:
545 f02be79d Roman Shaposhnik
        picture->linesize[0] = width + width/2;
546 cc9853d3 Vitor Sessak
        break;
547 00b2fa86 Luca Abeni
    case PIX_FMT_RGB4:
548
    case PIX_FMT_BGR4:
549 cc9853d3 Vitor Sessak
        picture->linesize[0] = width / 2;
550
        break;
551
    case PIX_FMT_MONOWHITE:
552
    case PIX_FMT_MONOBLACK:
553
        picture->linesize[0] = (width + 7) >> 3;
554
        break;
555
    case PIX_FMT_PAL8:
556 6337178b Michael Niedermayer
    case PIX_FMT_RGB8:
557
    case PIX_FMT_BGR8:
558
    case PIX_FMT_RGB4_BYTE:
559
    case PIX_FMT_BGR4_BYTE:
560
    case PIX_FMT_GRAY8:
561 cc9853d3 Vitor Sessak
        picture->linesize[0] = width;
562
        break;
563
    default:
564
        return -1;
565
    }
566
    return 0;
567
}
568
569 a61ec8e7 Stefano Sabatini
int ff_fill_pointer(AVPicture *picture, uint8_t *ptr, enum PixelFormat pix_fmt,
570 cc9853d3 Vitor Sessak
                    int height)
571
{
572
    int size, h2, size2;
573 14b903f3 Stefano Sabatini
    const AVPixFmtDescriptor *desc = &av_pix_fmt_descriptors[pix_fmt];
574 cc9853d3 Vitor Sessak
575
    size = picture->linesize[0] * height;
576
    switch(pix_fmt) {
577
    case PIX_FMT_YUV420P:
578
    case PIX_FMT_YUV422P:
579
    case PIX_FMT_YUV444P:
580
    case PIX_FMT_YUV410P:
581
    case PIX_FMT_YUV411P:
582
    case PIX_FMT_YUV440P:
583
    case PIX_FMT_YUVJ420P:
584
    case PIX_FMT_YUVJ422P:
585
    case PIX_FMT_YUVJ444P:
586
    case PIX_FMT_YUVJ440P:
587 35f6c154 Lars Täuber
    case PIX_FMT_YUV420P16LE:
588
    case PIX_FMT_YUV422P16LE:
589
    case PIX_FMT_YUV444P16LE:
590
    case PIX_FMT_YUV420P16BE:
591
    case PIX_FMT_YUV422P16BE:
592
    case PIX_FMT_YUV444P16BE:
593 14b903f3 Stefano Sabatini
        h2 = (height + (1 << desc->log2_chroma_h) - 1) >> desc->log2_chroma_h;
594 cc9853d3 Vitor Sessak
        size2 = picture->linesize[1] * h2;
595 00b2fa86 Luca Abeni
        picture->data[0] = ptr;
596 cc9853d3 Vitor Sessak
        picture->data[1] = picture->data[0] + size;
597
        picture->data[2] = picture->data[1] + size2;
598
        picture->data[3] = NULL;
599
        return size + 2 * size2;
600
    case PIX_FMT_YUVA420P:
601 14b903f3 Stefano Sabatini
        h2 = (height + (1 << desc->log2_chroma_h) - 1) >> desc->log2_chroma_h;
602 cc9853d3 Vitor Sessak
        size2 = picture->linesize[1] * h2;
603
        picture->data[0] = ptr;
604
        picture->data[1] = picture->data[0] + size;
605
        picture->data[2] = picture->data[1] + size2;
606
        picture->data[3] = picture->data[1] + size2 + size2;
607
        return 2 * size + 2 * size2;
608
    case PIX_FMT_NV12:
609
    case PIX_FMT_NV21:
610 14b903f3 Stefano Sabatini
        h2 = (height + (1 << desc->log2_chroma_h) - 1) >> desc->log2_chroma_h;
611 f2526204 Ramiro Polla
        size2 = picture->linesize[1] * h2;
612 cc9853d3 Vitor Sessak
        picture->data[0] = ptr;
613
        picture->data[1] = picture->data[0] + size;
614 00b2fa86 Luca Abeni
        picture->data[2] = NULL;
615 b70335a2 Aurelien Jacobs
        picture->data[3] = NULL;
616 f2526204 Ramiro Polla
        return size + size2;
617 cc9853d3 Vitor Sessak
    case PIX_FMT_RGB24:
618
    case PIX_FMT_BGR24:
619 6e08ca9c Stefano Sabatini
    case PIX_FMT_ARGB:
620
    case PIX_FMT_ABGR:
621
    case PIX_FMT_RGBA:
622
    case PIX_FMT_BGRA:
623 88c21a6f Peter Ross
    case PIX_FMT_RGB48BE:
624
    case PIX_FMT_RGB48LE:
625 cc9853d3 Vitor Sessak
    case PIX_FMT_GRAY16BE:
626
    case PIX_FMT_GRAY16LE:
627 ffd38d8b Alexis Ballier
    case PIX_FMT_BGR555BE:
628
    case PIX_FMT_BGR555LE:
629
    case PIX_FMT_BGR565BE:
630
    case PIX_FMT_BGR565LE:
631
    case PIX_FMT_RGB555BE:
632
    case PIX_FMT_RGB555LE:
633
    case PIX_FMT_RGB565BE:
634
    case PIX_FMT_RGB565LE:
635 cc9853d3 Vitor Sessak
    case PIX_FMT_YUYV422:
636
    case PIX_FMT_UYVY422:
637
    case PIX_FMT_UYYVYY411:
638
    case PIX_FMT_RGB4:
639
    case PIX_FMT_BGR4:
640 2a877875 Fabrice Bellard
    case PIX_FMT_MONOWHITE:
641
    case PIX_FMT_MONOBLACK:
642
        picture->data[0] = ptr;
643
        picture->data[1] = NULL;
644
        picture->data[2] = NULL;
645 b70335a2 Aurelien Jacobs
        picture->data[3] = NULL;
646 cc9853d3 Vitor Sessak
        return size;
647 7e6d70d0 Fabrice Bellard
    case PIX_FMT_PAL8:
648 6337178b Michael Niedermayer
    case PIX_FMT_RGB8:
649
    case PIX_FMT_BGR8:
650
    case PIX_FMT_RGB4_BYTE:
651
    case PIX_FMT_BGR4_BYTE:
652
    case PIX_FMT_GRAY8:
653 7e6d70d0 Fabrice Bellard
        size2 = (size + 3) & ~3;
654
        picture->data[0] = ptr;
655
        picture->data[1] = ptr + size2; /* palette is stored here as 256 32 bit words */
656
        picture->data[2] = NULL;
657 b70335a2 Aurelien Jacobs
        picture->data[3] = NULL;
658 7e6d70d0 Fabrice Bellard
        return size2 + 256 * 4;
659 2a877875 Fabrice Bellard
    default:
660
        picture->data[0] = NULL;
661
        picture->data[1] = NULL;
662
        picture->data[2] = NULL;
663 7e6d70d0 Fabrice Bellard
        picture->data[3] = NULL;
664 2a877875 Fabrice Bellard
        return -1;
665
    }
666
}
667
668 cc9853d3 Vitor Sessak
int avpicture_fill(AVPicture *picture, uint8_t *ptr,
669 a61ec8e7 Stefano Sabatini
                   enum PixelFormat pix_fmt, int width, int height)
670 cc9853d3 Vitor Sessak
{
671
672
    if(avcodec_check_dimensions(NULL, width, height))
673
        return -1;
674
675 fba95d3c Vitor Sessak
    if (ff_fill_linesize(picture, pix_fmt, width))
676 cc9853d3 Vitor Sessak
        return -1;
677
678 fba95d3c Vitor Sessak
    return ff_fill_pointer(picture, ptr, pix_fmt, height);
679 cc9853d3 Vitor Sessak
}
680
681 a61ec8e7 Stefano Sabatini
int avpicture_layout(const AVPicture* src, enum PixelFormat pix_fmt, int width, int height,
682 63167088 Roman Shaposhnik
                     unsigned char *dest, int dest_size)
683
{
684 62a05b5b Stefan Huehner
    const PixFmtInfo* pf = &pix_fmt_info[pix_fmt];
685 14b903f3 Stefano Sabatini
    const AVPixFmtDescriptor *desc = &av_pix_fmt_descriptors[pix_fmt];
686 5f59207d Cédric Schieli
    int i, j, w, ow, h, oh, data_planes;
687 115329f1 Diego Biurrun
    const unsigned char* s;
688 63167088 Roman Shaposhnik
    int size = avpicture_get_size(pix_fmt, width, height);
689
690 0ecca7a4 Michael Niedermayer
    if (size > dest_size || size < 0)
691 63167088 Roman Shaposhnik
        return -1;
692
693 affd55a1 Roman Shaposhnik
    if (pf->pixel_type == FF_PIXEL_PACKED || pf->pixel_type == FF_PIXEL_PALETTE) {
694 71e445fc Diego Biurrun
        if (pix_fmt == PIX_FMT_YUYV422 ||
695 115329f1 Diego Biurrun
            pix_fmt == PIX_FMT_UYVY422 ||
696 ffd38d8b Alexis Ballier
            pix_fmt == PIX_FMT_BGR565BE ||
697
            pix_fmt == PIX_FMT_BGR565LE ||
698
            pix_fmt == PIX_FMT_BGR555BE ||
699
            pix_fmt == PIX_FMT_BGR555LE ||
700
            pix_fmt == PIX_FMT_RGB565BE ||
701
            pix_fmt == PIX_FMT_RGB565LE ||
702
            pix_fmt == PIX_FMT_RGB555BE ||
703
            pix_fmt == PIX_FMT_RGB555LE)
704 ebb177dd Todd Kirby
            w = width * 2;
705 71e445fc Diego Biurrun
        else if (pix_fmt == PIX_FMT_UYYVYY411)
706 b16569d2 Ramiro Polla
            w = width + width/2;
707 bb270c08 Diego Biurrun
        else if (pix_fmt == PIX_FMT_PAL8)
708 b16569d2 Ramiro Polla
            w = width;
709 bb270c08 Diego Biurrun
        else
710 b16569d2 Ramiro Polla
            w = width * (pf->depth * pf->nb_channels / 8);
711 bb270c08 Diego Biurrun
712
        data_planes = 1;
713
        h = height;
714 63167088 Roman Shaposhnik
    } else {
715
        data_planes = pf->nb_channels;
716 bb270c08 Diego Biurrun
        w = (width*pf->depth + 7)/8;
717
        h = height;
718 63167088 Roman Shaposhnik
    }
719 115329f1 Diego Biurrun
720 5f59207d Cédric Schieli
    ow = w;
721
    oh = h;
722
723 63167088 Roman Shaposhnik
    for (i=0; i<data_planes; i++) {
724 b16569d2 Ramiro Polla
        if (i == 1) {
725 14b903f3 Stefano Sabatini
            w = ((width >> desc->log2_chroma_w) * pf->depth + 7) / 8;
726
            h = height >> desc->log2_chroma_h;
727 f2526204 Ramiro Polla
            if (pix_fmt == PIX_FMT_NV12 || pix_fmt == PIX_FMT_NV21)
728
                w <<= 1;
729 b16569d2 Ramiro Polla
        } else if (i == 3) {
730
            w = ow;
731
            h = oh;
732
        }
733
        s = src->data[i];
734
        for(j=0; j<h; j++) {
735
            memcpy(dest, s, w);
736
            dest += w;
737
            s += src->linesize[i];
738
        }
739 63167088 Roman Shaposhnik
    }
740 115329f1 Diego Biurrun
741 affd55a1 Roman Shaposhnik
    if (pf->pixel_type == FF_PIXEL_PALETTE)
742 bb270c08 Diego Biurrun
        memcpy((unsigned char *)(((size_t)dest + 3) & ~3), src->data[1], 256 * 4);
743 115329f1 Diego Biurrun
744 63167088 Roman Shaposhnik
    return size;
745
}
746
747 a61ec8e7 Stefano Sabatini
int avpicture_get_size(enum PixelFormat pix_fmt, int width, int height)
748 2a877875 Fabrice Bellard
{
749
    AVPicture dummy_pict;
750 899a8fa1 Reimar Döffinger
    if(avcodec_check_dimensions(NULL, width, height))
751
        return -1;
752
    switch (pix_fmt) {
753
    case PIX_FMT_RGB8:
754
    case PIX_FMT_BGR8:
755
    case PIX_FMT_RGB4_BYTE:
756
    case PIX_FMT_BGR4_BYTE:
757
    case PIX_FMT_GRAY8:
758
        // do not include palette for these pseudo-paletted formats
759
        return width * height;
760
    }
761 2a877875 Fabrice Bellard
    return avpicture_fill(&dummy_pict, NULL, pix_fmt, width, height);
762
}
763
764 a61ec8e7 Stefano Sabatini
int avcodec_get_pix_fmt_loss(enum PixelFormat dst_pix_fmt, enum PixelFormat src_pix_fmt,
765 b6147995 Fabrice Bellard
                             int has_alpha)
766
{
767
    const PixFmtInfo *pf, *ps;
768 14b903f3 Stefano Sabatini
    const AVPixFmtDescriptor *src_desc = &av_pix_fmt_descriptors[src_pix_fmt];
769
    const AVPixFmtDescriptor *dst_desc = &av_pix_fmt_descriptors[dst_pix_fmt];
770 b6147995 Fabrice Bellard
    int loss;
771
772
    ps = &pix_fmt_info[src_pix_fmt];
773
774
    /* compute loss */
775
    loss = 0;
776
    pf = &pix_fmt_info[dst_pix_fmt];
777 0a9ad8d1 Fabrice Bellard
    if (pf->depth < ps->depth ||
778 ffd38d8b Alexis Ballier
        ((dst_pix_fmt == PIX_FMT_RGB555BE || dst_pix_fmt == PIX_FMT_RGB555LE) &&
779
         (src_pix_fmt == PIX_FMT_RGB565BE || src_pix_fmt == PIX_FMT_RGB565LE)))
780 b6147995 Fabrice Bellard
        loss |= FF_LOSS_DEPTH;
781 14b903f3 Stefano Sabatini
    if (dst_desc->log2_chroma_w > src_desc->log2_chroma_w ||
782
        dst_desc->log2_chroma_h > src_desc->log2_chroma_h)
783 b6147995 Fabrice Bellard
        loss |= FF_LOSS_RESOLUTION;
784
    switch(pf->color_type) {
785
    case FF_COLOR_RGB:
786
        if (ps->color_type != FF_COLOR_RGB &&
787
            ps->color_type != FF_COLOR_GRAY)
788
            loss |= FF_LOSS_COLORSPACE;
789
        break;
790
    case FF_COLOR_GRAY:
791
        if (ps->color_type != FF_COLOR_GRAY)
792
            loss |= FF_LOSS_COLORSPACE;
793
        break;
794
    case FF_COLOR_YUV:
795
        if (ps->color_type != FF_COLOR_YUV)
796
            loss |= FF_LOSS_COLORSPACE;
797
        break;
798
    case FF_COLOR_YUV_JPEG:
799
        if (ps->color_type != FF_COLOR_YUV_JPEG &&
800 115329f1 Diego Biurrun
            ps->color_type != FF_COLOR_YUV &&
801 0a9ad8d1 Fabrice Bellard
            ps->color_type != FF_COLOR_GRAY)
802 b6147995 Fabrice Bellard
            loss |= FF_LOSS_COLORSPACE;
803
        break;
804
    default:
805
        /* fail safe test */
806
        if (ps->color_type != pf->color_type)
807
            loss |= FF_LOSS_COLORSPACE;
808
        break;
809
    }
810
    if (pf->color_type == FF_COLOR_GRAY &&
811
        ps->color_type != FF_COLOR_GRAY)
812
        loss |= FF_LOSS_CHROMA;
813
    if (!pf->is_alpha && (ps->is_alpha && has_alpha))
814
        loss |= FF_LOSS_ALPHA;
815 115329f1 Diego Biurrun
    if (pf->pixel_type == FF_PIXEL_PALETTE &&
816 7e7e5940 Fabrice Bellard
        (ps->pixel_type != FF_PIXEL_PALETTE && ps->color_type != FF_COLOR_GRAY))
817 b6147995 Fabrice Bellard
        loss |= FF_LOSS_COLORQUANT;
818
    return loss;
819
}
820
821 a61ec8e7 Stefano Sabatini
static int avg_bits_per_pixel(enum PixelFormat pix_fmt)
822 b6147995 Fabrice Bellard
{
823
    int bits;
824
    const PixFmtInfo *pf;
825 14b903f3 Stefano Sabatini
    const AVPixFmtDescriptor *desc = &av_pix_fmt_descriptors[pix_fmt];
826 b6147995 Fabrice Bellard
827
    pf = &pix_fmt_info[pix_fmt];
828 7e7e5940 Fabrice Bellard
    switch(pf->pixel_type) {
829
    case FF_PIXEL_PACKED:
830 b6147995 Fabrice Bellard
        switch(pix_fmt) {
831 71e445fc Diego Biurrun
        case PIX_FMT_YUYV422:
832 ebb177dd Todd Kirby
        case PIX_FMT_UYVY422:
833 ffd38d8b Alexis Ballier
        case PIX_FMT_RGB565BE:
834
        case PIX_FMT_RGB565LE:
835
        case PIX_FMT_RGB555BE:
836
        case PIX_FMT_RGB555LE:
837
        case PIX_FMT_BGR565BE:
838
        case PIX_FMT_BGR565LE:
839
        case PIX_FMT_BGR555BE:
840
        case PIX_FMT_BGR555LE:
841 b6147995 Fabrice Bellard
            bits = 16;
842
            break;
843 71e445fc Diego Biurrun
        case PIX_FMT_UYYVYY411:
844 bb270c08 Diego Biurrun
            bits = 12;
845
            break;
846 b6147995 Fabrice Bellard
        default:
847 7e7e5940 Fabrice Bellard
            bits = pf->depth * pf->nb_channels;
848 b6147995 Fabrice Bellard
            break;
849
        }
850 7e7e5940 Fabrice Bellard
        break;
851
    case FF_PIXEL_PLANAR:
852 14b903f3 Stefano Sabatini
        if (desc->log2_chroma_w == 0 && desc->log2_chroma_h == 0) {
853 7e7e5940 Fabrice Bellard
            bits = pf->depth * pf->nb_channels;
854
        } else {
855 115329f1 Diego Biurrun
            bits = pf->depth + ((2 * pf->depth) >>
856 14b903f3 Stefano Sabatini
                                (desc->log2_chroma_w + desc->log2_chroma_h));
857 7e7e5940 Fabrice Bellard
        }
858
        break;
859
    case FF_PIXEL_PALETTE:
860
        bits = 8;
861
        break;
862
    default:
863
        bits = -1;
864
        break;
865 b6147995 Fabrice Bellard
    }
866
    return bits;
867
}
868
869 a61ec8e7 Stefano Sabatini
static enum PixelFormat avcodec_find_best_pix_fmt1(int64_t pix_fmt_mask,
870
                                      enum PixelFormat src_pix_fmt,
871 b6147995 Fabrice Bellard
                                      int has_alpha,
872
                                      int loss_mask)
873
{
874 a61ec8e7 Stefano Sabatini
    int dist, i, loss, min_dist;
875
    enum PixelFormat dst_pix_fmt;
876 b6147995 Fabrice Bellard
877
    /* find exact color match with smallest size */
878 f0bc8449 Carl Eugen Hoyos
    dst_pix_fmt = PIX_FMT_NONE;
879 b6147995 Fabrice Bellard
    min_dist = 0x7fffffff;
880
    for(i = 0;i < PIX_FMT_NB; i++) {
881 31c3a4dc Anders Grönberg
        if (pix_fmt_mask & (1ULL << i)) {
882 b6147995 Fabrice Bellard
            loss = avcodec_get_pix_fmt_loss(i, src_pix_fmt, has_alpha) & loss_mask;
883
            if (loss == 0) {
884
                dist = avg_bits_per_pixel(i);
885
                if (dist < min_dist) {
886
                    min_dist = dist;
887
                    dst_pix_fmt = i;
888
                }
889
            }
890
        }
891
    }
892
    return dst_pix_fmt;
893
}
894
895 a61ec8e7 Stefano Sabatini
enum PixelFormat avcodec_find_best_pix_fmt(int64_t pix_fmt_mask, enum PixelFormat src_pix_fmt,
896 b6147995 Fabrice Bellard
                              int has_alpha, int *loss_ptr)
897
{
898 a61ec8e7 Stefano Sabatini
    enum PixelFormat dst_pix_fmt;
899
    int loss_mask, i;
900 b6147995 Fabrice Bellard
    static const int loss_mask_order[] = {
901
        ~0, /* no loss first */
902
        ~FF_LOSS_ALPHA,
903
        ~FF_LOSS_RESOLUTION,
904
        ~(FF_LOSS_COLORSPACE | FF_LOSS_RESOLUTION),
905
        ~FF_LOSS_COLORQUANT,
906
        ~FF_LOSS_DEPTH,
907
        0,
908
    };
909
910
    /* try with successive loss */
911
    i = 0;
912
    for(;;) {
913
        loss_mask = loss_mask_order[i++];
914 115329f1 Diego Biurrun
        dst_pix_fmt = avcodec_find_best_pix_fmt1(pix_fmt_mask, src_pix_fmt,
915 b6147995 Fabrice Bellard
                                                 has_alpha, loss_mask);
916
        if (dst_pix_fmt >= 0)
917
            goto found;
918
        if (loss_mask == 0)
919
            break;
920
    }
921 f0bc8449 Carl Eugen Hoyos
    return PIX_FMT_NONE;
922 b6147995 Fabrice Bellard
 found:
923
    if (loss_ptr)
924
        *loss_ptr = avcodec_get_pix_fmt_loss(dst_pix_fmt, src_pix_fmt, has_alpha);
925
    return dst_pix_fmt;
926
}
927
928 54009d42 Michael Niedermayer
void ff_img_copy_plane(uint8_t *dst, int dst_wrap,
929 e352ff08 Fabrice Bellard
                           const uint8_t *src, int src_wrap,
930
                           int width, int height)
931 7e7e5940 Fabrice Bellard
{
932 115329f1 Diego Biurrun
    if((!dst) || (!src))
933 5b2ad9f5 Michael Niedermayer
        return;
934 7e7e5940 Fabrice Bellard
    for(;height > 0; height--) {
935
        memcpy(dst, src, width);
936
        dst += dst_wrap;
937
        src += src_wrap;
938
    }
939
}
940
941 6dd36490 Vitor Sessak
int ff_get_plane_bytewidth(enum PixelFormat pix_fmt, int width, int plane)
942 7e7e5940 Fabrice Bellard
{
943 22ed53e5 Vitor Sessak
    int bits;
944 62a05b5b Stefan Huehner
    const PixFmtInfo *pf = &pix_fmt_info[pix_fmt];
945 14b903f3 Stefano Sabatini
    const AVPixFmtDescriptor *desc = &av_pix_fmt_descriptors[pix_fmt];
946 115329f1 Diego Biurrun
947 7e7e5940 Fabrice Bellard
    pf = &pix_fmt_info[pix_fmt];
948
    switch(pf->pixel_type) {
949
    case FF_PIXEL_PACKED:
950
        switch(pix_fmt) {
951 71e445fc Diego Biurrun
        case PIX_FMT_YUYV422:
952 ebb177dd Todd Kirby
        case PIX_FMT_UYVY422:
953 ffd38d8b Alexis Ballier
        case PIX_FMT_RGB565BE:
954
        case PIX_FMT_RGB565LE:
955
        case PIX_FMT_RGB555BE:
956
        case PIX_FMT_RGB555LE:
957
        case PIX_FMT_BGR565BE:
958
        case PIX_FMT_BGR565LE:
959
        case PIX_FMT_BGR555BE:
960
        case PIX_FMT_BGR555LE:
961 7e7e5940 Fabrice Bellard
            bits = 16;
962
            break;
963 71e445fc Diego Biurrun
        case PIX_FMT_UYYVYY411:
964 bb270c08 Diego Biurrun
            bits = 12;
965
            break;
966 7e7e5940 Fabrice Bellard
        default:
967
            bits = pf->depth * pf->nb_channels;
968
            break;
969
        }
970 22ed53e5 Vitor Sessak
        return (width * bits + 7) >> 3;
971
        break;
972
    case FF_PIXEL_PLANAR:
973
            if (plane == 1 || plane == 2)
974 14b903f3 Stefano Sabatini
                width= -((-width)>>desc->log2_chroma_w);
975 22ed53e5 Vitor Sessak
976
            return (width * pf->depth + 7) >> 3;
977
        break;
978
    case FF_PIXEL_PALETTE:
979
        if (plane == 0)
980
            return width;
981 7e7e5940 Fabrice Bellard
        break;
982 22ed53e5 Vitor Sessak
    }
983
984
    return -1;
985
}
986
987
void av_picture_copy(AVPicture *dst, const AVPicture *src,
988 a61ec8e7 Stefano Sabatini
                     enum PixelFormat pix_fmt, int width, int height)
989 22ed53e5 Vitor Sessak
{
990
    int i;
991
    const PixFmtInfo *pf = &pix_fmt_info[pix_fmt];
992 14b903f3 Stefano Sabatini
    const AVPixFmtDescriptor *desc = &av_pix_fmt_descriptors[pix_fmt];
993 22ed53e5 Vitor Sessak
994
    switch(pf->pixel_type) {
995
    case FF_PIXEL_PACKED:
996 7e7e5940 Fabrice Bellard
    case FF_PIXEL_PLANAR:
997
        for(i = 0; i < pf->nb_channels; i++) {
998 bc48bb08 Art Clarke
            int h;
999 6dd36490 Vitor Sessak
            int bwidth = ff_get_plane_bytewidth(pix_fmt, width, i);
1000 7e7e5940 Fabrice Bellard
            h = height;
1001
            if (i == 1 || i == 2) {
1002 14b903f3 Stefano Sabatini
                h= -((-height)>>desc->log2_chroma_h);
1003 7e7e5940 Fabrice Bellard
            }
1004 54009d42 Michael Niedermayer
            ff_img_copy_plane(dst->data[i], dst->linesize[i],
1005 7e7e5940 Fabrice Bellard
                           src->data[i], src->linesize[i],
1006
                           bwidth, h);
1007
        }
1008
        break;
1009
    case FF_PIXEL_PALETTE:
1010 54009d42 Michael Niedermayer
        ff_img_copy_plane(dst->data[0], dst->linesize[0],
1011 7e7e5940 Fabrice Bellard
                       src->data[0], src->linesize[0],
1012
                       width, height);
1013
        /* copy the palette */
1014 51ae2142 Vitor Sessak
        memcpy(dst->data[1], src->data[1], 4*256);
1015 7e7e5940 Fabrice Bellard
        break;
1016
    }
1017
}
1018 2a877875 Fabrice Bellard
1019 85c242d8 Fabrice Bellard
/* 2x2 -> 1x1 */
1020 54009d42 Michael Niedermayer
void ff_shrink22(uint8_t *dst, int dst_wrap,
1021 e352ff08 Fabrice Bellard
                     const uint8_t *src, int src_wrap,
1022 85c242d8 Fabrice Bellard
                     int width, int height)
1023
{
1024
    int w;
1025 e352ff08 Fabrice Bellard
    const uint8_t *s1, *s2;
1026
    uint8_t *d;
1027 85c242d8 Fabrice Bellard
1028
    for(;height > 0; height--) {
1029
        s1 = src;
1030
        s2 = s1 + src_wrap;
1031
        d = dst;
1032
        for(w = width;w >= 4; w-=4) {
1033 0a9ad8d1 Fabrice Bellard
            d[0] = (s1[0] + s1[1] + s2[0] + s2[1] + 2) >> 2;
1034
            d[1] = (s1[2] + s1[3] + s2[2] + s2[3] + 2) >> 2;
1035
            d[2] = (s1[4] + s1[5] + s2[4] + s2[5] + 2) >> 2;
1036
            d[3] = (s1[6] + s1[7] + s2[6] + s2[7] + 2) >> 2;
1037 85c242d8 Fabrice Bellard
            s1 += 8;
1038
            s2 += 8;
1039
            d += 4;
1040
        }
1041
        for(;w > 0; w--) {
1042 0a9ad8d1 Fabrice Bellard
            d[0] = (s1[0] + s1[1] + s2[0] + s2[1] + 2) >> 2;
1043 85c242d8 Fabrice Bellard
            s1 += 2;
1044
            s2 += 2;
1045
            d++;
1046
        }
1047
        src += 2 * src_wrap;
1048
        dst += dst_wrap;
1049
    }
1050
}
1051
1052 e352ff08 Fabrice Bellard
/* 4x4 -> 1x1 */
1053 54009d42 Michael Niedermayer
void ff_shrink44(uint8_t *dst, int dst_wrap,
1054 e352ff08 Fabrice Bellard
                     const uint8_t *src, int src_wrap,
1055 6742d95d François Revol
                     int width, int height)
1056
{
1057
    int w;
1058 e352ff08 Fabrice Bellard
    const uint8_t *s1, *s2, *s3, *s4;
1059
    uint8_t *d;
1060 6742d95d François Revol
1061
    for(;height > 0; height--) {
1062
        s1 = src;
1063 e352ff08 Fabrice Bellard
        s2 = s1 + src_wrap;
1064
        s3 = s2 + src_wrap;
1065
        s4 = s3 + src_wrap;
1066 6742d95d François Revol
        d = dst;
1067 e352ff08 Fabrice Bellard
        for(w = width;w > 0; w--) {
1068
            d[0] = (s1[0] + s1[1] + s1[2] + s1[3] +
1069
                    s2[0] + s2[1] + s2[2] + s2[3] +
1070
                    s3[0] + s3[1] + s3[2] + s3[3] +
1071
                    s4[0] + s4[1] + s4[2] + s4[3] + 8) >> 4;
1072
            s1 += 4;
1073
            s2 += 4;
1074
            s3 += 4;
1075
            s4 += 4;
1076 6742d95d François Revol
            d++;
1077
        }
1078 e352ff08 Fabrice Bellard
        src += 4 * src_wrap;
1079
        dst += dst_wrap;
1080
    }
1081
}
1082
1083 54009d42 Michael Niedermayer
/* 8x8 -> 1x1 */
1084
void ff_shrink88(uint8_t *dst, int dst_wrap,
1085
                     const uint8_t *src, int src_wrap,
1086
                     int width, int height)
1087
{
1088
    int w, i;
1089
1090
    for(;height > 0; height--) {
1091
        for(w = width;w > 0; w--) {
1092
            int tmp=0;
1093
            for(i=0; i<8; i++){
1094
                tmp += src[0] + src[1] + src[2] + src[3] + src[4] + src[5] + src[6] + src[7];
1095
                src += src_wrap;
1096
            }
1097
            *(dst++) = (tmp + 32)>>6;
1098
            src += 8 - 8*src_wrap;
1099
        }
1100
        src += 8*src_wrap - 8*width;
1101
        dst += dst_wrap - width;
1102
    }
1103
}
1104
1105 524c6b63 Fabrice Bellard
1106 75917b88 Drew Hess
int avpicture_alloc(AVPicture *picture,
1107 a61ec8e7 Stefano Sabatini
                    enum PixelFormat pix_fmt, int width, int height)
1108 524c6b63 Fabrice Bellard
{
1109 2d5545c3 Reimar Döffinger
    int size;
1110 524c6b63 Fabrice Bellard
    void *ptr;
1111
1112 899a8fa1 Reimar Döffinger
    size = avpicture_fill(picture, NULL, pix_fmt, width, height);
1113 0ecca7a4 Michael Niedermayer
    if(size<0)
1114
        goto fail;
1115 524c6b63 Fabrice Bellard
    ptr = av_malloc(size);
1116
    if (!ptr)
1117
        goto fail;
1118
    avpicture_fill(picture, ptr, pix_fmt, width, height);
1119 6337178b Michael Niedermayer
    if(picture->data[1] && !picture->data[2])
1120
        ff_set_systematic_pal((uint32_t*)picture->data[1], pix_fmt);
1121
1122 524c6b63 Fabrice Bellard
    return 0;
1123
 fail:
1124
    memset(picture, 0, sizeof(AVPicture));
1125
    return -1;
1126
}
1127
1128 75917b88 Drew Hess
void avpicture_free(AVPicture *picture)
1129 524c6b63 Fabrice Bellard
{
1130 8e1e6f31 Fabrice Bellard
    av_free(picture->data[0]);
1131 524c6b63 Fabrice Bellard
}
1132
1133 c50c0bc8 Fabrice Bellard
/* return true if yuv planar */
1134 62a05b5b Stefan Huehner
static inline int is_yuv_planar(const PixFmtInfo *ps)
1135 c50c0bc8 Fabrice Bellard
{
1136
    return (ps->color_type == FF_COLOR_YUV ||
1137 115329f1 Diego Biurrun
            ps->color_type == FF_COLOR_YUV_JPEG) &&
1138 7e7e5940 Fabrice Bellard
        ps->pixel_type == FF_PIXEL_PLANAR;
1139 c50c0bc8 Fabrice Bellard
}
1140
1141 636d6a4a Panagiotis Issaris
int av_picture_crop(AVPicture *dst, const AVPicture *src,
1142 4a30fff6 Måns Rullgård
                    enum PixelFormat pix_fmt, int top_band, int left_band)
1143 f2651e7a Baptiste Coudurier
{
1144
    int y_shift;
1145
    int x_shift;
1146
1147
    if (pix_fmt < 0 || pix_fmt >= PIX_FMT_NB || !is_yuv_planar(&pix_fmt_info[pix_fmt]))
1148
        return -1;
1149
1150 14b903f3 Stefano Sabatini
    y_shift = av_pix_fmt_descriptors[pix_fmt].log2_chroma_h;
1151
    x_shift = av_pix_fmt_descriptors[pix_fmt].log2_chroma_w;
1152 f2651e7a Baptiste Coudurier
1153
    dst->data[0] = src->data[0] + (top_band * src->linesize[0]) + left_band;
1154
    dst->data[1] = src->data[1] + ((top_band >> y_shift) * src->linesize[1]) + (left_band >> x_shift);
1155
    dst->data[2] = src->data[2] + ((top_band >> y_shift) * src->linesize[2]) + (left_band >> x_shift);
1156
1157
    dst->linesize[0] = src->linesize[0];
1158
    dst->linesize[1] = src->linesize[1];
1159
    dst->linesize[2] = src->linesize[2];
1160
    return 0;
1161
}
1162
1163 636d6a4a Panagiotis Issaris
int av_picture_pad(AVPicture *dst, const AVPicture *src, int height, int width,
1164 a61ec8e7 Stefano Sabatini
                   enum PixelFormat pix_fmt, int padtop, int padbottom, int padleft, int padright,
1165 6845801f Luca Barbato
            int *color)
1166 5341c209 Luca Abeni
{
1167 79acfb0e Luca Barbato
    uint8_t *optr;
1168 5341c209 Luca Abeni
    int y_shift;
1169
    int x_shift;
1170
    int yheight;
1171
    int i, y;
1172
1173 6845801f Luca Barbato
    if (pix_fmt < 0 || pix_fmt >= PIX_FMT_NB ||
1174
        !is_yuv_planar(&pix_fmt_info[pix_fmt])) return -1;
1175 5341c209 Luca Abeni
1176
    for (i = 0; i < 3; i++) {
1177 14b903f3 Stefano Sabatini
        x_shift = i ? av_pix_fmt_descriptors[pix_fmt].log2_chroma_w : 0;
1178
        y_shift = i ? av_pix_fmt_descriptors[pix_fmt].log2_chroma_h : 0;
1179 5341c209 Luca Abeni
1180
        if (padtop || padleft) {
1181 6845801f Luca Barbato
            memset(dst->data[i], color[i],
1182
                dst->linesize[i] * (padtop >> y_shift) + (padleft >> x_shift));
1183 5341c209 Luca Abeni
        }
1184
1185 79acfb0e Luca Barbato
        if (padleft || padright) {
1186
            optr = dst->data[i] + dst->linesize[i] * (padtop >> y_shift) +
1187
                (dst->linesize[i] - (padright >> x_shift));
1188
            yheight = (height - 1 - (padtop + padbottom)) >> y_shift;
1189
            for (y = 0; y < yheight; y++) {
1190
                memset(optr, color[i], (padleft + padright) >> x_shift);
1191
                optr += dst->linesize[i];
1192 5341c209 Luca Abeni
            }
1193 79acfb0e Luca Barbato
        }
1194
1195
        if (src) { /* first line */
1196
            uint8_t *iptr = src->data[i];
1197
            optr = dst->data[i] + dst->linesize[i] * (padtop >> y_shift) +
1198
                    (padleft >> x_shift);
1199 1be97a21 Baptiste Coudurier
            memcpy(optr, iptr, (width - padleft - padright) >> x_shift);
1200 79acfb0e Luca Barbato
            iptr += src->linesize[i];
1201 6845801f Luca Barbato
            optr = dst->data[i] + dst->linesize[i] * (padtop >> y_shift) +
1202
                (dst->linesize[i] - (padright >> x_shift));
1203 5341c209 Luca Abeni
            yheight = (height - 1 - (padtop + padbottom)) >> y_shift;
1204
            for (y = 0; y < yheight; y++) {
1205
                memset(optr, color[i], (padleft + padright) >> x_shift);
1206 79acfb0e Luca Barbato
                memcpy(optr + ((padleft + padright) >> x_shift), iptr,
1207 1be97a21 Baptiste Coudurier
                       (width - padleft - padright) >> x_shift);
1208 79acfb0e Luca Barbato
                iptr += src->linesize[i];
1209 5341c209 Luca Abeni
                optr += dst->linesize[i];
1210
            }
1211
        }
1212
1213
        if (padbottom || padright) {
1214 6845801f Luca Barbato
            optr = dst->data[i] + dst->linesize[i] *
1215
                ((height - padbottom) >> y_shift) - (padright >> x_shift);
1216
            memset(optr, color[i],dst->linesize[i] *
1217
                (padbottom >> y_shift) + (padright >> x_shift));
1218 5341c209 Luca Abeni
        }
1219
    }
1220
    return 0;
1221
}
1222
1223 0469baf1 Fabrice Bellard
/* NOTE: we scan all the pixels to have an exact information */
1224 da64ecc3 Drew Hess
static int get_alpha_info_pal8(const AVPicture *src, int width, int height)
1225 0469baf1 Fabrice Bellard
{
1226
    const unsigned char *p;
1227
    int src_wrap, ret, x, y;
1228
    unsigned int a;
1229
    uint32_t *palette = (uint32_t *)src->data[1];
1230 115329f1 Diego Biurrun
1231 0469baf1 Fabrice Bellard
    p = src->data[0];
1232
    src_wrap = src->linesize[0] - width;
1233
    ret = 0;
1234
    for(y=0;y<height;y++) {
1235
        for(x=0;x<width;x++) {
1236
            a = palette[p[0]] >> 24;
1237
            if (a == 0x00) {
1238
                ret |= FF_ALPHA_TRANSP;
1239
            } else if (a != 0xff) {
1240
                ret |= FF_ALPHA_SEMI_TRANSP;
1241
            }
1242
            p++;
1243
        }
1244
        p += src_wrap;
1245
    }
1246
    return ret;
1247
}
1248
1249 da64ecc3 Drew Hess
int img_get_alpha_info(const AVPicture *src,
1250 a61ec8e7 Stefano Sabatini
                       enum PixelFormat pix_fmt, int width, int height)
1251 0469baf1 Fabrice Bellard
{
1252 62a05b5b Stefan Huehner
    const PixFmtInfo *pf = &pix_fmt_info[pix_fmt];
1253 0469baf1 Fabrice Bellard
    int ret;
1254
1255
    /* no alpha can be represented in format */
1256
    if (!pf->is_alpha)
1257
        return 0;
1258
    switch(pix_fmt) {
1259
    case PIX_FMT_PAL8:
1260
        ret = get_alpha_info_pal8(src, width, height);
1261
        break;
1262
    default:
1263
        /* we do not know, so everything is indicated */
1264
        ret = FF_ALPHA_TRANSP | FF_ALPHA_SEMI_TRANSP;
1265
        break;
1266
    }
1267
    return ret;
1268
}
1269 5981f4e6 Fred
1270 b250f9c6 Aurelien Jacobs
#if HAVE_MMX
1271 5981f4e6 Fred
#define DEINT_INPLACE_LINE_LUM \
1272
                    movd_m2r(lum_m4[0],mm0);\
1273
                    movd_m2r(lum_m3[0],mm1);\
1274
                    movd_m2r(lum_m2[0],mm2);\
1275
                    movd_m2r(lum_m1[0],mm3);\
1276
                    movd_m2r(lum[0],mm4);\
1277
                    punpcklbw_r2r(mm7,mm0);\
1278
                    movd_r2m(mm2,lum_m4[0]);\
1279
                    punpcklbw_r2r(mm7,mm1);\
1280
                    punpcklbw_r2r(mm7,mm2);\
1281
                    punpcklbw_r2r(mm7,mm3);\
1282
                    punpcklbw_r2r(mm7,mm4);\
1283
                    paddw_r2r(mm3,mm1);\
1284
                    psllw_i2r(1,mm2);\
1285
                    paddw_r2r(mm4,mm0);\
1286
                    psllw_i2r(2,mm1);\
1287
                    paddw_r2r(mm6,mm2);\
1288
                    paddw_r2r(mm2,mm1);\
1289
                    psubusw_r2r(mm0,mm1);\
1290
                    psrlw_i2r(3,mm1);\
1291
                    packuswb_r2r(mm7,mm1);\
1292
                    movd_r2m(mm1,lum_m2[0]);
1293
1294
#define DEINT_LINE_LUM \
1295
                    movd_m2r(lum_m4[0],mm0);\
1296
                    movd_m2r(lum_m3[0],mm1);\
1297
                    movd_m2r(lum_m2[0],mm2);\
1298
                    movd_m2r(lum_m1[0],mm3);\
1299
                    movd_m2r(lum[0],mm4);\
1300
                    punpcklbw_r2r(mm7,mm0);\
1301
                    punpcklbw_r2r(mm7,mm1);\
1302
                    punpcklbw_r2r(mm7,mm2);\
1303
                    punpcklbw_r2r(mm7,mm3);\
1304
                    punpcklbw_r2r(mm7,mm4);\
1305
                    paddw_r2r(mm3,mm1);\
1306
                    psllw_i2r(1,mm2);\
1307
                    paddw_r2r(mm4,mm0);\
1308
                    psllw_i2r(2,mm1);\
1309
                    paddw_r2r(mm6,mm2);\
1310
                    paddw_r2r(mm2,mm1);\
1311
                    psubusw_r2r(mm0,mm1);\
1312
                    psrlw_i2r(3,mm1);\
1313
                    packuswb_r2r(mm7,mm1);\
1314
                    movd_r2m(mm1,dst[0]);
1315
#endif
1316
1317 85c242d8 Fabrice Bellard
/* filter parameters: [-1 4 2 4 -1] // 8 */
1318 115329f1 Diego Biurrun
static void deinterlace_line(uint8_t *dst,
1319 bb270c08 Diego Biurrun
                             const uint8_t *lum_m4, const uint8_t *lum_m3,
1320
                             const uint8_t *lum_m2, const uint8_t *lum_m1,
1321
                             const uint8_t *lum,
1322
                             int size)
1323 85c242d8 Fabrice Bellard
{
1324 b250f9c6 Aurelien Jacobs
#if !HAVE_MMX
1325 55fde95e Måns Rullgård
    uint8_t *cm = ff_cropTbl + MAX_NEG_CROP;
1326 85c242d8 Fabrice Bellard
    int sum;
1327
1328
    for(;size > 0;size--) {
1329 5981f4e6 Fred
        sum = -lum_m4[0];
1330
        sum += lum_m3[0] << 2;
1331
        sum += lum_m2[0] << 1;
1332
        sum += lum_m1[0] << 2;
1333
        sum += -lum[0];
1334 85c242d8 Fabrice Bellard
        dst[0] = cm[(sum + 4) >> 3];
1335 5981f4e6 Fred
        lum_m4++;
1336
        lum_m3++;
1337
        lum_m2++;
1338
        lum_m1++;
1339
        lum++;
1340 85c242d8 Fabrice Bellard
        dst++;
1341
    }
1342 5981f4e6 Fred
#else
1343
1344 782c5984 Michael Niedermayer
    {
1345
        pxor_r2r(mm7,mm7);
1346 d08ea32c Aurelien Jacobs
        movq_m2r(ff_pw_4,mm6);
1347 782c5984 Michael Niedermayer
    }
1348 5981f4e6 Fred
    for (;size > 3; size-=4) {
1349
        DEINT_LINE_LUM
1350
        lum_m4+=4;
1351
        lum_m3+=4;
1352
        lum_m2+=4;
1353
        lum_m1+=4;
1354
        lum+=4;
1355
        dst+=4;
1356
    }
1357
#endif
1358
}
1359 0c1a9eda Zdenek Kabelac
static void deinterlace_line_inplace(uint8_t *lum_m4, uint8_t *lum_m3, uint8_t *lum_m2, uint8_t *lum_m1, uint8_t *lum,
1360 5981f4e6 Fred
                             int size)
1361
{
1362 b250f9c6 Aurelien Jacobs
#if !HAVE_MMX
1363 55fde95e Måns Rullgård
    uint8_t *cm = ff_cropTbl + MAX_NEG_CROP;
1364 5981f4e6 Fred
    int sum;
1365
1366
    for(;size > 0;size--) {
1367
        sum = -lum_m4[0];
1368
        sum += lum_m3[0] << 2;
1369
        sum += lum_m2[0] << 1;
1370
        lum_m4[0]=lum_m2[0];
1371
        sum += lum_m1[0] << 2;
1372
        sum += -lum[0];
1373
        lum_m2[0] = cm[(sum + 4) >> 3];
1374
        lum_m4++;
1375
        lum_m3++;
1376
        lum_m2++;
1377
        lum_m1++;
1378
        lum++;
1379
    }
1380
#else
1381
1382 782c5984 Michael Niedermayer
    {
1383
        pxor_r2r(mm7,mm7);
1384 d08ea32c Aurelien Jacobs
        movq_m2r(ff_pw_4,mm6);
1385 782c5984 Michael Niedermayer
    }
1386 5981f4e6 Fred
    for (;size > 3; size-=4) {
1387
        DEINT_INPLACE_LINE_LUM
1388
        lum_m4+=4;
1389
        lum_m3+=4;
1390
        lum_m2+=4;
1391
        lum_m1+=4;
1392
        lum+=4;
1393
    }
1394
#endif
1395 85c242d8 Fabrice Bellard
}
1396
1397
/* deinterlacing : 2 temporal taps, 3 spatial taps linear filter. The
1398
   top field is copied as is, but the bottom field is deinterlaced
1399
   against the top field. */
1400 0c1a9eda Zdenek Kabelac
static void deinterlace_bottom_field(uint8_t *dst, int dst_wrap,
1401 da64ecc3 Drew Hess
                                    const uint8_t *src1, int src_wrap,
1402 5981f4e6 Fred
                                    int width, int height)
1403 85c242d8 Fabrice Bellard
{
1404 da64ecc3 Drew Hess
    const uint8_t *src_m2, *src_m1, *src_0, *src_p1, *src_p2;
1405 5981f4e6 Fred
    int y;
1406
1407
    src_m2 = src1;
1408
    src_m1 = src1;
1409
    src_0=&src_m1[src_wrap];
1410
    src_p1=&src_0[src_wrap];
1411
    src_p2=&src_p1[src_wrap];
1412
    for(y=0;y<(height-2);y+=2) {
1413
        memcpy(dst,src_m1,width);
1414 85c242d8 Fabrice Bellard
        dst += dst_wrap;
1415 5981f4e6 Fred
        deinterlace_line(dst,src_m2,src_m1,src_0,src_p1,src_p2,width);
1416
        src_m2 = src_0;
1417
        src_m1 = src_p1;
1418
        src_0 = src_p2;
1419
        src_p1 += 2*src_wrap;
1420
        src_p2 += 2*src_wrap;
1421 85c242d8 Fabrice Bellard
        dst += dst_wrap;
1422
    }
1423 5981f4e6 Fred
    memcpy(dst,src_m1,width);
1424
    dst += dst_wrap;
1425
    /* do last line */
1426
    deinterlace_line(dst,src_m2,src_m1,src_0,src_0,src_0,width);
1427
}
1428
1429 0c1a9eda Zdenek Kabelac
static void deinterlace_bottom_field_inplace(uint8_t *src1, int src_wrap,
1430 bb270c08 Diego Biurrun
                                             int width, int height)
1431 5981f4e6 Fred
{
1432 0c1a9eda Zdenek Kabelac
    uint8_t *src_m1, *src_0, *src_p1, *src_p2;
1433 5981f4e6 Fred
    int y;
1434 0c1a9eda Zdenek Kabelac
    uint8_t *buf;
1435
    buf = (uint8_t*)av_malloc(width);
1436 5981f4e6 Fred
1437
    src_m1 = src1;
1438
    memcpy(buf,src_m1,width);
1439
    src_0=&src_m1[src_wrap];
1440
    src_p1=&src_0[src_wrap];
1441
    src_p2=&src_p1[src_wrap];
1442
    for(y=0;y<(height-2);y+=2) {
1443
        deinterlace_line_inplace(buf,src_m1,src_0,src_p1,src_p2,width);
1444
        src_m1 = src_p1;
1445
        src_0 = src_p2;
1446
        src_p1 += 2*src_wrap;
1447
        src_p2 += 2*src_wrap;
1448
    }
1449
    /* do last line */
1450
    deinterlace_line_inplace(buf,src_m1,src_0,src_0,src_0,width);
1451 6000abfa Fabrice Bellard
    av_free(buf);
1452 85c242d8 Fabrice Bellard
}
1453
1454 da64ecc3 Drew Hess
int avpicture_deinterlace(AVPicture *dst, const AVPicture *src,
1455 a61ec8e7 Stefano Sabatini
                          enum PixelFormat pix_fmt, int width, int height)
1456 de6d9b64 Fabrice Bellard
{
1457 85c242d8 Fabrice Bellard
    int i;
1458
1459
    if (pix_fmt != PIX_FMT_YUV420P &&
1460
        pix_fmt != PIX_FMT_YUV422P &&
1461 47017dd8 Roman Shaposhnik
        pix_fmt != PIX_FMT_YUV444P &&
1462 2a7feb18 Andrea Gualano
        pix_fmt != PIX_FMT_YUV411P &&
1463
        pix_fmt != PIX_FMT_GRAY8)
1464 85c242d8 Fabrice Bellard
        return -1;
1465 5981f4e6 Fred
    if ((width & 3) != 0 || (height & 3) != 0)
1466 85c242d8 Fabrice Bellard
        return -1;
1467 5981f4e6 Fred
1468 85c242d8 Fabrice Bellard
    for(i=0;i<3;i++) {
1469
        if (i == 1) {
1470
            switch(pix_fmt) {
1471
            case PIX_FMT_YUV420P:
1472
                width >>= 1;
1473
                height >>= 1;
1474
                break;
1475
            case PIX_FMT_YUV422P:
1476
                width >>= 1;
1477
                break;
1478 47017dd8 Roman Shaposhnik
            case PIX_FMT_YUV411P:
1479
                width >>= 2;
1480
                break;
1481 85c242d8 Fabrice Bellard
            default:
1482
                break;
1483
            }
1484 2a7feb18 Andrea Gualano
            if (pix_fmt == PIX_FMT_GRAY8) {
1485
                break;
1486
            }
1487 85c242d8 Fabrice Bellard
        }
1488 5981f4e6 Fred
        if (src == dst) {
1489 da64ecc3 Drew Hess
            deinterlace_bottom_field_inplace(dst->data[i], dst->linesize[i],
1490 85c242d8 Fabrice Bellard
                                 width, height);
1491 5981f4e6 Fred
        } else {
1492
            deinterlace_bottom_field(dst->data[i],dst->linesize[i],
1493
                                        src->data[i], src->linesize[i],
1494
                                        width, height);
1495
        }
1496 de6d9b64 Fabrice Bellard
    }
1497 55ffe9df Ronald S. Bultje
    emms_c();
1498 85c242d8 Fabrice Bellard
    return 0;
1499 de6d9b64 Fabrice Bellard
}