Mercurial > sdl-ios-xcode
comparison src/video/SDL_yuv_sw.c @ 1895:c121d94672cb
SDL 1.2 is moving to a branch, and SDL 1.3 is becoming the head.
author | Sam Lantinga <slouken@libsdl.org> |
---|---|
date | Mon, 10 Jul 2006 21:04:37 +0000 |
parents | 8a858076f39d |
children | 8a162bfdc838 |
comparison
equal
deleted
inserted
replaced
1894:c69cee13dd76 | 1895:c121d94672cb |
---|---|
19 Sam Lantinga | 19 Sam Lantinga |
20 slouken@libsdl.org | 20 slouken@libsdl.org |
21 */ | 21 */ |
22 #include "SDL_config.h" | 22 #include "SDL_config.h" |
23 | 23 |
24 /* This is the software implementation of the YUV video overlay support */ | 24 /* This is the software implementation of the YUV texture support */ |
25 | 25 |
26 /* This code was derived from code carrying the following copyright notices: | 26 /* This code was derived from code carrying the following copyright notices: |
27 | 27 |
28 * Copyright (c) 1995 The Regents of the University of California. | 28 * Copyright (c) 1995 The Regents of the University of California. |
29 * All rights reserved. | 29 * All rights reserved. |
84 */ | 84 */ |
85 | 85 |
86 #include "SDL_video.h" | 86 #include "SDL_video.h" |
87 #include "SDL_cpuinfo.h" | 87 #include "SDL_cpuinfo.h" |
88 #include "SDL_stretch_c.h" | 88 #include "SDL_stretch_c.h" |
89 #include "SDL_yuvfuncs.h" | |
90 #include "SDL_yuv_sw_c.h" | 89 #include "SDL_yuv_sw_c.h" |
91 | 90 |
92 /* The functions used to manipulate software video overlays */ | 91 |
93 static struct private_yuvhwfuncs sw_yuvfuncs = { | 92 struct SDL_SW_YUVTexture |
94 SDL_LockYUV_SW, | 93 { |
95 SDL_UnlockYUV_SW, | 94 SDL_Texture *texture; |
96 SDL_DisplayYUV_SW, | 95 |
97 SDL_FreeYUV_SW | 96 Uint32 target_format; |
97 Uint8 *pixels; | |
98 int *colortab; | |
99 Uint32 *rgb_2_pix; | |
100 void (*Display1X) (int *colortab, Uint32 * rgb_2_pix, | |
101 unsigned char *lum, unsigned char *cr, | |
102 unsigned char *cb, unsigned char *out, | |
103 int rows, int cols, int mod); | |
104 void (*Display2X) (int *colortab, Uint32 * rgb_2_pix, | |
105 unsigned char *lum, unsigned char *cr, | |
106 unsigned char *cb, unsigned char *out, | |
107 int rows, int cols, int mod); | |
108 | |
109 /* These are just so we don't have to allocate them separately */ | |
110 Uint16 pitches[3]; | |
111 Uint8 *planes[3]; | |
112 | |
113 /* This is a temporary surface in case we have to stretch copy */ | |
114 SDL_Surface *stretch; | |
115 SDL_Surface *display; | |
98 }; | 116 }; |
99 | 117 |
100 /* RGB conversion lookup tables */ | |
101 struct private_yuvhwdata { | |
102 SDL_Surface *stretch; | |
103 SDL_Surface *display; | |
104 Uint8 *pixels; | |
105 int *colortab; | |
106 Uint32 *rgb_2_pix; | |
107 void (*Display1X)(int *colortab, Uint32 *rgb_2_pix, | |
108 unsigned char *lum, unsigned char *cr, | |
109 unsigned char *cb, unsigned char *out, | |
110 int rows, int cols, int mod ); | |
111 void (*Display2X)(int *colortab, Uint32 *rgb_2_pix, | |
112 unsigned char *lum, unsigned char *cr, | |
113 unsigned char *cb, unsigned char *out, | |
114 int rows, int cols, int mod ); | |
115 | |
116 /* These are just so we don't have to allocate them separately */ | |
117 Uint16 pitches[3]; | |
118 Uint8 *planes[3]; | |
119 }; | |
120 | |
121 | |
122 /* The colorspace conversion functions */ | 118 /* The colorspace conversion functions */ |
123 | 119 |
124 #if 0 /*defined(__GNUC__) && defined(__i386__) && SDL_ASSEMBLY_ROUTINES*/ | 120 #if 0 /*defined(__GNUC__) && defined(__i386__) && SDL_ASSEMBLY_ROUTINES */ |
125 extern void Color565DitherYV12MMX1X( int *colortab, Uint32 *rgb_2_pix, | 121 extern void Color565DitherYV12MMX1X(int *colortab, Uint32 * rgb_2_pix, |
126 unsigned char *lum, unsigned char *cr, | |
127 unsigned char *cb, unsigned char *out, | |
128 int rows, int cols, int mod ); | |
129 extern void ColorRGBDitherYV12MMX1X( int *colortab, Uint32 *rgb_2_pix, | |
130 unsigned char *lum, unsigned char *cr, | |
131 unsigned char *cb, unsigned char *out, | |
132 int rows, int cols, int mod ); | |
133 #endif | |
134 | |
135 static void Color16DitherYV12Mod1X( int *colortab, Uint32 *rgb_2_pix, | |
136 unsigned char *lum, unsigned char *cr, | 122 unsigned char *lum, unsigned char *cr, |
137 unsigned char *cb, unsigned char *out, | 123 unsigned char *cb, unsigned char *out, |
138 int rows, int cols, int mod ) | 124 int rows, int cols, int mod); |
139 { | 125 extern void ColorRGBDitherYV12MMX1X(int *colortab, Uint32 * rgb_2_pix, |
140 unsigned short* row1; | 126 unsigned char *lum, unsigned char *cr, |
141 unsigned short* row2; | 127 unsigned char *cb, unsigned char *out, |
142 unsigned char* lum2; | 128 int rows, int cols, int mod); |
129 #endif | |
130 | |
131 static void | |
132 Color16DitherYV12Mod1X(int *colortab, Uint32 * rgb_2_pix, | |
133 unsigned char *lum, unsigned char *cr, | |
134 unsigned char *cb, unsigned char *out, | |
135 int rows, int cols, int mod) | |
136 { | |
137 unsigned short *row1; | |
138 unsigned short *row2; | |
139 unsigned char *lum2; | |
143 int x, y; | 140 int x, y; |
144 int cr_r; | 141 int cr_r; |
145 int crb_g; | 142 int crb_g; |
146 int cb_b; | 143 int cb_b; |
147 int cols_2 = cols / 2; | 144 int cols_2 = cols / 2; |
148 | 145 |
149 row1 = (unsigned short*) out; | 146 row1 = (unsigned short *) out; |
150 row2 = row1 + cols + mod; | 147 row2 = row1 + cols + mod; |
151 lum2 = lum + cols; | 148 lum2 = lum + cols; |
152 | 149 |
153 mod += cols + mod; | 150 mod += cols + mod; |
154 | 151 |
155 y = rows / 2; | 152 y = rows / 2; |
156 while( y-- ) | 153 while (y--) { |
157 { | |
158 x = cols_2; | 154 x = cols_2; |
159 while( x-- ) | 155 while (x--) { |
160 { | |
161 register int L; | 156 register int L; |
162 | 157 |
163 cr_r = 0*768+256 + colortab[ *cr + 0*256 ]; | 158 cr_r = 0 * 768 + 256 + colortab[*cr + 0 * 256]; |
164 crb_g = 1*768+256 + colortab[ *cr + 1*256 ] | 159 crb_g = 1 * 768 + 256 + colortab[*cr + 1 * 256] |
165 + colortab[ *cb + 2*256 ]; | 160 + colortab[*cb + 2 * 256]; |
166 cb_b = 2*768+256 + colortab[ *cb + 3*256 ]; | 161 cb_b = 2 * 768 + 256 + colortab[*cb + 3 * 256]; |
167 ++cr; ++cb; | 162 ++cr; |
163 ++cb; | |
168 | 164 |
169 L = *lum++; | 165 L = *lum++; |
170 *row1++ = (unsigned short)(rgb_2_pix[ L + cr_r ] | | 166 *row1++ = (unsigned short) (rgb_2_pix[L + cr_r] | |
171 rgb_2_pix[ L + crb_g ] | | 167 rgb_2_pix[L + crb_g] | |
172 rgb_2_pix[ L + cb_b ]); | 168 rgb_2_pix[L + cb_b]); |
173 | 169 |
174 L = *lum++; | 170 L = *lum++; |
175 *row1++ = (unsigned short)(rgb_2_pix[ L + cr_r ] | | 171 *row1++ = (unsigned short) (rgb_2_pix[L + cr_r] | |
176 rgb_2_pix[ L + crb_g ] | | 172 rgb_2_pix[L + crb_g] | |
177 rgb_2_pix[ L + cb_b ]); | 173 rgb_2_pix[L + cb_b]); |
178 | 174 |
179 | 175 |
180 /* Now, do second row. */ | 176 /* Now, do second row. */ |
181 | 177 |
182 L = *lum2++; | 178 L = *lum2++; |
183 *row2++ = (unsigned short)(rgb_2_pix[ L + cr_r ] | | 179 *row2++ = (unsigned short) (rgb_2_pix[L + cr_r] | |
184 rgb_2_pix[ L + crb_g ] | | 180 rgb_2_pix[L + crb_g] | |
185 rgb_2_pix[ L + cb_b ]); | 181 rgb_2_pix[L + cb_b]); |
186 | 182 |
187 L = *lum2++; | 183 L = *lum2++; |
188 *row2++ = (unsigned short)(rgb_2_pix[ L + cr_r ] | | 184 *row2++ = (unsigned short) (rgb_2_pix[L + cr_r] | |
189 rgb_2_pix[ L + crb_g ] | | 185 rgb_2_pix[L + crb_g] | |
190 rgb_2_pix[ L + cb_b ]); | 186 rgb_2_pix[L + cb_b]); |
191 } | 187 } |
192 | 188 |
193 /* | 189 /* |
194 * These values are at the start of the next line, (due | 190 * These values are at the start of the next line, (due |
195 * to the ++'s above),but they need to be at the start | 191 * to the ++'s above),but they need to be at the start |
196 * of the line after that. | 192 * of the line after that. |
197 */ | 193 */ |
198 lum += cols; | 194 lum += cols; |
199 lum2 += cols; | 195 lum2 += cols; |
200 row1 += mod; | 196 row1 += mod; |
201 row2 += mod; | 197 row2 += mod; |
202 } | 198 } |
203 } | 199 } |
204 | 200 |
205 static void Color24DitherYV12Mod1X( int *colortab, Uint32 *rgb_2_pix, | 201 static void |
206 unsigned char *lum, unsigned char *cr, | 202 Color24DitherYV12Mod1X(int *colortab, Uint32 * rgb_2_pix, |
207 unsigned char *cb, unsigned char *out, | 203 unsigned char *lum, unsigned char *cr, |
208 int rows, int cols, int mod ) | 204 unsigned char *cb, unsigned char *out, |
205 int rows, int cols, int mod) | |
209 { | 206 { |
210 unsigned int value; | 207 unsigned int value; |
211 unsigned char* row1; | 208 unsigned char *row1; |
212 unsigned char* row2; | 209 unsigned char *row2; |
213 unsigned char* lum2; | 210 unsigned char *lum2; |
214 int x, y; | 211 int x, y; |
215 int cr_r; | 212 int cr_r; |
216 int crb_g; | 213 int crb_g; |
217 int cb_b; | 214 int cb_b; |
218 int cols_2 = cols / 2; | 215 int cols_2 = cols / 2; |
219 | 216 |
220 row1 = out; | 217 row1 = out; |
221 row2 = row1 + cols*3 + mod*3; | 218 row2 = row1 + cols * 3 + mod * 3; |
222 lum2 = lum + cols; | 219 lum2 = lum + cols; |
223 | 220 |
224 mod += cols + mod; | 221 mod += cols + mod; |
225 mod *= 3; | 222 mod *= 3; |
226 | 223 |
227 y = rows / 2; | 224 y = rows / 2; |
228 while( y-- ) | 225 while (y--) { |
229 { | |
230 x = cols_2; | 226 x = cols_2; |
231 while( x-- ) | 227 while (x--) { |
232 { | |
233 register int L; | 228 register int L; |
234 | 229 |
235 cr_r = 0*768+256 + colortab[ *cr + 0*256 ]; | 230 cr_r = 0 * 768 + 256 + colortab[*cr + 0 * 256]; |
236 crb_g = 1*768+256 + colortab[ *cr + 1*256 ] | 231 crb_g = 1 * 768 + 256 + colortab[*cr + 1 * 256] |
237 + colortab[ *cb + 2*256 ]; | 232 + colortab[*cb + 2 * 256]; |
238 cb_b = 2*768+256 + colortab[ *cb + 3*256 ]; | 233 cb_b = 2 * 768 + 256 + colortab[*cb + 3 * 256]; |
239 ++cr; ++cb; | 234 ++cr; |
235 ++cb; | |
240 | 236 |
241 L = *lum++; | 237 L = *lum++; |
242 value = (rgb_2_pix[ L + cr_r ] | | 238 value = (rgb_2_pix[L + cr_r] | |
243 rgb_2_pix[ L + crb_g ] | | 239 rgb_2_pix[L + crb_g] | rgb_2_pix[L + cb_b]); |
244 rgb_2_pix[ L + cb_b ]); | 240 *row1++ = (value) & 0xFF; |
245 *row1++ = (value ) & 0xFF; | 241 *row1++ = (value >> 8) & 0xFF; |
246 *row1++ = (value >> 8) & 0xFF; | |
247 *row1++ = (value >> 16) & 0xFF; | 242 *row1++ = (value >> 16) & 0xFF; |
248 | 243 |
249 L = *lum++; | 244 L = *lum++; |
250 value = (rgb_2_pix[ L + cr_r ] | | 245 value = (rgb_2_pix[L + cr_r] | |
251 rgb_2_pix[ L + crb_g ] | | 246 rgb_2_pix[L + crb_g] | rgb_2_pix[L + cb_b]); |
252 rgb_2_pix[ L + cb_b ]); | 247 *row1++ = (value) & 0xFF; |
253 *row1++ = (value ) & 0xFF; | 248 *row1++ = (value >> 8) & 0xFF; |
254 *row1++ = (value >> 8) & 0xFF; | |
255 *row1++ = (value >> 16) & 0xFF; | 249 *row1++ = (value >> 16) & 0xFF; |
256 | 250 |
257 | 251 |
258 /* Now, do second row. */ | 252 /* Now, do second row. */ |
259 | 253 |
260 L = *lum2++; | 254 L = *lum2++; |
261 value = (rgb_2_pix[ L + cr_r ] | | 255 value = (rgb_2_pix[L + cr_r] | |
262 rgb_2_pix[ L + crb_g ] | | 256 rgb_2_pix[L + crb_g] | rgb_2_pix[L + cb_b]); |
263 rgb_2_pix[ L + cb_b ]); | 257 *row2++ = (value) & 0xFF; |
264 *row2++ = (value ) & 0xFF; | 258 *row2++ = (value >> 8) & 0xFF; |
265 *row2++ = (value >> 8) & 0xFF; | |
266 *row2++ = (value >> 16) & 0xFF; | 259 *row2++ = (value >> 16) & 0xFF; |
267 | 260 |
268 L = *lum2++; | 261 L = *lum2++; |
269 value = (rgb_2_pix[ L + cr_r ] | | 262 value = (rgb_2_pix[L + cr_r] | |
270 rgb_2_pix[ L + crb_g ] | | 263 rgb_2_pix[L + crb_g] | rgb_2_pix[L + cb_b]); |
271 rgb_2_pix[ L + cb_b ]); | 264 *row2++ = (value) & 0xFF; |
272 *row2++ = (value ) & 0xFF; | 265 *row2++ = (value >> 8) & 0xFF; |
273 *row2++ = (value >> 8) & 0xFF; | |
274 *row2++ = (value >> 16) & 0xFF; | 266 *row2++ = (value >> 16) & 0xFF; |
275 } | 267 } |
276 | 268 |
277 /* | 269 /* |
278 * These values are at the start of the next line, (due | 270 * These values are at the start of the next line, (due |
279 * to the ++'s above),but they need to be at the start | 271 * to the ++'s above),but they need to be at the start |
280 * of the line after that. | 272 * of the line after that. |
281 */ | 273 */ |
282 lum += cols; | 274 lum += cols; |
283 lum2 += cols; | 275 lum2 += cols; |
284 row1 += mod; | 276 row1 += mod; |
285 row2 += mod; | 277 row2 += mod; |
286 } | 278 } |
287 } | 279 } |
288 | 280 |
289 static void Color32DitherYV12Mod1X( int *colortab, Uint32 *rgb_2_pix, | 281 static void |
290 unsigned char *lum, unsigned char *cr, | 282 Color32DitherYV12Mod1X(int *colortab, Uint32 * rgb_2_pix, |
291 unsigned char *cb, unsigned char *out, | 283 unsigned char *lum, unsigned char *cr, |
292 int rows, int cols, int mod ) | 284 unsigned char *cb, unsigned char *out, |
293 { | 285 int rows, int cols, int mod) |
294 unsigned int* row1; | 286 { |
295 unsigned int* row2; | 287 unsigned int *row1; |
296 unsigned char* lum2; | 288 unsigned int *row2; |
289 unsigned char *lum2; | |
297 int x, y; | 290 int x, y; |
298 int cr_r; | 291 int cr_r; |
299 int crb_g; | 292 int crb_g; |
300 int cb_b; | 293 int cb_b; |
301 int cols_2 = cols / 2; | 294 int cols_2 = cols / 2; |
302 | 295 |
303 row1 = (unsigned int*) out; | 296 row1 = (unsigned int *) out; |
304 row2 = row1 + cols + mod; | 297 row2 = row1 + cols + mod; |
305 lum2 = lum + cols; | 298 lum2 = lum + cols; |
306 | 299 |
307 mod += cols + mod; | 300 mod += cols + mod; |
308 | 301 |
309 y = rows / 2; | 302 y = rows / 2; |
310 while( y-- ) | 303 while (y--) { |
311 { | |
312 x = cols_2; | 304 x = cols_2; |
313 while( x-- ) | 305 while (x--) { |
314 { | |
315 register int L; | 306 register int L; |
316 | 307 |
317 cr_r = 0*768+256 + colortab[ *cr + 0*256 ]; | 308 cr_r = 0 * 768 + 256 + colortab[*cr + 0 * 256]; |
318 crb_g = 1*768+256 + colortab[ *cr + 1*256 ] | 309 crb_g = 1 * 768 + 256 + colortab[*cr + 1 * 256] |
319 + colortab[ *cb + 2*256 ]; | 310 + colortab[*cb + 2 * 256]; |
320 cb_b = 2*768+256 + colortab[ *cb + 3*256 ]; | 311 cb_b = 2 * 768 + 256 + colortab[*cb + 3 * 256]; |
321 ++cr; ++cb; | 312 ++cr; |
313 ++cb; | |
322 | 314 |
323 L = *lum++; | 315 L = *lum++; |
324 *row1++ = (rgb_2_pix[ L + cr_r ] | | 316 *row1++ = (rgb_2_pix[L + cr_r] | |
325 rgb_2_pix[ L + crb_g ] | | 317 rgb_2_pix[L + crb_g] | rgb_2_pix[L + cb_b]); |
326 rgb_2_pix[ L + cb_b ]); | |
327 | 318 |
328 L = *lum++; | 319 L = *lum++; |
329 *row1++ = (rgb_2_pix[ L + cr_r ] | | 320 *row1++ = (rgb_2_pix[L + cr_r] | |
330 rgb_2_pix[ L + crb_g ] | | 321 rgb_2_pix[L + crb_g] | rgb_2_pix[L + cb_b]); |
331 rgb_2_pix[ L + cb_b ]); | |
332 | 322 |
333 | 323 |
334 /* Now, do second row. */ | 324 /* Now, do second row. */ |
335 | 325 |
336 L = *lum2++; | 326 L = *lum2++; |
337 *row2++ = (rgb_2_pix[ L + cr_r ] | | 327 *row2++ = (rgb_2_pix[L + cr_r] | |
338 rgb_2_pix[ L + crb_g ] | | 328 rgb_2_pix[L + crb_g] | rgb_2_pix[L + cb_b]); |
339 rgb_2_pix[ L + cb_b ]); | |
340 | 329 |
341 L = *lum2++; | 330 L = *lum2++; |
342 *row2++ = (rgb_2_pix[ L + cr_r ] | | 331 *row2++ = (rgb_2_pix[L + cr_r] | |
343 rgb_2_pix[ L + crb_g ] | | 332 rgb_2_pix[L + crb_g] | rgb_2_pix[L + cb_b]); |
344 rgb_2_pix[ L + cb_b ]); | |
345 } | 333 } |
346 | 334 |
347 /* | 335 /* |
348 * These values are at the start of the next line, (due | 336 * These values are at the start of the next line, (due |
349 * to the ++'s above),but they need to be at the start | 337 * to the ++'s above),but they need to be at the start |
350 * of the line after that. | 338 * of the line after that. |
351 */ | 339 */ |
352 lum += cols; | 340 lum += cols; |
353 lum2 += cols; | 341 lum2 += cols; |
354 row1 += mod; | 342 row1 += mod; |
355 row2 += mod; | 343 row2 += mod; |
356 } | 344 } |
357 } | 345 } |
359 /* | 347 /* |
360 * In this function I make use of a nasty trick. The tables have the lower | 348 * In this function I make use of a nasty trick. The tables have the lower |
361 * 16 bits replicated in the upper 16. This means I can write ints and get | 349 * 16 bits replicated in the upper 16. This means I can write ints and get |
362 * the horisontal doubling for free (almost). | 350 * the horisontal doubling for free (almost). |
363 */ | 351 */ |
364 static void Color16DitherYV12Mod2X( int *colortab, Uint32 *rgb_2_pix, | 352 static void |
365 unsigned char *lum, unsigned char *cr, | 353 Color16DitherYV12Mod2X(int *colortab, Uint32 * rgb_2_pix, |
366 unsigned char *cb, unsigned char *out, | 354 unsigned char *lum, unsigned char *cr, |
367 int rows, int cols, int mod ) | 355 unsigned char *cb, unsigned char *out, |
368 { | 356 int rows, int cols, int mod) |
369 unsigned int* row1 = (unsigned int*) out; | 357 { |
370 const int next_row = cols+(mod/2); | 358 unsigned int *row1 = (unsigned int *) out; |
371 unsigned int* row2 = row1 + 2*next_row; | 359 const int next_row = cols + (mod / 2); |
372 unsigned char* lum2; | 360 unsigned int *row2 = row1 + 2 * next_row; |
361 unsigned char *lum2; | |
373 int x, y; | 362 int x, y; |
374 int cr_r; | 363 int cr_r; |
375 int crb_g; | 364 int crb_g; |
376 int cb_b; | 365 int cb_b; |
377 int cols_2 = cols / 2; | 366 int cols_2 = cols / 2; |
378 | 367 |
379 lum2 = lum + cols; | 368 lum2 = lum + cols; |
380 | 369 |
381 mod = (next_row * 3) + (mod/2); | 370 mod = (next_row * 3) + (mod / 2); |
382 | 371 |
383 y = rows / 2; | 372 y = rows / 2; |
384 while( y-- ) | 373 while (y--) { |
385 { | |
386 x = cols_2; | 374 x = cols_2; |
387 while( x-- ) | 375 while (x--) { |
388 { | |
389 register int L; | 376 register int L; |
390 | 377 |
391 cr_r = 0*768+256 + colortab[ *cr + 0*256 ]; | 378 cr_r = 0 * 768 + 256 + colortab[*cr + 0 * 256]; |
392 crb_g = 1*768+256 + colortab[ *cr + 1*256 ] | 379 crb_g = 1 * 768 + 256 + colortab[*cr + 1 * 256] |
393 + colortab[ *cb + 2*256 ]; | 380 + colortab[*cb + 2 * 256]; |
394 cb_b = 2*768+256 + colortab[ *cb + 3*256 ]; | 381 cb_b = 2 * 768 + 256 + colortab[*cb + 3 * 256]; |
395 ++cr; ++cb; | 382 ++cr; |
383 ++cb; | |
396 | 384 |
397 L = *lum++; | 385 L = *lum++; |
398 row1[0] = row1[next_row] = (rgb_2_pix[ L + cr_r ] | | 386 row1[0] = row1[next_row] = (rgb_2_pix[L + cr_r] | |
399 rgb_2_pix[ L + crb_g ] | | 387 rgb_2_pix[L + crb_g] | |
400 rgb_2_pix[ L + cb_b ]); | 388 rgb_2_pix[L + cb_b]); |
401 row1++; | 389 row1++; |
402 | 390 |
403 L = *lum++; | 391 L = *lum++; |
404 row1[0] = row1[next_row] = (rgb_2_pix[ L + cr_r ] | | 392 row1[0] = row1[next_row] = (rgb_2_pix[L + cr_r] | |
405 rgb_2_pix[ L + crb_g ] | | 393 rgb_2_pix[L + crb_g] | |
406 rgb_2_pix[ L + cb_b ]); | 394 rgb_2_pix[L + cb_b]); |
407 row1++; | 395 row1++; |
408 | 396 |
409 | 397 |
410 /* Now, do second row. */ | 398 /* Now, do second row. */ |
411 | 399 |
412 L = *lum2++; | 400 L = *lum2++; |
413 row2[0] = row2[next_row] = (rgb_2_pix[ L + cr_r ] | | 401 row2[0] = row2[next_row] = (rgb_2_pix[L + cr_r] | |
414 rgb_2_pix[ L + crb_g ] | | 402 rgb_2_pix[L + crb_g] | |
415 rgb_2_pix[ L + cb_b ]); | 403 rgb_2_pix[L + cb_b]); |
416 row2++; | 404 row2++; |
417 | 405 |
418 L = *lum2++; | 406 L = *lum2++; |
419 row2[0] = row2[next_row] = (rgb_2_pix[ L + cr_r ] | | 407 row2[0] = row2[next_row] = (rgb_2_pix[L + cr_r] | |
420 rgb_2_pix[ L + crb_g ] | | 408 rgb_2_pix[L + crb_g] | |
421 rgb_2_pix[ L + cb_b ]); | 409 rgb_2_pix[L + cb_b]); |
422 row2++; | 410 row2++; |
423 } | 411 } |
424 | 412 |
425 /* | 413 /* |
426 * These values are at the start of the next line, (due | 414 * These values are at the start of the next line, (due |
427 * to the ++'s above),but they need to be at the start | 415 * to the ++'s above),but they need to be at the start |
428 * of the line after that. | 416 * of the line after that. |
429 */ | 417 */ |
430 lum += cols; | 418 lum += cols; |
431 lum2 += cols; | 419 lum2 += cols; |
432 row1 += mod; | 420 row1 += mod; |
433 row2 += mod; | 421 row2 += mod; |
434 } | 422 } |
435 } | 423 } |
436 | 424 |
437 static void Color24DitherYV12Mod2X( int *colortab, Uint32 *rgb_2_pix, | 425 static void |
438 unsigned char *lum, unsigned char *cr, | 426 Color24DitherYV12Mod2X(int *colortab, Uint32 * rgb_2_pix, |
439 unsigned char *cb, unsigned char *out, | 427 unsigned char *lum, unsigned char *cr, |
440 int rows, int cols, int mod ) | 428 unsigned char *cb, unsigned char *out, |
429 int rows, int cols, int mod) | |
441 { | 430 { |
442 unsigned int value; | 431 unsigned int value; |
443 unsigned char* row1 = out; | 432 unsigned char *row1 = out; |
444 const int next_row = (cols*2 + mod) * 3; | 433 const int next_row = (cols * 2 + mod) * 3; |
445 unsigned char* row2 = row1 + 2*next_row; | 434 unsigned char *row2 = row1 + 2 * next_row; |
446 unsigned char* lum2; | 435 unsigned char *lum2; |
447 int x, y; | 436 int x, y; |
448 int cr_r; | 437 int cr_r; |
449 int crb_g; | 438 int crb_g; |
450 int cb_b; | 439 int cb_b; |
451 int cols_2 = cols / 2; | 440 int cols_2 = cols / 2; |
452 | 441 |
453 lum2 = lum + cols; | 442 lum2 = lum + cols; |
454 | 443 |
455 mod = next_row*3 + mod*3; | 444 mod = next_row * 3 + mod * 3; |
456 | 445 |
457 y = rows / 2; | 446 y = rows / 2; |
458 while( y-- ) | 447 while (y--) { |
459 { | |
460 x = cols_2; | 448 x = cols_2; |
461 while( x-- ) | 449 while (x--) { |
462 { | |
463 register int L; | 450 register int L; |
464 | 451 |
465 cr_r = 0*768+256 + colortab[ *cr + 0*256 ]; | 452 cr_r = 0 * 768 + 256 + colortab[*cr + 0 * 256]; |
466 crb_g = 1*768+256 + colortab[ *cr + 1*256 ] | 453 crb_g = 1 * 768 + 256 + colortab[*cr + 1 * 256] |
467 + colortab[ *cb + 2*256 ]; | 454 + colortab[*cb + 2 * 256]; |
468 cb_b = 2*768+256 + colortab[ *cb + 3*256 ]; | 455 cb_b = 2 * 768 + 256 + colortab[*cb + 3 * 256]; |
469 ++cr; ++cb; | 456 ++cr; |
457 ++cb; | |
470 | 458 |
471 L = *lum++; | 459 L = *lum++; |
472 value = (rgb_2_pix[ L + cr_r ] | | 460 value = (rgb_2_pix[L + cr_r] | |
473 rgb_2_pix[ L + crb_g ] | | 461 rgb_2_pix[L + crb_g] | rgb_2_pix[L + cb_b]); |
474 rgb_2_pix[ L + cb_b ]); | 462 row1[0 + 0] = row1[3 + 0] = row1[next_row + 0] = |
475 row1[0+0] = row1[3+0] = row1[next_row+0] = row1[next_row+3+0] = | 463 row1[next_row + 3 + 0] = (value) & 0xFF; |
476 (value ) & 0xFF; | 464 row1[0 + 1] = row1[3 + 1] = row1[next_row + 1] = |
477 row1[0+1] = row1[3+1] = row1[next_row+1] = row1[next_row+3+1] = | 465 row1[next_row + 3 + 1] = (value >> 8) & 0xFF; |
478 (value >> 8) & 0xFF; | 466 row1[0 + 2] = row1[3 + 2] = row1[next_row + 2] = |
479 row1[0+2] = row1[3+2] = row1[next_row+2] = row1[next_row+3+2] = | 467 row1[next_row + 3 + 2] = (value >> 16) & 0xFF; |
480 (value >> 16) & 0xFF; | 468 row1 += 2 * 3; |
481 row1 += 2*3; | |
482 | 469 |
483 L = *lum++; | 470 L = *lum++; |
484 value = (rgb_2_pix[ L + cr_r ] | | 471 value = (rgb_2_pix[L + cr_r] | |
485 rgb_2_pix[ L + crb_g ] | | 472 rgb_2_pix[L + crb_g] | rgb_2_pix[L + cb_b]); |
486 rgb_2_pix[ L + cb_b ]); | 473 row1[0 + 0] = row1[3 + 0] = row1[next_row + 0] = |
487 row1[0+0] = row1[3+0] = row1[next_row+0] = row1[next_row+3+0] = | 474 row1[next_row + 3 + 0] = (value) & 0xFF; |
488 (value ) & 0xFF; | 475 row1[0 + 1] = row1[3 + 1] = row1[next_row + 1] = |
489 row1[0+1] = row1[3+1] = row1[next_row+1] = row1[next_row+3+1] = | 476 row1[next_row + 3 + 1] = (value >> 8) & 0xFF; |
490 (value >> 8) & 0xFF; | 477 row1[0 + 2] = row1[3 + 2] = row1[next_row + 2] = |
491 row1[0+2] = row1[3+2] = row1[next_row+2] = row1[next_row+3+2] = | 478 row1[next_row + 3 + 2] = (value >> 16) & 0xFF; |
492 (value >> 16) & 0xFF; | 479 row1 += 2 * 3; |
493 row1 += 2*3; | |
494 | 480 |
495 | 481 |
496 /* Now, do second row. */ | 482 /* Now, do second row. */ |
497 | 483 |
498 L = *lum2++; | 484 L = *lum2++; |
499 value = (rgb_2_pix[ L + cr_r ] | | 485 value = (rgb_2_pix[L + cr_r] | |
500 rgb_2_pix[ L + crb_g ] | | 486 rgb_2_pix[L + crb_g] | rgb_2_pix[L + cb_b]); |
501 rgb_2_pix[ L + cb_b ]); | 487 row2[0 + 0] = row2[3 + 0] = row2[next_row + 0] = |
502 row2[0+0] = row2[3+0] = row2[next_row+0] = row2[next_row+3+0] = | 488 row2[next_row + 3 + 0] = (value) & 0xFF; |
503 (value ) & 0xFF; | 489 row2[0 + 1] = row2[3 + 1] = row2[next_row + 1] = |
504 row2[0+1] = row2[3+1] = row2[next_row+1] = row2[next_row+3+1] = | 490 row2[next_row + 3 + 1] = (value >> 8) & 0xFF; |
505 (value >> 8) & 0xFF; | 491 row2[0 + 2] = row2[3 + 2] = row2[next_row + 2] = |
506 row2[0+2] = row2[3+2] = row2[next_row+2] = row2[next_row+3+2] = | 492 row2[next_row + 3 + 2] = (value >> 16) & 0xFF; |
507 (value >> 16) & 0xFF; | 493 row2 += 2 * 3; |
508 row2 += 2*3; | |
509 | 494 |
510 L = *lum2++; | 495 L = *lum2++; |
511 value = (rgb_2_pix[ L + cr_r ] | | 496 value = (rgb_2_pix[L + cr_r] | |
512 rgb_2_pix[ L + crb_g ] | | 497 rgb_2_pix[L + crb_g] | rgb_2_pix[L + cb_b]); |
513 rgb_2_pix[ L + cb_b ]); | 498 row2[0 + 0] = row2[3 + 0] = row2[next_row + 0] = |
514 row2[0+0] = row2[3+0] = row2[next_row+0] = row2[next_row+3+0] = | 499 row2[next_row + 3 + 0] = (value) & 0xFF; |
515 (value ) & 0xFF; | 500 row2[0 + 1] = row2[3 + 1] = row2[next_row + 1] = |
516 row2[0+1] = row2[3+1] = row2[next_row+1] = row2[next_row+3+1] = | 501 row2[next_row + 3 + 1] = (value >> 8) & 0xFF; |
517 (value >> 8) & 0xFF; | 502 row2[0 + 2] = row2[3 + 2] = row2[next_row + 2] = |
518 row2[0+2] = row2[3+2] = row2[next_row+2] = row2[next_row+3+2] = | 503 row2[next_row + 3 + 2] = (value >> 16) & 0xFF; |
519 (value >> 16) & 0xFF; | 504 row2 += 2 * 3; |
520 row2 += 2*3; | |
521 } | 505 } |
522 | 506 |
523 /* | 507 /* |
524 * These values are at the start of the next line, (due | 508 * These values are at the start of the next line, (due |
525 * to the ++'s above),but they need to be at the start | 509 * to the ++'s above),but they need to be at the start |
526 * of the line after that. | 510 * of the line after that. |
527 */ | 511 */ |
528 lum += cols; | 512 lum += cols; |
529 lum2 += cols; | 513 lum2 += cols; |
530 row1 += mod; | 514 row1 += mod; |
531 row2 += mod; | 515 row2 += mod; |
532 } | 516 } |
533 } | 517 } |
534 | 518 |
535 static void Color32DitherYV12Mod2X( int *colortab, Uint32 *rgb_2_pix, | 519 static void |
536 unsigned char *lum, unsigned char *cr, | 520 Color32DitherYV12Mod2X(int *colortab, Uint32 * rgb_2_pix, |
537 unsigned char *cb, unsigned char *out, | 521 unsigned char *lum, unsigned char *cr, |
538 int rows, int cols, int mod ) | 522 unsigned char *cb, unsigned char *out, |
539 { | 523 int rows, int cols, int mod) |
540 unsigned int* row1 = (unsigned int*) out; | 524 { |
541 const int next_row = cols*2+mod; | 525 unsigned int *row1 = (unsigned int *) out; |
542 unsigned int* row2 = row1 + 2*next_row; | 526 const int next_row = cols * 2 + mod; |
543 unsigned char* lum2; | 527 unsigned int *row2 = row1 + 2 * next_row; |
528 unsigned char *lum2; | |
544 int x, y; | 529 int x, y; |
545 int cr_r; | 530 int cr_r; |
546 int crb_g; | 531 int crb_g; |
547 int cb_b; | 532 int cb_b; |
548 int cols_2 = cols / 2; | 533 int cols_2 = cols / 2; |
550 lum2 = lum + cols; | 535 lum2 = lum + cols; |
551 | 536 |
552 mod = (next_row * 3) + mod; | 537 mod = (next_row * 3) + mod; |
553 | 538 |
554 y = rows / 2; | 539 y = rows / 2; |
555 while( y-- ) | 540 while (y--) { |
556 { | |
557 x = cols_2; | 541 x = cols_2; |
558 while( x-- ) | 542 while (x--) { |
559 { | |
560 register int L; | 543 register int L; |
561 | 544 |
562 cr_r = 0*768+256 + colortab[ *cr + 0*256 ]; | 545 cr_r = 0 * 768 + 256 + colortab[*cr + 0 * 256]; |
563 crb_g = 1*768+256 + colortab[ *cr + 1*256 ] | 546 crb_g = 1 * 768 + 256 + colortab[*cr + 1 * 256] |
564 + colortab[ *cb + 2*256 ]; | 547 + colortab[*cb + 2 * 256]; |
565 cb_b = 2*768+256 + colortab[ *cb + 3*256 ]; | 548 cb_b = 2 * 768 + 256 + colortab[*cb + 3 * 256]; |
566 ++cr; ++cb; | 549 ++cr; |
550 ++cb; | |
567 | 551 |
568 L = *lum++; | 552 L = *lum++; |
569 row1[0] = row1[1] = row1[next_row] = row1[next_row+1] = | 553 row1[0] = row1[1] = row1[next_row] = row1[next_row + 1] = |
570 (rgb_2_pix[ L + cr_r ] | | 554 (rgb_2_pix[L + cr_r] | |
571 rgb_2_pix[ L + crb_g ] | | 555 rgb_2_pix[L + crb_g] | rgb_2_pix[L + cb_b]); |
572 rgb_2_pix[ L + cb_b ]); | |
573 row1 += 2; | 556 row1 += 2; |
574 | 557 |
575 L = *lum++; | 558 L = *lum++; |
576 row1[0] = row1[1] = row1[next_row] = row1[next_row+1] = | 559 row1[0] = row1[1] = row1[next_row] = row1[next_row + 1] = |
577 (rgb_2_pix[ L + cr_r ] | | 560 (rgb_2_pix[L + cr_r] | |
578 rgb_2_pix[ L + crb_g ] | | 561 rgb_2_pix[L + crb_g] | rgb_2_pix[L + cb_b]); |
579 rgb_2_pix[ L + cb_b ]); | |
580 row1 += 2; | 562 row1 += 2; |
581 | 563 |
582 | 564 |
583 /* Now, do second row. */ | 565 /* Now, do second row. */ |
584 | 566 |
585 L = *lum2++; | 567 L = *lum2++; |
586 row2[0] = row2[1] = row2[next_row] = row2[next_row+1] = | 568 row2[0] = row2[1] = row2[next_row] = row2[next_row + 1] = |
587 (rgb_2_pix[ L + cr_r ] | | 569 (rgb_2_pix[L + cr_r] | |
588 rgb_2_pix[ L + crb_g ] | | 570 rgb_2_pix[L + crb_g] | rgb_2_pix[L + cb_b]); |
589 rgb_2_pix[ L + cb_b ]); | |
590 row2 += 2; | 571 row2 += 2; |
591 | 572 |
592 L = *lum2++; | 573 L = *lum2++; |
593 row2[0] = row2[1] = row2[next_row] = row2[next_row+1] = | 574 row2[0] = row2[1] = row2[next_row] = row2[next_row + 1] = |
594 (rgb_2_pix[ L + cr_r ] | | 575 (rgb_2_pix[L + cr_r] | |
595 rgb_2_pix[ L + crb_g ] | | 576 rgb_2_pix[L + crb_g] | rgb_2_pix[L + cb_b]); |
596 rgb_2_pix[ L + cb_b ]); | |
597 row2 += 2; | 577 row2 += 2; |
598 } | 578 } |
599 | 579 |
600 /* | 580 /* |
601 * These values are at the start of the next line, (due | 581 * These values are at the start of the next line, (due |
602 * to the ++'s above),but they need to be at the start | 582 * to the ++'s above),but they need to be at the start |
603 * of the line after that. | 583 * of the line after that. |
604 */ | 584 */ |
605 lum += cols; | 585 lum += cols; |
606 lum2 += cols; | 586 lum2 += cols; |
607 row1 += mod; | 587 row1 += mod; |
608 row2 += mod; | 588 row2 += mod; |
609 } | 589 } |
610 } | 590 } |
611 | 591 |
612 static void Color16DitherYUY2Mod1X( int *colortab, Uint32 *rgb_2_pix, | 592 static void |
613 unsigned char *lum, unsigned char *cr, | 593 Color16DitherYUY2Mod1X(int *colortab, Uint32 * rgb_2_pix, |
614 unsigned char *cb, unsigned char *out, | 594 unsigned char *lum, unsigned char *cr, |
615 int rows, int cols, int mod ) | 595 unsigned char *cb, unsigned char *out, |
616 { | 596 int rows, int cols, int mod) |
617 unsigned short* row; | 597 { |
598 unsigned short *row; | |
618 int x, y; | 599 int x, y; |
619 int cr_r; | 600 int cr_r; |
620 int crb_g; | 601 int crb_g; |
621 int cb_b; | 602 int cb_b; |
622 int cols_2 = cols / 2; | 603 int cols_2 = cols / 2; |
623 | 604 |
624 row = (unsigned short*) out; | 605 row = (unsigned short *) out; |
625 | 606 |
626 y = rows; | 607 y = rows; |
627 while( y-- ) | 608 while (y--) { |
628 { | |
629 x = cols_2; | 609 x = cols_2; |
630 while( x-- ) | 610 while (x--) { |
631 { | |
632 register int L; | 611 register int L; |
633 | 612 |
634 cr_r = 0*768+256 + colortab[ *cr + 0*256 ]; | 613 cr_r = 0 * 768 + 256 + colortab[*cr + 0 * 256]; |
635 crb_g = 1*768+256 + colortab[ *cr + 1*256 ] | 614 crb_g = 1 * 768 + 256 + colortab[*cr + 1 * 256] |
636 + colortab[ *cb + 2*256 ]; | 615 + colortab[*cb + 2 * 256]; |
637 cb_b = 2*768+256 + colortab[ *cb + 3*256 ]; | 616 cb_b = 2 * 768 + 256 + colortab[*cb + 3 * 256]; |
638 cr += 4; cb += 4; | 617 cr += 4; |
639 | 618 cb += 4; |
640 L = *lum; lum += 2; | 619 |
641 *row++ = (unsigned short)(rgb_2_pix[ L + cr_r ] | | 620 L = *lum; |
642 rgb_2_pix[ L + crb_g ] | | 621 lum += 2; |
643 rgb_2_pix[ L + cb_b ]); | 622 *row++ = (unsigned short) (rgb_2_pix[L + cr_r] | |
644 | 623 rgb_2_pix[L + crb_g] | |
645 L = *lum; lum += 2; | 624 rgb_2_pix[L + cb_b]); |
646 *row++ = (unsigned short)(rgb_2_pix[ L + cr_r ] | | 625 |
647 rgb_2_pix[ L + crb_g ] | | 626 L = *lum; |
648 rgb_2_pix[ L + cb_b ]); | 627 lum += 2; |
628 *row++ = (unsigned short) (rgb_2_pix[L + cr_r] | | |
629 rgb_2_pix[L + crb_g] | | |
630 rgb_2_pix[L + cb_b]); | |
649 | 631 |
650 } | 632 } |
651 | 633 |
652 row += mod; | 634 row += mod; |
653 } | 635 } |
654 } | 636 } |
655 | 637 |
656 static void Color24DitherYUY2Mod1X( int *colortab, Uint32 *rgb_2_pix, | 638 static void |
657 unsigned char *lum, unsigned char *cr, | 639 Color24DitherYUY2Mod1X(int *colortab, Uint32 * rgb_2_pix, |
658 unsigned char *cb, unsigned char *out, | 640 unsigned char *lum, unsigned char *cr, |
659 int rows, int cols, int mod ) | 641 unsigned char *cb, unsigned char *out, |
642 int rows, int cols, int mod) | |
660 { | 643 { |
661 unsigned int value; | 644 unsigned int value; |
662 unsigned char* row; | 645 unsigned char *row; |
663 int x, y; | 646 int x, y; |
664 int cr_r; | 647 int cr_r; |
665 int crb_g; | 648 int crb_g; |
666 int cb_b; | 649 int cb_b; |
667 int cols_2 = cols / 2; | 650 int cols_2 = cols / 2; |
668 | 651 |
669 row = (unsigned char*) out; | 652 row = (unsigned char *) out; |
670 mod *= 3; | 653 mod *= 3; |
671 y = rows; | 654 y = rows; |
672 while( y-- ) | 655 while (y--) { |
673 { | |
674 x = cols_2; | 656 x = cols_2; |
675 while( x-- ) | 657 while (x--) { |
676 { | |
677 register int L; | 658 register int L; |
678 | 659 |
679 cr_r = 0*768+256 + colortab[ *cr + 0*256 ]; | 660 cr_r = 0 * 768 + 256 + colortab[*cr + 0 * 256]; |
680 crb_g = 1*768+256 + colortab[ *cr + 1*256 ] | 661 crb_g = 1 * 768 + 256 + colortab[*cr + 1 * 256] |
681 + colortab[ *cb + 2*256 ]; | 662 + colortab[*cb + 2 * 256]; |
682 cb_b = 2*768+256 + colortab[ *cb + 3*256 ]; | 663 cb_b = 2 * 768 + 256 + colortab[*cb + 3 * 256]; |
683 cr += 4; cb += 4; | 664 cr += 4; |
684 | 665 cb += 4; |
685 L = *lum; lum += 2; | 666 |
686 value = (rgb_2_pix[ L + cr_r ] | | 667 L = *lum; |
687 rgb_2_pix[ L + crb_g ] | | 668 lum += 2; |
688 rgb_2_pix[ L + cb_b ]); | 669 value = (rgb_2_pix[L + cr_r] | |
689 *row++ = (value ) & 0xFF; | 670 rgb_2_pix[L + crb_g] | rgb_2_pix[L + cb_b]); |
690 *row++ = (value >> 8) & 0xFF; | 671 *row++ = (value) & 0xFF; |
672 *row++ = (value >> 8) & 0xFF; | |
691 *row++ = (value >> 16) & 0xFF; | 673 *row++ = (value >> 16) & 0xFF; |
692 | 674 |
693 L = *lum; lum += 2; | 675 L = *lum; |
694 value = (rgb_2_pix[ L + cr_r ] | | 676 lum += 2; |
695 rgb_2_pix[ L + crb_g ] | | 677 value = (rgb_2_pix[L + cr_r] | |
696 rgb_2_pix[ L + cb_b ]); | 678 rgb_2_pix[L + crb_g] | rgb_2_pix[L + cb_b]); |
697 *row++ = (value ) & 0xFF; | 679 *row++ = (value) & 0xFF; |
698 *row++ = (value >> 8) & 0xFF; | 680 *row++ = (value >> 8) & 0xFF; |
699 *row++ = (value >> 16) & 0xFF; | 681 *row++ = (value >> 16) & 0xFF; |
700 | 682 |
701 } | 683 } |
702 row += mod; | 684 row += mod; |
703 } | 685 } |
704 } | 686 } |
705 | 687 |
706 static void Color32DitherYUY2Mod1X( int *colortab, Uint32 *rgb_2_pix, | 688 static void |
707 unsigned char *lum, unsigned char *cr, | 689 Color32DitherYUY2Mod1X(int *colortab, Uint32 * rgb_2_pix, |
708 unsigned char *cb, unsigned char *out, | 690 unsigned char *lum, unsigned char *cr, |
709 int rows, int cols, int mod ) | 691 unsigned char *cb, unsigned char *out, |
710 { | 692 int rows, int cols, int mod) |
711 unsigned int* row; | 693 { |
694 unsigned int *row; | |
712 int x, y; | 695 int x, y; |
713 int cr_r; | 696 int cr_r; |
714 int crb_g; | 697 int crb_g; |
715 int cb_b; | 698 int cb_b; |
716 int cols_2 = cols / 2; | 699 int cols_2 = cols / 2; |
717 | 700 |
718 row = (unsigned int*) out; | 701 row = (unsigned int *) out; |
719 y = rows; | 702 y = rows; |
720 while( y-- ) | 703 while (y--) { |
721 { | |
722 x = cols_2; | 704 x = cols_2; |
723 while( x-- ) | 705 while (x--) { |
724 { | |
725 register int L; | 706 register int L; |
726 | 707 |
727 cr_r = 0*768+256 + colortab[ *cr + 0*256 ]; | 708 cr_r = 0 * 768 + 256 + colortab[*cr + 0 * 256]; |
728 crb_g = 1*768+256 + colortab[ *cr + 1*256 ] | 709 crb_g = 1 * 768 + 256 + colortab[*cr + 1 * 256] |
729 + colortab[ *cb + 2*256 ]; | 710 + colortab[*cb + 2 * 256]; |
730 cb_b = 2*768+256 + colortab[ *cb + 3*256 ]; | 711 cb_b = 2 * 768 + 256 + colortab[*cb + 3 * 256]; |
731 cr += 4; cb += 4; | 712 cr += 4; |
732 | 713 cb += 4; |
733 L = *lum; lum += 2; | 714 |
734 *row++ = (rgb_2_pix[ L + cr_r ] | | 715 L = *lum; |
735 rgb_2_pix[ L + crb_g ] | | 716 lum += 2; |
736 rgb_2_pix[ L + cb_b ]); | 717 *row++ = (rgb_2_pix[L + cr_r] | |
737 | 718 rgb_2_pix[L + crb_g] | rgb_2_pix[L + cb_b]); |
738 L = *lum; lum += 2; | 719 |
739 *row++ = (rgb_2_pix[ L + cr_r ] | | 720 L = *lum; |
740 rgb_2_pix[ L + crb_g ] | | 721 lum += 2; |
741 rgb_2_pix[ L + cb_b ]); | 722 *row++ = (rgb_2_pix[L + cr_r] | |
723 rgb_2_pix[L + crb_g] | rgb_2_pix[L + cb_b]); | |
742 | 724 |
743 | 725 |
744 } | 726 } |
745 row += mod; | 727 row += mod; |
746 } | 728 } |
749 /* | 731 /* |
750 * In this function I make use of a nasty trick. The tables have the lower | 732 * In this function I make use of a nasty trick. The tables have the lower |
751 * 16 bits replicated in the upper 16. This means I can write ints and get | 733 * 16 bits replicated in the upper 16. This means I can write ints and get |
752 * the horisontal doubling for free (almost). | 734 * the horisontal doubling for free (almost). |
753 */ | 735 */ |
754 static void Color16DitherYUY2Mod2X( int *colortab, Uint32 *rgb_2_pix, | 736 static void |
755 unsigned char *lum, unsigned char *cr, | 737 Color16DitherYUY2Mod2X(int *colortab, Uint32 * rgb_2_pix, |
756 unsigned char *cb, unsigned char *out, | 738 unsigned char *lum, unsigned char *cr, |
757 int rows, int cols, int mod ) | 739 unsigned char *cb, unsigned char *out, |
758 { | 740 int rows, int cols, int mod) |
759 unsigned int* row = (unsigned int*) out; | 741 { |
760 const int next_row = cols+(mod/2); | 742 unsigned int *row = (unsigned int *) out; |
743 const int next_row = cols + (mod / 2); | |
761 int x, y; | 744 int x, y; |
762 int cr_r; | 745 int cr_r; |
763 int crb_g; | 746 int crb_g; |
764 int cb_b; | 747 int cb_b; |
765 int cols_2 = cols / 2; | 748 int cols_2 = cols / 2; |
766 | 749 |
767 y = rows; | 750 y = rows; |
768 while( y-- ) | 751 while (y--) { |
769 { | |
770 x = cols_2; | 752 x = cols_2; |
771 while( x-- ) | 753 while (x--) { |
772 { | |
773 register int L; | 754 register int L; |
774 | 755 |
775 cr_r = 0*768+256 + colortab[ *cr + 0*256 ]; | 756 cr_r = 0 * 768 + 256 + colortab[*cr + 0 * 256]; |
776 crb_g = 1*768+256 + colortab[ *cr + 1*256 ] | 757 crb_g = 1 * 768 + 256 + colortab[*cr + 1 * 256] |
777 + colortab[ *cb + 2*256 ]; | 758 + colortab[*cb + 2 * 256]; |
778 cb_b = 2*768+256 + colortab[ *cb + 3*256 ]; | 759 cb_b = 2 * 768 + 256 + colortab[*cb + 3 * 256]; |
779 cr += 4; cb += 4; | 760 cr += 4; |
780 | 761 cb += 4; |
781 L = *lum; lum += 2; | 762 |
782 row[0] = row[next_row] = (rgb_2_pix[ L + cr_r ] | | 763 L = *lum; |
783 rgb_2_pix[ L + crb_g ] | | 764 lum += 2; |
784 rgb_2_pix[ L + cb_b ]); | 765 row[0] = row[next_row] = (rgb_2_pix[L + cr_r] | |
766 rgb_2_pix[L + crb_g] | | |
767 rgb_2_pix[L + cb_b]); | |
785 row++; | 768 row++; |
786 | 769 |
787 L = *lum; lum += 2; | 770 L = *lum; |
788 row[0] = row[next_row] = (rgb_2_pix[ L + cr_r ] | | 771 lum += 2; |
789 rgb_2_pix[ L + crb_g ] | | 772 row[0] = row[next_row] = (rgb_2_pix[L + cr_r] | |
790 rgb_2_pix[ L + cb_b ]); | 773 rgb_2_pix[L + crb_g] | |
774 rgb_2_pix[L + cb_b]); | |
791 row++; | 775 row++; |
792 | 776 |
793 } | 777 } |
794 row += next_row; | 778 row += next_row; |
795 } | 779 } |
796 } | 780 } |
797 | 781 |
798 static void Color24DitherYUY2Mod2X( int *colortab, Uint32 *rgb_2_pix, | 782 static void |
799 unsigned char *lum, unsigned char *cr, | 783 Color24DitherYUY2Mod2X(int *colortab, Uint32 * rgb_2_pix, |
800 unsigned char *cb, unsigned char *out, | 784 unsigned char *lum, unsigned char *cr, |
801 int rows, int cols, int mod ) | 785 unsigned char *cb, unsigned char *out, |
786 int rows, int cols, int mod) | |
802 { | 787 { |
803 unsigned int value; | 788 unsigned int value; |
804 unsigned char* row = out; | 789 unsigned char *row = out; |
805 const int next_row = (cols*2 + mod) * 3; | 790 const int next_row = (cols * 2 + mod) * 3; |
806 int x, y; | 791 int x, y; |
807 int cr_r; | 792 int cr_r; |
808 int crb_g; | 793 int crb_g; |
809 int cb_b; | 794 int cb_b; |
810 int cols_2 = cols / 2; | 795 int cols_2 = cols / 2; |
811 y = rows; | 796 y = rows; |
812 while( y-- ) | 797 while (y--) { |
813 { | |
814 x = cols_2; | 798 x = cols_2; |
815 while( x-- ) | 799 while (x--) { |
816 { | |
817 register int L; | 800 register int L; |
818 | 801 |
819 cr_r = 0*768+256 + colortab[ *cr + 0*256 ]; | 802 cr_r = 0 * 768 + 256 + colortab[*cr + 0 * 256]; |
820 crb_g = 1*768+256 + colortab[ *cr + 1*256 ] | 803 crb_g = 1 * 768 + 256 + colortab[*cr + 1 * 256] |
821 + colortab[ *cb + 2*256 ]; | 804 + colortab[*cb + 2 * 256]; |
822 cb_b = 2*768+256 + colortab[ *cb + 3*256 ]; | 805 cb_b = 2 * 768 + 256 + colortab[*cb + 3 * 256]; |
823 cr += 4; cb += 4; | 806 cr += 4; |
824 | 807 cb += 4; |
825 L = *lum; lum += 2; | 808 |
826 value = (rgb_2_pix[ L + cr_r ] | | 809 L = *lum; |
827 rgb_2_pix[ L + crb_g ] | | 810 lum += 2; |
828 rgb_2_pix[ L + cb_b ]); | 811 value = (rgb_2_pix[L + cr_r] | |
829 row[0+0] = row[3+0] = row[next_row+0] = row[next_row+3+0] = | 812 rgb_2_pix[L + crb_g] | rgb_2_pix[L + cb_b]); |
830 (value ) & 0xFF; | 813 row[0 + 0] = row[3 + 0] = row[next_row + 0] = |
831 row[0+1] = row[3+1] = row[next_row+1] = row[next_row+3+1] = | 814 row[next_row + 3 + 0] = (value) & 0xFF; |
832 (value >> 8) & 0xFF; | 815 row[0 + 1] = row[3 + 1] = row[next_row + 1] = |
833 row[0+2] = row[3+2] = row[next_row+2] = row[next_row+3+2] = | 816 row[next_row + 3 + 1] = (value >> 8) & 0xFF; |
834 (value >> 16) & 0xFF; | 817 row[0 + 2] = row[3 + 2] = row[next_row + 2] = |
835 row += 2*3; | 818 row[next_row + 3 + 2] = (value >> 16) & 0xFF; |
836 | 819 row += 2 * 3; |
837 L = *lum; lum += 2; | 820 |
838 value = (rgb_2_pix[ L + cr_r ] | | 821 L = *lum; |
839 rgb_2_pix[ L + crb_g ] | | 822 lum += 2; |
840 rgb_2_pix[ L + cb_b ]); | 823 value = (rgb_2_pix[L + cr_r] | |
841 row[0+0] = row[3+0] = row[next_row+0] = row[next_row+3+0] = | 824 rgb_2_pix[L + crb_g] | rgb_2_pix[L + cb_b]); |
842 (value ) & 0xFF; | 825 row[0 + 0] = row[3 + 0] = row[next_row + 0] = |
843 row[0+1] = row[3+1] = row[next_row+1] = row[next_row+3+1] = | 826 row[next_row + 3 + 0] = (value) & 0xFF; |
844 (value >> 8) & 0xFF; | 827 row[0 + 1] = row[3 + 1] = row[next_row + 1] = |
845 row[0+2] = row[3+2] = row[next_row+2] = row[next_row+3+2] = | 828 row[next_row + 3 + 1] = (value >> 8) & 0xFF; |
846 (value >> 16) & 0xFF; | 829 row[0 + 2] = row[3 + 2] = row[next_row + 2] = |
847 row += 2*3; | 830 row[next_row + 3 + 2] = (value >> 16) & 0xFF; |
831 row += 2 * 3; | |
848 | 832 |
849 } | 833 } |
850 row += next_row; | 834 row += next_row; |
851 } | 835 } |
852 } | 836 } |
853 | 837 |
854 static void Color32DitherYUY2Mod2X( int *colortab, Uint32 *rgb_2_pix, | 838 static void |
855 unsigned char *lum, unsigned char *cr, | 839 Color32DitherYUY2Mod2X(int *colortab, Uint32 * rgb_2_pix, |
856 unsigned char *cb, unsigned char *out, | 840 unsigned char *lum, unsigned char *cr, |
857 int rows, int cols, int mod ) | 841 unsigned char *cb, unsigned char *out, |
858 { | 842 int rows, int cols, int mod) |
859 unsigned int* row = (unsigned int*) out; | 843 { |
860 const int next_row = cols*2+mod; | 844 unsigned int *row = (unsigned int *) out; |
845 const int next_row = cols * 2 + mod; | |
861 int x, y; | 846 int x, y; |
862 int cr_r; | 847 int cr_r; |
863 int crb_g; | 848 int crb_g; |
864 int cb_b; | 849 int cb_b; |
865 int cols_2 = cols / 2; | 850 int cols_2 = cols / 2; |
866 mod+=mod; | 851 mod += mod; |
867 y = rows; | 852 y = rows; |
868 while( y-- ) | 853 while (y--) { |
869 { | |
870 x = cols_2; | 854 x = cols_2; |
871 while( x-- ) | 855 while (x--) { |
872 { | |
873 register int L; | 856 register int L; |
874 | 857 |
875 cr_r = 0*768+256 + colortab[ *cr + 0*256 ]; | 858 cr_r = 0 * 768 + 256 + colortab[*cr + 0 * 256]; |
876 crb_g = 1*768+256 + colortab[ *cr + 1*256 ] | 859 crb_g = 1 * 768 + 256 + colortab[*cr + 1 * 256] |
877 + colortab[ *cb + 2*256 ]; | 860 + colortab[*cb + 2 * 256]; |
878 cb_b = 2*768+256 + colortab[ *cb + 3*256 ]; | 861 cb_b = 2 * 768 + 256 + colortab[*cb + 3 * 256]; |
879 cr += 4; cb += 4; | 862 cr += 4; |
880 | 863 cb += 4; |
881 L = *lum; lum += 2; | 864 |
882 row[0] = row[1] = row[next_row] = row[next_row+1] = | 865 L = *lum; |
883 (rgb_2_pix[ L + cr_r ] | | 866 lum += 2; |
884 rgb_2_pix[ L + crb_g ] | | 867 row[0] = row[1] = row[next_row] = row[next_row + 1] = |
885 rgb_2_pix[ L + cb_b ]); | 868 (rgb_2_pix[L + cr_r] | |
869 rgb_2_pix[L + crb_g] | rgb_2_pix[L + cb_b]); | |
886 row += 2; | 870 row += 2; |
887 | 871 |
888 L = *lum; lum += 2; | 872 L = *lum; |
889 row[0] = row[1] = row[next_row] = row[next_row+1] = | 873 lum += 2; |
890 (rgb_2_pix[ L + cr_r ] | | 874 row[0] = row[1] = row[next_row] = row[next_row + 1] = |
891 rgb_2_pix[ L + crb_g ] | | 875 (rgb_2_pix[L + cr_r] | |
892 rgb_2_pix[ L + cb_b ]); | 876 rgb_2_pix[L + crb_g] | rgb_2_pix[L + cb_b]); |
893 row += 2; | 877 row += 2; |
894 | 878 |
895 | 879 |
896 } | 880 } |
897 | 881 |
901 | 885 |
902 /* | 886 /* |
903 * How many 1 bits are there in the Uint32. | 887 * How many 1 bits are there in the Uint32. |
904 * Low performance, do not call often. | 888 * Low performance, do not call often. |
905 */ | 889 */ |
906 static int number_of_bits_set( Uint32 a ) | 890 static int |
907 { | 891 number_of_bits_set(Uint32 a) |
908 if(!a) return 0; | 892 { |
909 if(a & 1) return 1 + number_of_bits_set(a >> 1); | 893 if (!a) |
910 return(number_of_bits_set(a >> 1)); | 894 return 0; |
895 if (a & 1) | |
896 return 1 + number_of_bits_set(a >> 1); | |
897 return (number_of_bits_set(a >> 1)); | |
911 } | 898 } |
912 | 899 |
913 /* | 900 /* |
914 * How many 0 bits are there at least significant end of Uint32. | 901 * How many 0 bits are there at least significant end of Uint32. |
915 * Low performance, do not call often. | 902 * Low performance, do not call often. |
916 */ | 903 */ |
917 static int free_bits_at_bottom( Uint32 a ) | 904 static int |
918 { | 905 free_bits_at_bottom(Uint32 a) |
919 /* assume char is 8 bits */ | 906 { |
920 if(!a) return sizeof(Uint32) * 8; | 907 /* assume char is 8 bits */ |
921 if(((Sint32)a) & 1l) return 0; | 908 if (!a) |
922 return 1 + free_bits_at_bottom ( a >> 1); | 909 return sizeof(Uint32) * 8; |
923 } | 910 if (((Sint32) a) & 1l) |
924 | 911 return 0; |
925 | 912 return 1 + free_bits_at_bottom(a >> 1); |
926 SDL_Overlay *SDL_CreateYUV_SW(_THIS, int width, int height, Uint32 format, SDL_Surface *display) | 913 } |
927 { | 914 |
928 SDL_Overlay *overlay; | 915 static int |
929 struct private_yuvhwdata *swdata; | 916 SDL_SW_SetupYUVDisplay(SDL_SW_YUVTexture * swdata, Uint32 target_format) |
930 int *Cr_r_tab; | 917 { |
931 int *Cr_g_tab; | 918 Uint32 *r_2_pix_alloc; |
932 int *Cb_g_tab; | 919 Uint32 *g_2_pix_alloc; |
933 int *Cb_b_tab; | 920 Uint32 *b_2_pix_alloc; |
934 Uint32 *r_2_pix_alloc; | 921 int i; |
935 Uint32 *g_2_pix_alloc; | 922 int bpp; |
936 Uint32 *b_2_pix_alloc; | 923 Uint32 Rmask, Gmask, Bmask, Amask; |
937 int i; | 924 |
938 int CR, CB; | 925 if (!SDL_PixelFormatEnumToMasks |
939 Uint32 Rmask, Gmask, Bmask; | 926 (target_format, &bpp, &Rmask, &Gmask, &Bmask, &Amask) || bpp < 15) { |
940 | 927 SDL_SetError("Unsupported YUV destination format"); |
941 /* Only RGB packed pixel conversion supported */ | 928 return -1; |
942 if ( (display->format->BytesPerPixel != 2) && | 929 } |
943 (display->format->BytesPerPixel != 3) && | 930 |
944 (display->format->BytesPerPixel != 4) ) { | 931 swdata->target_format = target_format; |
945 SDL_SetError("Can't use YUV data on non 16/24/32 bit surfaces"); | 932 r_2_pix_alloc = &swdata->rgb_2_pix[0 * 768]; |
946 return(NULL); | 933 g_2_pix_alloc = &swdata->rgb_2_pix[1 * 768]; |
947 } | 934 b_2_pix_alloc = &swdata->rgb_2_pix[2 * 768]; |
948 | 935 |
949 /* Verify that we support the format */ | 936 /* |
950 switch (format) { | 937 * Set up entries 0-255 in rgb-to-pixel value tables. |
951 case SDL_YV12_OVERLAY: | 938 */ |
952 case SDL_IYUV_OVERLAY: | 939 for (i = 0; i < 256; ++i) { |
953 case SDL_YUY2_OVERLAY: | 940 r_2_pix_alloc[i + 256] = i >> (8 - number_of_bits_set(Rmask)); |
954 case SDL_UYVY_OVERLAY: | 941 r_2_pix_alloc[i + 256] <<= free_bits_at_bottom(Rmask); |
955 case SDL_YVYU_OVERLAY: | 942 g_2_pix_alloc[i + 256] = i >> (8 - number_of_bits_set(Gmask)); |
956 break; | 943 g_2_pix_alloc[i + 256] <<= free_bits_at_bottom(Gmask); |
957 default: | 944 b_2_pix_alloc[i + 256] = i >> (8 - number_of_bits_set(Bmask)); |
958 SDL_SetError("Unsupported YUV format"); | 945 b_2_pix_alloc[i + 256] <<= free_bits_at_bottom(Bmask); |
959 return(NULL); | 946 } |
960 } | 947 |
961 | 948 /* |
962 /* Create the overlay structure */ | 949 * If we have 16-bit output depth, then we double the value |
963 overlay = (SDL_Overlay *)SDL_malloc(sizeof *overlay); | 950 * in the top word. This means that we can write out both |
964 if ( overlay == NULL ) { | 951 * pixels in the pixel doubling mode with one op. It is |
965 SDL_OutOfMemory(); | 952 * harmless in the normal case as storing a 32-bit value |
966 return(NULL); | 953 * through a short pointer will lose the top bits anyway. |
967 } | 954 */ |
968 SDL_memset(overlay, 0, (sizeof *overlay)); | 955 if (SDL_BYTESPERPIXEL(target_format) == 2) { |
969 | 956 for (i = 0; i < 256; ++i) { |
970 /* Fill in the basic members */ | 957 r_2_pix_alloc[i + 256] |= (r_2_pix_alloc[i + 256]) << 16; |
971 overlay->format = format; | 958 g_2_pix_alloc[i + 256] |= (g_2_pix_alloc[i + 256]) << 16; |
972 overlay->w = width; | 959 b_2_pix_alloc[i + 256] |= (b_2_pix_alloc[i + 256]) << 16; |
973 overlay->h = height; | 960 } |
974 | 961 } |
975 /* Set up the YUV surface function structure */ | 962 |
976 overlay->hwfuncs = &sw_yuvfuncs; | 963 /* |
977 | 964 * Spread out the values we have to the rest of the array so that |
978 /* Create the pixel data and lookup tables */ | 965 * we do not need to check for overflow. |
979 swdata = (struct private_yuvhwdata *)SDL_malloc(sizeof *swdata); | 966 */ |
980 overlay->hwdata = swdata; | 967 for (i = 0; i < 256; ++i) { |
981 if ( swdata == NULL ) { | 968 r_2_pix_alloc[i] = r_2_pix_alloc[256]; |
982 SDL_OutOfMemory(); | 969 r_2_pix_alloc[i + 512] = r_2_pix_alloc[511]; |
983 SDL_FreeYUVOverlay(overlay); | 970 g_2_pix_alloc[i] = g_2_pix_alloc[256]; |
984 return(NULL); | 971 g_2_pix_alloc[i + 512] = g_2_pix_alloc[511]; |
985 } | 972 b_2_pix_alloc[i] = b_2_pix_alloc[256]; |
986 swdata->stretch = NULL; | 973 b_2_pix_alloc[i + 512] = b_2_pix_alloc[511]; |
987 swdata->display = display; | 974 } |
988 swdata->pixels = (Uint8 *) SDL_malloc(width*height*2); | 975 |
989 swdata->colortab = (int *)SDL_malloc(4*256*sizeof(int)); | 976 /* You have chosen wisely... */ |
990 Cr_r_tab = &swdata->colortab[0*256]; | 977 switch (swdata->texture->format) { |
991 Cr_g_tab = &swdata->colortab[1*256]; | 978 case SDL_PixelFormat_YV12: |
992 Cb_g_tab = &swdata->colortab[2*256]; | 979 case SDL_PixelFormat_IYUV: |
993 Cb_b_tab = &swdata->colortab[3*256]; | 980 if (SDL_BYTESPERPIXEL(target_format) == 2) { |
994 swdata->rgb_2_pix = (Uint32 *)SDL_malloc(3*768*sizeof(Uint32)); | 981 #if 0 /*defined(__GNUC__) && defined(__i386__) && SDL_ASSEMBLY_ROUTINES */ |
995 r_2_pix_alloc = &swdata->rgb_2_pix[0*768]; | 982 /* inline assembly functions */ |
996 g_2_pix_alloc = &swdata->rgb_2_pix[1*768]; | 983 if (SDL_HasMMX() && (Rmask == 0xF800) && |
997 b_2_pix_alloc = &swdata->rgb_2_pix[2*768]; | 984 (Gmask == 0x07E0) && (Bmask == 0x001F) && (width & 15) == 0) { |
998 if ( ! swdata->pixels || ! swdata->colortab || ! swdata->rgb_2_pix ) { | |
999 SDL_OutOfMemory(); | |
1000 SDL_FreeYUVOverlay(overlay); | |
1001 return(NULL); | |
1002 } | |
1003 | |
1004 /* Generate the tables for the display surface */ | |
1005 for (i=0; i<256; i++) { | |
1006 /* Gamma correction (luminescence table) and chroma correction | |
1007 would be done here. See the Berkeley mpeg_play sources. | |
1008 */ | |
1009 CB = CR = (i-128); | |
1010 Cr_r_tab[i] = (int) ( (0.419/0.299) * CR); | |
1011 Cr_g_tab[i] = (int) (-(0.299/0.419) * CR); | |
1012 Cb_g_tab[i] = (int) (-(0.114/0.331) * CB); | |
1013 Cb_b_tab[i] = (int) ( (0.587/0.331) * CB); | |
1014 } | |
1015 | |
1016 /* | |
1017 * Set up entries 0-255 in rgb-to-pixel value tables. | |
1018 */ | |
1019 Rmask = display->format->Rmask; | |
1020 Gmask = display->format->Gmask; | |
1021 Bmask = display->format->Bmask; | |
1022 for ( i=0; i<256; ++i ) { | |
1023 r_2_pix_alloc[i+256] = i >> (8 - number_of_bits_set(Rmask)); | |
1024 r_2_pix_alloc[i+256] <<= free_bits_at_bottom(Rmask); | |
1025 g_2_pix_alloc[i+256] = i >> (8 - number_of_bits_set(Gmask)); | |
1026 g_2_pix_alloc[i+256] <<= free_bits_at_bottom(Gmask); | |
1027 b_2_pix_alloc[i+256] = i >> (8 - number_of_bits_set(Bmask)); | |
1028 b_2_pix_alloc[i+256] <<= free_bits_at_bottom(Bmask); | |
1029 } | |
1030 | |
1031 /* | |
1032 * If we have 16-bit output depth, then we double the value | |
1033 * in the top word. This means that we can write out both | |
1034 * pixels in the pixel doubling mode with one op. It is | |
1035 * harmless in the normal case as storing a 32-bit value | |
1036 * through a short pointer will lose the top bits anyway. | |
1037 */ | |
1038 if( display->format->BytesPerPixel == 2 ) { | |
1039 for ( i=0; i<256; ++i ) { | |
1040 r_2_pix_alloc[i+256] |= (r_2_pix_alloc[i+256]) << 16; | |
1041 g_2_pix_alloc[i+256] |= (g_2_pix_alloc[i+256]) << 16; | |
1042 b_2_pix_alloc[i+256] |= (b_2_pix_alloc[i+256]) << 16; | |
1043 } | |
1044 } | |
1045 | |
1046 /* | |
1047 * Spread out the values we have to the rest of the array so that | |
1048 * we do not need to check for overflow. | |
1049 */ | |
1050 for ( i=0; i<256; ++i ) { | |
1051 r_2_pix_alloc[i] = r_2_pix_alloc[256]; | |
1052 r_2_pix_alloc[i+512] = r_2_pix_alloc[511]; | |
1053 g_2_pix_alloc[i] = g_2_pix_alloc[256]; | |
1054 g_2_pix_alloc[i+512] = g_2_pix_alloc[511]; | |
1055 b_2_pix_alloc[i] = b_2_pix_alloc[256]; | |
1056 b_2_pix_alloc[i+512] = b_2_pix_alloc[511]; | |
1057 } | |
1058 | |
1059 /* You have chosen wisely... */ | |
1060 switch (format) { | |
1061 case SDL_YV12_OVERLAY: | |
1062 case SDL_IYUV_OVERLAY: | |
1063 if ( display->format->BytesPerPixel == 2 ) { | |
1064 #if 0 /*defined(__GNUC__) && defined(__i386__) && SDL_ASSEMBLY_ROUTINES*/ | |
1065 /* inline assembly functions */ | |
1066 if ( SDL_HasMMX() && (Rmask == 0xF800) && | |
1067 (Gmask == 0x07E0) && | |
1068 (Bmask == 0x001F) && | |
1069 (width & 15) == 0) { | |
1070 /*printf("Using MMX 16-bit 565 dither\n");*/ | 985 /*printf("Using MMX 16-bit 565 dither\n");*/ |
1071 swdata->Display1X = Color565DitherYV12MMX1X; | 986 swdata->Display1X = Color565DitherYV12MMX1X; |
1072 } else { | 987 } else { |
1073 /*printf("Using C 16-bit dither\n");*/ | 988 /*printf("Using C 16-bit dither\n");*/ |
1074 swdata->Display1X = Color16DitherYV12Mod1X; | 989 swdata->Display1X = Color16DitherYV12Mod1X; |
1075 } | 990 } |
1076 #else | 991 #else |
1077 swdata->Display1X = Color16DitherYV12Mod1X; | 992 swdata->Display1X = Color16DitherYV12Mod1X; |
1078 #endif | 993 #endif |
1079 swdata->Display2X = Color16DitherYV12Mod2X; | 994 swdata->Display2X = Color16DitherYV12Mod2X; |
1080 } | 995 } |
1081 if ( display->format->BytesPerPixel == 3 ) { | 996 if (SDL_BYTESPERPIXEL(target_format) == 3) { |
1082 swdata->Display1X = Color24DitherYV12Mod1X; | 997 swdata->Display1X = Color24DitherYV12Mod1X; |
1083 swdata->Display2X = Color24DitherYV12Mod2X; | 998 swdata->Display2X = Color24DitherYV12Mod2X; |
1084 } | 999 } |
1085 if ( display->format->BytesPerPixel == 4 ) { | 1000 if (SDL_BYTESPERPIXEL(target_format) == 4) { |
1086 #if 0 /*defined(__GNUC__) && defined(__i386__) && SDL_ASSEMBLY_ROUTINES*/ | 1001 #if 0 /*defined(__GNUC__) && defined(__i386__) && SDL_ASSEMBLY_ROUTINES */ |
1087 /* inline assembly functions */ | 1002 /* inline assembly functions */ |
1088 if ( SDL_HasMMX() && (Rmask == 0x00FF0000) && | 1003 if (SDL_HasMMX() && (Rmask == 0x00FF0000) && |
1089 (Gmask == 0x0000FF00) && | 1004 (Gmask == 0x0000FF00) && |
1090 (Bmask == 0x000000FF) && | 1005 (Bmask == 0x000000FF) && (width & 15) == 0) { |
1091 (width & 15) == 0) { | |
1092 /*printf("Using MMX 32-bit dither\n");*/ | 1006 /*printf("Using MMX 32-bit dither\n");*/ |
1093 swdata->Display1X = ColorRGBDitherYV12MMX1X; | 1007 swdata->Display1X = ColorRGBDitherYV12MMX1X; |
1094 } else { | 1008 } else { |
1095 /*printf("Using C 32-bit dither\n");*/ | 1009 /*printf("Using C 32-bit dither\n");*/ |
1096 swdata->Display1X = Color32DitherYV12Mod1X; | 1010 swdata->Display1X = Color32DitherYV12Mod1X; |
1097 } | 1011 } |
1098 #else | 1012 #else |
1099 swdata->Display1X = Color32DitherYV12Mod1X; | 1013 swdata->Display1X = Color32DitherYV12Mod1X; |
1100 #endif | 1014 #endif |
1101 swdata->Display2X = Color32DitherYV12Mod2X; | 1015 swdata->Display2X = Color32DitherYV12Mod2X; |
1102 } | 1016 } |
1103 break; | 1017 break; |
1104 case SDL_YUY2_OVERLAY: | 1018 case SDL_PixelFormat_YUY2: |
1105 case SDL_UYVY_OVERLAY: | 1019 case SDL_PixelFormat_UYVY: |
1106 case SDL_YVYU_OVERLAY: | 1020 case SDL_PixelFormat_YVYU: |
1107 if ( display->format->BytesPerPixel == 2 ) { | 1021 if (SDL_BYTESPERPIXEL(target_format) == 2) { |
1108 swdata->Display1X = Color16DitherYUY2Mod1X; | 1022 swdata->Display1X = Color16DitherYUY2Mod1X; |
1109 swdata->Display2X = Color16DitherYUY2Mod2X; | 1023 swdata->Display2X = Color16DitherYUY2Mod2X; |
1110 } | 1024 } |
1111 if ( display->format->BytesPerPixel == 3 ) { | 1025 if (SDL_BYTESPERPIXEL(target_format) == 3) { |
1112 swdata->Display1X = Color24DitherYUY2Mod1X; | 1026 swdata->Display1X = Color24DitherYUY2Mod1X; |
1113 swdata->Display2X = Color24DitherYUY2Mod2X; | 1027 swdata->Display2X = Color24DitherYUY2Mod2X; |
1114 } | 1028 } |
1115 if ( display->format->BytesPerPixel == 4 ) { | 1029 if (SDL_BYTESPERPIXEL(target_format) == 4) { |
1116 swdata->Display1X = Color32DitherYUY2Mod1X; | 1030 swdata->Display1X = Color32DitherYUY2Mod1X; |
1117 swdata->Display2X = Color32DitherYUY2Mod2X; | 1031 swdata->Display2X = Color32DitherYUY2Mod2X; |
1118 } | 1032 } |
1119 break; | 1033 break; |
1120 default: | 1034 default: |
1121 /* We should never get here (caught above) */ | 1035 /* We should never get here (caught above) */ |
1122 break; | 1036 break; |
1123 } | 1037 } |
1124 | 1038 |
1125 /* Find the pitch and offset values for the overlay */ | 1039 if (swdata->display) { |
1126 overlay->pitches = swdata->pitches; | 1040 SDL_FreeSurface(swdata->display); |
1127 overlay->pixels = swdata->planes; | 1041 swdata->display = NULL; |
1128 switch (format) { | 1042 } |
1129 case SDL_YV12_OVERLAY: | 1043 return 0; |
1130 case SDL_IYUV_OVERLAY: | 1044 } |
1131 overlay->pitches[0] = overlay->w; | 1045 |
1132 overlay->pitches[1] = overlay->pitches[0] / 2; | 1046 SDL_SW_YUVTexture * |
1133 overlay->pitches[2] = overlay->pitches[0] / 2; | 1047 SDL_SW_CreateYUVTexture(SDL_Texture * texture) |
1134 overlay->pixels[0] = swdata->pixels; | 1048 { |
1135 overlay->pixels[1] = overlay->pixels[0] + | 1049 SDL_SW_YUVTexture *swdata; |
1136 overlay->pitches[0] * overlay->h; | 1050 int *Cr_r_tab; |
1137 overlay->pixels[2] = overlay->pixels[1] + | 1051 int *Cr_g_tab; |
1138 overlay->pitches[1] * overlay->h / 2; | 1052 int *Cb_g_tab; |
1139 overlay->planes = 3; | 1053 int *Cb_b_tab; |
1140 break; | 1054 int i; |
1141 case SDL_YUY2_OVERLAY: | 1055 int CR, CB; |
1142 case SDL_UYVY_OVERLAY: | 1056 |
1143 case SDL_YVYU_OVERLAY: | 1057 swdata = (SDL_SW_YUVTexture *) SDL_malloc(sizeof(*swdata)); |
1144 overlay->pitches[0] = overlay->w*2; | 1058 if (!swdata) { |
1145 overlay->pixels[0] = swdata->pixels; | 1059 SDL_OutOfMemory(); |
1146 overlay->planes = 1; | 1060 return NULL; |
1147 break; | 1061 } |
1148 default: | 1062 SDL_zerop(swdata); |
1149 /* We should never get here (caught above) */ | 1063 |
1150 break; | 1064 switch (texture->format) { |
1151 } | 1065 case SDL_PixelFormat_YV12: |
1152 | 1066 case SDL_PixelFormat_IYUV: |
1153 /* We're all done.. */ | 1067 case SDL_PixelFormat_YUY2: |
1154 return(overlay); | 1068 case SDL_PixelFormat_UYVY: |
1155 } | 1069 case SDL_PixelFormat_YVYU: |
1156 | 1070 break; |
1157 int SDL_LockYUV_SW(_THIS, SDL_Overlay *overlay) | 1071 default: |
1158 { | 1072 SDL_SetError("Unsupported YUV format"); |
1159 return(0); | 1073 return NULL; |
1160 } | 1074 } |
1161 | 1075 |
1162 void SDL_UnlockYUV_SW(_THIS, SDL_Overlay *overlay) | 1076 swdata->texture = texture; |
1163 { | 1077 swdata->target_format = SDL_PixelFormat_Unknown; |
1164 return; | 1078 swdata->pixels = (Uint8 *) SDL_malloc(texture->w * texture->h * 2); |
1165 } | 1079 swdata->colortab = (int *) SDL_malloc(4 * 256 * sizeof(int)); |
1166 | 1080 swdata->rgb_2_pix = (Uint32 *) SDL_malloc(3 * 768 * sizeof(Uint32)); |
1167 int SDL_DisplayYUV_SW(_THIS, SDL_Overlay *overlay, SDL_Rect *src, SDL_Rect *dst) | 1081 if (!swdata->pixels || !swdata->colortab || !swdata->rgb_2_pix) { |
1168 { | 1082 SDL_OutOfMemory(); |
1169 struct private_yuvhwdata *swdata; | 1083 SDL_SW_DestroyYUVTexture(swdata); |
1170 int stretch; | 1084 return NULL; |
1171 int scale_2x; | 1085 } |
1172 SDL_Surface *display; | 1086 |
1173 Uint8 *lum, *Cr, *Cb; | 1087 /* Generate the tables for the display surface */ |
1174 Uint8 *dstp; | 1088 Cr_r_tab = &swdata->colortab[0 * 256]; |
1175 int mod; | 1089 Cr_g_tab = &swdata->colortab[1 * 256]; |
1176 | 1090 Cb_g_tab = &swdata->colortab[2 * 256]; |
1177 swdata = overlay->hwdata; | 1091 Cb_b_tab = &swdata->colortab[3 * 256]; |
1178 stretch = 0; | 1092 for (i = 0; i < 256; i++) { |
1179 scale_2x = 0; | 1093 /* Gamma correction (luminescence table) and chroma correction |
1180 if ( src->x || src->y || src->w < overlay->w || src->h < overlay->h ) { | 1094 would be done here. See the Berkeley mpeg_play sources. |
1181 /* The source rectangle has been clipped. | 1095 */ |
1182 Using a scratch surface is easier than adding clipped | 1096 CB = CR = (i - 128); |
1183 source support to all the blitters, plus that would | 1097 Cr_r_tab[i] = (int) ((0.419 / 0.299) * CR); |
1184 slow them down in the general unclipped case. | 1098 Cr_g_tab[i] = (int) (-(0.299 / 0.419) * CR); |
1185 */ | 1099 Cb_g_tab[i] = (int) (-(0.114 / 0.331) * CB); |
1186 stretch = 1; | 1100 Cb_b_tab[i] = (int) ((0.587 / 0.331) * CB); |
1187 } else if ( (src->w != dst->w) || (src->h != dst->h) ) { | 1101 } |
1188 if ( (dst->w == 2*src->w) && | 1102 |
1189 (dst->h == 2*src->h) ) { | 1103 /* Find the pitch and offset values for the overlay */ |
1190 scale_2x = 1; | 1104 switch (texture->format) { |
1191 } else { | 1105 case SDL_PixelFormat_YV12: |
1192 stretch = 1; | 1106 case SDL_PixelFormat_IYUV: |
1193 } | 1107 swdata->pitches[0] = texture->w; |
1194 } | 1108 swdata->pitches[1] = swdata->pitches[0] / 2; |
1195 if ( stretch ) { | 1109 swdata->pitches[2] = swdata->pitches[0] / 2; |
1196 if ( ! swdata->stretch ) { | 1110 swdata->planes[0] = swdata->pixels; |
1197 display = swdata->display; | 1111 swdata->planes[1] = |
1198 swdata->stretch = SDL_CreateRGBSurface( | 1112 swdata->planes[0] + swdata->pitches[0] * texture->h; |
1199 SDL_SWSURFACE, | 1113 swdata->planes[2] = |
1200 overlay->w, overlay->h, | 1114 swdata->planes[1] + swdata->pitches[1] * texture->h / 2; |
1201 display->format->BitsPerPixel, | 1115 break; |
1202 display->format->Rmask, | 1116 case SDL_PixelFormat_YUY2: |
1203 display->format->Gmask, | 1117 case SDL_PixelFormat_UYVY: |
1204 display->format->Bmask, 0); | 1118 case SDL_PixelFormat_YVYU: |
1205 if ( ! swdata->stretch ) { | 1119 swdata->pitches[0] = texture->w * 2; |
1206 return(-1); | 1120 swdata->planes[0] = swdata->pixels; |
1207 } | 1121 break; |
1208 } | 1122 default: |
1209 display = swdata->stretch; | 1123 /* We should never get here (caught above) */ |
1210 } else { | 1124 break; |
1211 display = swdata->display; | 1125 } |
1212 } | 1126 |
1213 switch (overlay->format) { | 1127 /* We're all done.. */ |
1214 case SDL_YV12_OVERLAY: | 1128 return (swdata); |
1215 lum = overlay->pixels[0]; | 1129 } |
1216 Cr = overlay->pixels[1]; | 1130 |
1217 Cb = overlay->pixels[2]; | 1131 int |
1218 break; | 1132 SDL_SW_QueryYUVTexturePixels(SDL_SW_YUVTexture * swdata, void **pixels, |
1219 case SDL_IYUV_OVERLAY: | 1133 int *pitch) |
1220 lum = overlay->pixels[0]; | 1134 { |
1221 Cr = overlay->pixels[2]; | 1135 *pixels = swdata->planes[0]; |
1222 Cb = overlay->pixels[1]; | 1136 *pitch = swdata->pitches[0]; |
1223 break; | 1137 return 0; |
1224 case SDL_YUY2_OVERLAY: | 1138 } |
1225 lum = overlay->pixels[0]; | 1139 |
1226 Cr = lum + 3; | 1140 int |
1227 Cb = lum + 1; | 1141 SDL_SW_UpdateYUVTexture(SDL_SW_YUVTexture * swdata, const SDL_Rect * rect, |
1228 break; | 1142 const void *pixels, int pitch) |
1229 case SDL_UYVY_OVERLAY: | 1143 { |
1230 lum = overlay->pixels[0]+1; | 1144 SDL_Texture *texture = swdata->texture; |
1231 Cr = lum + 1; | 1145 |
1232 Cb = lum - 1; | 1146 switch (texture->format) { |
1233 break; | 1147 case SDL_PixelFormat_YV12: |
1234 case SDL_YVYU_OVERLAY: | 1148 case SDL_PixelFormat_IYUV: |
1235 lum = overlay->pixels[0]; | 1149 if (rect |
1236 Cr = lum + 1; | 1150 && (rect->x != 0 || rect->y != 0 || rect->w != texture->w |
1237 Cb = lum + 3; | 1151 || rect->h != texture->h)) { |
1238 break; | 1152 SDL_SetError |
1239 default: | 1153 ("YV12 and IYUV textures only support full surface updates"); |
1240 SDL_SetError("Unsupported YUV format in blit"); | 1154 return -1; |
1241 return(-1); | 1155 } |
1242 } | 1156 SDL_memcpy(swdata->pixels, pixels, texture->h * texture->w * 2); |
1243 if ( SDL_MUSTLOCK(display) ) { | 1157 break; |
1244 if ( SDL_LockSurface(display) < 0 ) { | 1158 case SDL_PixelFormat_YUY2: |
1245 return(-1); | 1159 case SDL_PixelFormat_UYVY: |
1246 } | 1160 case SDL_PixelFormat_YVYU: |
1247 } | 1161 { |
1248 if ( stretch ) { | 1162 Uint8 *src, *dst; |
1249 dstp = (Uint8 *)swdata->stretch->pixels; | 1163 int row; |
1250 } else { | 1164 size_t length; |
1251 dstp = (Uint8 *)display->pixels | 1165 |
1252 + dst->x * display->format->BytesPerPixel | 1166 src = (Uint8 *) pixels; |
1253 + dst->y * display->pitch; | 1167 dst = |
1254 } | 1168 swdata->planes[0] + rect->y * swdata->pitches[0] + |
1255 mod = (display->pitch / display->format->BytesPerPixel); | 1169 rect->x * 2; |
1256 | 1170 length = rect->w * 2; |
1257 if ( scale_2x ) { | 1171 for (row = 0; row < rect->h; ++row) { |
1258 mod -= (overlay->w * 2); | 1172 SDL_memcpy(dst, src, length); |
1259 swdata->Display2X(swdata->colortab, swdata->rgb_2_pix, | 1173 src += pitch; |
1260 lum, Cr, Cb, dstp, overlay->h, overlay->w, mod); | 1174 dst += swdata->pitches[0]; |
1261 } else { | 1175 } |
1262 mod -= overlay->w; | 1176 } |
1263 swdata->Display1X(swdata->colortab, swdata->rgb_2_pix, | 1177 break; |
1264 lum, Cr, Cb, dstp, overlay->h, overlay->w, mod); | 1178 } |
1265 } | 1179 return 0; |
1266 if ( SDL_MUSTLOCK(display) ) { | 1180 } |
1267 SDL_UnlockSurface(display); | 1181 |
1268 } | 1182 int |
1269 if ( stretch ) { | 1183 SDL_SW_LockYUVTexture(SDL_SW_YUVTexture * swdata, const SDL_Rect * rect, |
1270 display = swdata->display; | 1184 int markDirty, void **pixels, int *pitch) |
1271 SDL_SoftStretch(swdata->stretch, src, display, dst); | 1185 { |
1272 } | 1186 SDL_Texture *texture = swdata->texture; |
1273 SDL_UpdateRects(display, 1, dst); | 1187 |
1274 | 1188 switch (texture->format) { |
1275 return(0); | 1189 case SDL_PixelFormat_YV12: |
1276 } | 1190 case SDL_PixelFormat_IYUV: |
1277 | 1191 if (rect |
1278 void SDL_FreeYUV_SW(_THIS, SDL_Overlay *overlay) | 1192 && (rect->x != 0 || rect->y != 0 || rect->w != texture->w |
1279 { | 1193 || rect->h != texture->h)) { |
1280 struct private_yuvhwdata *swdata; | 1194 SDL_SetError |
1281 | 1195 ("YV12 and IYUV textures only support full surface locks"); |
1282 swdata = overlay->hwdata; | 1196 return -1; |
1283 if ( swdata ) { | 1197 } |
1284 if ( swdata->stretch ) { | 1198 break; |
1285 SDL_FreeSurface(swdata->stretch); | 1199 } |
1286 } | 1200 |
1287 if ( swdata->pixels ) { | 1201 *pixels = swdata->planes[0] + rect->y * swdata->pitches[0] + rect->x * 2; |
1288 SDL_free(swdata->pixels); | 1202 *pitch = swdata->pitches[0]; |
1289 } | 1203 return 0; |
1290 if ( swdata->colortab ) { | 1204 } |
1291 SDL_free(swdata->colortab); | 1205 |
1292 } | 1206 void |
1293 if ( swdata->rgb_2_pix ) { | 1207 SDL_SW_UnlockYUVTexture(SDL_SW_YUVTexture * swdata) |
1294 SDL_free(swdata->rgb_2_pix); | 1208 { |
1295 } | 1209 } |
1296 SDL_free(swdata); | 1210 |
1297 } | 1211 int |
1298 } | 1212 SDL_SW_CopyYUVToRGB(SDL_SW_YUVTexture * swdata, const SDL_Rect * srcrect, |
1213 Uint32 target_format, int w, int h, void *pixels, | |
1214 int pitch) | |
1215 { | |
1216 SDL_Texture *texture = swdata->texture; | |
1217 int stretch; | |
1218 int scale_2x; | |
1219 Uint8 *lum, *Cr, *Cb; | |
1220 int mod; | |
1221 | |
1222 /* Make sure we're set up to display in the desired format */ | |
1223 if (target_format != swdata->target_format) { | |
1224 if (SDL_SW_SetupYUVDisplay(swdata, target_format) < 0) { | |
1225 return -1; | |
1226 } | |
1227 } | |
1228 | |
1229 stretch = 0; | |
1230 scale_2x = 0; | |
1231 if (srcrect->x || srcrect->y || srcrect->w < texture->w | |
1232 || srcrect->h < texture->h) { | |
1233 /* The source rectangle has been clipped. | |
1234 Using a scratch surface is easier than adding clipped | |
1235 source support to all the blitters, plus that would | |
1236 slow them down in the general unclipped case. | |
1237 */ | |
1238 stretch = 1; | |
1239 } else if ((srcrect->w != w) || (srcrect->h != h)) { | |
1240 if ((w == 2 * srcrect->w) && (h == 2 * srcrect->h)) { | |
1241 scale_2x = 1; | |
1242 } else { | |
1243 stretch = 1; | |
1244 } | |
1245 } | |
1246 if (stretch) { | |
1247 int bpp; | |
1248 Uint32 Rmask, Gmask, Bmask, Amask; | |
1249 | |
1250 if (swdata->display) { | |
1251 swdata->display->w = w; | |
1252 swdata->display->h = h; | |
1253 swdata->display->pixels = pixels; | |
1254 swdata->display->pitch = pitch; | |
1255 } else { | |
1256 /* This must have succeeded in SDL_SW_SetupYUVDisplay() earlier */ | |
1257 SDL_PixelFormatEnumToMasks(target_format, &bpp, &Rmask, &Gmask, | |
1258 &Bmask, &Amask); | |
1259 swdata->display = | |
1260 SDL_CreateRGBSurfaceFrom(pixels, w, h, bpp, pitch, Rmask, | |
1261 Gmask, Bmask, Amask); | |
1262 if (!swdata->display) { | |
1263 return (-1); | |
1264 } | |
1265 } | |
1266 if (!swdata->stretch) { | |
1267 /* This must have succeeded in SDL_SW_SetupYUVDisplay() earlier */ | |
1268 SDL_PixelFormatEnumToMasks(target_format, &bpp, &Rmask, &Gmask, | |
1269 &Bmask, &Amask); | |
1270 swdata->stretch = | |
1271 SDL_CreateRGBSurface(0, texture->w, texture->h, bpp, Rmask, | |
1272 Gmask, Bmask, Amask); | |
1273 if (!swdata->stretch) { | |
1274 return (-1); | |
1275 } | |
1276 } | |
1277 pixels = swdata->stretch->pixels; | |
1278 pitch = swdata->stretch->pitch; | |
1279 } | |
1280 switch (texture->format) { | |
1281 case SDL_PixelFormat_YV12: | |
1282 lum = swdata->planes[0]; | |
1283 Cr = swdata->planes[1]; | |
1284 Cb = swdata->planes[2]; | |
1285 break; | |
1286 case SDL_PixelFormat_IYUV: | |
1287 lum = swdata->planes[0]; | |
1288 Cr = swdata->planes[2]; | |
1289 Cb = swdata->planes[1]; | |
1290 break; | |
1291 case SDL_PixelFormat_YUY2: | |
1292 lum = swdata->planes[0]; | |
1293 Cr = lum + 3; | |
1294 Cb = lum + 1; | |
1295 break; | |
1296 case SDL_PixelFormat_UYVY: | |
1297 lum = swdata->planes[0] + 1; | |
1298 Cr = lum + 1; | |
1299 Cb = lum - 1; | |
1300 break; | |
1301 case SDL_PixelFormat_YVYU: | |
1302 lum = swdata->planes[0]; | |
1303 Cr = lum + 1; | |
1304 Cb = lum + 3; | |
1305 break; | |
1306 default: | |
1307 SDL_SetError("Unsupported YUV format in copy"); | |
1308 return (-1); | |
1309 } | |
1310 mod = (pitch / SDL_BYTESPERPIXEL(target_format)); | |
1311 | |
1312 if (scale_2x) { | |
1313 mod -= (texture->w * 2); | |
1314 swdata->Display2X(swdata->colortab, swdata->rgb_2_pix, | |
1315 lum, Cr, Cb, pixels, texture->h, texture->w, mod); | |
1316 } else { | |
1317 mod -= texture->w; | |
1318 swdata->Display1X(swdata->colortab, swdata->rgb_2_pix, | |
1319 lum, Cr, Cb, pixels, texture->h, texture->w, mod); | |
1320 } | |
1321 if (stretch) { | |
1322 SDL_Rect rect = *srcrect; | |
1323 SDL_SoftStretch(swdata->stretch, &rect, swdata->display, NULL); | |
1324 } | |
1325 return 0; | |
1326 } | |
1327 | |
1328 void | |
1329 SDL_SW_DestroyYUVTexture(SDL_SW_YUVTexture * swdata) | |
1330 { | |
1331 if (swdata) { | |
1332 if (swdata->pixels) { | |
1333 SDL_free(swdata->pixels); | |
1334 } | |
1335 if (swdata->colortab) { | |
1336 SDL_free(swdata->colortab); | |
1337 } | |
1338 if (swdata->rgb_2_pix) { | |
1339 SDL_free(swdata->rgb_2_pix); | |
1340 } | |
1341 if (swdata->stretch) { | |
1342 SDL_FreeSurface(swdata->stretch); | |
1343 } | |
1344 if (swdata->display) { | |
1345 SDL_FreeSurface(swdata->display); | |
1346 } | |
1347 SDL_free(swdata); | |
1348 } | |
1349 } | |
1350 | |
1351 /* vi: set ts=4 sw=4 expandtab: */ |