Mercurial > sdl-ios-xcode
annotate src/video/SDL_yuv_sw.c @ 4157:baf615f9f2a0 SDL-1.2
Date: Thu, 16 Oct 2008 20:27:34 +0400
From: "Ilya Kasnacheev" <ilya.kasnacheev@gmail.com>
To: sdl@lists.libsdl.org
Subject: [SDL] SDL for Windows CE: a few GAPI patches
Hi *!
I've just ported a POWDER roguelike ( http://www.zincland.com/powder/ ) to
Windows CE (PDAs, Windows Mobile/Pocket PC). To do that, I had to get libsdl
working. Thanks for the awesome project files, it built without a hitch.
Nevertheless, I've found quite a few bugs in Windows CE (GAPI) SDL
implementation, which I've solved and now present as a serie of patches.
I'll try carefully annotate them. Please annotate them so I can work
toward accepting
them into the main source tree since without them SDL isn't really working on
Windows CE (I wonder why nobody fixed them before, btw: why isn't SDL popular as
a way to develop Windows CE games? Where are no ports?)
These changes can't be considered flawless, but they can be considered working
because I've yet to hear complains about things I fixed and POWDER build for
Windows CE is now considered stable.
Note: my comments start with !!, delete them before applying.
diff -bru SDL-1.2.13/src/video/gapi/SDL_gapivideo.c
SDL-1.2.13-new/src/video/gapi/SDL_gapivideo.c
--- SDL-1.2.13/src/video/gapi/SDL_gapivideo.c 2007-12-31
07:48:00.000000000 +0300
+++ SDL-1.2.13-new/src/video/gapi/SDL_gapivideo.c 2008-10-16
20:02:11.000000000 +0400
@@ -643,6 +643,7 @@
}
gapi->userOrientation = SDL_ORIENTATION_UP;
+ gapi->systemOrientation = SDL_ORIENTATION_UP;
video->flags = SDL_FULLSCREEN; /* Clear flags, GAPI supports
fullscreen only */
/* GAPI or VGA? */
@@ -661,18 +662,21 @@
}
/* detect user landscape mode */
- if( (width > height) && (GetSystemMetrics(SM_CXSCREEN) <
GetSystemMetrics(SM_CYSCREEN)))
+ if( (width > height) && (gapi->gxProperties.cxWidth <
gapi->gxProperties.cyHeight))
gapi->userOrientation = SDL_ORIENTATION_RIGHT;
+ if(GetSystemMetrics(SM_CYSCREEN) < GetSystemMetrics(SM_CXSCREEN))
+ gapi->systemOrientation = SDL_ORIENTATION_RIGHT;
+
/* shall we apply hires fix? for example when we do not use
hires resource */
gapi->hiresFix = 0;
- if( gapi->userOrientation == SDL_ORIENTATION_RIGHT )
+ if( gapi->systemOrientation == gapi->userOrientation )
{
- if( (width > GetSystemMetrics(SM_CYSCREEN)) || (height
> GetSystemMetrics(SM_CXSCREEN)))
+ if( (width > GetSystemMetrics(SM_CXSCREEN)) || (height
> GetSystemMetrics(SM_CYSCREEN)))
gapi->hiresFix = 1;
} else
- if( (width > GetSystemMetrics(SM_CXSCREEN)) || (height
> GetSystemMetrics(SM_CYSCREEN)))
- if( !((width == GetSystemMetrics(SM_CYSCREEN))
&& (height == GetSystemMetrics(SM_CXSCREEN)))) // user portrait,
device landscape
+ if( (width > GetSystemMetrics(SM_CYSCREEN)) || (height
> GetSystemMetrics(SM_CXSCREEN)))
+// if( !((width == gapi->gxProperties.cyHeight)
&& (height == gapi->gxProperties.cxWidth))) // user portrait, device
landscape
gapi->hiresFix = 1;
switch( gapi->userOrientation )
!! It used to query system metrics which return dimensions according to screen
!! orientation, which can really be portrait, left landscape or right landscape.
!! This is presumably incorrect because we couldn't care less about user mode
!! dimensions - all we want are the GAPI framebuffer dimensions, which
only match
!! user dimensions in one of possible orientations.
!! There's a fair dose of cargo cult programming involved in this fix, but it
!! used to work only in one orientation (portrait for PDAs, where frame-buffer
!! have same orientation as user screen), and now it works on all orientations.
@@ -742,21 +746,30 @@
WIN_FlushMessageQueue();
/* Open GAPI display */
- if( !gapi->useVga && this->hidden->useGXOpenDisplay )
+ if( !gapi->useVga && this->hidden->useGXOpenDisplay &&
!this->hidden->alreadyGXOpened )
+ {
+ this->hidden->alreadyGXOpened = 1;
if( !gapi->gxFunc.GXOpenDisplay(SDL_Window, GX_FULLSCREEN) )
{
SDL_SetError("Couldn't initialize GAPI");
return(NULL);
}
+ }
#if REPORT_VIDEO_INFO
printf("Video properties:\n");
printf("display bpp: %d\n", gapi->gxProperties.cBPP);
printf("display width: %d\n", gapi->gxProperties.cxWidth);
printf("display height: %d\n", gapi->gxProperties.cyHeight);
+ printf("system display width: %d\n", GetSystemMetrics(SM_CXSCREEN));
+ printf("system display height: %d\n", GetSystemMetrics(SM_CYSCREEN));
printf("x pitch: %d\n", gapi->gxProperties.cbxPitch);
printf("y pitch: %d\n", gapi->gxProperties.cbyPitch);
printf("gapi flags: 0x%x\n", gapi->gxProperties.ffFormat);
+ printf("user orientation: %d\n", gapi->userOrientation);
+ printf("system orientation: %d\n", gapi->userOrientation);
+ printf("gapi orientation: %d\n", gapi->gapiOrientation);
+
if( !gapi->useVga && this->hidden->useGXOpenDisplay && gapi->needUpdate)
{
!! Previous version used to call gapi->gxFunc.GXOpenDisplay each time the video
!! mode would be changed. You shouldn't, because this call has a
meaning "Lock the
!! GAPI framebuffer, designate it as busy", so the second call will fail (it is
!! already locked/busy).
!! Testing might not find that because most programs set up the video mode only
!! once, but POWDER does this once in a while, so it crashed when in
320x240 mode
!! (640x480 mode doesn't use that code, it worked fine).
diff -bru SDL-1.2.13/src/video/gapi/SDL_gapivideo.h
SDL-1.2.13-new/src/video/gapi/SDL_gapivideo.h
--- SDL-1.2.13/src/video/gapi/SDL_gapivideo.h 2007-12-31
07:48:00.000000000 +0300
+++ SDL-1.2.13-new/src/video/gapi/SDL_gapivideo.h 2008-10-16
20:02:11.000000000 +0400
@@ -132,12 +132,17 @@
#define NUM_MODELISTS 4 /* 8, 16, 24, and 32 bits-per-pixel */
int SDL_nummodes[NUM_MODELISTS];
SDL_Rect **SDL_modelist[NUM_MODELISTS];
+ // The orientation of the video mode user wants to get
+ // Probably restricted to UP and RIGHT
enum SDL_ScreenOrientation userOrientation;
int invert;
char hiresFix; // using hires mode without defining hires resource
// --------------
int useGXOpenDisplay; /* use GXOpenDispplay */
+ int alreadyGXOpened;
int w, h;
+ // The orientation of GAPI framebuffer.
+ // Never changes on the same device.
enum SDL_ScreenOrientation gapiOrientation;
void *buffer; // may be 8, 16, 24, 32 bpp
@@ -153,6 +158,10 @@
int startOffset; // in bytes
int useVga;
int suspended; // do not pu anything into video memory
+ // The orientation of the system, as defined by SM_CXSCREEN
and SM_CYSCREEN
+ // User can change it by using 'screen layout' in system options
+ // Restricted to UP or RIGHT
+ enum SDL_ScreenOrientation systemOrientation;
};
!! This is a flag variable, see the previous comment
!! And yet another orientation: now we have to keep three of them in mind.
diff -bru SDL-1.2.13/src/video/wincommon/SDL_sysevents.c
SDL-1.2.13-new/src/video/wincommon/SDL_sysevents.c
--- SDL-1.2.13/src/video/wincommon/SDL_sysevents.c 2007-12-31
07:48:02.000000000 +0300
+++ SDL-1.2.13-new/src/video/wincommon/SDL_sysevents.c 2008-10-16
20:02:12.000000000 +0400
@@ -160,10 +160,22 @@
#endif */
}
break;
+ // FIXME: Older version used just SDL_VideoSurface->(w, h)
+ // w and h are "clipped" while x and y are "raw", which caused
+ // x in former and y in latter case to be clipped in a
wrong direction,
+ // thus offsetting the coordinate on 2 x clip pixels
+ // (like, 128 for 640 -> 512 clipping).
+ // We will now try to extract and use raw values.
+ // The way to do that RIGHT is do
(orientation-dependent) clipping before
+ // doing this transform, but it's hardly possible.
+
+ // SEE SDL_mouse.c /ClipOffset to understand these calculations.
case SDL_ORIENTATION_RIGHT:
if (!SDL_VideoSurface)
break;
- rotatedX = SDL_VideoSurface->w - *y;
+ rotatedX = (2 *
((SDL_VideoSurface->offset%SDL_VideoSurface->pitch)/
+ SDL_VideoSurface->format->BytesPerPixel))
+ + SDL_VideoSurface->w - *y;
rotatedY = *x;
*x = rotatedX;
*y = rotatedY;
@@ -172,7 +184,8 @@
if (!SDL_VideoSurface)
break;
rotatedX = *y;
- rotatedY = SDL_VideoSurface->h - *x;
+ rotatedY = (2 *
(SDL_VideoSurface->offset/SDL_VideoSurface->pitch))
+ + SDL_VideoSurface->h - *x;
*x = rotatedX;
*y = rotatedY;
break;
!! That's the trickest part, hence the long comment.
!! GAPI would really support only 320x240 or 640x480 mode, if application
!! requested the different screen size (as POWDER did, wishing
256x192), then SDL
!! is going to grab the first mode that fits the requested, and pad the screen
!! with black bars (as they do with wide-screen films).
!! It would also get, say, 240x320 mode, and to turn it into 256x192 it would
!! need to rotate mouse clicks.
!! It worked, but one bug slipped through: it would receive mouse clicks
!! unpadded, then rotate them, and then pad the black bars. The
problem is: rotate
!! is done by GAPI driver while padding is done by SDL core. SDL core
doesn't know
!! anything about rotating, so it would pad one of dimensions incorrectly.
I understand that some of my claims (or code) might seem unbacked, but you can
always grab the POWDER binary, compile your own libsdl with one or more of
those fixes turned off, and see how weird it would misbehave. I can even supply
you with those custom builds of libsdl if you don't want to set up the build
environment for windows ce, you'll just need a PDA or a smartphone with it.
I plan to take care of SDL on Windows CE as long as I maintain the POWDER port.
POWDER is good for that because it:
Employs both padded (with centered image, black bars) and unpadded
(image occupies full screen) graphics; initializes video more than
once; uses both 320x240 and 640x480 video; uses both stylus and
buttons.
There's still a list of unresolved issues which I'm planning to fix:
1) Arrow buttons on PDA return weird scancodes compared to PC, this
caused the game to misbehave before I've fixed that. You can see it on
those diagrams:
http://wrar.name/upload/powder-htc.png
http://wrar.name/upload/powder-pda.png
2) SDL (or underlying windows) doesn't care to rotate arrow presses
when we're in a low-res GAPI mode, but it will rotate them in VGA mode
(because of different screen orientations, the same arrow buttons can
suddently mean different directions). Solution: we should stick to
GAPI user orientation (the orientation the program supposedly wants)
and rotate the keys on our own.
_______________________________________________
SDL mailing list
SDL@lists.libsdl.org
http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org
author | Sam Lantinga <slouken@libsdl.org> |
---|---|
date | Fri, 07 Nov 2008 04:15:36 +0000 |
parents | 940fddb81bea |
children | 96ce26f24b01 |
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 */ |
1402
d910939febfa
Use consistent identifiers for the various platforms we support.
Sam Lantinga <slouken@libsdl.org>
parents:
1361
diff
changeset
|
22 #include "SDL_config.h" |
0 | 23 |
24 /* This is the software implementation of the YUV video overlay support */ | |
25 | |
26 /* This code was derived from code carrying the following copyright notices: | |
27 | |
28 * Copyright (c) 1995 The Regents of the University of California. | |
29 * All rights reserved. | |
30 * | |
31 * Permission to use, copy, modify, and distribute this software and its | |
32 * documentation for any purpose, without fee, and without written agreement is | |
33 * hereby granted, provided that the above copyright notice and the following | |
34 * two paragraphs appear in all copies of this software. | |
35 * | |
36 * IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR | |
37 * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT | |
38 * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE UNIVERSITY OF | |
39 * CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |
40 * | |
41 * THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES, | |
42 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY | |
43 * AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS | |
44 * ON AN "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATION TO | |
45 * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. | |
46 | |
47 * Copyright (c) 1995 Erik Corry | |
48 * All rights reserved. | |
49 * | |
50 * Permission to use, copy, modify, and distribute this software and its | |
51 * documentation for any purpose, without fee, and without written agreement is | |
52 * hereby granted, provided that the above copyright notice and the following | |
53 * two paragraphs appear in all copies of this software. | |
54 * | |
55 * IN NO EVENT SHALL ERIK CORRY BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, | |
56 * SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OF | |
57 * THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF ERIK CORRY HAS BEEN ADVISED | |
58 * OF THE POSSIBILITY OF SUCH DAMAGE. | |
59 * | |
60 * ERIK CORRY SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT | |
61 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A | |
62 * PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" | |
63 * BASIS, AND ERIK CORRY HAS NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, | |
64 * UPDATES, ENHANCEMENTS, OR MODIFICATIONS. | |
65 | |
66 * Portions of this software Copyright (c) 1995 Brown University. | |
67 * All rights reserved. | |
68 * | |
69 * Permission to use, copy, modify, and distribute this software and its | |
70 * documentation for any purpose, without fee, and without written agreement | |
71 * is hereby granted, provided that the above copyright notice and the | |
72 * following two paragraphs appear in all copies of this software. | |
73 * | |
74 * IN NO EVENT SHALL BROWN UNIVERSITY BE LIABLE TO ANY PARTY FOR | |
75 * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT | |
76 * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF BROWN | |
77 * UNIVERSITY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |
78 * | |
79 * BROWN UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT | |
80 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A | |
81 * PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" | |
82 * BASIS, AND BROWN UNIVERSITY HAS NO OBLIGATION TO PROVIDE MAINTENANCE, | |
83 * SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. | |
84 */ | |
85 | |
86 #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
|
87 #include "SDL_cpuinfo.h" |
0 | 88 #include "SDL_stretch_c.h" |
89 #include "SDL_yuvfuncs.h" | |
90 #include "SDL_yuv_sw_c.h" | |
91 | |
92 /* The functions used to manipulate software video overlays */ | |
93 static struct private_yuvhwfuncs sw_yuvfuncs = { | |
94 SDL_LockYUV_SW, | |
95 SDL_UnlockYUV_SW, | |
96 SDL_DisplayYUV_SW, | |
97 SDL_FreeYUV_SW | |
98 }; | |
99 | |
100 /* RGB conversion lookup tables */ | |
101 struct private_yuvhwdata { | |
102 SDL_Surface *stretch; | |
103 SDL_Surface *display; | |
104 Uint8 *pixels; | |
105 int *colortab; | |
106 Uint32 *rgb_2_pix; | |
107 void (*Display1X)(int *colortab, Uint32 *rgb_2_pix, | |
108 unsigned char *lum, unsigned char *cr, | |
109 unsigned char *cb, unsigned char *out, | |
110 int rows, int cols, int mod ); | |
111 void (*Display2X)(int *colortab, Uint32 *rgb_2_pix, | |
112 unsigned char *lum, unsigned char *cr, | |
113 unsigned char *cb, unsigned char *out, | |
114 int rows, int cols, int mod ); | |
115 | |
116 /* These are just so we don't have to allocate them separately */ | |
117 Uint16 pitches[3]; | |
118 Uint8 *planes[3]; | |
119 }; | |
120 | |
121 | |
122 /* The colorspace conversion functions */ | |
123 | |
4064
940fddb81bea
Mac OS X/x86 won't build the MMX/YUV inline assembly without optimizations
Ryan C. Gordon <icculus@icculus.org>
parents:
4045
diff
changeset
|
124 #if (__GNUC__ > 2) && defined(__i386__) && __OPTIMIZE__ && SDL_ASSEMBLY_ROUTINES |
0 | 125 extern void Color565DitherYV12MMX1X( int *colortab, Uint32 *rgb_2_pix, |
126 unsigned char *lum, unsigned char *cr, | |
127 unsigned char *cb, unsigned char *out, | |
128 int rows, int cols, int mod ); | |
129 extern void ColorRGBDitherYV12MMX1X( int *colortab, Uint32 *rgb_2_pix, | |
130 unsigned char *lum, unsigned char *cr, | |
131 unsigned char *cb, unsigned char *out, | |
132 int rows, int cols, int mod ); | |
1413 | 133 #endif |
0 | 134 |
135 static void Color16DitherYV12Mod1X( int *colortab, Uint32 *rgb_2_pix, | |
136 unsigned char *lum, unsigned char *cr, | |
137 unsigned char *cb, unsigned char *out, | |
138 int rows, int cols, int mod ) | |
139 { | |
140 unsigned short* row1; | |
141 unsigned short* row2; | |
142 unsigned char* lum2; | |
143 int x, y; | |
144 int cr_r; | |
145 int crb_g; | |
146 int cb_b; | |
147 int cols_2 = cols / 2; | |
148 | |
149 row1 = (unsigned short*) out; | |
150 row2 = row1 + cols + mod; | |
151 lum2 = lum + cols; | |
152 | |
153 mod += cols + mod; | |
154 | |
155 y = rows / 2; | |
156 while( y-- ) | |
157 { | |
158 x = cols_2; | |
159 while( x-- ) | |
160 { | |
161 register int L; | |
162 | |
163 cr_r = 0*768+256 + colortab[ *cr + 0*256 ]; | |
164 crb_g = 1*768+256 + colortab[ *cr + 1*256 ] | |
165 + colortab[ *cb + 2*256 ]; | |
166 cb_b = 2*768+256 + colortab[ *cb + 3*256 ]; | |
167 ++cr; ++cb; | |
168 | |
169 L = *lum++; | |
1428
5f52867ba65c
Update for Visual C++ 6.0
Sam Lantinga <slouken@libsdl.org>
parents:
1413
diff
changeset
|
170 *row1++ = (unsigned short)(rgb_2_pix[ L + cr_r ] | |
5f52867ba65c
Update for Visual C++ 6.0
Sam Lantinga <slouken@libsdl.org>
parents:
1413
diff
changeset
|
171 rgb_2_pix[ L + crb_g ] | |
5f52867ba65c
Update for Visual C++ 6.0
Sam Lantinga <slouken@libsdl.org>
parents:
1413
diff
changeset
|
172 rgb_2_pix[ L + cb_b ]); |
0 | 173 |
174 L = *lum++; | |
1428
5f52867ba65c
Update for Visual C++ 6.0
Sam Lantinga <slouken@libsdl.org>
parents:
1413
diff
changeset
|
175 *row1++ = (unsigned short)(rgb_2_pix[ L + cr_r ] | |
5f52867ba65c
Update for Visual C++ 6.0
Sam Lantinga <slouken@libsdl.org>
parents:
1413
diff
changeset
|
176 rgb_2_pix[ L + crb_g ] | |
5f52867ba65c
Update for Visual C++ 6.0
Sam Lantinga <slouken@libsdl.org>
parents:
1413
diff
changeset
|
177 rgb_2_pix[ L + cb_b ]); |
0 | 178 |
179 | |
180 /* Now, do second row. */ | |
181 | |
182 L = *lum2++; | |
1428
5f52867ba65c
Update for Visual C++ 6.0
Sam Lantinga <slouken@libsdl.org>
parents:
1413
diff
changeset
|
183 *row2++ = (unsigned short)(rgb_2_pix[ L + cr_r ] | |
5f52867ba65c
Update for Visual C++ 6.0
Sam Lantinga <slouken@libsdl.org>
parents:
1413
diff
changeset
|
184 rgb_2_pix[ L + crb_g ] | |
5f52867ba65c
Update for Visual C++ 6.0
Sam Lantinga <slouken@libsdl.org>
parents:
1413
diff
changeset
|
185 rgb_2_pix[ L + cb_b ]); |
0 | 186 |
187 L = *lum2++; | |
1428
5f52867ba65c
Update for Visual C++ 6.0
Sam Lantinga <slouken@libsdl.org>
parents:
1413
diff
changeset
|
188 *row2++ = (unsigned short)(rgb_2_pix[ L + cr_r ] | |
5f52867ba65c
Update for Visual C++ 6.0
Sam Lantinga <slouken@libsdl.org>
parents:
1413
diff
changeset
|
189 rgb_2_pix[ L + crb_g ] | |
5f52867ba65c
Update for Visual C++ 6.0
Sam Lantinga <slouken@libsdl.org>
parents:
1413
diff
changeset
|
190 rgb_2_pix[ L + cb_b ]); |
0 | 191 } |
192 | |
193 /* | |
194 * These values are at the start of the next line, (due | |
195 * to the ++'s above),but they need to be at the start | |
196 * of the line after that. | |
197 */ | |
198 lum += cols; | |
199 lum2 += cols; | |
200 row1 += mod; | |
201 row2 += mod; | |
202 } | |
203 } | |
204 | |
205 static void Color24DitherYV12Mod1X( int *colortab, Uint32 *rgb_2_pix, | |
206 unsigned char *lum, unsigned char *cr, | |
207 unsigned char *cb, unsigned char *out, | |
208 int rows, int cols, int mod ) | |
209 { | |
210 unsigned int value; | |
211 unsigned char* row1; | |
212 unsigned char* row2; | |
213 unsigned char* lum2; | |
214 int x, y; | |
215 int cr_r; | |
216 int crb_g; | |
217 int cb_b; | |
218 int cols_2 = cols / 2; | |
219 | |
220 row1 = out; | |
221 row2 = row1 + cols*3 + mod*3; | |
222 lum2 = lum + cols; | |
223 | |
224 mod += cols + mod; | |
225 mod *= 3; | |
226 | |
227 y = rows / 2; | |
228 while( y-- ) | |
229 { | |
230 x = cols_2; | |
231 while( x-- ) | |
232 { | |
233 register int L; | |
234 | |
235 cr_r = 0*768+256 + colortab[ *cr + 0*256 ]; | |
236 crb_g = 1*768+256 + colortab[ *cr + 1*256 ] | |
237 + colortab[ *cb + 2*256 ]; | |
238 cb_b = 2*768+256 + colortab[ *cb + 3*256 ]; | |
239 ++cr; ++cb; | |
240 | |
241 L = *lum++; | |
242 value = (rgb_2_pix[ L + cr_r ] | | |
243 rgb_2_pix[ L + crb_g ] | | |
244 rgb_2_pix[ L + cb_b ]); | |
245 *row1++ = (value ) & 0xFF; | |
246 *row1++ = (value >> 8) & 0xFF; | |
247 *row1++ = (value >> 16) & 0xFF; | |
248 | |
249 L = *lum++; | |
250 value = (rgb_2_pix[ L + cr_r ] | | |
251 rgb_2_pix[ L + crb_g ] | | |
252 rgb_2_pix[ L + cb_b ]); | |
253 *row1++ = (value ) & 0xFF; | |
254 *row1++ = (value >> 8) & 0xFF; | |
255 *row1++ = (value >> 16) & 0xFF; | |
256 | |
257 | |
258 /* Now, do second row. */ | |
259 | |
260 L = *lum2++; | |
261 value = (rgb_2_pix[ L + cr_r ] | | |
262 rgb_2_pix[ L + crb_g ] | | |
263 rgb_2_pix[ L + cb_b ]); | |
264 *row2++ = (value ) & 0xFF; | |
265 *row2++ = (value >> 8) & 0xFF; | |
266 *row2++ = (value >> 16) & 0xFF; | |
267 | |
268 L = *lum2++; | |
269 value = (rgb_2_pix[ L + cr_r ] | | |
270 rgb_2_pix[ L + crb_g ] | | |
271 rgb_2_pix[ L + cb_b ]); | |
272 *row2++ = (value ) & 0xFF; | |
273 *row2++ = (value >> 8) & 0xFF; | |
274 *row2++ = (value >> 16) & 0xFF; | |
275 } | |
276 | |
277 /* | |
278 * These values are at the start of the next line, (due | |
279 * to the ++'s above),but they need to be at the start | |
280 * of the line after that. | |
281 */ | |
282 lum += cols; | |
283 lum2 += cols; | |
284 row1 += mod; | |
285 row2 += mod; | |
286 } | |
287 } | |
288 | |
289 static void Color32DitherYV12Mod1X( int *colortab, Uint32 *rgb_2_pix, | |
290 unsigned char *lum, unsigned char *cr, | |
291 unsigned char *cb, unsigned char *out, | |
292 int rows, int cols, int mod ) | |
293 { | |
294 unsigned int* row1; | |
295 unsigned int* row2; | |
296 unsigned char* lum2; | |
297 int x, y; | |
298 int cr_r; | |
299 int crb_g; | |
300 int cb_b; | |
301 int cols_2 = cols / 2; | |
302 | |
303 row1 = (unsigned int*) out; | |
304 row2 = row1 + cols + mod; | |
305 lum2 = lum + cols; | |
306 | |
307 mod += cols + mod; | |
308 | |
309 y = rows / 2; | |
310 while( y-- ) | |
311 { | |
312 x = cols_2; | |
313 while( x-- ) | |
314 { | |
315 register int L; | |
316 | |
317 cr_r = 0*768+256 + colortab[ *cr + 0*256 ]; | |
318 crb_g = 1*768+256 + colortab[ *cr + 1*256 ] | |
319 + colortab[ *cb + 2*256 ]; | |
320 cb_b = 2*768+256 + colortab[ *cb + 3*256 ]; | |
321 ++cr; ++cb; | |
322 | |
323 L = *lum++; | |
324 *row1++ = (rgb_2_pix[ L + cr_r ] | | |
325 rgb_2_pix[ L + crb_g ] | | |
326 rgb_2_pix[ L + cb_b ]); | |
327 | |
328 L = *lum++; | |
329 *row1++ = (rgb_2_pix[ L + cr_r ] | | |
330 rgb_2_pix[ L + crb_g ] | | |
331 rgb_2_pix[ L + cb_b ]); | |
332 | |
333 | |
334 /* Now, do second row. */ | |
335 | |
336 L = *lum2++; | |
337 *row2++ = (rgb_2_pix[ L + cr_r ] | | |
338 rgb_2_pix[ L + crb_g ] | | |
339 rgb_2_pix[ L + cb_b ]); | |
340 | |
341 L = *lum2++; | |
342 *row2++ = (rgb_2_pix[ L + cr_r ] | | |
343 rgb_2_pix[ L + crb_g ] | | |
344 rgb_2_pix[ L + cb_b ]); | |
345 } | |
346 | |
347 /* | |
348 * These values are at the start of the next line, (due | |
349 * to the ++'s above),but they need to be at the start | |
350 * of the line after that. | |
351 */ | |
352 lum += cols; | |
353 lum2 += cols; | |
354 row1 += mod; | |
355 row2 += mod; | |
356 } | |
357 } | |
358 | |
359 /* | |
360 * In this function I make use of a nasty trick. The tables have the lower | |
361 * 16 bits replicated in the upper 16. This means I can write ints and get | |
362 * the horisontal doubling for free (almost). | |
363 */ | |
364 static void Color16DitherYV12Mod2X( int *colortab, Uint32 *rgb_2_pix, | |
365 unsigned char *lum, unsigned char *cr, | |
366 unsigned char *cb, unsigned char *out, | |
367 int rows, int cols, int mod ) | |
368 { | |
369 unsigned int* row1 = (unsigned int*) out; | |
370 const int next_row = cols+(mod/2); | |
371 unsigned int* row2 = row1 + 2*next_row; | |
372 unsigned char* lum2; | |
373 int x, y; | |
374 int cr_r; | |
375 int crb_g; | |
376 int cb_b; | |
377 int cols_2 = cols / 2; | |
378 | |
379 lum2 = lum + cols; | |
380 | |
381 mod = (next_row * 3) + (mod/2); | |
382 | |
383 y = rows / 2; | |
384 while( y-- ) | |
385 { | |
386 x = cols_2; | |
387 while( x-- ) | |
388 { | |
389 register int L; | |
390 | |
391 cr_r = 0*768+256 + colortab[ *cr + 0*256 ]; | |
392 crb_g = 1*768+256 + colortab[ *cr + 1*256 ] | |
393 + colortab[ *cb + 2*256 ]; | |
394 cb_b = 2*768+256 + colortab[ *cb + 3*256 ]; | |
395 ++cr; ++cb; | |
396 | |
397 L = *lum++; | |
398 row1[0] = row1[next_row] = (rgb_2_pix[ L + cr_r ] | | |
399 rgb_2_pix[ L + crb_g ] | | |
400 rgb_2_pix[ L + cb_b ]); | |
401 row1++; | |
402 | |
403 L = *lum++; | |
404 row1[0] = row1[next_row] = (rgb_2_pix[ L + cr_r ] | | |
405 rgb_2_pix[ L + crb_g ] | | |
406 rgb_2_pix[ L + cb_b ]); | |
407 row1++; | |
408 | |
409 | |
410 /* Now, do second row. */ | |
411 | |
412 L = *lum2++; | |
413 row2[0] = row2[next_row] = (rgb_2_pix[ L + cr_r ] | | |
414 rgb_2_pix[ L + crb_g ] | | |
415 rgb_2_pix[ L + cb_b ]); | |
416 row2++; | |
417 | |
418 L = *lum2++; | |
419 row2[0] = row2[next_row] = (rgb_2_pix[ L + cr_r ] | | |
420 rgb_2_pix[ L + crb_g ] | | |
421 rgb_2_pix[ L + cb_b ]); | |
422 row2++; | |
423 } | |
424 | |
425 /* | |
426 * These values are at the start of the next line, (due | |
427 * to the ++'s above),but they need to be at the start | |
428 * of the line after that. | |
429 */ | |
430 lum += cols; | |
431 lum2 += cols; | |
432 row1 += mod; | |
433 row2 += mod; | |
434 } | |
435 } | |
436 | |
437 static void Color24DitherYV12Mod2X( int *colortab, Uint32 *rgb_2_pix, | |
438 unsigned char *lum, unsigned char *cr, | |
439 unsigned char *cb, unsigned char *out, | |
440 int rows, int cols, int mod ) | |
441 { | |
442 unsigned int value; | |
443 unsigned char* row1 = out; | |
444 const int next_row = (cols*2 + mod) * 3; | |
445 unsigned char* row2 = row1 + 2*next_row; | |
446 unsigned char* lum2; | |
447 int x, y; | |
448 int cr_r; | |
449 int crb_g; | |
450 int cb_b; | |
451 int cols_2 = cols / 2; | |
452 | |
453 lum2 = lum + cols; | |
454 | |
455 mod = next_row*3 + mod*3; | |
456 | |
457 y = rows / 2; | |
458 while( y-- ) | |
459 { | |
460 x = cols_2; | |
461 while( x-- ) | |
462 { | |
463 register int L; | |
464 | |
465 cr_r = 0*768+256 + colortab[ *cr + 0*256 ]; | |
466 crb_g = 1*768+256 + colortab[ *cr + 1*256 ] | |
467 + colortab[ *cb + 2*256 ]; | |
468 cb_b = 2*768+256 + colortab[ *cb + 3*256 ]; | |
469 ++cr; ++cb; | |
470 | |
471 L = *lum++; | |
472 value = (rgb_2_pix[ L + cr_r ] | | |
473 rgb_2_pix[ L + crb_g ] | | |
474 rgb_2_pix[ L + cb_b ]); | |
475 row1[0+0] = row1[3+0] = row1[next_row+0] = row1[next_row+3+0] = | |
476 (value ) & 0xFF; | |
477 row1[0+1] = row1[3+1] = row1[next_row+1] = row1[next_row+3+1] = | |
478 (value >> 8) & 0xFF; | |
479 row1[0+2] = row1[3+2] = row1[next_row+2] = row1[next_row+3+2] = | |
480 (value >> 16) & 0xFF; | |
481 row1 += 2*3; | |
482 | |
483 L = *lum++; | |
484 value = (rgb_2_pix[ L + cr_r ] | | |
485 rgb_2_pix[ L + crb_g ] | | |
486 rgb_2_pix[ L + cb_b ]); | |
487 row1[0+0] = row1[3+0] = row1[next_row+0] = row1[next_row+3+0] = | |
488 (value ) & 0xFF; | |
489 row1[0+1] = row1[3+1] = row1[next_row+1] = row1[next_row+3+1] = | |
490 (value >> 8) & 0xFF; | |
491 row1[0+2] = row1[3+2] = row1[next_row+2] = row1[next_row+3+2] = | |
492 (value >> 16) & 0xFF; | |
493 row1 += 2*3; | |
494 | |
495 | |
496 /* Now, do second row. */ | |
497 | |
498 L = *lum2++; | |
499 value = (rgb_2_pix[ L + cr_r ] | | |
500 rgb_2_pix[ L + crb_g ] | | |
501 rgb_2_pix[ L + cb_b ]); | |
502 row2[0+0] = row2[3+0] = row2[next_row+0] = row2[next_row+3+0] = | |
503 (value ) & 0xFF; | |
504 row2[0+1] = row2[3+1] = row2[next_row+1] = row2[next_row+3+1] = | |
505 (value >> 8) & 0xFF; | |
506 row2[0+2] = row2[3+2] = row2[next_row+2] = row2[next_row+3+2] = | |
507 (value >> 16) & 0xFF; | |
508 row2 += 2*3; | |
509 | |
510 L = *lum2++; | |
511 value = (rgb_2_pix[ L + cr_r ] | | |
512 rgb_2_pix[ L + crb_g ] | | |
513 rgb_2_pix[ L + cb_b ]); | |
514 row2[0+0] = row2[3+0] = row2[next_row+0] = row2[next_row+3+0] = | |
515 (value ) & 0xFF; | |
516 row2[0+1] = row2[3+1] = row2[next_row+1] = row2[next_row+3+1] = | |
517 (value >> 8) & 0xFF; | |
518 row2[0+2] = row2[3+2] = row2[next_row+2] = row2[next_row+3+2] = | |
519 (value >> 16) & 0xFF; | |
520 row2 += 2*3; | |
521 } | |
522 | |
523 /* | |
524 * These values are at the start of the next line, (due | |
525 * to the ++'s above),but they need to be at the start | |
526 * of the line after that. | |
527 */ | |
528 lum += cols; | |
529 lum2 += cols; | |
530 row1 += mod; | |
531 row2 += mod; | |
532 } | |
533 } | |
534 | |
535 static void Color32DitherYV12Mod2X( int *colortab, Uint32 *rgb_2_pix, | |
536 unsigned char *lum, unsigned char *cr, | |
537 unsigned char *cb, unsigned char *out, | |
538 int rows, int cols, int mod ) | |
539 { | |
540 unsigned int* row1 = (unsigned int*) out; | |
541 const int next_row = cols*2+mod; | |
542 unsigned int* row2 = row1 + 2*next_row; | |
543 unsigned char* lum2; | |
544 int x, y; | |
545 int cr_r; | |
546 int crb_g; | |
547 int cb_b; | |
548 int cols_2 = cols / 2; | |
549 | |
550 lum2 = lum + cols; | |
551 | |
552 mod = (next_row * 3) + mod; | |
553 | |
554 y = rows / 2; | |
555 while( y-- ) | |
556 { | |
557 x = cols_2; | |
558 while( x-- ) | |
559 { | |
560 register int L; | |
561 | |
562 cr_r = 0*768+256 + colortab[ *cr + 0*256 ]; | |
563 crb_g = 1*768+256 + colortab[ *cr + 1*256 ] | |
564 + colortab[ *cb + 2*256 ]; | |
565 cb_b = 2*768+256 + colortab[ *cb + 3*256 ]; | |
566 ++cr; ++cb; | |
567 | |
568 L = *lum++; | |
569 row1[0] = row1[1] = row1[next_row] = row1[next_row+1] = | |
570 (rgb_2_pix[ L + cr_r ] | | |
571 rgb_2_pix[ L + crb_g ] | | |
572 rgb_2_pix[ L + cb_b ]); | |
573 row1 += 2; | |
574 | |
575 L = *lum++; | |
576 row1[0] = row1[1] = row1[next_row] = row1[next_row+1] = | |
577 (rgb_2_pix[ L + cr_r ] | | |
578 rgb_2_pix[ L + crb_g ] | | |
579 rgb_2_pix[ L + cb_b ]); | |
580 row1 += 2; | |
581 | |
582 | |
583 /* Now, do second row. */ | |
584 | |
585 L = *lum2++; | |
586 row2[0] = row2[1] = row2[next_row] = row2[next_row+1] = | |
587 (rgb_2_pix[ L + cr_r ] | | |
588 rgb_2_pix[ L + crb_g ] | | |
589 rgb_2_pix[ L + cb_b ]); | |
590 row2 += 2; | |
591 | |
592 L = *lum2++; | |
593 row2[0] = row2[1] = row2[next_row] = row2[next_row+1] = | |
594 (rgb_2_pix[ L + cr_r ] | | |
595 rgb_2_pix[ L + crb_g ] | | |
596 rgb_2_pix[ L + cb_b ]); | |
597 row2 += 2; | |
598 } | |
599 | |
600 /* | |
601 * These values are at the start of the next line, (due | |
602 * to the ++'s above),but they need to be at the start | |
603 * of the line after that. | |
604 */ | |
605 lum += cols; | |
606 lum2 += cols; | |
607 row1 += mod; | |
608 row2 += mod; | |
609 } | |
610 } | |
611 | |
612 static void Color16DitherYUY2Mod1X( 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 short* row; | |
618 int x, y; | |
619 int cr_r; | |
620 int crb_g; | |
621 int cb_b; | |
622 int cols_2 = cols / 2; | |
623 | |
624 row = (unsigned short*) out; | |
625 | |
626 y = rows; | |
627 while( y-- ) | |
628 { | |
629 x = cols_2; | |
630 while( x-- ) | |
631 { | |
632 register int L; | |
633 | |
634 cr_r = 0*768+256 + colortab[ *cr + 0*256 ]; | |
635 crb_g = 1*768+256 + colortab[ *cr + 1*256 ] | |
636 + colortab[ *cb + 2*256 ]; | |
637 cb_b = 2*768+256 + colortab[ *cb + 3*256 ]; | |
638 cr += 4; cb += 4; | |
639 | |
640 L = *lum; lum += 2; | |
1428
5f52867ba65c
Update for Visual C++ 6.0
Sam Lantinga <slouken@libsdl.org>
parents:
1413
diff
changeset
|
641 *row++ = (unsigned short)(rgb_2_pix[ L + cr_r ] | |
5f52867ba65c
Update for Visual C++ 6.0
Sam Lantinga <slouken@libsdl.org>
parents:
1413
diff
changeset
|
642 rgb_2_pix[ L + crb_g ] | |
5f52867ba65c
Update for Visual C++ 6.0
Sam Lantinga <slouken@libsdl.org>
parents:
1413
diff
changeset
|
643 rgb_2_pix[ L + cb_b ]); |
0 | 644 |
645 L = *lum; lum += 2; | |
1428
5f52867ba65c
Update for Visual C++ 6.0
Sam Lantinga <slouken@libsdl.org>
parents:
1413
diff
changeset
|
646 *row++ = (unsigned short)(rgb_2_pix[ L + cr_r ] | |
5f52867ba65c
Update for Visual C++ 6.0
Sam Lantinga <slouken@libsdl.org>
parents:
1413
diff
changeset
|
647 rgb_2_pix[ L + crb_g ] | |
5f52867ba65c
Update for Visual C++ 6.0
Sam Lantinga <slouken@libsdl.org>
parents:
1413
diff
changeset
|
648 rgb_2_pix[ L + cb_b ]); |
0 | 649 |
650 } | |
651 | |
652 row += mod; | |
653 } | |
654 } | |
655 | |
656 static void Color24DitherYUY2Mod1X( int *colortab, Uint32 *rgb_2_pix, | |
657 unsigned char *lum, unsigned char *cr, | |
658 unsigned char *cb, unsigned char *out, | |
659 int rows, int cols, int mod ) | |
660 { | |
661 unsigned int value; | |
662 unsigned char* row; | |
663 int x, y; | |
664 int cr_r; | |
665 int crb_g; | |
666 int cb_b; | |
667 int cols_2 = cols / 2; | |
668 | |
669 row = (unsigned char*) out; | |
670 mod *= 3; | |
671 y = rows; | |
672 while( y-- ) | |
673 { | |
674 x = cols_2; | |
675 while( x-- ) | |
676 { | |
677 register int L; | |
678 | |
679 cr_r = 0*768+256 + colortab[ *cr + 0*256 ]; | |
680 crb_g = 1*768+256 + colortab[ *cr + 1*256 ] | |
681 + colortab[ *cb + 2*256 ]; | |
682 cb_b = 2*768+256 + colortab[ *cb + 3*256 ]; | |
683 cr += 4; cb += 4; | |
684 | |
685 L = *lum; lum += 2; | |
686 value = (rgb_2_pix[ L + cr_r ] | | |
687 rgb_2_pix[ L + crb_g ] | | |
688 rgb_2_pix[ L + cb_b ]); | |
689 *row++ = (value ) & 0xFF; | |
690 *row++ = (value >> 8) & 0xFF; | |
691 *row++ = (value >> 16) & 0xFF; | |
692 | |
693 L = *lum; lum += 2; | |
694 value = (rgb_2_pix[ L + cr_r ] | | |
695 rgb_2_pix[ L + crb_g ] | | |
696 rgb_2_pix[ L + cb_b ]); | |
697 *row++ = (value ) & 0xFF; | |
698 *row++ = (value >> 8) & 0xFF; | |
699 *row++ = (value >> 16) & 0xFF; | |
700 | |
701 } | |
702 row += mod; | |
703 } | |
704 } | |
705 | |
706 static void Color32DitherYUY2Mod1X( int *colortab, Uint32 *rgb_2_pix, | |
707 unsigned char *lum, unsigned char *cr, | |
708 unsigned char *cb, unsigned char *out, | |
709 int rows, int cols, int mod ) | |
710 { | |
711 unsigned int* row; | |
712 int x, y; | |
713 int cr_r; | |
714 int crb_g; | |
715 int cb_b; | |
716 int cols_2 = cols / 2; | |
717 | |
718 row = (unsigned int*) out; | |
719 y = rows; | |
720 while( y-- ) | |
721 { | |
722 x = cols_2; | |
723 while( x-- ) | |
724 { | |
725 register int L; | |
726 | |
727 cr_r = 0*768+256 + colortab[ *cr + 0*256 ]; | |
728 crb_g = 1*768+256 + colortab[ *cr + 1*256 ] | |
729 + colortab[ *cb + 2*256 ]; | |
730 cb_b = 2*768+256 + colortab[ *cb + 3*256 ]; | |
731 cr += 4; cb += 4; | |
732 | |
733 L = *lum; lum += 2; | |
734 *row++ = (rgb_2_pix[ L + cr_r ] | | |
735 rgb_2_pix[ L + crb_g ] | | |
736 rgb_2_pix[ L + cb_b ]); | |
737 | |
738 L = *lum; lum += 2; | |
739 *row++ = (rgb_2_pix[ L + cr_r ] | | |
740 rgb_2_pix[ L + crb_g ] | | |
741 rgb_2_pix[ L + cb_b ]); | |
742 | |
743 | |
744 } | |
745 row += mod; | |
746 } | |
747 } | |
748 | |
749 /* | |
750 * In this function I make use of a nasty trick. The tables have the lower | |
751 * 16 bits replicated in the upper 16. This means I can write ints and get | |
752 * the horisontal doubling for free (almost). | |
753 */ | |
754 static void Color16DitherYUY2Mod2X( int *colortab, Uint32 *rgb_2_pix, | |
755 unsigned char *lum, unsigned char *cr, | |
756 unsigned char *cb, unsigned char *out, | |
757 int rows, int cols, int mod ) | |
758 { | |
759 unsigned int* row = (unsigned int*) out; | |
760 const int next_row = cols+(mod/2); | |
761 int x, y; | |
762 int cr_r; | |
763 int crb_g; | |
764 int cb_b; | |
765 int cols_2 = cols / 2; | |
766 | |
767 y = rows; | |
768 while( y-- ) | |
769 { | |
770 x = cols_2; | |
771 while( x-- ) | |
772 { | |
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; cb += 4; | |
780 | |
781 L = *lum; lum += 2; | |
782 row[0] = row[next_row] = (rgb_2_pix[ L + cr_r ] | | |
783 rgb_2_pix[ L + crb_g ] | | |
784 rgb_2_pix[ L + cb_b ]); | |
785 row++; | |
786 | |
787 L = *lum; lum += 2; | |
788 row[0] = row[next_row] = (rgb_2_pix[ L + cr_r ] | | |
789 rgb_2_pix[ L + crb_g ] | | |
790 rgb_2_pix[ L + cb_b ]); | |
791 row++; | |
792 | |
793 } | |
794 row += next_row; | |
795 } | |
796 } | |
797 | |
798 static void Color24DitherYUY2Mod2X( int *colortab, Uint32 *rgb_2_pix, | |
799 unsigned char *lum, unsigned char *cr, | |
800 unsigned char *cb, unsigned char *out, | |
801 int rows, int cols, int mod ) | |
802 { | |
803 unsigned int value; | |
804 unsigned char* row = out; | |
805 const int next_row = (cols*2 + mod) * 3; | |
806 int x, y; | |
807 int cr_r; | |
808 int crb_g; | |
809 int cb_b; | |
810 int cols_2 = cols / 2; | |
811 y = rows; | |
812 while( y-- ) | |
813 { | |
814 x = cols_2; | |
815 while( x-- ) | |
816 { | |
817 register int L; | |
818 | |
819 cr_r = 0*768+256 + colortab[ *cr + 0*256 ]; | |
820 crb_g = 1*768+256 + colortab[ *cr + 1*256 ] | |
821 + colortab[ *cb + 2*256 ]; | |
822 cb_b = 2*768+256 + colortab[ *cb + 3*256 ]; | |
823 cr += 4; cb += 4; | |
824 | |
825 L = *lum; lum += 2; | |
826 value = (rgb_2_pix[ L + cr_r ] | | |
827 rgb_2_pix[ L + crb_g ] | | |
828 rgb_2_pix[ L + cb_b ]); | |
829 row[0+0] = row[3+0] = row[next_row+0] = row[next_row+3+0] = | |
830 (value ) & 0xFF; | |
831 row[0+1] = row[3+1] = row[next_row+1] = row[next_row+3+1] = | |
832 (value >> 8) & 0xFF; | |
833 row[0+2] = row[3+2] = row[next_row+2] = row[next_row+3+2] = | |
834 (value >> 16) & 0xFF; | |
835 row += 2*3; | |
836 | |
837 L = *lum; lum += 2; | |
838 value = (rgb_2_pix[ L + cr_r ] | | |
839 rgb_2_pix[ L + crb_g ] | | |
840 rgb_2_pix[ L + cb_b ]); | |
841 row[0+0] = row[3+0] = row[next_row+0] = row[next_row+3+0] = | |
842 (value ) & 0xFF; | |
843 row[0+1] = row[3+1] = row[next_row+1] = row[next_row+3+1] = | |
844 (value >> 8) & 0xFF; | |
845 row[0+2] = row[3+2] = row[next_row+2] = row[next_row+3+2] = | |
846 (value >> 16) & 0xFF; | |
847 row += 2*3; | |
848 | |
849 } | |
850 row += next_row; | |
851 } | |
852 } | |
853 | |
854 static void Color32DitherYUY2Mod2X( int *colortab, Uint32 *rgb_2_pix, | |
855 unsigned char *lum, unsigned char *cr, | |
856 unsigned char *cb, unsigned char *out, | |
857 int rows, int cols, int mod ) | |
858 { | |
859 unsigned int* row = (unsigned int*) out; | |
860 const int next_row = cols*2+mod; | |
861 int x, y; | |
862 int cr_r; | |
863 int crb_g; | |
864 int cb_b; | |
865 int cols_2 = cols / 2; | |
866 mod+=mod; | |
867 y = rows; | |
868 while( y-- ) | |
869 { | |
870 x = cols_2; | |
871 while( x-- ) | |
872 { | |
873 register int L; | |
874 | |
875 cr_r = 0*768+256 + colortab[ *cr + 0*256 ]; | |
876 crb_g = 1*768+256 + colortab[ *cr + 1*256 ] | |
877 + colortab[ *cb + 2*256 ]; | |
878 cb_b = 2*768+256 + colortab[ *cb + 3*256 ]; | |
879 cr += 4; cb += 4; | |
880 | |
881 L = *lum; lum += 2; | |
882 row[0] = row[1] = row[next_row] = row[next_row+1] = | |
883 (rgb_2_pix[ L + cr_r ] | | |
884 rgb_2_pix[ L + crb_g ] | | |
885 rgb_2_pix[ L + cb_b ]); | |
886 row += 2; | |
887 | |
888 L = *lum; lum += 2; | |
889 row[0] = row[1] = row[next_row] = row[next_row+1] = | |
890 (rgb_2_pix[ L + cr_r ] | | |
891 rgb_2_pix[ L + crb_g ] | | |
892 rgb_2_pix[ L + cb_b ]); | |
893 row += 2; | |
894 | |
895 | |
896 } | |
897 | |
898 row += next_row; | |
899 } | |
900 } | |
901 | |
902 /* | |
903 * How many 1 bits are there in the Uint32. | |
904 * Low performance, do not call often. | |
905 */ | |
906 static int number_of_bits_set( Uint32 a ) | |
907 { | |
908 if(!a) return 0; | |
909 if(a & 1) return 1 + number_of_bits_set(a >> 1); | |
910 return(number_of_bits_set(a >> 1)); | |
911 } | |
912 | |
913 /* | |
914 * How many 0 bits are there at least significant end of Uint32. | |
915 * Low performance, do not call often. | |
916 */ | |
917 static int free_bits_at_bottom( Uint32 a ) | |
918 { | |
919 /* assume char is 8 bits */ | |
920 if(!a) return sizeof(Uint32) * 8; | |
921 if(((Sint32)a) & 1l) return 0; | |
922 return 1 + free_bits_at_bottom ( a >> 1); | |
923 } | |
924 | |
925 | |
926 SDL_Overlay *SDL_CreateYUV_SW(_THIS, int width, int height, Uint32 format, SDL_Surface *display) | |
927 { | |
928 SDL_Overlay *overlay; | |
929 struct private_yuvhwdata *swdata; | |
930 int *Cr_r_tab; | |
931 int *Cr_g_tab; | |
932 int *Cb_g_tab; | |
933 int *Cb_b_tab; | |
934 Uint32 *r_2_pix_alloc; | |
935 Uint32 *g_2_pix_alloc; | |
936 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
|
937 int i; |
0 | 938 int CR, CB; |
939 Uint32 Rmask, Gmask, Bmask; | |
940 | |
941 /* Only RGB packed pixel conversion supported */ | |
942 if ( (display->format->BytesPerPixel != 2) && | |
943 (display->format->BytesPerPixel != 3) && | |
944 (display->format->BytesPerPixel != 4) ) { | |
945 SDL_SetError("Can't use YUV data on non 16/24/32 bit surfaces"); | |
946 return(NULL); | |
947 } | |
948 | |
949 /* Verify that we support the format */ | |
950 switch (format) { | |
951 case SDL_YV12_OVERLAY: | |
952 case SDL_IYUV_OVERLAY: | |
953 case SDL_YUY2_OVERLAY: | |
954 case SDL_UYVY_OVERLAY: | |
955 case SDL_YVYU_OVERLAY: | |
956 break; | |
957 default: | |
958 SDL_SetError("Unsupported YUV format"); | |
959 return(NULL); | |
960 } | |
961 | |
962 /* Create the overlay structure */ | |
1336
3692456e7b0f
Use SDL_ prefixed versions of C library functions.
Sam Lantinga <slouken@libsdl.org>
parents:
1330
diff
changeset
|
963 overlay = (SDL_Overlay *)SDL_malloc(sizeof *overlay); |
0 | 964 if ( overlay == NULL ) { |
965 SDL_OutOfMemory(); | |
966 return(NULL); | |
967 } | |
1336
3692456e7b0f
Use SDL_ prefixed versions of C library functions.
Sam Lantinga <slouken@libsdl.org>
parents:
1330
diff
changeset
|
968 SDL_memset(overlay, 0, (sizeof *overlay)); |
0 | 969 |
970 /* Fill in the basic members */ | |
971 overlay->format = format; | |
972 overlay->w = width; | |
973 overlay->h = height; | |
974 | |
975 /* Set up the YUV surface function structure */ | |
976 overlay->hwfuncs = &sw_yuvfuncs; | |
977 | |
978 /* Create the pixel data and lookup tables */ | |
1336
3692456e7b0f
Use SDL_ prefixed versions of C library functions.
Sam Lantinga <slouken@libsdl.org>
parents:
1330
diff
changeset
|
979 swdata = (struct private_yuvhwdata *)SDL_malloc(sizeof *swdata); |
0 | 980 overlay->hwdata = swdata; |
981 if ( swdata == NULL ) { | |
982 SDL_OutOfMemory(); | |
983 SDL_FreeYUVOverlay(overlay); | |
984 return(NULL); | |
985 } | |
986 swdata->stretch = NULL; | |
987 swdata->display = display; | |
1336
3692456e7b0f
Use SDL_ prefixed versions of C library functions.
Sam Lantinga <slouken@libsdl.org>
parents:
1330
diff
changeset
|
988 swdata->pixels = (Uint8 *) SDL_malloc(width*height*2); |
3692456e7b0f
Use SDL_ prefixed versions of C library functions.
Sam Lantinga <slouken@libsdl.org>
parents:
1330
diff
changeset
|
989 swdata->colortab = (int *)SDL_malloc(4*256*sizeof(int)); |
0 | 990 Cr_r_tab = &swdata->colortab[0*256]; |
991 Cr_g_tab = &swdata->colortab[1*256]; | |
992 Cb_g_tab = &swdata->colortab[2*256]; | |
993 Cb_b_tab = &swdata->colortab[3*256]; | |
1336
3692456e7b0f
Use SDL_ prefixed versions of C library functions.
Sam Lantinga <slouken@libsdl.org>
parents:
1330
diff
changeset
|
994 swdata->rgb_2_pix = (Uint32 *)SDL_malloc(3*768*sizeof(Uint32)); |
0 | 995 r_2_pix_alloc = &swdata->rgb_2_pix[0*768]; |
996 g_2_pix_alloc = &swdata->rgb_2_pix[1*768]; | |
997 b_2_pix_alloc = &swdata->rgb_2_pix[2*768]; | |
998 if ( ! swdata->pixels || ! swdata->colortab || ! swdata->rgb_2_pix ) { | |
999 SDL_OutOfMemory(); | |
1000 SDL_FreeYUVOverlay(overlay); | |
1001 return(NULL); | |
1002 } | |
1003 | |
1004 /* Generate the tables for the display surface */ | |
1005 for (i=0; i<256; i++) { | |
1006 /* Gamma correction (luminescence table) and chroma correction | |
1007 would be done here. See the Berkeley mpeg_play sources. | |
1008 */ | |
1009 CB = CR = (i-128); | |
1010 Cr_r_tab[i] = (int) ( (0.419/0.299) * CR); | |
1011 Cr_g_tab[i] = (int) (-(0.299/0.419) * CR); | |
1012 Cb_g_tab[i] = (int) (-(0.114/0.331) * CB); | |
1013 Cb_b_tab[i] = (int) ( (0.587/0.331) * CB); | |
1014 } | |
1015 | |
1016 /* | |
1017 * Set up entries 0-255 in rgb-to-pixel value tables. | |
1018 */ | |
1019 Rmask = display->format->Rmask; | |
1020 Gmask = display->format->Gmask; | |
1021 Bmask = display->format->Bmask; | |
1022 for ( i=0; i<256; ++i ) { | |
1023 r_2_pix_alloc[i+256] = i >> (8 - number_of_bits_set(Rmask)); | |
1024 r_2_pix_alloc[i+256] <<= free_bits_at_bottom(Rmask); | |
1025 g_2_pix_alloc[i+256] = i >> (8 - number_of_bits_set(Gmask)); | |
1026 g_2_pix_alloc[i+256] <<= free_bits_at_bottom(Gmask); | |
1027 b_2_pix_alloc[i+256] = i >> (8 - number_of_bits_set(Bmask)); | |
1028 b_2_pix_alloc[i+256] <<= free_bits_at_bottom(Bmask); | |
1029 } | |
1030 | |
1031 /* | |
1032 * If we have 16-bit output depth, then we double the value | |
1033 * in the top word. This means that we can write out both | |
1034 * pixels in the pixel doubling mode with one op. It is | |
1035 * harmless in the normal case as storing a 32-bit value | |
1036 * through a short pointer will lose the top bits anyway. | |
1037 */ | |
1038 if( display->format->BytesPerPixel == 2 ) { | |
1039 for ( i=0; i<256; ++i ) { | |
1040 r_2_pix_alloc[i+256] |= (r_2_pix_alloc[i+256]) << 16; | |
1041 g_2_pix_alloc[i+256] |= (g_2_pix_alloc[i+256]) << 16; | |
1042 b_2_pix_alloc[i+256] |= (b_2_pix_alloc[i+256]) << 16; | |
1043 } | |
1044 } | |
1045 | |
1046 /* | |
1047 * Spread out the values we have to the rest of the array so that | |
1048 * we do not need to check for overflow. | |
1049 */ | |
1050 for ( i=0; i<256; ++i ) { | |
1051 r_2_pix_alloc[i] = r_2_pix_alloc[256]; | |
1052 r_2_pix_alloc[i+512] = r_2_pix_alloc[511]; | |
1053 g_2_pix_alloc[i] = g_2_pix_alloc[256]; | |
1054 g_2_pix_alloc[i+512] = g_2_pix_alloc[511]; | |
1055 b_2_pix_alloc[i] = b_2_pix_alloc[256]; | |
1056 b_2_pix_alloc[i+512] = b_2_pix_alloc[511]; | |
1057 } | |
1058 | |
1059 /* You have chosen wisely... */ | |
1060 switch (format) { | |
1061 case SDL_YV12_OVERLAY: | |
1062 case SDL_IYUV_OVERLAY: | |
1063 if ( display->format->BytesPerPixel == 2 ) { | |
4064
940fddb81bea
Mac OS X/x86 won't build the MMX/YUV inline assembly without optimizations
Ryan C. Gordon <icculus@icculus.org>
parents:
4045
diff
changeset
|
1064 #if (__GNUC__ > 2) && defined(__i386__) && __OPTIMIZE__ && SDL_ASSEMBLY_ROUTINES |
0 | 1065 /* 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
|
1066 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
|
1067 (Gmask == 0x07E0) && |
22dbf364c017
Added SDL_HasMMX(), SDL_Has3DNow(), SDL_HasSSE() in SDL_cpuinfo.h
Sam Lantinga <slouken@libsdl.org>
parents:
366
diff
changeset
|
1068 (Bmask == 0x001F) && |
22dbf364c017
Added SDL_HasMMX(), SDL_Has3DNow(), SDL_HasSSE() in SDL_cpuinfo.h
Sam Lantinga <slouken@libsdl.org>
parents:
366
diff
changeset
|
1069 (width & 15) == 0) { |
0 | 1070 /*printf("Using MMX 16-bit 565 dither\n");*/ |
1071 swdata->Display1X = Color565DitherYV12MMX1X; | |
1072 } else { | |
1073 /*printf("Using C 16-bit dither\n");*/ | |
1074 swdata->Display1X = Color16DitherYV12Mod1X; | |
1075 } | |
1076 #else | |
1077 swdata->Display1X = Color16DitherYV12Mod1X; | |
1078 #endif | |
1079 swdata->Display2X = Color16DitherYV12Mod2X; | |
1080 } | |
1081 if ( display->format->BytesPerPixel == 3 ) { | |
1082 swdata->Display1X = Color24DitherYV12Mod1X; | |
1083 swdata->Display2X = Color24DitherYV12Mod2X; | |
1084 } | |
1085 if ( display->format->BytesPerPixel == 4 ) { | |
4064
940fddb81bea
Mac OS X/x86 won't build the MMX/YUV inline assembly without optimizations
Ryan C. Gordon <icculus@icculus.org>
parents:
4045
diff
changeset
|
1086 #if (__GNUC__ > 2) && defined(__i386__) && __OPTIMIZE__ && SDL_ASSEMBLY_ROUTINES |
0 | 1087 /* 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
|
1088 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
|
1089 (Gmask == 0x0000FF00) && |
22dbf364c017
Added SDL_HasMMX(), SDL_Has3DNow(), SDL_HasSSE() in SDL_cpuinfo.h
Sam Lantinga <slouken@libsdl.org>
parents:
366
diff
changeset
|
1090 (Bmask == 0x000000FF) && |
22dbf364c017
Added SDL_HasMMX(), SDL_Has3DNow(), SDL_HasSSE() in SDL_cpuinfo.h
Sam Lantinga <slouken@libsdl.org>
parents:
366
diff
changeset
|
1091 (width & 15) == 0) { |
0 | 1092 /*printf("Using MMX 32-bit dither\n");*/ |
1093 swdata->Display1X = ColorRGBDitherYV12MMX1X; | |
1094 } else { | |
1095 /*printf("Using C 32-bit dither\n");*/ | |
1096 swdata->Display1X = Color32DitherYV12Mod1X; | |
1097 } | |
1098 #else | |
1099 swdata->Display1X = Color32DitherYV12Mod1X; | |
1100 #endif | |
1101 swdata->Display2X = Color32DitherYV12Mod2X; | |
1102 } | |
1103 break; | |
1104 case SDL_YUY2_OVERLAY: | |
1105 case SDL_UYVY_OVERLAY: | |
1106 case SDL_YVYU_OVERLAY: | |
1107 if ( display->format->BytesPerPixel == 2 ) { | |
1108 swdata->Display1X = Color16DitherYUY2Mod1X; | |
1109 swdata->Display2X = Color16DitherYUY2Mod2X; | |
1110 } | |
1111 if ( display->format->BytesPerPixel == 3 ) { | |
1112 swdata->Display1X = Color24DitherYUY2Mod1X; | |
1113 swdata->Display2X = Color24DitherYUY2Mod2X; | |
1114 } | |
1115 if ( display->format->BytesPerPixel == 4 ) { | |
1116 swdata->Display1X = Color32DitherYUY2Mod1X; | |
1117 swdata->Display2X = Color32DitherYUY2Mod2X; | |
1118 } | |
1119 break; | |
1120 default: | |
1121 /* We should never get here (caught above) */ | |
1122 break; | |
1123 } | |
1124 | |
1125 /* Find the pitch and offset values for the overlay */ | |
1126 overlay->pitches = swdata->pitches; | |
1127 overlay->pixels = swdata->planes; | |
1128 switch (format) { | |
1129 case SDL_YV12_OVERLAY: | |
1130 case SDL_IYUV_OVERLAY: | |
1131 overlay->pitches[0] = overlay->w; | |
1132 overlay->pitches[1] = overlay->pitches[0] / 2; | |
1133 overlay->pitches[2] = overlay->pitches[0] / 2; | |
1134 overlay->pixels[0] = swdata->pixels; | |
1135 overlay->pixels[1] = overlay->pixels[0] + | |
1136 overlay->pitches[0] * overlay->h; | |
1137 overlay->pixels[2] = overlay->pixels[1] + | |
1138 overlay->pitches[1] * overlay->h / 2; | |
1139 overlay->planes = 3; | |
1140 break; | |
1141 case SDL_YUY2_OVERLAY: | |
1142 case SDL_UYVY_OVERLAY: | |
1143 case SDL_YVYU_OVERLAY: | |
1144 overlay->pitches[0] = overlay->w*2; | |
1145 overlay->pixels[0] = swdata->pixels; | |
1146 overlay->planes = 1; | |
1147 break; | |
1148 default: | |
1149 /* We should never get here (caught above) */ | |
1150 break; | |
1151 } | |
1152 | |
1153 /* We're all done.. */ | |
1154 return(overlay); | |
1155 } | |
1156 | |
1157 int SDL_LockYUV_SW(_THIS, SDL_Overlay *overlay) | |
1158 { | |
1159 return(0); | |
1160 } | |
1161 | |
1162 void SDL_UnlockYUV_SW(_THIS, SDL_Overlay *overlay) | |
1163 { | |
1164 return; | |
1165 } | |
1166 | |
1643
51038e80ae59
More general fix for bug #189
Sam Lantinga <slouken@libsdl.org>
parents:
1428
diff
changeset
|
1167 int SDL_DisplayYUV_SW(_THIS, SDL_Overlay *overlay, SDL_Rect *src, SDL_Rect *dst) |
0 | 1168 { |
1169 struct private_yuvhwdata *swdata; | |
1643
51038e80ae59
More general fix for bug #189
Sam Lantinga <slouken@libsdl.org>
parents:
1428
diff
changeset
|
1170 int stretch; |
0 | 1171 int scale_2x; |
1643
51038e80ae59
More general fix for bug #189
Sam Lantinga <slouken@libsdl.org>
parents:
1428
diff
changeset
|
1172 SDL_Surface *display; |
0 | 1173 Uint8 *lum, *Cr, *Cb; |
1643
51038e80ae59
More general fix for bug #189
Sam Lantinga <slouken@libsdl.org>
parents:
1428
diff
changeset
|
1174 Uint8 *dstp; |
0 | 1175 int mod; |
1176 | |
1177 swdata = overlay->hwdata; | |
1643
51038e80ae59
More general fix for bug #189
Sam Lantinga <slouken@libsdl.org>
parents:
1428
diff
changeset
|
1178 stretch = 0; |
0 | 1179 scale_2x = 0; |
1643
51038e80ae59
More general fix for bug #189
Sam Lantinga <slouken@libsdl.org>
parents:
1428
diff
changeset
|
1180 if ( src->x || src->y || src->w < overlay->w || src->h < overlay->h ) { |
1644
8a858076f39d
Added a note so I remember what the heck I was doing later. :)
Sam Lantinga <slouken@libsdl.org>
parents:
1643
diff
changeset
|
1181 /* The source rectangle has been clipped. |
8a858076f39d
Added a note so I remember what the heck I was doing later. :)
Sam Lantinga <slouken@libsdl.org>
parents:
1643
diff
changeset
|
1182 Using a scratch surface is easier than adding clipped |
8a858076f39d
Added a note so I remember what the heck I was doing later. :)
Sam Lantinga <slouken@libsdl.org>
parents:
1643
diff
changeset
|
1183 source support to all the blitters, plus that would |
8a858076f39d
Added a note so I remember what the heck I was doing later. :)
Sam Lantinga <slouken@libsdl.org>
parents:
1643
diff
changeset
|
1184 slow them down in the general unclipped case. |
8a858076f39d
Added a note so I remember what the heck I was doing later. :)
Sam Lantinga <slouken@libsdl.org>
parents:
1643
diff
changeset
|
1185 */ |
1643
51038e80ae59
More general fix for bug #189
Sam Lantinga <slouken@libsdl.org>
parents:
1428
diff
changeset
|
1186 stretch = 1; |
51038e80ae59
More general fix for bug #189
Sam Lantinga <slouken@libsdl.org>
parents:
1428
diff
changeset
|
1187 } else if ( (src->w != dst->w) || (src->h != dst->h) ) { |
51038e80ae59
More general fix for bug #189
Sam Lantinga <slouken@libsdl.org>
parents:
1428
diff
changeset
|
1188 if ( (dst->w == 2*src->w) && |
51038e80ae59
More general fix for bug #189
Sam Lantinga <slouken@libsdl.org>
parents:
1428
diff
changeset
|
1189 (dst->h == 2*src->h) ) { |
0 | 1190 scale_2x = 1; |
1191 } else { | |
1643
51038e80ae59
More general fix for bug #189
Sam Lantinga <slouken@libsdl.org>
parents:
1428
diff
changeset
|
1192 stretch = 1; |
0 | 1193 } |
1194 } | |
1195 if ( stretch ) { | |
1643
51038e80ae59
More general fix for bug #189
Sam Lantinga <slouken@libsdl.org>
parents:
1428
diff
changeset
|
1196 if ( ! swdata->stretch ) { |
51038e80ae59
More general fix for bug #189
Sam Lantinga <slouken@libsdl.org>
parents:
1428
diff
changeset
|
1197 display = swdata->display; |
51038e80ae59
More general fix for bug #189
Sam Lantinga <slouken@libsdl.org>
parents:
1428
diff
changeset
|
1198 swdata->stretch = SDL_CreateRGBSurface( |
51038e80ae59
More general fix for bug #189
Sam Lantinga <slouken@libsdl.org>
parents:
1428
diff
changeset
|
1199 SDL_SWSURFACE, |
51038e80ae59
More general fix for bug #189
Sam Lantinga <slouken@libsdl.org>
parents:
1428
diff
changeset
|
1200 overlay->w, overlay->h, |
51038e80ae59
More general fix for bug #189
Sam Lantinga <slouken@libsdl.org>
parents:
1428
diff
changeset
|
1201 display->format->BitsPerPixel, |
51038e80ae59
More general fix for bug #189
Sam Lantinga <slouken@libsdl.org>
parents:
1428
diff
changeset
|
1202 display->format->Rmask, |
51038e80ae59
More general fix for bug #189
Sam Lantinga <slouken@libsdl.org>
parents:
1428
diff
changeset
|
1203 display->format->Gmask, |
51038e80ae59
More general fix for bug #189
Sam Lantinga <slouken@libsdl.org>
parents:
1428
diff
changeset
|
1204 display->format->Bmask, 0); |
51038e80ae59
More general fix for bug #189
Sam Lantinga <slouken@libsdl.org>
parents:
1428
diff
changeset
|
1205 if ( ! swdata->stretch ) { |
51038e80ae59
More general fix for bug #189
Sam Lantinga <slouken@libsdl.org>
parents:
1428
diff
changeset
|
1206 return(-1); |
51038e80ae59
More general fix for bug #189
Sam Lantinga <slouken@libsdl.org>
parents:
1428
diff
changeset
|
1207 } |
51038e80ae59
More general fix for bug #189
Sam Lantinga <slouken@libsdl.org>
parents:
1428
diff
changeset
|
1208 } |
51038e80ae59
More general fix for bug #189
Sam Lantinga <slouken@libsdl.org>
parents:
1428
diff
changeset
|
1209 display = swdata->stretch; |
0 | 1210 } else { |
1211 display = swdata->display; | |
1212 } | |
1213 switch (overlay->format) { | |
1214 case SDL_YV12_OVERLAY: | |
1215 lum = overlay->pixels[0]; | |
1216 Cr = overlay->pixels[1]; | |
1217 Cb = overlay->pixels[2]; | |
1218 break; | |
1219 case SDL_IYUV_OVERLAY: | |
1220 lum = overlay->pixels[0]; | |
1221 Cr = overlay->pixels[2]; | |
1222 Cb = overlay->pixels[1]; | |
1223 break; | |
1224 case SDL_YUY2_OVERLAY: | |
1225 lum = overlay->pixels[0]; | |
1226 Cr = lum + 3; | |
1227 Cb = lum + 1; | |
1228 break; | |
1229 case SDL_UYVY_OVERLAY: | |
1230 lum = overlay->pixels[0]+1; | |
1231 Cr = lum + 1; | |
1232 Cb = lum - 1; | |
1233 break; | |
1234 case SDL_YVYU_OVERLAY: | |
1235 lum = overlay->pixels[0]; | |
1236 Cr = lum + 1; | |
1237 Cb = lum + 3; | |
1238 break; | |
1239 default: | |
292
eadc0746dfaf
Added SDL_LockRect() and SDL_UnlockRect()
Sam Lantinga <slouken@libsdl.org>
parents:
252
diff
changeset
|
1240 SDL_SetError("Unsupported YUV format in blit"); |
0 | 1241 return(-1); |
1242 } | |
1243 if ( SDL_MUSTLOCK(display) ) { | |
1244 if ( SDL_LockSurface(display) < 0 ) { | |
1245 return(-1); | |
1246 } | |
1247 } | |
1248 if ( stretch ) { | |
1643
51038e80ae59
More general fix for bug #189
Sam Lantinga <slouken@libsdl.org>
parents:
1428
diff
changeset
|
1249 dstp = (Uint8 *)swdata->stretch->pixels; |
0 | 1250 } else { |
1643
51038e80ae59
More general fix for bug #189
Sam Lantinga <slouken@libsdl.org>
parents:
1428
diff
changeset
|
1251 dstp = (Uint8 *)display->pixels |
51038e80ae59
More general fix for bug #189
Sam Lantinga <slouken@libsdl.org>
parents:
1428
diff
changeset
|
1252 + dst->x * display->format->BytesPerPixel |
51038e80ae59
More general fix for bug #189
Sam Lantinga <slouken@libsdl.org>
parents:
1428
diff
changeset
|
1253 + dst->y * display->pitch; |
0 | 1254 } |
1255 mod = (display->pitch / display->format->BytesPerPixel); | |
1256 | |
1257 if ( scale_2x ) { | |
1258 mod -= (overlay->w * 2); | |
1259 swdata->Display2X(swdata->colortab, swdata->rgb_2_pix, | |
1643
51038e80ae59
More general fix for bug #189
Sam Lantinga <slouken@libsdl.org>
parents:
1428
diff
changeset
|
1260 lum, Cr, Cb, dstp, overlay->h, overlay->w, mod); |
0 | 1261 } else { |
1262 mod -= overlay->w; | |
1263 swdata->Display1X(swdata->colortab, swdata->rgb_2_pix, | |
1643
51038e80ae59
More general fix for bug #189
Sam Lantinga <slouken@libsdl.org>
parents:
1428
diff
changeset
|
1264 lum, Cr, Cb, dstp, overlay->h, overlay->w, mod); |
0 | 1265 } |
1266 if ( SDL_MUSTLOCK(display) ) { | |
1267 SDL_UnlockSurface(display); | |
1268 } | |
1269 if ( stretch ) { | |
1270 display = swdata->display; | |
1643
51038e80ae59
More general fix for bug #189
Sam Lantinga <slouken@libsdl.org>
parents:
1428
diff
changeset
|
1271 SDL_SoftStretch(swdata->stretch, src, display, dst); |
0 | 1272 } |
1643
51038e80ae59
More general fix for bug #189
Sam Lantinga <slouken@libsdl.org>
parents:
1428
diff
changeset
|
1273 SDL_UpdateRects(display, 1, dst); |
0 | 1274 |
1275 return(0); | |
1276 } | |
1277 | |
1278 void SDL_FreeYUV_SW(_THIS, SDL_Overlay *overlay) | |
1279 { | |
1280 struct private_yuvhwdata *swdata; | |
1281 | |
1282 swdata = overlay->hwdata; | |
1283 if ( swdata ) { | |
9
a1c15fa4abb9
Fixed memory leak in software YUV stretch code
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
1284 if ( swdata->stretch ) { |
a1c15fa4abb9
Fixed memory leak in software YUV stretch code
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
1285 SDL_FreeSurface(swdata->stretch); |
a1c15fa4abb9
Fixed memory leak in software YUV stretch code
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
1286 } |
0 | 1287 if ( swdata->pixels ) { |
1336
3692456e7b0f
Use SDL_ prefixed versions of C library functions.
Sam Lantinga <slouken@libsdl.org>
parents:
1330
diff
changeset
|
1288 SDL_free(swdata->pixels); |
0 | 1289 } |
1290 if ( swdata->colortab ) { | |
1336
3692456e7b0f
Use SDL_ prefixed versions of C library functions.
Sam Lantinga <slouken@libsdl.org>
parents:
1330
diff
changeset
|
1291 SDL_free(swdata->colortab); |
0 | 1292 } |
1293 if ( swdata->rgb_2_pix ) { | |
1336
3692456e7b0f
Use SDL_ prefixed versions of C library functions.
Sam Lantinga <slouken@libsdl.org>
parents:
1330
diff
changeset
|
1294 SDL_free(swdata->rgb_2_pix); |
0 | 1295 } |
1336
3692456e7b0f
Use SDL_ prefixed versions of C library functions.
Sam Lantinga <slouken@libsdl.org>
parents:
1330
diff
changeset
|
1296 SDL_free(swdata); |
0 | 1297 } |
1298 } |