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