comparison imgconvert.c @ 989:fe9083c56733 libavcodec

simplified code (need automatic testing) - added primitive new format support.
author bellard
date Sat, 11 Jan 2003 00:08:48 +0000
parents ef769ec24115
children 895d3b01c6f4
comparison
equal deleted inserted replaced
988:001b7d3045e5 989:fe9083c56733
1 /* 1 /*
2 * Misc image convertion routines 2 * Misc image convertion routines
3 * Copyright (c) 2001, 2002 Fabrice Bellard. 3 * Copyright (c) 2001, 2002, 2003 Fabrice Bellard.
4 * 4 *
5 * This library is free software; you can redistribute it and/or 5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public 6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either 7 * License as published by the Free Software Foundation; either
8 * version 2 of the License, or (at your option) any later version. 8 * version 2 of the License, or (at your option) any later version.
24 #endif 24 #endif
25 25
26 #ifdef HAVE_MMX 26 #ifdef HAVE_MMX
27 #include "i386/mmx.h" 27 #include "i386/mmx.h"
28 #endif 28 #endif
29
30 typedef struct PixFmtInfo {
31 const char *name;
32 UINT8 nb_components; /* number of components in AVPicture array */
33 UINT8 is_yuv : 1; /* true if YUV instead of RGB color space */
34 UINT8 is_packed : 1; /* true if multiple components in same word */
35 UINT8 is_paletted : 1; /* true if paletted */
36 UINT8 is_alpha : 1; /* true if alpha can be specified */
37 UINT8 is_gray : 1; /* true if gray or monochrome format */
38 UINT8 x_chroma_shift; /* X chroma subsampling factor is 2 ^ shift */
39 UINT8 y_chroma_shift; /* Y chroma subsampling factor is 2 ^ shift */
40 } PixFmtInfo;
41
42 /* this table gives more information about formats */
43 static PixFmtInfo pix_fmt_info[PIX_FMT_NB] = {
44 /* YUV formats */
45 [PIX_FMT_YUV420P] = {
46 name: "yuv420p",
47 nb_components: 3, is_yuv: 1,
48 x_chroma_shift: 1, y_chroma_shift: 1,
49 },
50 [PIX_FMT_YUV422P] = {
51 name: "yuv422p",
52 nb_components: 3, is_yuv: 1,
53 x_chroma_shift: 1, y_chroma_shift: 0,
54 },
55 [PIX_FMT_YUV444P] = {
56 name: "yuv444p",
57 nb_components: 3, is_yuv: 1,
58 x_chroma_shift: 0, y_chroma_shift: 0,
59 },
60 [PIX_FMT_YUV422] = {
61 name: "yuv422",
62 nb_components: 1, is_yuv: 1, is_packed: 1,
63 x_chroma_shift: 1, y_chroma_shift: 0,
64 },
65 [PIX_FMT_YUV410P] = {
66 name: "yuv410p",
67 nb_components: 3, is_yuv: 1,
68 x_chroma_shift: 2, y_chroma_shift: 2,
69 },
70 [PIX_FMT_YUV411P] = {
71 name: "yuv411p",
72 nb_components: 3, is_yuv: 1,
73 x_chroma_shift: 2, y_chroma_shift: 0,
74 },
75
76 /* RGB formats */
77 [PIX_FMT_RGB24] = {
78 name: "rgb24",
79 nb_components: 1, is_packed: 1,
80 },
81 [PIX_FMT_BGR24] = {
82 name: "bgr24",
83 nb_components: 1, is_packed: 1,
84 },
85 [PIX_FMT_RGBA32] = {
86 name: "rgba32",
87 nb_components: 1, is_packed: 1, is_alpha: 1,
88 },
89 [PIX_FMT_RGB565] = {
90 name: "rgb565",
91 nb_components: 1, is_packed: 1,
92 },
93 [PIX_FMT_RGB555] = {
94 name: "rgb555",
95 nb_components: 1, is_packed: 1, is_alpha : 1,
96 },
97
98 /* gray / mono formats */
99 [PIX_FMT_GRAY8] = {
100 name: "gray",
101 nb_components: 1, is_gray: 1,
102 },
103 [PIX_FMT_MONOWHITE] = {
104 name: "monow",
105 nb_components: 1, is_packed: 1, is_gray: 1,
106 },
107 [PIX_FMT_MONOBLACK] = {
108 name: "monob",
109 nb_components: 1, is_packed: 1, is_gray: 1,
110 },
111 };
112
113 void avcodec_get_chroma_sub_sample(int pix_fmt, int *h_shift, int *v_shift)
114 {
115 if (pix_fmt_info[pix_fmt].is_yuv) {
116 *h_shift = pix_fmt_info[pix_fmt].x_chroma_shift;
117 *v_shift = pix_fmt_info[pix_fmt].y_chroma_shift;
118 } else {
119 *h_shift=0;
120 *v_shift=0;
121 }
122 }
123
124 const char *avcodec_get_pix_fmt_name(int pix_fmt)
125 {
126 if (pix_fmt < 0 || pix_fmt >= PIX_FMT_NB)
127 return "???";
128 else
129 return pix_fmt_info[pix_fmt].name;
130 }
131
29 /* XXX: totally non optimized */ 132 /* XXX: totally non optimized */
30 133
31 static void yuv422_to_yuv420p(UINT8 *lum, UINT8 *cb, UINT8 *cr, 134 static void yuv422_to_yuv420p(AVPicture *dst, AVPicture *src,
32 UINT8 *src, int width, int height) 135 int width, int height)
33 { 136 {
137 UINT8 *lum, *cb, *cr;
34 int x, y; 138 int x, y;
35 UINT8 *p = src; 139 const UINT8 *p;
36 140
141 lum = dst->data[0];
142 cb = dst->data[1];
143 cr = dst->data[2];
144 p = src->data[0];
145
37 for(y=0;y<height;y+=2) { 146 for(y=0;y<height;y+=2) {
38 for(x=0;x<width;x+=2) { 147 for(x=0;x<width;x+=2) {
39 lum[0] = p[0]; 148 lum[0] = p[0];
40 cb[0] = p[1]; 149 cb[0] = p[1];
41 lum[1] = p[2]; 150 lum[1] = p[2];
55 } 164 }
56 165
57 #define SCALEBITS 8 166 #define SCALEBITS 8
58 #define ONE_HALF (1 << (SCALEBITS - 1)) 167 #define ONE_HALF (1 << (SCALEBITS - 1))
59 #define FIX(x) ((int) ((x) * (1L<<SCALEBITS) + 0.5)) 168 #define FIX(x) ((int) ((x) * (1L<<SCALEBITS) + 0.5))
60
61 static void rgb24_to_yuv420p(UINT8 *lum, UINT8 *cb, UINT8 *cr,
62 UINT8 *src, int width, int height)
63 {
64 int wrap, wrap3, x, y;
65 int r, g, b, r1, g1, b1;
66 UINT8 *p;
67
68 wrap = width;
69 wrap3 = width * 3;
70 p = src;
71 for(y=0;y<height;y+=2) {
72 for(x=0;x<width;x+=2) {
73 r = p[0];
74 g = p[1];
75 b = p[2];
76 r1 = r;
77 g1 = g;
78 b1 = b;
79 lum[0] = (FIX(0.29900) * r + FIX(0.58700) * g +
80 FIX(0.11400) * b + ONE_HALF) >> SCALEBITS;
81 r = p[3];
82 g = p[4];
83 b = p[5];
84 r1 += r;
85 g1 += g;
86 b1 += b;
87 lum[1] = (FIX(0.29900) * r + FIX(0.58700) * g +
88 FIX(0.11400) * b + ONE_HALF) >> SCALEBITS;
89 p += wrap3;
90 lum += wrap;
91
92 r = p[0];
93 g = p[1];
94 b = p[2];
95 r1 += r;
96 g1 += g;
97 b1 += b;
98 lum[0] = (FIX(0.29900) * r + FIX(0.58700) * g +
99 FIX(0.11400) * b + ONE_HALF) >> SCALEBITS;
100 r = p[3];
101 g = p[4];
102 b = p[5];
103 r1 += r;
104 g1 += g;
105 b1 += b;
106 lum[1] = (FIX(0.29900) * r + FIX(0.58700) * g +
107 FIX(0.11400) * b + ONE_HALF) >> SCALEBITS;
108
109 cb[0] = ((- FIX(0.16874) * r1 - FIX(0.33126) * g1 +
110 FIX(0.50000) * b1 + 4 * ONE_HALF - 1) >> (SCALEBITS + 2)) + 128;
111 cr[0] = ((FIX(0.50000) * r1 - FIX(0.41869) * g1 -
112 FIX(0.08131) * b1 + 4 * ONE_HALF - 1) >> (SCALEBITS + 2)) + 128;
113
114 cb++;
115 cr++;
116 p += -wrap3 + 2 * 3;
117 lum += -wrap + 2;
118 }
119 p += wrap3;
120 lum += wrap;
121 }
122 }
123
124 static void rgba32_to_yuv420p(UINT8 *lum, UINT8 *cb, UINT8 *cr,
125 UINT8 *src, int width, int height)
126 {
127 int wrap, wrap4, x, y;
128 int r, g, b, r1, g1, b1;
129 UINT8 *p;
130
131 wrap = width;
132 wrap4 = width * 4;
133 p = src;
134 for(y=0;y<height;y+=2) {
135 for(x=0;x<width;x+=2) {
136 r = p[0];
137 g = p[1];
138 b = p[2];
139 r1 = r;
140 g1 = g;
141 b1 = b;
142 lum[0] = (FIX(0.29900) * r + FIX(0.58700) * g +
143 FIX(0.11400) * b + ONE_HALF) >> SCALEBITS;
144 r = p[4];
145 g = p[5];
146 b = p[6];
147 r1 += r;
148 g1 += g;
149 b1 += b;
150 lum[1] = (FIX(0.29900) * r + FIX(0.58700) * g +
151 FIX(0.11400) * b + ONE_HALF) >> SCALEBITS;
152 p += wrap4;
153 lum += wrap;
154
155 r = p[0];
156 g = p[1];
157 b = p[2];
158 r1 += r;
159 g1 += g;
160 b1 += b;
161 lum[0] = (FIX(0.29900) * r + FIX(0.58700) * g +
162 FIX(0.11400) * b + ONE_HALF) >> SCALEBITS;
163 r = p[4];
164 g = p[5];
165 b = p[6];
166 r1 += r;
167 g1 += g;
168 b1 += b;
169 lum[1] = (FIX(0.29900) * r + FIX(0.58700) * g +
170 FIX(0.11400) * b + ONE_HALF) >> SCALEBITS;
171
172 cb[0] = ((- FIX(0.16874) * r1 - FIX(0.33126) * g1 +
173 FIX(0.50000) * b1 + 4 * ONE_HALF - 1) >> (SCALEBITS + 2)) + 128;
174 cr[0] = ((FIX(0.50000) * r1 - FIX(0.41869) * g1 -
175 FIX(0.08131) * b1 + 4 * ONE_HALF - 1) >> (SCALEBITS + 2)) + 128;
176
177 cb++;
178 cr++;
179 p += -wrap4 + 2 * 4;
180 lum += -wrap + 2;
181 }
182 p += wrap4;
183 lum += wrap;
184 }
185 }
186
187 #define rgb565_to_yuv420p(lum,cb,cr,src,width,height) rgbmisc_to_yuv420p((lum),(cb),(cr),(src),(width),(height),0x0800,31, 0x0020,63,0x0001,31)
188 #define rgb555_to_yuv420p(lum,cb,cr,src,width,height) rgbmisc_to_yuv420p((lum),(cb),(cr),(src),(width),(height),0x0400,31, 0x0020,31,0x0001,31)
189 #define rgb5551_to_yuv420p(lum,cb,cr,src,width,height) rgbmisc_to_yuv420p((lum),(cb),(cr),(src),(width),(height),0x0800,31, 0x0040,31,0x0002,31)
190 #define bgr565_to_yuv420p(lum,cb,cr,src,width,height) rgbmisc_to_yuv420p((lum),(cb),(cr),(src),(width),(height),0x0001,31, 0x0020,63,0x0800,31)
191 #define bgr555_to_yuv420p(lum,cb,cr,src,width,height) rgbmisc_to_yuv420p((lum),(cb),(cr),(src),(width),(height),0x0001,31, 0x0020,31,0x0400,31)
192 #define gbr565_to_yuv420p(lum,cb,cr,src,width,height) rgbmisc_to_yuv420p((lum),(cb),(cr),(src),(width),(height),0x0001,31, 0x0800,31,0x0040,63)
193 #define gbr555_to_yuv420p(lum,cb,cr,src,width,height) rgbmisc_to_yuv420p((lum),(cb),(cr),(src),(width),(height),0x0001,31, 0x0400,31,0x0020,31)
194
195 static void rgbmisc_to_yuv420p
196 (UINT8 *lum, UINT8 *cb, UINT8 *cr,
197 UINT8 *src, int width, int height,
198
199 UINT16 R_LOWMASK, UINT16 R_MAX,
200 UINT16 G_LOWMASK, UINT16 G_MAX,
201 UINT16 B_LOWMASK, UINT16 B_MAX
202 )
203 {
204 int wrap, wrap2, x, y;
205 int r, g, b, r1, g1, b1;
206 UINT8 *p;
207 UINT16 pixel;
208
209 wrap = width;
210 wrap2 = width * 2;
211 p = src;
212 for(y=0;y<height;y+=2) {
213 for(x=0;x<width;x+=2) {
214 pixel = p[0] | (p[1]<<8);
215 r = (((pixel/R_LOWMASK) & R_MAX) * (0x100 / (R_MAX+1)));
216 g = (((pixel/G_LOWMASK) & G_MAX) * (0x100 / (G_MAX+1)));
217 b = (((pixel/B_LOWMASK) & B_MAX) * (0x100 / (B_MAX+1)));
218 r1 = r;
219 g1 = g;
220 b1 = b;
221 lum[0] = (FIX(0.29900) * r + FIX(0.58700) * g +
222 FIX(0.11400) * b + ONE_HALF) >> SCALEBITS;
223
224 pixel = p[2] | (p[3]<<8);
225 r = (((pixel/R_LOWMASK) & R_MAX) * (0x100 / (R_MAX+1)));
226 g = (((pixel/G_LOWMASK) & G_MAX) * (0x100 / (G_MAX+1)));
227 b = (((pixel/B_LOWMASK) & B_MAX) * (0x100 / (B_MAX+1)));
228 r1 += r;
229 g1 += g;
230 b1 += b;
231 lum[1] = (FIX(0.29900) * r + FIX(0.58700) * g +
232 FIX(0.11400) * b + ONE_HALF) >> SCALEBITS;
233 p += wrap2;
234 lum += wrap;
235
236 pixel = p[0] | (p[1]<<8);
237 r = (((pixel/R_LOWMASK) & R_MAX) * (0x100 / (R_MAX+1)));
238 g = (((pixel/G_LOWMASK) & G_MAX) * (0x100 / (G_MAX+1)));
239 b = (((pixel/B_LOWMASK) & B_MAX) * (0x100 / (B_MAX+1)));
240 r1 += r;
241 g1 += g;
242 b1 += b;
243 lum[0] = (FIX(0.29900) * r + FIX(0.58700) * g +
244 FIX(0.11400) * b + ONE_HALF) >> SCALEBITS;
245 pixel = p[2] | (p[3]<<8);
246 r = (((pixel/R_LOWMASK) & R_MAX) * (0x100 / (R_MAX+1)));
247 g = (((pixel/G_LOWMASK) & G_MAX) * (0x100 / (G_MAX+1)));
248 b = (((pixel/B_LOWMASK) & B_MAX) * (0x100 / (B_MAX+1)));
249 r1 += r;
250 g1 += g;
251 b1 += b;
252 lum[1] = (FIX(0.29900) * r + FIX(0.58700) * g +
253 FIX(0.11400) * b + ONE_HALF) >> SCALEBITS;
254
255 cb[0] = ((- FIX(0.16874) * r1 - FIX(0.33126) * g1 +
256 FIX(0.50000) * b1 + 4 * ONE_HALF - 1) >> (SCALEBITS + 2)) + 128;
257 cr[0] = ((FIX(0.50000) * r1 - FIX(0.41869) * g1 -
258 FIX(0.08131) * b1 + 4 * ONE_HALF - 1) >> (SCALEBITS + 2)) + 128;
259
260 cb++;
261 cr++;
262 p += -wrap2 + 2 * 2;
263 lum += -wrap + 2;
264 }
265 p += wrap2;
266 lum += wrap;
267 }
268 }
269
270
271 static void bgr24_to_yuv420p(UINT8 *lum, UINT8 *cb, UINT8 *cr,
272 UINT8 *src, int width, int height)
273 {
274 int wrap, wrap3, x, y;
275 int r, g, b, r1, g1, b1;
276 UINT8 *p;
277
278 wrap = width;
279 wrap3 = width * 3;
280 p = src;
281 for(y=0;y<height;y+=2) {
282 for(x=0;x<width;x+=2) {
283 b = p[0];
284 g = p[1];
285 r = p[2];
286 r1 = r;
287 g1 = g;
288 b1 = b;
289 lum[0] = (FIX(0.29900) * r + FIX(0.58700) * g +
290 FIX(0.11400) * b + ONE_HALF) >> SCALEBITS;
291 b = p[3];
292 g = p[4];
293 r = p[5];
294 r1 += r;
295 g1 += g;
296 b1 += b;
297 lum[1] = (FIX(0.29900) * r + FIX(0.58700) * g +
298 FIX(0.11400) * b + ONE_HALF) >> SCALEBITS;
299 p += wrap3;
300 lum += wrap;
301
302 b = p[0];
303 g = p[1];
304 r = p[2];
305 r1 += r;
306 g1 += g;
307 b1 += b;
308 lum[0] = (FIX(0.29900) * r + FIX(0.58700) * g +
309 FIX(0.11400) * b + ONE_HALF) >> SCALEBITS;
310 b = p[3];
311 g = p[4];
312 r = p[5];
313 r1 += r;
314 g1 += g;
315 b1 += b;
316 lum[1] = (FIX(0.29900) * r + FIX(0.58700) * g +
317 FIX(0.11400) * b + ONE_HALF) >> SCALEBITS;
318
319 cb[0] = ((- FIX(0.16874) * r1 - FIX(0.33126) * g1 +
320 FIX(0.50000) * b1 + 4 * ONE_HALF - 1) >> (SCALEBITS + 2)) + 128;
321 cr[0] = ((FIX(0.50000) * r1 - FIX(0.41869) * g1 -
322 FIX(0.08131) * b1 + 4 * ONE_HALF - 1) >> (SCALEBITS + 2)) + 128;
323
324 cb++;
325 cr++;
326 p += -wrap3 + 2 * 3;
327 lum += -wrap + 2;
328 }
329 p += wrap3;
330 lum += wrap;
331 }
332 }
333
334 static void bgra32_to_yuv420p(UINT8 *lum, UINT8 *cb, UINT8 *cr,
335 UINT8 *src, int width, int height)
336 {
337 int wrap, wrap4, x, y;
338 int r, g, b, r1, g1, b1;
339 UINT8 *p;
340
341 wrap = width;
342 wrap4 = width * 4;
343 p = src;
344 for(y=0;y<height;y+=2) {
345 for(x=0;x<width;x+=2) {
346 b = p[0];
347 g = p[1];
348 r = p[2];
349 r1 = r;
350 g1 = g;
351 b1 = b;
352 lum[0] = (FIX(0.29900) * r + FIX(0.58700) * g +
353 FIX(0.11400) * b + ONE_HALF) >> SCALEBITS;
354 b = p[4];
355 g = p[5];
356 r = p[6];
357 r1 += r;
358 g1 += g;
359 b1 += b;
360 lum[1] = (FIX(0.29900) * r + FIX(0.58700) * g +
361 FIX(0.11400) * b + ONE_HALF) >> SCALEBITS;
362 p += wrap4;
363 lum += wrap;
364
365 b = p[0];
366 g = p[1];
367 r = p[2];
368 r1 += r;
369 g1 += g;
370 b1 += b;
371 lum[0] = (FIX(0.29900) * r + FIX(0.58700) * g +
372 FIX(0.11400) * b + ONE_HALF) >> SCALEBITS;
373 b = p[4];
374 g = p[5];
375 r = p[6];
376 r1 += r;
377 g1 += g;
378 b1 += b;
379 lum[1] = (FIX(0.29900) * r + FIX(0.58700) * g +
380 FIX(0.11400) * b + ONE_HALF) >> SCALEBITS;
381
382 cb[0] = ((- FIX(0.16874) * r1 - FIX(0.33126) * g1 +
383 FIX(0.50000) * b1 + 4 * ONE_HALF - 1) >> (SCALEBITS + 2)) + 128;
384 cr[0] = ((FIX(0.50000) * r1 - FIX(0.41869) * g1 -
385 FIX(0.08131) * b1 + 4 * ONE_HALF - 1) >> (SCALEBITS + 2)) + 128;
386
387 cb++;
388 cr++;
389 p += -wrap4 + 2 * 4;
390 lum += -wrap + 2;
391 }
392 p += wrap4;
393 lum += wrap;
394 }
395 }
396 169
397 /* XXX: use generic filter ? */ 170 /* XXX: use generic filter ? */
398 /* 1x2 -> 1x1 */ 171 /* 1x2 -> 1x1 */
399 static void shrink2(UINT8 *dst, int dst_wrap, 172 static void shrink2(UINT8 *dst, int dst_wrap,
400 UINT8 *src, int src_wrap, 173 UINT8 *src, int src_wrap,
485 src += src_wrap; 258 src += src_wrap;
486 dst += dst_wrap; 259 dst += dst_wrap;
487 } 260 }
488 } 261 }
489 262
490 /* 1x2 -> 2x1. width and height are given for the source picture */ 263 /* 1x2 -> 2x1 */
491 static void conv411(UINT8 *dst, int dst_wrap, 264 static void conv411(UINT8 *dst, int dst_wrap,
492 UINT8 *src, int src_wrap, 265 UINT8 *src, int src_wrap,
493 int width, int height) 266 int width, int height)
494 { 267 {
495 int w, c; 268 int w, c;
496 UINT8 *s1, *s2, *d; 269 UINT8 *s1, *s2, *d;
497 270
498 for(;height > 0; height -= 2) { 271 for(;height > 0; height--) {
499 s1 = src; 272 s1 = src;
500 s2 = src + src_wrap; 273 s2 = src + src_wrap;
501 d = dst; 274 d = dst;
502 for(w = width;w > 0; w--) { 275 for(w = width;w > 0; w--) {
503 c = (s1[0] + s2[0]) >> 1; 276 c = (s1[0] + s2[0]) >> 1;
529 #define C_RV (117504 >> (16 - SCALE_BITS)) 302 #define C_RV (117504 >> (16 - SCALE_BITS))
530 #define C_BU (138453 >> (16 - SCALE_BITS)) 303 #define C_BU (138453 >> (16 - SCALE_BITS))
531 #define C_GU (13954 >> (16 - SCALE_BITS)) 304 #define C_GU (13954 >> (16 - SCALE_BITS))
532 #define C_GV (34903 >> (16 - SCALE_BITS)) 305 #define C_GV (34903 >> (16 - SCALE_BITS))
533 306
534 #define RGBOUT(r, g, b, y1)\ 307 #define YUV_TO_RGB2(r, g, b, y1)\
535 {\ 308 {\
536 y = (y1 - 16) * C_Y;\ 309 y = (y1 - 16) * C_Y;\
537 r = cm[(y + r_add) >> SCALE_BITS];\ 310 r = cm[(y + r_add) >> SCALE_BITS];\
538 g = cm[(y + g_add) >> SCALE_BITS];\ 311 g = cm[(y + g_add) >> SCALE_BITS];\
539 b = cm[(y + b_add) >> SCALE_BITS];\ 312 b = cm[(y + b_add) >> SCALE_BITS];\
540 } 313 }
541 314
542 /* XXX: no chroma interpolating is done */ 315 /* XXX: no chroma interpolating is done */
543 static void yuv420p_to_bgra32(AVPicture *dst, AVPicture *src, 316 #define RGB_FUNCTIONS(rgb_name) \
544 int width, int height) 317 \
545 { 318 static void yuv420p_to_ ## rgb_name (AVPicture *dst, AVPicture *src, \
546 UINT8 *y1_ptr, *y2_ptr, *cb_ptr, *cr_ptr, *d, *d1, *d2; 319 int width, int height) \
547 int w, y, cb, cr, r_add, g_add, b_add, width2; 320 { \
548 UINT8 *cm = cropTbl + MAX_NEG_CROP; 321 UINT8 *y1_ptr, *y2_ptr, *cb_ptr, *cr_ptr, *d, *d1, *d2; \
549 322 int w, y, cb, cr, r_add, g_add, b_add, width2; \
550 d = dst->data[0]; 323 UINT8 *cm = cropTbl + MAX_NEG_CROP; \
551 y1_ptr = src->data[0]; 324 unsigned int r, g, b; \
552 cb_ptr = src->data[1]; 325 \
553 cr_ptr = src->data[2]; 326 d = dst->data[0]; \
554 width2 = width >> 1; 327 y1_ptr = src->data[0]; \
555 for(;height > 0; height -= 2) { 328 cb_ptr = src->data[1]; \
556 d1 = d; 329 cr_ptr = src->data[2]; \
557 d2 = d + dst->linesize[0]; 330 width2 = width >> 1; \
558 y2_ptr = y1_ptr + src->linesize[0]; 331 for(;height > 0; height -= 2) { \
559 for(w = width2; w > 0; w --) { 332 d1 = d; \
560 cb = cb_ptr[0] - 128; 333 d2 = d + dst->linesize[0]; \
561 cr = cr_ptr[0] - 128; 334 y2_ptr = y1_ptr + src->linesize[0]; \
562 r_add = C_RV * cr + (1 << (SCALE_BITS - 1)); 335 for(w = width2; w > 0; w --) { \
563 g_add = - C_GU * cb - C_GV * cr + (1 << (SCALE_BITS - 1)); 336 cb = cb_ptr[0] - 128; \
564 b_add = C_BU * cb + (1 << (SCALE_BITS - 1)); 337 cr = cr_ptr[0] - 128; \
338 r_add = C_RV * cr + (1 << (SCALE_BITS - 1)); \
339 g_add = - C_GU * cb - C_GV * cr + (1 << (SCALE_BITS - 1)); \
340 b_add = C_BU * cb + (1 << (SCALE_BITS - 1)); \
341 \
342 /* output 4 pixels */ \
343 YUV_TO_RGB2(r, g, b, y1_ptr[0]); \
344 RGB_OUT(d1, r, g, b); \
345 \
346 YUV_TO_RGB2(r, g, b, y1_ptr[1]); \
347 RGB_OUT(d1 + BPP, r, g, b); \
348 \
349 YUV_TO_RGB2(r, g, b, y2_ptr[0]); \
350 RGB_OUT(d2, r, g, b); \
351 \
352 YUV_TO_RGB2(r, g, b, y2_ptr[1]); \
353 RGB_OUT(d2 + BPP, r, g, b); \
354 \
355 d1 += 2 * BPP; \
356 d2 += 2 * BPP; \
357 \
358 y1_ptr += 2; \
359 y2_ptr += 2; \
360 cb_ptr++; \
361 cr_ptr++; \
362 } \
363 d += 2 * dst->linesize[0]; \
364 y1_ptr += 2 * src->linesize[0] - width; \
365 cb_ptr += src->linesize[1] - width2; \
366 cr_ptr += src->linesize[2] - width2; \
367 } \
368 } \
369 \
370 /* XXX: no chroma interpolating is done */ \
371 static void yuv422p_to_ ## rgb_name (AVPicture *dst, AVPicture *src, \
372 int width, int height) \
373 { \
374 UINT8 *y1_ptr, *cb_ptr, *cr_ptr, *d, *d1; \
375 int w, y, cb, cr, r_add, g_add, b_add, width2; \
376 UINT8 *cm = cropTbl + MAX_NEG_CROP; \
377 unsigned int r, g, b; \
378 \
379 d = dst->data[0]; \
380 y1_ptr = src->data[0]; \
381 cb_ptr = src->data[1]; \
382 cr_ptr = src->data[2]; \
383 width2 = width >> 1; \
384 for(;height > 0; height --) { \
385 d1 = d; \
386 for(w = width2; w > 0; w --) { \
387 cb = cb_ptr[0] - 128; \
388 cr = cr_ptr[0] - 128; \
389 r_add = C_RV * cr + (1 << (SCALE_BITS - 1)); \
390 g_add = - C_GU * cb - C_GV * cr + (1 << (SCALE_BITS - 1)); \
391 b_add = C_BU * cb + (1 << (SCALE_BITS - 1)); \
392 \
393 /* output 2 pixels */ \
394 YUV_TO_RGB2(r, g, b, y1_ptr[0]); \
395 RGB_OUT(d, r, g, b); \
396 \
397 YUV_TO_RGB2(r, g, b, y1_ptr[1]); \
398 RGB_OUT(d + BPP, r, g, b); \
399 \
400 d += 2 * BPP; \
401 \
402 y1_ptr += 2; \
403 cb_ptr++; \
404 cr_ptr++; \
405 } \
406 d += dst->linesize[0]; \
407 y1_ptr += src->linesize[0] - width; \
408 cb_ptr += src->linesize[1] - width2; \
409 cr_ptr += src->linesize[2] - width2; \
410 } \
411 } \
412 \
413 static void rgb_name ## _to_yuv420p(AVPicture *dst, AVPicture *src, \
414 int width, int height) \
415 { \
416 int wrap, wrap3, x, y; \
417 int r, g, b, r1, g1, b1; \
418 UINT8 *lum, *cb, *cr; \
419 const UINT8 *p; \
420 \
421 lum = dst->data[0]; \
422 cb = dst->data[1]; \
423 cr = dst->data[2]; \
424 \
425 wrap = width; \
426 wrap3 = width * 3; \
427 p = src->data[0]; \
428 for(y=0;y<height;y+=2) { \
429 for(x=0;x<width;x+=2) { \
430 RGB_IN(r, g, b, p); \
431 r1 = r; \
432 g1 = g; \
433 b1 = b; \
434 lum[0] = (FIX(0.29900) * r + FIX(0.58700) * g + \
435 FIX(0.11400) * b + ONE_HALF) >> SCALEBITS; \
436 RGB_IN(r, g, b, p + BPP); \
437 r1 += r; \
438 g1 += g; \
439 b1 += b; \
440 lum[1] = (FIX(0.29900) * r + FIX(0.58700) * g + \
441 FIX(0.11400) * b + ONE_HALF) >> SCALEBITS; \
442 p += wrap3; \
443 lum += wrap; \
444 \
445 RGB_IN(r, g, b, p); \
446 r1 += r; \
447 g1 += g; \
448 b1 += b; \
449 lum[0] = (FIX(0.29900) * r + FIX(0.58700) * g + \
450 FIX(0.11400) * b + ONE_HALF) >> SCALEBITS; \
451 \
452 RGB_IN(r, g, b, p + BPP); \
453 r1 += r; \
454 g1 += g; \
455 b1 += b; \
456 lum[1] = (FIX(0.29900) * r + FIX(0.58700) * g + \
457 FIX(0.11400) * b + ONE_HALF) >> SCALEBITS; \
458 \
459 cb[0] = ((- FIX(0.16874) * r1 - FIX(0.33126) * g1 + \
460 FIX(0.50000) * b1 + 4 * ONE_HALF - 1) >> \
461 (SCALEBITS + 2)) + 128; \
462 cr[0] = ((FIX(0.50000) * r1 - FIX(0.41869) * g1 - \
463 FIX(0.08131) * b1 + 4 * ONE_HALF - 1) >> \
464 (SCALEBITS + 2)) + 128; \
465 \
466 cb++; \
467 cr++; \
468 p += -wrap3 + 2 * 3; \
469 lum += -wrap + 2; \
470 } \
471 p += wrap3; \
472 lum += wrap; \
473 } \
474 }
475
476 /* copy bit n to bits 0 ... n - 1 */
477 static inline unsigned int bitcopy_n(unsigned int a, int n)
478 {
479 int mask;
480 mask = (1 << n) - 1;
481 return (a & (0xff & ~mask)) | ((-((a >> n) & 1)) & mask);
482 }
483
484 /* rgb555 handling */
485
486 #define RGB_IN(r, g, b, s)\
487 {\
488 unsigned int v = ((UINT16 *)(s))[0];\
489 r = bitcopy_n(v >> (10 - 3), 3);\
490 g = bitcopy_n(v >> (5 - 3), 3);\
491 b = bitcopy_n(v << 3, 3);\
492 }
493
494 #define RGB_OUT(d, r, g, b)\
495 {\
496 ((UINT16 *)(d))[0] = ((r >> 3) << 10) | ((g >> 3) << 5) | (b >> 3) | 0x8000;\
497 }
498
499 #define BPP 2
500
501 RGB_FUNCTIONS(rgb555)
502
503 #undef RGB_IN
504 #undef RGB_OUT
505 #undef BPP
506
507 /* rgb565 handling */
508
509 #define RGB_IN(r, g, b, s)\
510 {\
511 unsigned int v = ((UINT16 *)(s))[0];\
512 r = bitcopy_n(v >> (11 - 3), 3);\
513 g = bitcopy_n(v >> (5 - 2), 2);\
514 b = bitcopy_n(v << 3, 3);\
515 }
516
517 #define RGB_OUT(d, r, g, b)\
518 {\
519 ((UINT16 *)(d))[0] = ((r >> 3) << 11) | ((g >> 2) << 5) | (b >> 3);\
520 }
521
522 #define BPP 2
523
524 RGB_FUNCTIONS(rgb565)
525
526 #undef RGB_IN
527 #undef RGB_OUT
528 #undef BPP
529
530 /* bgr24 handling */
531
532 #define RGB_IN(r, g, b, s)\
533 {\
534 b = (s)[0];\
535 g = (s)[1];\
536 r = (s)[2];\
537 }
538
539 #define RGB_OUT(d, r, g, b)\
540 {\
541 (d)[0] = b;\
542 (d)[1] = g;\
543 (d)[2] = r;\
544 }
545
546 #define BPP 3
547
548 RGB_FUNCTIONS(bgr24)
549
550 #undef RGB_IN
551 #undef RGB_OUT
552 #undef BPP
553
554 /* rgb24 handling */
555
556 #define RGB_IN(r, g, b, s)\
557 {\
558 r = (s)[0];\
559 g = (s)[1];\
560 b = (s)[2];\
561 }
562
563 #define RGB_OUT(d, r, g, b)\
564 {\
565 (d)[0] = r;\
566 (d)[1] = g;\
567 (d)[2] = b;\
568 }
569
570 #define BPP 3
571
572 RGB_FUNCTIONS(rgb24)
573
574 #undef RGB_IN
575 #undef RGB_OUT
576 #undef BPP
577
578 /* rgba32 handling */
579
580 #define RGB_IN(r, g, b, s)\
581 {\
582 unsigned int v = ((UINT32 *)(s))[0];\
583 r = (v >> 16) & 0xff;\
584 g = (v >> 8) & 0xff;\
585 b = v & 0xff;\
586 }
587
588 #define RGB_OUT(d, r, g, b)\
589 {\
590 ((UINT32 *)(d))[0] = (0xff << 24) | (r << 16) | (g << 8) | b;\
591 }
592
593 #define BPP 4
594
595 RGB_FUNCTIONS(rgba32)
596
597 #undef RGB_IN
598 #undef RGB_OUT
599 #undef BPP
600
601
602 static void rgb24_to_rgb565(AVPicture *dst, AVPicture *src,
603 int width, int height)
604 {
605 const unsigned char *p;
606 unsigned char *q;
607 int r, g, b, dst_wrap, src_wrap;
608 int x, y;
609
610 p = src->data[0];
611 src_wrap = src->linesize[0] - 3 * width;
612
613 q = dst->data[0];
614 dst_wrap = dst->linesize[0] - 2 * width;
615
616 for(y=0;y<height;y++) {
617 for(x=0;x<width;x++) {
618 r = p[0];
619 g = p[1];
620 b = p[2];
621
622 ((unsigned short *)q)[0] =
623 ((r >> 3) << 11) | ((g >> 2) << 5) | (b >> 3);
624 q += 2;
625 p += 3;
626 }
627 p += src_wrap;
628 q += dst_wrap;
629 }
630 }
631
632 /* NOTE: we also add a dummy alpha bit */
633 static void rgb24_to_rgb555(AVPicture *dst, AVPicture *src,
634 int width, int height)
635 {
636 const unsigned char *p;
637 unsigned char *q;
638 int r, g, b, dst_wrap, src_wrap;
639 int x, y;
640
641 p = src->data[0];
642 src_wrap = src->linesize[0] - 3 * width;
643
644 q = dst->data[0];
645 dst_wrap = dst->linesize[0] - 2 * width;
646
647 for(y=0;y<height;y++) {
648 for(x=0;x<width;x++) {
649 r = p[0];
650 g = p[1];
651 b = p[2];
652
653 ((unsigned short *)q)[0] =
654 ((r >> 3) << 10) | ((g >> 3) << 5) | (b >> 3) | 0x8000;
655 q += 2;
656 p += 3;
657 }
658 p += src_wrap;
659 q += dst_wrap;
660 }
661 }
662
663 static void rgb24_to_gray(AVPicture *dst, AVPicture *src,
664 int width, int height)
665 {
666 const unsigned char *p;
667 unsigned char *q;
668 int r, g, b, dst_wrap, src_wrap;
669 int x, y;
670
671 p = src->data[0];
672 src_wrap = src->linesize[0] - 3 * width;
673
674 q = dst->data[0];
675 dst_wrap = dst->linesize[0] - width;
676
677 for(y=0;y<height;y++) {
678 for(x=0;x<width;x++) {
679 r = p[0];
680 g = p[1];
681 b = p[2];
682
683 q[0] = (FIX(0.29900) * r + FIX(0.58700) * g +
684 FIX(0.11400) * b + ONE_HALF) >> SCALEBITS;
685 q++;
686 p += 3;
687 }
688 p += src_wrap;
689 q += dst_wrap;
690 }
691 }
692
693 static void gray_to_rgb24(AVPicture *dst, AVPicture *src,
694 int width, int height)
695 {
696 const unsigned char *p;
697 unsigned char *q;
698 int r, dst_wrap, src_wrap;
699 int x, y;
700
701 p = src->data[0];
702 src_wrap = src->linesize[0] - width;
703
704 q = dst->data[0];
705 dst_wrap = dst->linesize[0] - 3 * width;
706
707 for(y=0;y<height;y++) {
708 for(x=0;x<width;x++) {
709 r = p[0];
710
711 q[0] = r;
712 q[1] = r;
713 q[2] = r;
565 714
566 /* output 4 pixels */ 715 q += 3;
567 RGBOUT(d1[2], d1[1], d1[0], y1_ptr[0]); 716 p ++;
568 RGBOUT(d1[6], d1[5], d1[4], y1_ptr[1]); 717 }
569 RGBOUT(d2[2], d2[1], d2[0], y2_ptr[0]); 718 p += src_wrap;
570 RGBOUT(d2[6], d2[5], d2[4], y2_ptr[1]); 719 q += dst_wrap;
571 720 }
572 d1[3] = d1[7] = d2[3] = d2[7] = 255; 721 }
573 722
574 d1 += 8; 723 static void monowhite_to_rgb24(AVPicture *dst, AVPicture *src,
575 d2 += 8; 724 int width, int height)
576 y1_ptr += 2; 725 {
577 y2_ptr += 2; 726 const unsigned char *p;
578 cb_ptr++; 727 unsigned char *q;
579 cr_ptr++; 728 int v, dst_wrap, src_wrap;
580 } 729 int y, w;
581 d += 2 * dst->linesize[0]; 730
582 y1_ptr += 2 * src->linesize[0] - width; 731 p = src->data[0];
583 cb_ptr += src->linesize[1] - width2; 732 src_wrap = src->linesize[0] - ((width + 7) >> 3);
584 cr_ptr += src->linesize[2] - width2; 733
585 } 734 q = dst->data[0];
586 } 735 dst_wrap = dst->linesize[0] - 3 * width;
587 736
588 /* XXX: no chroma interpolating is done */ 737 for(y=0;y<height;y++) {
589 static void yuv420p_to_rgba32(AVPicture *dst, AVPicture *src, 738 w = width;
590 int width, int height) 739 while (w >= 8) {
591 { 740 v = *p++ ^ 0xff;
592 UINT8 *y1_ptr, *y2_ptr, *cb_ptr, *cr_ptr, *d, *d1, *d2; 741 q[0] = q[1] = q[2] = -(v >> 7); q += 3;
593 int w, y, cb, cr, r_add, g_add, b_add, width2; 742 q[0] = q[1] = q[2] = -((v >> 6) & 1); q += 3;
594 UINT8 *cm = cropTbl + MAX_NEG_CROP; 743 q[0] = q[1] = q[2] = -((v >> 5) & 1); q += 3;
595 744 q[0] = q[1] = q[2] = -((v >> 4) & 1); q += 3;
596 d = dst->data[0]; 745 q[0] = q[1] = q[2] = -((v >> 3) & 1); q += 3;
597 y1_ptr = src->data[0]; 746 q[0] = q[1] = q[2] = -((v >> 2) & 1); q += 3;
598 cb_ptr = src->data[1]; 747 q[0] = q[1] = q[2] = -((v >> 1) & 1); q += 3;
599 cr_ptr = src->data[2]; 748 q[0] = q[1] = q[2] = -((v >> 0) & 1); q += 3;
600 width2 = width >> 1; 749 w -= 8;
601 for(;height > 0; height -= 2) { 750 }
602 d1 = d; 751 if (w > 0) {
603 d2 = d + dst->linesize[0]; 752 v = *p++ ^ 0xff;
604 y2_ptr = y1_ptr + src->linesize[0]; 753 do {
605 for(w = width2; w > 0; w --) { 754 q[0] = q[1] = q[2] = -((v >> 7) & 1); q += 3;
606 cb = cb_ptr[0] - 128; 755 v <<= 1;
607 cr = cr_ptr[0] - 128; 756 } while (--w);
608 r_add = C_RV * cr + (1 << (SCALE_BITS - 1)); 757 }
609 g_add = - C_GU * cb - C_GV * cr + (1 << (SCALE_BITS - 1)); 758 p += src_wrap;
610 b_add = C_BU * cb + (1 << (SCALE_BITS - 1)); 759 q += dst_wrap;
611 760 }
612 /* output 4 pixels */ 761 }
613 RGBOUT(d1[0], d1[1], d1[2], y1_ptr[0]); 762
614 RGBOUT(d1[4], d1[5], d1[6], y1_ptr[1]); 763 static void monoblack_to_rgb24(AVPicture *dst, AVPicture *src,
615 RGBOUT(d2[0], d2[1], d2[2], y2_ptr[0]); 764 int width, int height)
616 RGBOUT(d2[4], d2[5], d2[6], y2_ptr[1]); 765 {
617 766 const unsigned char *p;
618 d1[3] = d1[7] = d2[3] = d2[7] = 255; 767 unsigned char *q;
619 768 int v, dst_wrap, src_wrap;
620 d1 += 8; 769 int y, w;
621 d2 += 8; 770
622 y1_ptr += 2; 771 p = src->data[0];
623 y2_ptr += 2; 772 src_wrap = src->linesize[0] - ((width + 7) >> 3);
624 cb_ptr++; 773
625 cr_ptr++; 774 q = dst->data[0];
626 } 775 dst_wrap = dst->linesize[0] - 3 * width;
627 d += 2 * dst->linesize[0]; 776
628 y1_ptr += 2 * src->linesize[0] - width; 777 for(y=0;y<height;y++) {
629 cb_ptr += src->linesize[1] - width2; 778 w = width;
630 cr_ptr += src->linesize[2] - width2; 779 while (w >= 8) {
631 } 780 v = *p++;
632 } 781 q[0] = q[1] = q[2] = -(v >> 7); q += 3;
633 782 q[0] = q[1] = q[2] = -((v >> 6) & 1); q += 3;
634 /* XXX: no chroma interpolating is done */ 783 q[0] = q[1] = q[2] = -((v >> 5) & 1); q += 3;
635 static void yuv420p_to_rgb24(AVPicture *dst, AVPicture *src, 784 q[0] = q[1] = q[2] = -((v >> 4) & 1); q += 3;
636 int width, int height) 785 q[0] = q[1] = q[2] = -((v >> 3) & 1); q += 3;
637 { 786 q[0] = q[1] = q[2] = -((v >> 2) & 1); q += 3;
638 UINT8 *y1_ptr, *y2_ptr, *cb_ptr, *cr_ptr, *d, *d1, *d2; 787 q[0] = q[1] = q[2] = -((v >> 1) & 1); q += 3;
639 int w, y, cb, cr, r_add, g_add, b_add, width2; 788 q[0] = q[1] = q[2] = -((v >> 0) & 1); q += 3;
640 UINT8 *cm = cropTbl + MAX_NEG_CROP; 789 w -= 8;
641 790 }
642 d = dst->data[0]; 791 if (w > 0) {
643 y1_ptr = src->data[0]; 792 v = *p++;
644 cb_ptr = src->data[1]; 793 do {
645 cr_ptr = src->data[2]; 794 q[0] = q[1] = q[2] = -((v >> 7) & 1); q += 3;
646 width2 = width >> 1; 795 v <<= 1;
647 for(;height > 0; height -= 2) { 796 } while (--w);
648 d1 = d; 797 }
649 d2 = d + dst->linesize[0]; 798 p += src_wrap;
650 y2_ptr = y1_ptr + src->linesize[0]; 799 q += dst_wrap;
651 for(w = width2; w > 0; w --) { 800 }
652 cb = cb_ptr[0] - 128; 801 }
653 cr = cr_ptr[0] - 128; 802
654 r_add = C_RV * cr + (1 << (SCALE_BITS - 1)); 803 typedef struct ConvertEntry {
655 g_add = - C_GU * cb - C_GV * cr + (1 << (SCALE_BITS - 1)); 804 void (*convert)(AVPicture *dst, AVPicture *src, int width, int height);
656 b_add = C_BU * cb + (1 << (SCALE_BITS - 1)); 805 } ConvertEntry;
657 806
658 /* output 4 pixels */ 807 /* add each new convertion function in this table */
659 RGBOUT(d1[0], d1[1], d1[2], y1_ptr[0]); 808 /* constraints;
660 RGBOUT(d1[3], d1[4], d1[5], y1_ptr[1]); 809 - all non YUV modes must convert at least to and from PIX_FMT_RGB24
661 RGBOUT(d2[0], d2[1], d2[2], y2_ptr[0]); 810 */
662 RGBOUT(d2[3], d2[4], d2[5], y2_ptr[1]); 811 static ConvertEntry convert_table[PIX_FMT_NB][PIX_FMT_NB] = {
663 812 [PIX_FMT_YUV420P] = {
664 d1 += 6; 813 [PIX_FMT_RGB555] = {
665 d2 += 6; 814 convert: yuv420p_to_rgb555
666 y1_ptr += 2; 815 },
667 y2_ptr += 2; 816 [PIX_FMT_RGB565] = {
668 cb_ptr++; 817 convert: yuv420p_to_rgb565
669 cr_ptr++; 818 },
670 } 819 [PIX_FMT_BGR24] = {
671 d += 2 * dst->linesize[0]; 820 convert: yuv420p_to_bgr24
672 y1_ptr += 2 * src->linesize[0] - width; 821 },
673 cb_ptr += src->linesize[1] - width2; 822 [PIX_FMT_RGB24] = {
674 cr_ptr += src->linesize[2] - width2; 823 convert: yuv420p_to_rgb24
675 } 824 },
676 } 825 [PIX_FMT_RGBA32] = {
677 826 convert: yuv420p_to_rgba32
678 /* XXX: no chroma interpolating is done */ 827 },
679 static void yuv422p_to_rgb24(AVPicture *dst, AVPicture *src, 828 },
680 int width, int height) 829 [PIX_FMT_YUV422P] = {
681 { 830 [PIX_FMT_RGB555] = {
682 UINT8 *y1_ptr, *cb_ptr, *cr_ptr, *d, *d1; 831 convert: yuv422p_to_rgb555
683 int w, y, cb, cr, r_add, g_add, b_add, width2; 832 },
684 UINT8 *cm = cropTbl + MAX_NEG_CROP; 833 [PIX_FMT_RGB565] = {
685 834 convert: yuv422p_to_rgb565
686 d = dst->data[0]; 835 },
687 y1_ptr = src->data[0]; 836 [PIX_FMT_BGR24] = {
688 cb_ptr = src->data[1]; 837 convert: yuv422p_to_bgr24
689 cr_ptr = src->data[2]; 838 },
690 width2 = width >> 1; 839 [PIX_FMT_RGB24] = {
691 for(;height > 0; height --) { 840 convert: yuv422p_to_rgb24
692 d1 = d; 841 },
693 for(w = width2; w > 0; w --) { 842 [PIX_FMT_RGBA32] = {
694 cb = cb_ptr[0] - 128; 843 convert: yuv422p_to_rgba32
695 cr = cr_ptr[0] - 128; 844 },
696 r_add = C_RV * cr + (1 << (SCALE_BITS - 1)); 845 },
697 g_add = - C_GU * cb - C_GV * cr + (1 << (SCALE_BITS - 1)); 846 [PIX_FMT_YUV422] = {
698 b_add = C_BU * cb + (1 << (SCALE_BITS - 1)); 847 [PIX_FMT_YUV420P] = {
699 848 convert: yuv422_to_yuv420p,
700 /* output 2 pixels */ 849 },
701 RGBOUT(d1[0], d1[1], d1[2], y1_ptr[0]); 850 },
702 RGBOUT(d1[3], d1[4], d1[5], y1_ptr[1]); 851
703 852 [PIX_FMT_RGB24] = {
704 d1 += 6; 853 [PIX_FMT_YUV420P] = {
705 y1_ptr += 2; 854 convert: rgb24_to_yuv420p
706 cb_ptr++; 855 },
707 cr_ptr++; 856 [PIX_FMT_RGB565] = {
708 } 857 convert: rgb24_to_rgb565
709 d += dst->linesize[0]; 858 },
710 y1_ptr += src->linesize[0] - width; 859 [PIX_FMT_RGB555] = {
711 cb_ptr += src->linesize[1] - width2; 860 convert: rgb24_to_rgb555
712 cr_ptr += src->linesize[2] - width2; 861 },
713 } 862 [PIX_FMT_GRAY8] = {
863 convert: rgb24_to_gray
864 },
865 },
866 [PIX_FMT_RGBA32] = {
867 [PIX_FMT_YUV420P] = {
868 convert: rgba32_to_yuv420p
869 },
870 },
871 [PIX_FMT_BGR24] = {
872 [PIX_FMT_YUV420P] = {
873 convert: bgr24_to_yuv420p
874 },
875 },
876 [PIX_FMT_RGB555] = {
877 [PIX_FMT_YUV420P] = {
878 convert: rgb555_to_yuv420p
879 },
880 },
881 [PIX_FMT_RGB565] = {
882 [PIX_FMT_YUV420P] = {
883 convert: rgb565_to_yuv420p
884 },
885 },
886 [PIX_FMT_GRAY8] = {
887 [PIX_FMT_RGB24] = {
888 convert: gray_to_rgb24
889 },
890 },
891 [PIX_FMT_MONOWHITE] = {
892 [PIX_FMT_RGB24] = {
893 convert: monowhite_to_rgb24
894 },
895 },
896 [PIX_FMT_MONOBLACK] = {
897 [PIX_FMT_RGB24] = {
898 convert: monoblack_to_rgb24
899 },
900 },
901 };
902
903 static int avpicture_alloc(AVPicture *picture,
904 int pix_fmt, int width, int height)
905 {
906 int size;
907 void *ptr;
908
909 size = avpicture_get_size(pix_fmt, width, height);
910 if (size < 0)
911 goto fail;
912 ptr = av_malloc(size);
913 if (!ptr)
914 goto fail;
915 avpicture_fill(picture, ptr, pix_fmt, width, height);
916 return 0;
917 fail:
918 memset(picture, 0, sizeof(AVPicture));
919 return -1;
920 }
921
922 static void avpicture_free(AVPicture *picture)
923 {
924 free(picture->data[0]);
714 } 925 }
715 926
716 /* XXX: always use linesize. Return -1 if not supported */ 927 /* XXX: always use linesize. Return -1 if not supported */
717 int img_convert(AVPicture *dst, int dst_pix_fmt, 928 int img_convert(AVPicture *dst, int dst_pix_fmt,
718 AVPicture *src, int pix_fmt, 929 AVPicture *src, int src_pix_fmt,
719 int width, int height) 930 int src_width, int src_height)
720 { 931 {
721 int i; 932 int i, ret, dst_width, dst_height;
722 933 PixFmtInfo *src_pix, *dst_pix;
723 if (dst_pix_fmt == pix_fmt) { 934 ConvertEntry *ce;
724 switch(pix_fmt) { 935 AVPicture tmp1, *tmp = &tmp1;
725 case PIX_FMT_YUV420P: 936
726 for(i=0;i<3;i++) { 937 if (src_pix_fmt < 0 || src_pix_fmt >= PIX_FMT_NB ||
727 if (i == 1) { 938 dst_pix_fmt < 0 || dst_pix_fmt >= PIX_FMT_NB)
728 width >>= 1; 939 return -1;
729 height >>= 1; 940 if (src_width <= 0 || src_height <= 0)
730 } 941 return 0;
731 img_copy(dst->data[i], dst->linesize[i], 942
732 src->data[i], src->linesize[i], 943 dst_width = src_width;
733 width, height); 944 dst_height = src_height;
945
946 dst_pix = &pix_fmt_info[dst_pix_fmt];
947 src_pix = &pix_fmt_info[src_pix_fmt];
948 if (src_pix_fmt == dst_pix_fmt) {
949 /* same format: just copy */
950 for(i = 0; i < dst_pix->nb_components; i++) {
951 int w, h;
952 w = dst_width;
953 h = dst_height;
954 if (dst_pix->is_yuv && (i == 1 || i == 2)) {
955 w >>= dst_pix->x_chroma_shift;
956 h >>= dst_pix->y_chroma_shift;
734 } 957 }
735 break; 958 img_copy(dst->data[i], dst->linesize[i],
736 default: 959 src->data[i], src->linesize[i],
960 w, h);
961 }
962 return 0;
963 }
964
965 ce = &convert_table[src_pix_fmt][dst_pix_fmt];
966 if (ce->convert) {
967 /* specific convertion routine */
968 ce->convert(dst, src, dst_width, dst_height);
969 return 0;
970 }
971
972 /* if both format are not YUV, try to use RGB24 as common
973 format */
974 if (!dst_pix->is_yuv && !src_pix->is_yuv) {
975 if (avpicture_alloc(tmp, PIX_FMT_RGB24, dst_width, dst_height) < 0)
737 return -1; 976 return -1;
738 } 977 ret = -1;
739 } else if (dst_pix_fmt == PIX_FMT_YUV420P) { 978 if (img_convert(tmp, PIX_FMT_RGB24,
740 979 src, src_pix_fmt, src_width, src_height) < 0)
741 switch(pix_fmt) { 980 goto fail1;
742 case PIX_FMT_YUV411P: 981 if (img_convert(dst, dst_pix_fmt,
743 img_copy(dst->data[0], dst->linesize[0], 982 tmp, PIX_FMT_RGB24, dst_width, dst_height) < 0)
744 src->data[0], src->linesize[0], 983 goto fail1;
745 width, height); 984 ret = 0;
746 conv411(dst->data[1], dst->linesize[1], 985 fail1:
747 src->data[1], src->linesize[1], 986 avpicture_free(tmp);
748 width / 4, height); 987 return ret;
749 conv411(dst->data[2], dst->linesize[2], 988 }
750 src->data[2], src->linesize[2], 989
751 width / 4, height); 990 /* gray to YUV */
752 break; 991 if (dst_pix->is_yuv && src_pix_fmt == PIX_FMT_GRAY8) {
753 case PIX_FMT_YUV410P: 992 int w, h, y;
754 img_copy(dst->data[0], dst->linesize[0], 993 uint8_t *d;
755 src->data[0], src->linesize[0], 994
756 width, height); 995 img_copy(dst->data[0], dst->linesize[0],
757 grow22(dst->data[1], dst->linesize[1], 996 src->data[0], src->linesize[0],
758 src->data[1], src->linesize[1], 997 dst_width, dst_height);
759 width/2, height/2); 998 /* fill U and V with 128 */
760 grow22(dst->data[2], dst->linesize[2], 999 w = dst_width;
761 src->data[2], src->linesize[2], 1000 h = dst_height;
762 width/2, height/2); 1001 w >>= dst_pix->x_chroma_shift;
763 break; 1002 h >>= dst_pix->y_chroma_shift;
764 case PIX_FMT_YUV420P: 1003 for(i = 1; i <= 2; i++) {
765 for(i=0;i<3;i++) { 1004 d = dst->data[i];
766 img_copy(dst->data[i], dst->linesize[i], 1005 for(y = 0; y<h; y++) {
767 src->data[i], src->linesize[i], 1006 memset(d, 128, 0);
768 width, height); 1007 d += dst->linesize[i];
769 } 1008 }
770 break; 1009 }
771 case PIX_FMT_YUV422P: 1010 return 0;
772 img_copy(dst->data[0], dst->linesize[0], 1011 }
773 src->data[0], src->linesize[0], 1012
774 width, height); 1013 /* YUV to gray */
775 width >>= 1; 1014 if (src_pix->is_yuv && dst_pix_fmt == PIX_FMT_GRAY8) {
776 height >>= 1; 1015 img_copy(dst->data[0], dst->linesize[0],
777 for(i=1;i<3;i++) { 1016 src->data[0], src->linesize[0],
778 shrink2(dst->data[i], dst->linesize[i], 1017 dst_width, dst_height);
779 src->data[i], src->linesize[i], 1018 return 0;
780 width, height); 1019 }
781 } 1020
782 break; 1021 /* YUV to YUV */
783 case PIX_FMT_YUV444P: 1022 if (dst_pix->is_yuv && src_pix->is_yuv) {
784 img_copy(dst->data[0], dst->linesize[0], 1023 int x_shift, y_shift, w, h;
785 src->data[0], src->linesize[0], 1024 void (*resize_func)(UINT8 *dst, int dst_wrap,
786 width, height); 1025 UINT8 *src, int src_wrap,
787 width >>= 1; 1026 int width, int height);
788 height >>= 1; 1027
789 for(i=1;i<3;i++) { 1028 /* compute chroma size of the smallest dimensions */
790 shrink22(dst->data[i], dst->linesize[i], 1029 w = dst_width;
791 src->data[i], src->linesize[i], 1030 h = dst_height;
792 width, height); 1031 if (dst_pix->x_chroma_shift >= src_pix->x_chroma_shift)
793 } 1032 w >>= dst_pix->x_chroma_shift;
794 break; 1033 else
795 case PIX_FMT_YUV422: 1034 w >>= src_pix->x_chroma_shift;
796 yuv422_to_yuv420p(dst->data[0], dst->data[1], dst->data[2], 1035 if (dst_pix->y_chroma_shift >= src_pix->y_chroma_shift)
797 src->data[0], width, height); 1036 h >>= dst_pix->y_chroma_shift;
798 break; 1037 else
799 case PIX_FMT_RGB24: 1038 h >>= src_pix->y_chroma_shift;
800 rgb24_to_yuv420p(dst->data[0], dst->data[1], dst->data[2], 1039
801 src->data[0], width, height); 1040 x_shift = (dst_pix->x_chroma_shift - src_pix->x_chroma_shift);
802 break; 1041 y_shift = (dst_pix->y_chroma_shift - src_pix->y_chroma_shift);
803 case PIX_FMT_RGBA32: 1042 if (x_shift == 0 && y_shift == 0) {
804 rgba32_to_yuv420p(dst->data[0], dst->data[1], dst->data[2], 1043 resize_func = img_copy; /* should never happen */
805 src->data[0], width, height); 1044 } else if (x_shift == 0 && y_shift == 1) {
806 break; 1045 resize_func = shrink2;
807 case PIX_FMT_BGR24: 1046 } else if (x_shift == 1 && y_shift == 1) {
808 bgr24_to_yuv420p(dst->data[0], dst->data[1], dst->data[2], 1047 resize_func = shrink22;
809 src->data[0], width, height); 1048 } else if (x_shift == -1 && y_shift == -1) {
810 break; 1049 resize_func = grow22;
811 case PIX_FMT_BGRA32: 1050 } else if (x_shift == -1 && y_shift == 1) {
812 bgra32_to_yuv420p(dst->data[0], dst->data[1], dst->data[2], 1051 resize_func = conv411;
813 src->data[0], width, height); 1052 } else {
814 break; 1053 /* currently not handled */
815 case PIX_FMT_RGB565:
816 rgb565_to_yuv420p(dst->data[0], dst->data[1], dst->data[2],
817 src->data[0], width, height);
818 break;
819 case PIX_FMT_RGB555:
820 rgb555_to_yuv420p(dst->data[0], dst->data[1], dst->data[2],
821 src->data[0], width, height);
822 break;
823 /* case PIX_FMT_RGB5551:
824 rgb5551_to_yuv420p(dst->data[0], dst->data[1], dst->data[2],
825 src->data[0], width, height);
826 break;*/
827 case PIX_FMT_BGR565:
828 bgr565_to_yuv420p(dst->data[0], dst->data[1], dst->data[2],
829 src->data[0], width, height);
830 break;
831 case PIX_FMT_BGR555:
832 bgr555_to_yuv420p(dst->data[0], dst->data[1], dst->data[2],
833 src->data[0], width, height);
834 break;
835 /* case PIX_FMT_GBR565:
836 gbr565_to_yuv420p(dst->data[0], dst->data[1], dst->data[2],
837 src->data[0], width, height);
838 break;
839 case PIX_FMT_GBR555:
840 gbr555_to_yuv420p(dst->data[0], dst->data[1], dst->data[2],
841 src->data[0], width, height);
842 break;*/
843 default:
844 return -1; 1054 return -1;
845 } 1055 }
846 } else if (dst_pix_fmt == PIX_FMT_RGB24) { 1056
847 switch(pix_fmt) { 1057 img_copy(dst->data[0], dst->linesize[0],
848 case PIX_FMT_YUV420P: 1058 src->data[0], src->linesize[0],
849 yuv420p_to_rgb24(dst, src, width, height); 1059 dst_width, dst_height);
850 break; 1060 for(i = 1;i <= 2; i++)
851 case PIX_FMT_YUV422P: 1061 resize_func(dst->data[1], dst->linesize[1],
852 yuv422p_to_rgb24(dst, src, width, height); 1062 src->data[1], src->linesize[1],
853 break; 1063 w, h);
854 default: 1064 }
855 return -1; 1065
856 } 1066 /* cannot convert yet */
857 } else if (dst_pix_fmt == PIX_FMT_RGBA32) { 1067
858 switch(pix_fmt) { 1068 return -1;
859 case PIX_FMT_YUV420P:
860 yuv420p_to_rgba32(dst, src, width, height);
861 break;
862 default:
863 return -1;
864 }
865 } else if (dst_pix_fmt == PIX_FMT_BGRA32) {
866 switch(pix_fmt) {
867 case PIX_FMT_YUV420P:
868 yuv420p_to_bgra32(dst, src, width, height);
869 break;
870 default:
871 return -1;
872 }
873 } else {
874 return -1;
875 }
876 return 0;
877 } 1069 }
878 1070
879 1071
880 #ifdef HAVE_MMX 1072 #ifdef HAVE_MMX
881 #define DEINT_INPLACE_LINE_LUM \ 1073 #define DEINT_INPLACE_LINE_LUM \