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 | } |