Mercurial > sdl-ios-xcode
annotate src/video/SDL_yuv_sw.c @ 934:af585d6efec8
Date: Thu, 17 Jun 2004 11:38:51 -0700 (PDT)
From: Eric Wing <ewing2121@yahoo.com>
Subject: New OS X patch (was Re: [SDL] Bug with inverted mouse coordinates in
I have a new patch for OS X I would like to submit.
First, it appears no further action has been taken on
my fix from Apple on the OpenGL windowed mode mouse
inversion problem. The fix would reunify the code, and
no longer require case checking for which version of
the OS you are running. This is probably a good fix
because the behavior with the old code could change
again with future versions of the OS, so those fixes
are included in this new patch.
But in addition, when I was at Apple, I asked them
about the ability to distinguish between the modifier
keys on the left and right sides of the keyboard (e.g.
Left Shift, Right Shift, Left/Right Alt, L/R Cmd, L/R
Ctrl). They told me that starting with Panther, the OS
began supporting this feature. This has always been a
source of annoyance for me when bringing a program
that comes from Windows or Linux to OS X when the
keybindings happened to need distinguishable left-side
and right-side keys. So the rest of the patch I am
submitting contains new code to support this feature
on Panther (and presumably later versions of the OS).
So after removing the OS version checks for the mouse
inversion problem, I reused the OS version checks to
activate the Left/Right detection of modifier keys. If
you are running Panther (or above), the new code will
attempt to distinguish between sides. For the older
OS's, the code path reverts to the original code.
I've tested with Panther on a G4 Cube, G5 dual
processor, and Powerbook Rev C. The Cube and G5
keyboards demonstrated the ability to distinguish
between sides. The Powerbook seems to only have
left-side keys, but the patch was still able to handle
it by producing the same results as before the patch.
I also wanted to test a non-Apple keyboard.
Unfortunately, I don't have any PC USB keyboards.
However, I was able to borrow a Sun Microsystems USB
keyboard, so I tried that out on the G5, and I got the
correct behavior for left and right sides. I'm
expecting that if it worked with a Sun keyboard, most
other keyboards should work with no problems.
author | Sam Lantinga <slouken@libsdl.org> |
---|---|
date | Fri, 20 Aug 2004 22:35:23 +0000 |
parents | b8d311d90021 |
children | c9b51268668f |
rev | line source |
---|---|
0 | 1 /* |
2 SDL - Simple DirectMedia Layer | |
769
b8d311d90021
Updated copyright information for 2004 (Happy New Year!)
Sam Lantinga <slouken@libsdl.org>
parents:
739
diff
changeset
|
3 Copyright (C) 1997-2004 Sam Lantinga |
0 | 4 |
5 This library is free software; you can redistribute it and/or | |
6 modify it under the terms of the GNU Library General Public | |
7 License as published by the Free Software Foundation; either | |
8 version 2 of the License, or (at your option) any later version. | |
9 | |
10 This library is distributed in the hope that it will be useful, | |
11 but WITHOUT ANY WARRANTY; without even the implied warranty of | |
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
13 Library General Public License for more details. | |
14 | |
15 You should have received a copy of the GNU Library General Public | |
16 License along with this library; if not, write to the Free | |
17 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | |
18 | |
19 Sam Lantinga | |
252
e8157fcb3114
Updated the source with the correct e-mail address
Sam Lantinga <slouken@libsdl.org>
parents:
9
diff
changeset
|
20 slouken@libsdl.org |
0 | 21 */ |
22 | |
23 #ifdef SAVE_RCSID | |
24 static char rcsid = | |
25 "@(#) $Id$"; | |
26 #endif | |
27 | |
28 /* This is the software implementation of the YUV video overlay support */ | |
29 | |
30 /* This code was derived from code carrying the following copyright notices: | |
31 | |
32 * Copyright (c) 1995 The Regents of the University of California. | |
33 * All rights reserved. | |
34 * | |
35 * Permission to use, copy, modify, and distribute this software and its | |
36 * documentation for any purpose, without fee, and without written agreement is | |
37 * hereby granted, provided that the above copyright notice and the following | |
38 * two paragraphs appear in all copies of this software. | |
39 * | |
40 * IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR | |
41 * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT | |
42 * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE UNIVERSITY OF | |
43 * CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |
44 * | |
45 * THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES, | |
46 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY | |
47 * AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS | |
48 * ON AN "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATION TO | |
49 * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. | |
50 | |
51 * Copyright (c) 1995 Erik Corry | |
52 * All rights reserved. | |
53 * | |
54 * Permission to use, copy, modify, and distribute this software and its | |
55 * documentation for any purpose, without fee, and without written agreement is | |
56 * hereby granted, provided that the above copyright notice and the following | |
57 * two paragraphs appear in all copies of this software. | |
58 * | |
59 * IN NO EVENT SHALL ERIK CORRY BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, | |
60 * SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OF | |
61 * THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF ERIK CORRY HAS BEEN ADVISED | |
62 * OF THE POSSIBILITY OF SUCH DAMAGE. | |
63 * | |
64 * ERIK CORRY SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT | |
65 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A | |
66 * PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" | |
67 * BASIS, AND ERIK CORRY HAS NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, | |
68 * UPDATES, ENHANCEMENTS, OR MODIFICATIONS. | |
69 | |
70 * Portions of this software Copyright (c) 1995 Brown University. | |
71 * All rights reserved. | |
72 * | |
73 * Permission to use, copy, modify, and distribute this software and its | |
74 * documentation for any purpose, without fee, and without written agreement | |
75 * is hereby granted, provided that the above copyright notice and the | |
76 * following two paragraphs appear in all copies of this software. | |
77 * | |
78 * IN NO EVENT SHALL BROWN UNIVERSITY BE LIABLE TO ANY PARTY FOR | |
79 * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT | |
80 * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF BROWN | |
81 * UNIVERSITY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |
82 * | |
83 * BROWN UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT | |
84 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A | |
85 * PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" | |
86 * BASIS, AND BROWN UNIVERSITY HAS NO OBLIGATION TO PROVIDE MAINTENANCE, | |
87 * SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. | |
88 */ | |
89 | |
90 #include <stdlib.h> | |
91 #include <string.h> | |
92 | |
93 #include "SDL_error.h" | |
94 #include "SDL_video.h" | |
739
22dbf364c017
Added SDL_HasMMX(), SDL_Has3DNow(), SDL_HasSSE() in SDL_cpuinfo.h
Sam Lantinga <slouken@libsdl.org>
parents:
366
diff
changeset
|
95 #include "SDL_cpuinfo.h" |
0 | 96 #include "SDL_stretch_c.h" |
97 #include "SDL_yuvfuncs.h" | |
98 #include "SDL_yuv_sw_c.h" | |
99 | |
100 /* The functions used to manipulate software video overlays */ | |
101 static struct private_yuvhwfuncs sw_yuvfuncs = { | |
102 SDL_LockYUV_SW, | |
103 SDL_UnlockYUV_SW, | |
104 SDL_DisplayYUV_SW, | |
105 SDL_FreeYUV_SW | |
106 }; | |
107 | |
108 /* RGB conversion lookup tables */ | |
109 struct private_yuvhwdata { | |
110 SDL_Surface *stretch; | |
111 SDL_Surface *display; | |
112 Uint8 *pixels; | |
113 int *colortab; | |
114 Uint32 *rgb_2_pix; | |
115 void (*Display1X)(int *colortab, Uint32 *rgb_2_pix, | |
116 unsigned char *lum, unsigned char *cr, | |
117 unsigned char *cb, unsigned char *out, | |
118 int rows, int cols, int mod ); | |
119 void (*Display2X)(int *colortab, Uint32 *rgb_2_pix, | |
120 unsigned char *lum, unsigned char *cr, | |
121 unsigned char *cb, unsigned char *out, | |
122 int rows, int cols, int mod ); | |
123 | |
124 /* These are just so we don't have to allocate them separately */ | |
125 Uint16 pitches[3]; | |
126 Uint8 *planes[3]; | |
127 }; | |
128 | |
129 | |
130 /* The colorspace conversion functions */ | |
131 | |
132 extern void Color565DitherYV12MMX1X( 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 extern void ColorRGBDitherYV12MMX1X( int *colortab, Uint32 *rgb_2_pix, | |
137 unsigned char *lum, unsigned char *cr, | |
138 unsigned char *cb, unsigned char *out, | |
139 int rows, int cols, int mod ); | |
140 | |
141 static void Color16DitherYV12Mod1X( int *colortab, Uint32 *rgb_2_pix, | |
142 unsigned char *lum, unsigned char *cr, | |
143 unsigned char *cb, unsigned char *out, | |
144 int rows, int cols, int mod ) | |
145 { | |
146 unsigned short* row1; | |
147 unsigned short* row2; | |
148 unsigned char* lum2; | |
149 int x, y; | |
150 int cr_r; | |
151 int crb_g; | |
152 int cb_b; | |
153 int cols_2 = cols / 2; | |
154 | |
155 row1 = (unsigned short*) out; | |
156 row2 = row1 + cols + mod; | |
157 lum2 = lum + cols; | |
158 | |
159 mod += cols + mod; | |
160 | |
161 y = rows / 2; | |
162 while( y-- ) | |
163 { | |
164 x = cols_2; | |
165 while( x-- ) | |
166 { | |
167 register int L; | |
168 | |
169 cr_r = 0*768+256 + colortab[ *cr + 0*256 ]; | |
170 crb_g = 1*768+256 + colortab[ *cr + 1*256 ] | |
171 + colortab[ *cb + 2*256 ]; | |
172 cb_b = 2*768+256 + colortab[ *cb + 3*256 ]; | |
173 ++cr; ++cb; | |
174 | |
175 L = *lum++; | |
176 *row1++ = (rgb_2_pix[ L + cr_r ] | | |
177 rgb_2_pix[ L + crb_g ] | | |
178 rgb_2_pix[ L + cb_b ]); | |
179 | |
180 L = *lum++; | |
181 *row1++ = (rgb_2_pix[ L + cr_r ] | | |
182 rgb_2_pix[ L + crb_g ] | | |
183 rgb_2_pix[ L + cb_b ]); | |
184 | |
185 | |
186 /* Now, do second row. */ | |
187 | |
188 L = *lum2++; | |
189 *row2++ = (rgb_2_pix[ L + cr_r ] | | |
190 rgb_2_pix[ L + crb_g ] | | |
191 rgb_2_pix[ L + cb_b ]); | |
192 | |
193 L = *lum2++; | |
194 *row2++ = (rgb_2_pix[ L + cr_r ] | | |
195 rgb_2_pix[ L + crb_g ] | | |
196 rgb_2_pix[ L + cb_b ]); | |
197 } | |
198 | |
199 /* | |
200 * These values are at the start of the next line, (due | |
201 * to the ++'s above),but they need to be at the start | |
202 * of the line after that. | |
203 */ | |
204 lum += cols; | |
205 lum2 += cols; | |
206 row1 += mod; | |
207 row2 += mod; | |
208 } | |
209 } | |
210 | |
211 static void Color24DitherYV12Mod1X( int *colortab, Uint32 *rgb_2_pix, | |
212 unsigned char *lum, unsigned char *cr, | |
213 unsigned char *cb, unsigned char *out, | |
214 int rows, int cols, int mod ) | |
215 { | |
216 unsigned int value; | |
217 unsigned char* row1; | |
218 unsigned char* row2; | |
219 unsigned char* lum2; | |
220 int x, y; | |
221 int cr_r; | |
222 int crb_g; | |
223 int cb_b; | |
224 int cols_2 = cols / 2; | |
225 | |
226 row1 = out; | |
227 row2 = row1 + cols*3 + mod*3; | |
228 lum2 = lum + cols; | |
229 | |
230 mod += cols + mod; | |
231 mod *= 3; | |
232 | |
233 y = rows / 2; | |
234 while( y-- ) | |
235 { | |
236 x = cols_2; | |
237 while( x-- ) | |
238 { | |
239 register int L; | |
240 | |
241 cr_r = 0*768+256 + colortab[ *cr + 0*256 ]; | |
242 crb_g = 1*768+256 + colortab[ *cr + 1*256 ] | |
243 + colortab[ *cb + 2*256 ]; | |
244 cb_b = 2*768+256 + colortab[ *cb + 3*256 ]; | |
245 ++cr; ++cb; | |
246 | |
247 L = *lum++; | |
248 value = (rgb_2_pix[ L + cr_r ] | | |
249 rgb_2_pix[ L + crb_g ] | | |
250 rgb_2_pix[ L + cb_b ]); | |
251 *row1++ = (value ) & 0xFF; | |
252 *row1++ = (value >> 8) & 0xFF; | |
253 *row1++ = (value >> 16) & 0xFF; | |
254 | |
255 L = *lum++; | |
256 value = (rgb_2_pix[ L + cr_r ] | | |
257 rgb_2_pix[ L + crb_g ] | | |
258 rgb_2_pix[ L + cb_b ]); | |
259 *row1++ = (value ) & 0xFF; | |
260 *row1++ = (value >> 8) & 0xFF; | |
261 *row1++ = (value >> 16) & 0xFF; | |
262 | |
263 | |
264 /* Now, do second row. */ | |
265 | |
266 L = *lum2++; | |
267 value = (rgb_2_pix[ L + cr_r ] | | |
268 rgb_2_pix[ L + crb_g ] | | |
269 rgb_2_pix[ L + cb_b ]); | |
270 *row2++ = (value ) & 0xFF; | |
271 *row2++ = (value >> 8) & 0xFF; | |
272 *row2++ = (value >> 16) & 0xFF; | |
273 | |
274 L = *lum2++; | |
275 value = (rgb_2_pix[ L + cr_r ] | | |
276 rgb_2_pix[ L + crb_g ] | | |
277 rgb_2_pix[ L + cb_b ]); | |
278 *row2++ = (value ) & 0xFF; | |
279 *row2++ = (value >> 8) & 0xFF; | |
280 *row2++ = (value >> 16) & 0xFF; | |
281 } | |
282 | |
283 /* | |
284 * These values are at the start of the next line, (due | |
285 * to the ++'s above),but they need to be at the start | |
286 * of the line after that. | |
287 */ | |
288 lum += cols; | |
289 lum2 += cols; | |
290 row1 += mod; | |
291 row2 += mod; | |
292 } | |
293 } | |
294 | |
295 static void Color32DitherYV12Mod1X( int *colortab, Uint32 *rgb_2_pix, | |
296 unsigned char *lum, unsigned char *cr, | |
297 unsigned char *cb, unsigned char *out, | |
298 int rows, int cols, int mod ) | |
299 { | |
300 unsigned int* row1; | |
301 unsigned int* row2; | |
302 unsigned char* lum2; | |
303 int x, y; | |
304 int cr_r; | |
305 int crb_g; | |
306 int cb_b; | |
307 int cols_2 = cols / 2; | |
308 | |
309 row1 = (unsigned int*) out; | |
310 row2 = row1 + cols + mod; | |
311 lum2 = lum + cols; | |
312 | |
313 mod += cols + mod; | |
314 | |
315 y = rows / 2; | |
316 while( y-- ) | |
317 { | |
318 x = cols_2; | |
319 while( x-- ) | |
320 { | |
321 register int L; | |
322 | |
323 cr_r = 0*768+256 + colortab[ *cr + 0*256 ]; | |
324 crb_g = 1*768+256 + colortab[ *cr + 1*256 ] | |
325 + colortab[ *cb + 2*256 ]; | |
326 cb_b = 2*768+256 + colortab[ *cb + 3*256 ]; | |
327 ++cr; ++cb; | |
328 | |
329 L = *lum++; | |
330 *row1++ = (rgb_2_pix[ L + cr_r ] | | |
331 rgb_2_pix[ L + crb_g ] | | |
332 rgb_2_pix[ L + cb_b ]); | |
333 | |
334 L = *lum++; | |
335 *row1++ = (rgb_2_pix[ L + cr_r ] | | |
336 rgb_2_pix[ L + crb_g ] | | |
337 rgb_2_pix[ L + cb_b ]); | |
338 | |
339 | |
340 /* Now, do second row. */ | |
341 | |
342 L = *lum2++; | |
343 *row2++ = (rgb_2_pix[ L + cr_r ] | | |
344 rgb_2_pix[ L + crb_g ] | | |
345 rgb_2_pix[ L + cb_b ]); | |
346 | |
347 L = *lum2++; | |
348 *row2++ = (rgb_2_pix[ L + cr_r ] | | |
349 rgb_2_pix[ L + crb_g ] | | |
350 rgb_2_pix[ L + cb_b ]); | |
351 } | |
352 | |
353 /* | |
354 * These values are at the start of the next line, (due | |
355 * to the ++'s above),but they need to be at the start | |
356 * of the line after that. | |
357 */ | |
358 lum += cols; | |
359 lum2 += cols; | |
360 row1 += mod; | |
361 row2 += mod; | |
362 } | |
363 } | |
364 | |
365 /* | |
366 * In this function I make use of a nasty trick. The tables have the lower | |
367 * 16 bits replicated in the upper 16. This means I can write ints and get | |
368 * the horisontal doubling for free (almost). | |
369 */ | |
370 static void Color16DitherYV12Mod2X( int *colortab, Uint32 *rgb_2_pix, | |
371 unsigned char *lum, unsigned char *cr, | |
372 unsigned char *cb, unsigned char *out, | |
373 int rows, int cols, int mod ) | |
374 { | |
375 unsigned int* row1 = (unsigned int*) out; | |
376 const int next_row = cols+(mod/2); | |
377 unsigned int* row2 = row1 + 2*next_row; | |
378 unsigned char* lum2; | |
379 int x, y; | |
380 int cr_r; | |
381 int crb_g; | |
382 int cb_b; | |
383 int cols_2 = cols / 2; | |
384 | |
385 lum2 = lum + cols; | |
386 | |
387 mod = (next_row * 3) + (mod/2); | |
388 | |
389 y = rows / 2; | |
390 while( y-- ) | |
391 { | |
392 x = cols_2; | |
393 while( x-- ) | |
394 { | |
395 register int L; | |
396 | |
397 cr_r = 0*768+256 + colortab[ *cr + 0*256 ]; | |
398 crb_g = 1*768+256 + colortab[ *cr + 1*256 ] | |
399 + colortab[ *cb + 2*256 ]; | |
400 cb_b = 2*768+256 + colortab[ *cb + 3*256 ]; | |
401 ++cr; ++cb; | |
402 | |
403 L = *lum++; | |
404 row1[0] = row1[next_row] = (rgb_2_pix[ L + cr_r ] | | |
405 rgb_2_pix[ L + crb_g ] | | |
406 rgb_2_pix[ L + cb_b ]); | |
407 row1++; | |
408 | |
409 L = *lum++; | |
410 row1[0] = row1[next_row] = (rgb_2_pix[ L + cr_r ] | | |
411 rgb_2_pix[ L + crb_g ] | | |
412 rgb_2_pix[ L + cb_b ]); | |
413 row1++; | |
414 | |
415 | |
416 /* Now, do second row. */ | |
417 | |
418 L = *lum2++; | |
419 row2[0] = row2[next_row] = (rgb_2_pix[ L + cr_r ] | | |
420 rgb_2_pix[ L + crb_g ] | | |
421 rgb_2_pix[ L + cb_b ]); | |
422 row2++; | |
423 | |
424 L = *lum2++; | |
425 row2[0] = row2[next_row] = (rgb_2_pix[ L + cr_r ] | | |
426 rgb_2_pix[ L + crb_g ] | | |
427 rgb_2_pix[ L + cb_b ]); | |
428 row2++; | |
429 } | |
430 | |
431 /* | |
432 * These values are at the start of the next line, (due | |
433 * to the ++'s above),but they need to be at the start | |
434 * of the line after that. | |
435 */ | |
436 lum += cols; | |
437 lum2 += cols; | |
438 row1 += mod; | |
439 row2 += mod; | |
440 } | |
441 } | |
442 | |
443 static void Color24DitherYV12Mod2X( int *colortab, Uint32 *rgb_2_pix, | |
444 unsigned char *lum, unsigned char *cr, | |
445 unsigned char *cb, unsigned char *out, | |
446 int rows, int cols, int mod ) | |
447 { | |
448 unsigned int value; | |
449 unsigned char* row1 = out; | |
450 const int next_row = (cols*2 + mod) * 3; | |
451 unsigned char* row2 = row1 + 2*next_row; | |
452 unsigned char* lum2; | |
453 int x, y; | |
454 int cr_r; | |
455 int crb_g; | |
456 int cb_b; | |
457 int cols_2 = cols / 2; | |
458 | |
459 lum2 = lum + cols; | |
460 | |
461 mod = next_row*3 + mod*3; | |
462 | |
463 y = rows / 2; | |
464 while( y-- ) | |
465 { | |
466 x = cols_2; | |
467 while( x-- ) | |
468 { | |
469 register int L; | |
470 | |
471 cr_r = 0*768+256 + colortab[ *cr + 0*256 ]; | |
472 crb_g = 1*768+256 + colortab[ *cr + 1*256 ] | |
473 + colortab[ *cb + 2*256 ]; | |
474 cb_b = 2*768+256 + colortab[ *cb + 3*256 ]; | |
475 ++cr; ++cb; | |
476 | |
477 L = *lum++; | |
478 value = (rgb_2_pix[ L + cr_r ] | | |
479 rgb_2_pix[ L + crb_g ] | | |
480 rgb_2_pix[ L + cb_b ]); | |
481 row1[0+0] = row1[3+0] = row1[next_row+0] = row1[next_row+3+0] = | |
482 (value ) & 0xFF; | |
483 row1[0+1] = row1[3+1] = row1[next_row+1] = row1[next_row+3+1] = | |
484 (value >> 8) & 0xFF; | |
485 row1[0+2] = row1[3+2] = row1[next_row+2] = row1[next_row+3+2] = | |
486 (value >> 16) & 0xFF; | |
487 row1 += 2*3; | |
488 | |
489 L = *lum++; | |
490 value = (rgb_2_pix[ L + cr_r ] | | |
491 rgb_2_pix[ L + crb_g ] | | |
492 rgb_2_pix[ L + cb_b ]); | |
493 row1[0+0] = row1[3+0] = row1[next_row+0] = row1[next_row+3+0] = | |
494 (value ) & 0xFF; | |
495 row1[0+1] = row1[3+1] = row1[next_row+1] = row1[next_row+3+1] = | |
496 (value >> 8) & 0xFF; | |
497 row1[0+2] = row1[3+2] = row1[next_row+2] = row1[next_row+3+2] = | |
498 (value >> 16) & 0xFF; | |
499 row1 += 2*3; | |
500 | |
501 | |
502 /* Now, do second row. */ | |
503 | |
504 L = *lum2++; | |
505 value = (rgb_2_pix[ L + cr_r ] | | |
506 rgb_2_pix[ L + crb_g ] | | |
507 rgb_2_pix[ L + cb_b ]); | |
508 row2[0+0] = row2[3+0] = row2[next_row+0] = row2[next_row+3+0] = | |
509 (value ) & 0xFF; | |
510 row2[0+1] = row2[3+1] = row2[next_row+1] = row2[next_row+3+1] = | |
511 (value >> 8) & 0xFF; | |
512 row2[0+2] = row2[3+2] = row2[next_row+2] = row2[next_row+3+2] = | |
513 (value >> 16) & 0xFF; | |
514 row2 += 2*3; | |
515 | |
516 L = *lum2++; | |
517 value = (rgb_2_pix[ L + cr_r ] | | |
518 rgb_2_pix[ L + crb_g ] | | |
519 rgb_2_pix[ L + cb_b ]); | |
520 row2[0+0] = row2[3+0] = row2[next_row+0] = row2[next_row+3+0] = | |
521 (value ) & 0xFF; | |
522 row2[0+1] = row2[3+1] = row2[next_row+1] = row2[next_row+3+1] = | |
523 (value >> 8) & 0xFF; | |
524 row2[0+2] = row2[3+2] = row2[next_row+2] = row2[next_row+3+2] = | |
525 (value >> 16) & 0xFF; | |
526 row2 += 2*3; | |
527 } | |
528 | |
529 /* | |
530 * These values are at the start of the next line, (due | |
531 * to the ++'s above),but they need to be at the start | |
532 * of the line after that. | |
533 */ | |
534 lum += cols; | |
535 lum2 += cols; | |
536 row1 += mod; | |
537 row2 += mod; | |
538 } | |
539 } | |
540 | |
541 static void Color32DitherYV12Mod2X( int *colortab, Uint32 *rgb_2_pix, | |
542 unsigned char *lum, unsigned char *cr, | |
543 unsigned char *cb, unsigned char *out, | |
544 int rows, int cols, int mod ) | |
545 { | |
546 unsigned int* row1 = (unsigned int*) out; | |
547 const int next_row = cols*2+mod; | |
548 unsigned int* row2 = row1 + 2*next_row; | |
549 unsigned char* lum2; | |
550 int x, y; | |
551 int cr_r; | |
552 int crb_g; | |
553 int cb_b; | |
554 int cols_2 = cols / 2; | |
555 | |
556 lum2 = lum + cols; | |
557 | |
558 mod = (next_row * 3) + mod; | |
559 | |
560 y = rows / 2; | |
561 while( y-- ) | |
562 { | |
563 x = cols_2; | |
564 while( x-- ) | |
565 { | |
566 register int L; | |
567 | |
568 cr_r = 0*768+256 + colortab[ *cr + 0*256 ]; | |
569 crb_g = 1*768+256 + colortab[ *cr + 1*256 ] | |
570 + colortab[ *cb + 2*256 ]; | |
571 cb_b = 2*768+256 + colortab[ *cb + 3*256 ]; | |
572 ++cr; ++cb; | |
573 | |
574 L = *lum++; | |
575 row1[0] = row1[1] = row1[next_row] = row1[next_row+1] = | |
576 (rgb_2_pix[ L + cr_r ] | | |
577 rgb_2_pix[ L + crb_g ] | | |
578 rgb_2_pix[ L + cb_b ]); | |
579 row1 += 2; | |
580 | |
581 L = *lum++; | |
582 row1[0] = row1[1] = row1[next_row] = row1[next_row+1] = | |
583 (rgb_2_pix[ L + cr_r ] | | |
584 rgb_2_pix[ L + crb_g ] | | |
585 rgb_2_pix[ L + cb_b ]); | |
586 row1 += 2; | |
587 | |
588 | |
589 /* Now, do second row. */ | |
590 | |
591 L = *lum2++; | |
592 row2[0] = row2[1] = row2[next_row] = row2[next_row+1] = | |
593 (rgb_2_pix[ L + cr_r ] | | |
594 rgb_2_pix[ L + crb_g ] | | |
595 rgb_2_pix[ L + cb_b ]); | |
596 row2 += 2; | |
597 | |
598 L = *lum2++; | |
599 row2[0] = row2[1] = row2[next_row] = row2[next_row+1] = | |
600 (rgb_2_pix[ L + cr_r ] | | |
601 rgb_2_pix[ L + crb_g ] | | |
602 rgb_2_pix[ L + cb_b ]); | |
603 row2 += 2; | |
604 } | |
605 | |
606 /* | |
607 * These values are at the start of the next line, (due | |
608 * to the ++'s above),but they need to be at the start | |
609 * of the line after that. | |
610 */ | |
611 lum += cols; | |
612 lum2 += cols; | |
613 row1 += mod; | |
614 row2 += mod; | |
615 } | |
616 } | |
617 | |
618 static void Color16DitherYUY2Mod1X( int *colortab, Uint32 *rgb_2_pix, | |
619 unsigned char *lum, unsigned char *cr, | |
620 unsigned char *cb, unsigned char *out, | |
621 int rows, int cols, int mod ) | |
622 { | |
623 unsigned short* row; | |
624 int x, y; | |
625 int cr_r; | |
626 int crb_g; | |
627 int cb_b; | |
628 int cols_2 = cols / 2; | |
629 | |
630 row = (unsigned short*) out; | |
631 | |
632 y = rows; | |
633 while( y-- ) | |
634 { | |
635 x = cols_2; | |
636 while( x-- ) | |
637 { | |
638 register int L; | |
639 | |
640 cr_r = 0*768+256 + colortab[ *cr + 0*256 ]; | |
641 crb_g = 1*768+256 + colortab[ *cr + 1*256 ] | |
642 + colortab[ *cb + 2*256 ]; | |
643 cb_b = 2*768+256 + colortab[ *cb + 3*256 ]; | |
644 cr += 4; cb += 4; | |
645 | |
646 L = *lum; lum += 2; | |
647 *row++ = (rgb_2_pix[ L + cr_r ] | | |
648 rgb_2_pix[ L + crb_g ] | | |
649 rgb_2_pix[ L + cb_b ]); | |
650 | |
651 L = *lum; lum += 2; | |
652 *row++ = (rgb_2_pix[ L + cr_r ] | | |
653 rgb_2_pix[ L + crb_g ] | | |
654 rgb_2_pix[ L + cb_b ]); | |
655 | |
656 } | |
657 | |
658 row += mod; | |
659 } | |
660 } | |
661 | |
662 static void Color24DitherYUY2Mod1X( int *colortab, Uint32 *rgb_2_pix, | |
663 unsigned char *lum, unsigned char *cr, | |
664 unsigned char *cb, unsigned char *out, | |
665 int rows, int cols, int mod ) | |
666 { | |
667 unsigned int value; | |
668 unsigned char* row; | |
669 int x, y; | |
670 int cr_r; | |
671 int crb_g; | |
672 int cb_b; | |
673 int cols_2 = cols / 2; | |
674 | |
675 row = (unsigned char*) out; | |
676 mod *= 3; | |
677 y = rows; | |
678 while( y-- ) | |
679 { | |
680 x = cols_2; | |
681 while( x-- ) | |
682 { | |
683 register int L; | |
684 | |
685 cr_r = 0*768+256 + colortab[ *cr + 0*256 ]; | |
686 crb_g = 1*768+256 + colortab[ *cr + 1*256 ] | |
687 + colortab[ *cb + 2*256 ]; | |
688 cb_b = 2*768+256 + colortab[ *cb + 3*256 ]; | |
689 cr += 4; cb += 4; | |
690 | |
691 L = *lum; lum += 2; | |
692 value = (rgb_2_pix[ L + cr_r ] | | |
693 rgb_2_pix[ L + crb_g ] | | |
694 rgb_2_pix[ L + cb_b ]); | |
695 *row++ = (value ) & 0xFF; | |
696 *row++ = (value >> 8) & 0xFF; | |
697 *row++ = (value >> 16) & 0xFF; | |
698 | |
699 L = *lum; lum += 2; | |
700 value = (rgb_2_pix[ L + cr_r ] | | |
701 rgb_2_pix[ L + crb_g ] | | |
702 rgb_2_pix[ L + cb_b ]); | |
703 *row++ = (value ) & 0xFF; | |
704 *row++ = (value >> 8) & 0xFF; | |
705 *row++ = (value >> 16) & 0xFF; | |
706 | |
707 } | |
708 row += mod; | |
709 } | |
710 } | |
711 | |
712 static void Color32DitherYUY2Mod1X( int *colortab, Uint32 *rgb_2_pix, | |
713 unsigned char *lum, unsigned char *cr, | |
714 unsigned char *cb, unsigned char *out, | |
715 int rows, int cols, int mod ) | |
716 { | |
717 unsigned int* row; | |
718 int x, y; | |
719 int cr_r; | |
720 int crb_g; | |
721 int cb_b; | |
722 int cols_2 = cols / 2; | |
723 | |
724 row = (unsigned int*) out; | |
725 y = rows; | |
726 while( y-- ) | |
727 { | |
728 x = cols_2; | |
729 while( x-- ) | |
730 { | |
731 register int L; | |
732 | |
733 cr_r = 0*768+256 + colortab[ *cr + 0*256 ]; | |
734 crb_g = 1*768+256 + colortab[ *cr + 1*256 ] | |
735 + colortab[ *cb + 2*256 ]; | |
736 cb_b = 2*768+256 + colortab[ *cb + 3*256 ]; | |
737 cr += 4; cb += 4; | |
738 | |
739 L = *lum; lum += 2; | |
740 *row++ = (rgb_2_pix[ L + cr_r ] | | |
741 rgb_2_pix[ L + crb_g ] | | |
742 rgb_2_pix[ L + cb_b ]); | |
743 | |
744 L = *lum; lum += 2; | |
745 *row++ = (rgb_2_pix[ L + cr_r ] | | |
746 rgb_2_pix[ L + crb_g ] | | |
747 rgb_2_pix[ L + cb_b ]); | |
748 | |
749 | |
750 } | |
751 row += mod; | |
752 } | |
753 } | |
754 | |
755 /* | |
756 * In this function I make use of a nasty trick. The tables have the lower | |
757 * 16 bits replicated in the upper 16. This means I can write ints and get | |
758 * the horisontal doubling for free (almost). | |
759 */ | |
760 static void Color16DitherYUY2Mod2X( int *colortab, Uint32 *rgb_2_pix, | |
761 unsigned char *lum, unsigned char *cr, | |
762 unsigned char *cb, unsigned char *out, | |
763 int rows, int cols, int mod ) | |
764 { | |
765 unsigned int* row = (unsigned int*) out; | |
766 const int next_row = cols+(mod/2); | |
767 int x, y; | |
768 int cr_r; | |
769 int crb_g; | |
770 int cb_b; | |
771 int cols_2 = cols / 2; | |
772 | |
773 y = rows; | |
774 while( y-- ) | |
775 { | |
776 x = cols_2; | |
777 while( x-- ) | |
778 { | |
779 register int L; | |
780 | |
781 cr_r = 0*768+256 + colortab[ *cr + 0*256 ]; | |
782 crb_g = 1*768+256 + colortab[ *cr + 1*256 ] | |
783 + colortab[ *cb + 2*256 ]; | |
784 cb_b = 2*768+256 + colortab[ *cb + 3*256 ]; | |
785 cr += 4; cb += 4; | |
786 | |
787 L = *lum; lum += 2; | |
788 row[0] = row[next_row] = (rgb_2_pix[ L + cr_r ] | | |
789 rgb_2_pix[ L + crb_g ] | | |
790 rgb_2_pix[ L + cb_b ]); | |
791 row++; | |
792 | |
793 L = *lum; lum += 2; | |
794 row[0] = row[next_row] = (rgb_2_pix[ L + cr_r ] | | |
795 rgb_2_pix[ L + crb_g ] | | |
796 rgb_2_pix[ L + cb_b ]); | |
797 row++; | |
798 | |
799 } | |
800 row += next_row; | |
801 } | |
802 } | |
803 | |
804 static void Color24DitherYUY2Mod2X( int *colortab, Uint32 *rgb_2_pix, | |
805 unsigned char *lum, unsigned char *cr, | |
806 unsigned char *cb, unsigned char *out, | |
807 int rows, int cols, int mod ) | |
808 { | |
809 unsigned int value; | |
810 unsigned char* row = out; | |
811 const int next_row = (cols*2 + mod) * 3; | |
812 int x, y; | |
813 int cr_r; | |
814 int crb_g; | |
815 int cb_b; | |
816 int cols_2 = cols / 2; | |
817 y = rows; | |
818 while( y-- ) | |
819 { | |
820 x = cols_2; | |
821 while( x-- ) | |
822 { | |
823 register int L; | |
824 | |
825 cr_r = 0*768+256 + colortab[ *cr + 0*256 ]; | |
826 crb_g = 1*768+256 + colortab[ *cr + 1*256 ] | |
827 + colortab[ *cb + 2*256 ]; | |
828 cb_b = 2*768+256 + colortab[ *cb + 3*256 ]; | |
829 cr += 4; cb += 4; | |
830 | |
831 L = *lum; lum += 2; | |
832 value = (rgb_2_pix[ L + cr_r ] | | |
833 rgb_2_pix[ L + crb_g ] | | |
834 rgb_2_pix[ L + cb_b ]); | |
835 row[0+0] = row[3+0] = row[next_row+0] = row[next_row+3+0] = | |
836 (value ) & 0xFF; | |
837 row[0+1] = row[3+1] = row[next_row+1] = row[next_row+3+1] = | |
838 (value >> 8) & 0xFF; | |
839 row[0+2] = row[3+2] = row[next_row+2] = row[next_row+3+2] = | |
840 (value >> 16) & 0xFF; | |
841 row += 2*3; | |
842 | |
843 L = *lum; lum += 2; | |
844 value = (rgb_2_pix[ L + cr_r ] | | |
845 rgb_2_pix[ L + crb_g ] | | |
846 rgb_2_pix[ L + cb_b ]); | |
847 row[0+0] = row[3+0] = row[next_row+0] = row[next_row+3+0] = | |
848 (value ) & 0xFF; | |
849 row[0+1] = row[3+1] = row[next_row+1] = row[next_row+3+1] = | |
850 (value >> 8) & 0xFF; | |
851 row[0+2] = row[3+2] = row[next_row+2] = row[next_row+3+2] = | |
852 (value >> 16) & 0xFF; | |
853 row += 2*3; | |
854 | |
855 } | |
856 row += next_row; | |
857 } | |
858 } | |
859 | |
860 static void Color32DitherYUY2Mod2X( int *colortab, Uint32 *rgb_2_pix, | |
861 unsigned char *lum, unsigned char *cr, | |
862 unsigned char *cb, unsigned char *out, | |
863 int rows, int cols, int mod ) | |
864 { | |
865 unsigned int* row = (unsigned int*) out; | |
866 const int next_row = cols*2+mod; | |
867 int x, y; | |
868 int cr_r; | |
869 int crb_g; | |
870 int cb_b; | |
871 int cols_2 = cols / 2; | |
872 mod+=mod; | |
873 y = rows; | |
874 while( y-- ) | |
875 { | |
876 x = cols_2; | |
877 while( x-- ) | |
878 { | |
879 register int L; | |
880 | |
881 cr_r = 0*768+256 + colortab[ *cr + 0*256 ]; | |
882 crb_g = 1*768+256 + colortab[ *cr + 1*256 ] | |
883 + colortab[ *cb + 2*256 ]; | |
884 cb_b = 2*768+256 + colortab[ *cb + 3*256 ]; | |
885 cr += 4; cb += 4; | |
886 | |
887 L = *lum; lum += 2; | |
888 row[0] = row[1] = row[next_row] = row[next_row+1] = | |
889 (rgb_2_pix[ L + cr_r ] | | |
890 rgb_2_pix[ L + crb_g ] | | |
891 rgb_2_pix[ L + cb_b ]); | |
892 row += 2; | |
893 | |
894 L = *lum; lum += 2; | |
895 row[0] = row[1] = row[next_row] = row[next_row+1] = | |
896 (rgb_2_pix[ L + cr_r ] | | |
897 rgb_2_pix[ L + crb_g ] | | |
898 rgb_2_pix[ L + cb_b ]); | |
899 row += 2; | |
900 | |
901 | |
902 } | |
903 | |
904 row += next_row; | |
905 } | |
906 } | |
907 | |
908 /* | |
909 * How many 1 bits are there in the Uint32. | |
910 * Low performance, do not call often. | |
911 */ | |
912 static int number_of_bits_set( Uint32 a ) | |
913 { | |
914 if(!a) return 0; | |
915 if(a & 1) return 1 + number_of_bits_set(a >> 1); | |
916 return(number_of_bits_set(a >> 1)); | |
917 } | |
918 | |
919 /* | |
920 * How many 0 bits are there at least significant end of Uint32. | |
921 * Low performance, do not call often. | |
922 */ | |
923 static int free_bits_at_bottom( Uint32 a ) | |
924 { | |
925 /* assume char is 8 bits */ | |
926 if(!a) return sizeof(Uint32) * 8; | |
927 if(((Sint32)a) & 1l) return 0; | |
928 return 1 + free_bits_at_bottom ( a >> 1); | |
929 } | |
930 | |
931 | |
932 SDL_Overlay *SDL_CreateYUV_SW(_THIS, int width, int height, Uint32 format, SDL_Surface *display) | |
933 { | |
934 SDL_Overlay *overlay; | |
935 struct private_yuvhwdata *swdata; | |
936 int *Cr_r_tab; | |
937 int *Cr_g_tab; | |
938 int *Cb_g_tab; | |
939 int *Cb_b_tab; | |
940 Uint32 *r_2_pix_alloc; | |
941 Uint32 *g_2_pix_alloc; | |
942 Uint32 *b_2_pix_alloc; | |
739
22dbf364c017
Added SDL_HasMMX(), SDL_Has3DNow(), SDL_HasSSE() in SDL_cpuinfo.h
Sam Lantinga <slouken@libsdl.org>
parents:
366
diff
changeset
|
943 int i; |
0 | 944 int CR, CB; |
945 Uint32 Rmask, Gmask, Bmask; | |
946 | |
947 /* Only RGB packed pixel conversion supported */ | |
948 if ( (display->format->BytesPerPixel != 2) && | |
949 (display->format->BytesPerPixel != 3) && | |
950 (display->format->BytesPerPixel != 4) ) { | |
951 SDL_SetError("Can't use YUV data on non 16/24/32 bit surfaces"); | |
952 return(NULL); | |
953 } | |
954 | |
955 /* Verify that we support the format */ | |
956 switch (format) { | |
957 case SDL_YV12_OVERLAY: | |
958 case SDL_IYUV_OVERLAY: | |
959 case SDL_YUY2_OVERLAY: | |
960 case SDL_UYVY_OVERLAY: | |
961 case SDL_YVYU_OVERLAY: | |
962 break; | |
963 default: | |
964 SDL_SetError("Unsupported YUV format"); | |
965 return(NULL); | |
966 } | |
967 | |
968 /* Create the overlay structure */ | |
969 overlay = (SDL_Overlay *)malloc(sizeof *overlay); | |
970 if ( overlay == NULL ) { | |
971 SDL_OutOfMemory(); | |
972 return(NULL); | |
973 } | |
974 memset(overlay, 0, (sizeof *overlay)); | |
975 | |
976 /* Fill in the basic members */ | |
977 overlay->format = format; | |
978 overlay->w = width; | |
979 overlay->h = height; | |
980 | |
981 /* Set up the YUV surface function structure */ | |
982 overlay->hwfuncs = &sw_yuvfuncs; | |
983 | |
984 /* Create the pixel data and lookup tables */ | |
985 swdata = (struct private_yuvhwdata *)malloc(sizeof *swdata); | |
986 overlay->hwdata = swdata; | |
987 if ( swdata == NULL ) { | |
988 SDL_OutOfMemory(); | |
989 SDL_FreeYUVOverlay(overlay); | |
990 return(NULL); | |
991 } | |
992 swdata->stretch = NULL; | |
993 swdata->display = display; | |
994 swdata->pixels = (Uint8 *) malloc(width*height*2); | |
995 swdata->colortab = (int *)malloc(4*256*sizeof(int)); | |
996 Cr_r_tab = &swdata->colortab[0*256]; | |
997 Cr_g_tab = &swdata->colortab[1*256]; | |
998 Cb_g_tab = &swdata->colortab[2*256]; | |
999 Cb_b_tab = &swdata->colortab[3*256]; | |
1000 swdata->rgb_2_pix = (Uint32 *)malloc(3*768*sizeof(Uint32)); | |
1001 r_2_pix_alloc = &swdata->rgb_2_pix[0*768]; | |
1002 g_2_pix_alloc = &swdata->rgb_2_pix[1*768]; | |
1003 b_2_pix_alloc = &swdata->rgb_2_pix[2*768]; | |
1004 if ( ! swdata->pixels || ! swdata->colortab || ! swdata->rgb_2_pix ) { | |
1005 SDL_OutOfMemory(); | |
1006 SDL_FreeYUVOverlay(overlay); | |
1007 return(NULL); | |
1008 } | |
1009 | |
1010 /* Generate the tables for the display surface */ | |
1011 for (i=0; i<256; i++) { | |
1012 /* Gamma correction (luminescence table) and chroma correction | |
1013 would be done here. See the Berkeley mpeg_play sources. | |
1014 */ | |
1015 CB = CR = (i-128); | |
1016 Cr_r_tab[i] = (int) ( (0.419/0.299) * CR); | |
1017 Cr_g_tab[i] = (int) (-(0.299/0.419) * CR); | |
1018 Cb_g_tab[i] = (int) (-(0.114/0.331) * CB); | |
1019 Cb_b_tab[i] = (int) ( (0.587/0.331) * CB); | |
1020 } | |
1021 | |
1022 /* | |
1023 * Set up entries 0-255 in rgb-to-pixel value tables. | |
1024 */ | |
1025 Rmask = display->format->Rmask; | |
1026 Gmask = display->format->Gmask; | |
1027 Bmask = display->format->Bmask; | |
1028 for ( i=0; i<256; ++i ) { | |
1029 r_2_pix_alloc[i+256] = i >> (8 - number_of_bits_set(Rmask)); | |
1030 r_2_pix_alloc[i+256] <<= free_bits_at_bottom(Rmask); | |
1031 g_2_pix_alloc[i+256] = i >> (8 - number_of_bits_set(Gmask)); | |
1032 g_2_pix_alloc[i+256] <<= free_bits_at_bottom(Gmask); | |
1033 b_2_pix_alloc[i+256] = i >> (8 - number_of_bits_set(Bmask)); | |
1034 b_2_pix_alloc[i+256] <<= free_bits_at_bottom(Bmask); | |
1035 } | |
1036 | |
1037 /* | |
1038 * If we have 16-bit output depth, then we double the value | |
1039 * in the top word. This means that we can write out both | |
1040 * pixels in the pixel doubling mode with one op. It is | |
1041 * harmless in the normal case as storing a 32-bit value | |
1042 * through a short pointer will lose the top bits anyway. | |
1043 */ | |
1044 if( display->format->BytesPerPixel == 2 ) { | |
1045 for ( i=0; i<256; ++i ) { | |
1046 r_2_pix_alloc[i+256] |= (r_2_pix_alloc[i+256]) << 16; | |
1047 g_2_pix_alloc[i+256] |= (g_2_pix_alloc[i+256]) << 16; | |
1048 b_2_pix_alloc[i+256] |= (b_2_pix_alloc[i+256]) << 16; | |
1049 } | |
1050 } | |
1051 | |
1052 /* | |
1053 * Spread out the values we have to the rest of the array so that | |
1054 * we do not need to check for overflow. | |
1055 */ | |
1056 for ( i=0; i<256; ++i ) { | |
1057 r_2_pix_alloc[i] = r_2_pix_alloc[256]; | |
1058 r_2_pix_alloc[i+512] = r_2_pix_alloc[511]; | |
1059 g_2_pix_alloc[i] = g_2_pix_alloc[256]; | |
1060 g_2_pix_alloc[i+512] = g_2_pix_alloc[511]; | |
1061 b_2_pix_alloc[i] = b_2_pix_alloc[256]; | |
1062 b_2_pix_alloc[i+512] = b_2_pix_alloc[511]; | |
1063 } | |
1064 | |
1065 /* You have chosen wisely... */ | |
1066 switch (format) { | |
1067 case SDL_YV12_OVERLAY: | |
1068 case SDL_IYUV_OVERLAY: | |
1069 if ( display->format->BytesPerPixel == 2 ) { | |
1070 #if defined(i386) && defined(__GNUC__) && defined(USE_ASMBLIT) | |
1071 /* inline assembly functions */ | |
739
22dbf364c017
Added SDL_HasMMX(), SDL_Has3DNow(), SDL_HasSSE() in SDL_cpuinfo.h
Sam Lantinga <slouken@libsdl.org>
parents:
366
diff
changeset
|
1072 if ( SDL_HasMMX() && (Rmask == 0xF800) && |
22dbf364c017
Added SDL_HasMMX(), SDL_Has3DNow(), SDL_HasSSE() in SDL_cpuinfo.h
Sam Lantinga <slouken@libsdl.org>
parents:
366
diff
changeset
|
1073 (Gmask == 0x07E0) && |
22dbf364c017
Added SDL_HasMMX(), SDL_Has3DNow(), SDL_HasSSE() in SDL_cpuinfo.h
Sam Lantinga <slouken@libsdl.org>
parents:
366
diff
changeset
|
1074 (Bmask == 0x001F) && |
22dbf364c017
Added SDL_HasMMX(), SDL_Has3DNow(), SDL_HasSSE() in SDL_cpuinfo.h
Sam Lantinga <slouken@libsdl.org>
parents:
366
diff
changeset
|
1075 (width & 15) == 0) { |
0 | 1076 /*printf("Using MMX 16-bit 565 dither\n");*/ |
1077 swdata->Display1X = Color565DitherYV12MMX1X; | |
1078 } else { | |
1079 /*printf("Using C 16-bit dither\n");*/ | |
1080 swdata->Display1X = Color16DitherYV12Mod1X; | |
1081 } | |
1082 #else | |
1083 swdata->Display1X = Color16DitherYV12Mod1X; | |
1084 #endif | |
1085 swdata->Display2X = Color16DitherYV12Mod2X; | |
1086 } | |
1087 if ( display->format->BytesPerPixel == 3 ) { | |
1088 swdata->Display1X = Color24DitherYV12Mod1X; | |
1089 swdata->Display2X = Color24DitherYV12Mod2X; | |
1090 } | |
1091 if ( display->format->BytesPerPixel == 4 ) { | |
1092 #if defined(i386) && defined(__GNUC__) && defined(USE_ASMBLIT) | |
1093 /* inline assembly functions */ | |
739
22dbf364c017
Added SDL_HasMMX(), SDL_Has3DNow(), SDL_HasSSE() in SDL_cpuinfo.h
Sam Lantinga <slouken@libsdl.org>
parents:
366
diff
changeset
|
1094 if ( SDL_HasMMX() && (Rmask == 0x00FF0000) && |
22dbf364c017
Added SDL_HasMMX(), SDL_Has3DNow(), SDL_HasSSE() in SDL_cpuinfo.h
Sam Lantinga <slouken@libsdl.org>
parents:
366
diff
changeset
|
1095 (Gmask == 0x0000FF00) && |
22dbf364c017
Added SDL_HasMMX(), SDL_Has3DNow(), SDL_HasSSE() in SDL_cpuinfo.h
Sam Lantinga <slouken@libsdl.org>
parents:
366
diff
changeset
|
1096 (Bmask == 0x000000FF) && |
22dbf364c017
Added SDL_HasMMX(), SDL_Has3DNow(), SDL_HasSSE() in SDL_cpuinfo.h
Sam Lantinga <slouken@libsdl.org>
parents:
366
diff
changeset
|
1097 (width & 15) == 0) { |
0 | 1098 /*printf("Using MMX 32-bit dither\n");*/ |
1099 swdata->Display1X = ColorRGBDitherYV12MMX1X; | |
1100 } else { | |
1101 /*printf("Using C 32-bit dither\n");*/ | |
1102 swdata->Display1X = Color32DitherYV12Mod1X; | |
1103 } | |
1104 #else | |
1105 swdata->Display1X = Color32DitherYV12Mod1X; | |
1106 #endif | |
1107 swdata->Display2X = Color32DitherYV12Mod2X; | |
1108 } | |
1109 break; | |
1110 case SDL_YUY2_OVERLAY: | |
1111 case SDL_UYVY_OVERLAY: | |
1112 case SDL_YVYU_OVERLAY: | |
1113 if ( display->format->BytesPerPixel == 2 ) { | |
1114 swdata->Display1X = Color16DitherYUY2Mod1X; | |
1115 swdata->Display2X = Color16DitherYUY2Mod2X; | |
1116 } | |
1117 if ( display->format->BytesPerPixel == 3 ) { | |
1118 swdata->Display1X = Color24DitherYUY2Mod1X; | |
1119 swdata->Display2X = Color24DitherYUY2Mod2X; | |
1120 } | |
1121 if ( display->format->BytesPerPixel == 4 ) { | |
1122 swdata->Display1X = Color32DitherYUY2Mod1X; | |
1123 swdata->Display2X = Color32DitherYUY2Mod2X; | |
1124 } | |
1125 break; | |
1126 default: | |
1127 /* We should never get here (caught above) */ | |
1128 break; | |
1129 } | |
1130 | |
1131 /* Find the pitch and offset values for the overlay */ | |
1132 overlay->pitches = swdata->pitches; | |
1133 overlay->pixels = swdata->planes; | |
1134 switch (format) { | |
1135 case SDL_YV12_OVERLAY: | |
1136 case SDL_IYUV_OVERLAY: | |
1137 overlay->pitches[0] = overlay->w; | |
1138 overlay->pitches[1] = overlay->pitches[0] / 2; | |
1139 overlay->pitches[2] = overlay->pitches[0] / 2; | |
1140 overlay->pixels[0] = swdata->pixels; | |
1141 overlay->pixels[1] = overlay->pixels[0] + | |
1142 overlay->pitches[0] * overlay->h; | |
1143 overlay->pixels[2] = overlay->pixels[1] + | |
1144 overlay->pitches[1] * overlay->h / 2; | |
1145 overlay->planes = 3; | |
1146 break; | |
1147 case SDL_YUY2_OVERLAY: | |
1148 case SDL_UYVY_OVERLAY: | |
1149 case SDL_YVYU_OVERLAY: | |
1150 overlay->pitches[0] = overlay->w*2; | |
1151 overlay->pixels[0] = swdata->pixels; | |
1152 overlay->planes = 1; | |
1153 break; | |
1154 default: | |
1155 /* We should never get here (caught above) */ | |
1156 break; | |
1157 } | |
1158 | |
1159 /* We're all done.. */ | |
1160 return(overlay); | |
1161 } | |
1162 | |
1163 int SDL_LockYUV_SW(_THIS, SDL_Overlay *overlay) | |
1164 { | |
1165 return(0); | |
1166 } | |
1167 | |
1168 void SDL_UnlockYUV_SW(_THIS, SDL_Overlay *overlay) | |
1169 { | |
1170 return; | |
1171 } | |
1172 | |
1173 int SDL_DisplayYUV_SW(_THIS, SDL_Overlay *overlay, SDL_Rect *dstrect) | |
1174 { | |
1175 struct private_yuvhwdata *swdata; | |
1176 SDL_Surface *stretch; | |
1177 SDL_Surface *display; | |
1178 int scale_2x; | |
1179 Uint8 *lum, *Cr, *Cb; | |
1180 Uint8 *dst; | |
1181 int mod; | |
1182 | |
1183 swdata = overlay->hwdata; | |
1184 scale_2x = 0; | |
1185 stretch = 0; | |
1186 if ( (overlay->w != dstrect->w) || (overlay->h != dstrect->h) ) { | |
1187 if ( (dstrect->w == 2*overlay->w) && | |
1188 (dstrect->h == 2*overlay->h) ) { | |
1189 scale_2x = 1; | |
1190 } else { | |
1191 if ( ! swdata->stretch ) { | |
1192 display = swdata->display; | |
1193 swdata->stretch = SDL_CreateRGBSurface( | |
1194 SDL_SWSURFACE, | |
1195 overlay->w, overlay->h, | |
1196 display->format->BitsPerPixel, | |
1197 display->format->Rmask, | |
1198 display->format->Gmask, | |
1199 display->format->Bmask, 0); | |
1200 if ( ! swdata->stretch ) { | |
1201 return(-1); | |
1202 } | |
1203 } | |
1204 stretch = swdata->stretch; | |
1205 } | |
1206 } | |
1207 | |
1208 if ( stretch ) { | |
1209 display = stretch; | |
1210 } else { | |
1211 display = swdata->display; | |
1212 } | |
1213 switch (overlay->format) { | |
1214 case SDL_YV12_OVERLAY: | |
1215 lum = overlay->pixels[0]; | |
1216 Cr = overlay->pixels[1]; | |
1217 Cb = overlay->pixels[2]; | |
1218 break; | |
1219 case SDL_IYUV_OVERLAY: | |
1220 lum = overlay->pixels[0]; | |
1221 Cr = overlay->pixels[2]; | |
1222 Cb = overlay->pixels[1]; | |
1223 break; | |
1224 case SDL_YUY2_OVERLAY: | |
1225 lum = overlay->pixels[0]; | |
1226 Cr = lum + 3; | |
1227 Cb = lum + 1; | |
1228 break; | |
1229 case SDL_UYVY_OVERLAY: | |
1230 lum = overlay->pixels[0]+1; | |
1231 Cr = lum + 1; | |
1232 Cb = lum - 1; | |
1233 break; | |
1234 case SDL_YVYU_OVERLAY: | |
1235 lum = overlay->pixels[0]; | |
1236 Cr = lum + 1; | |
1237 Cb = lum + 3; | |
1238 break; | |
1239 default: | |
292
eadc0746dfaf
Added SDL_LockRect() and SDL_UnlockRect()
Sam Lantinga <slouken@libsdl.org>
parents:
252
diff
changeset
|
1240 SDL_SetError("Unsupported YUV format in blit"); |
0 | 1241 return(-1); |
1242 } | |
1243 if ( SDL_MUSTLOCK(display) ) { | |
1244 if ( SDL_LockSurface(display) < 0 ) { | |
1245 return(-1); | |
1246 } | |
1247 } | |
1248 if ( stretch ) { | |
1249 dst = (Uint8 *)stretch->pixels; | |
1250 } else { | |
1251 dst = (Uint8 *)display->pixels | |
1252 + dstrect->x * display->format->BytesPerPixel | |
1253 + dstrect->y * display->pitch; | |
1254 } | |
1255 mod = (display->pitch / display->format->BytesPerPixel); | |
1256 | |
1257 if ( scale_2x ) { | |
1258 mod -= (overlay->w * 2); | |
1259 swdata->Display2X(swdata->colortab, swdata->rgb_2_pix, | |
1260 lum, Cr, Cb, dst, overlay->h, overlay->w,mod); | |
1261 } else { | |
1262 mod -= overlay->w; | |
1263 swdata->Display1X(swdata->colortab, swdata->rgb_2_pix, | |
1264 lum, Cr, Cb, dst, overlay->h, overlay->w,mod); | |
1265 } | |
1266 if ( SDL_MUSTLOCK(display) ) { | |
1267 SDL_UnlockSurface(display); | |
1268 } | |
1269 if ( stretch ) { | |
1270 display = swdata->display; | |
1271 SDL_SoftStretch(stretch, NULL, display, dstrect); | |
1272 } | |
1273 SDL_UpdateRects(display, 1, dstrect); | |
1274 | |
1275 return(0); | |
1276 } | |
1277 | |
1278 void SDL_FreeYUV_SW(_THIS, SDL_Overlay *overlay) | |
1279 { | |
1280 struct private_yuvhwdata *swdata; | |
1281 | |
1282 swdata = overlay->hwdata; | |
1283 if ( swdata ) { | |
9
a1c15fa4abb9
Fixed memory leak in software YUV stretch code
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
1284 if ( swdata->stretch ) { |
a1c15fa4abb9
Fixed memory leak in software YUV stretch code
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
1285 SDL_FreeSurface(swdata->stretch); |
a1c15fa4abb9
Fixed memory leak in software YUV stretch code
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
1286 } |
0 | 1287 if ( swdata->pixels ) { |
1288 free(swdata->pixels); | |
1289 } | |
1290 if ( swdata->colortab ) { | |
1291 free(swdata->colortab); | |
1292 } | |
1293 if ( swdata->rgb_2_pix ) { | |
1294 free(swdata->rgb_2_pix); | |
1295 } | |
1296 free(swdata); | |
1297 } | |
1298 } |