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: */