zenilib: zenilib/jni/external/sdl/src/render/SDL_yuv_sw.c Source File

zenilib 0.5.3.0

- Main Page
- Modules
- Namespaces
- Classes
- Files

- File List
- File Members

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