1 /*
2 pixels.c
3
4 For Tux Paint
5 Pixel read/write functions
6
7 bill@newbreedsoftware.com
8 http://www.newbreedsoftware.com/tuxpaint/
9
10 Brought to tuxmath/tuxtype, slight modified, and license updated to
11 "GPL3 or later" as detailed below.
12
13 Copyright 2007, 2008, 2009, 2010.
14 Copyright 2002-2006, 2007, 2008, 2009, 2010.
15 Authors: Bill Kendrick and others from Tux Paint,
16 David Bruce, Brendan Luchen.
17
18 Project email: <tux4kids-tuxtype-dev@lists.alioth.debian.org>
19 Project website: http://tux4kids.alioth.debian.org
20
21 pixels.c is part of Tux Typing, a.k.a "tuxtype".
22
23 Tux Typing is free software: you can redistribute it and/or modify
24 it under the terms of the GNU General Public License as published by
25 the Free Software Foundation; either version 3 of the License, or
26 (at your option) any later version.
27
28 Tux Typing is distributed in the hope that it will be useful,
29 but WITHOUT ANY WARRANTY; without even the implied warranty of
30 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
31 GNU General Public License for more details.
32
33 You should have received a copy of the GNU General Public License
34 along with this program. If not, see <http://www.gnu.org/licenses/>.
35 */
36
37
38
39 #include "pixels.h"
40 #include "compiler.h"
41 //#include "debug.h"
42
43 /* Draw a single pixel into the surface: */
putpixel8(SDL_Surface * surface,int x,int y,Uint32 pixel)44 void putpixel8(SDL_Surface * surface, int x, int y, Uint32 pixel)
45 {
46 Uint8 *p;
47
48 /* Assuming the X/Y values are within the bounds of this surface... */
49 if (likely
50 (likely((unsigned) x < (unsigned) surface->w)
51 && likely((unsigned) y < (unsigned) surface->h)))
52 {
53 // Set a pointer to the exact location in memory of the pixel
54 p = (Uint8 *) (((Uint8 *) surface->pixels) + /* Start: beginning of RAM */
55 (y * surface->pitch) + /* Go down Y lines */
56 x); /* Go in X pixels */
57
58
59 /* Set the (correctly-sized) piece of data in the surface's RAM
60 * to the pixel value sent in: */
61
62 *p = pixel;
63 }
64 }
65
66 /* Draw a single pixel into the surface: */
putpixel16(SDL_Surface * surface,int x,int y,Uint32 pixel)67 void putpixel16(SDL_Surface * surface, int x, int y, Uint32 pixel)
68 {
69 Uint8 *p;
70
71 /* Assuming the X/Y values are within the bounds of this surface... */
72 if (likely
73 (likely((unsigned) x < (unsigned) surface->w)
74 && likely((unsigned) y < (unsigned) surface->h)))
75 {
76 // Set a pointer to the exact location in memory of the pixel
77 p = (Uint8 *) (((Uint8 *) surface->pixels) + /* Start: beginning of RAM */
78 (y * surface->pitch) + /* Go down Y lines */
79 (x * 2)); /* Go in X pixels */
80
81
82 /* Set the (correctly-sized) piece of data in the surface's RAM
83 * to the pixel value sent in: */
84
85 *(Uint16 *) p = pixel;
86 }
87 }
88
89 /* Draw a single pixel into the surface: */
putpixel24(SDL_Surface * surface,int x,int y,Uint32 pixel)90 void putpixel24(SDL_Surface * surface, int x, int y, Uint32 pixel)
91 {
92 Uint8 *p;
93
94 /* Assuming the X/Y values are within the bounds of this surface... */
95 if (likely
96 (likely((unsigned) x < (unsigned) surface->w)
97 && likely((unsigned) y < (unsigned) surface->h)))
98 {
99 // Set a pointer to the exact location in memory of the pixel
100 p = (Uint8 *) (((Uint8 *) surface->pixels) + /* Start: beginning of RAM */
101 (y * surface->pitch) + /* Go down Y lines */
102 (x * 3)); /* Go in X pixels */
103
104
105 /* Set the (correctly-sized) piece of data in the surface's RAM
106 * to the pixel value sent in: */
107
108 if (SDL_BYTEORDER == SDL_BIG_ENDIAN)
109 {
110 p[0] = (pixel >> 16) & 0xff;
111 p[1] = (pixel >> 8) & 0xff;
112 p[2] = pixel & 0xff;
113 }
114 else
115 {
116 p[0] = pixel & 0xff;
117 p[1] = (pixel >> 8) & 0xff;
118 p[2] = (pixel >> 16) & 0xff;
119 }
120
121 }
122 }
123
124 /* Draw a single pixel into the surface: */
putpixel32(SDL_Surface * surface,int x,int y,Uint32 pixel)125 void putpixel32(SDL_Surface * surface, int x, int y, Uint32 pixel)
126 {
127 Uint8 *p;
128
129 /* Assuming the X/Y values are within the bounds of this surface... */
130 if (likely
131 (likely((unsigned) x < (unsigned) surface->w)
132 && likely((unsigned) y < (unsigned) surface->h)))
133 {
134 // Set a pointer to the exact location in memory of the pixel
135 p = (Uint8 *) (((Uint8 *) surface->pixels) + /* Start: beginning of RAM */
136 (y * surface->pitch) + /* Go down Y lines */
137 (x * 4)); /* Go in X pixels */
138
139
140 /* Set the (correctly-sized) piece of data in the surface's RAM
141 * to the pixel value sent in: */
142
143 *(Uint32 *) p = pixel; // 32-bit display
144 }
145 }
146
147 /* Get a pixel: */
getpixel8(SDL_Surface * surface,int x,int y)148 Uint32 getpixel8(SDL_Surface * surface, int x, int y)
149 {
150 Uint8 *p;
151
152 /* get the X/Y values within the bounds of this surface */
153 if (unlikely((unsigned) x > (unsigned) surface->w - 1u))
154 x = (x < 0) ? 0 : surface->w - 1;
155 if (unlikely((unsigned) y > (unsigned) surface->h - 1u))
156 y = (y < 0) ? 0 : surface->h - 1;
157
158 /* Set a pointer to the exact location in memory of the pixel
159 in question: */
160
161 p = (Uint8 *) (((Uint8 *) surface->pixels) + /* Start at top of RAM */
162 (y * surface->pitch) + /* Go down Y lines */
163 x); /* Go in X pixels */
164
165
166 /* Return the correctly-sized piece of data containing the
167 * pixel's value (an 8-bit palette value, or a 16-, 24- or 32-bit
168 * RGB value) */
169
170 return (*p);
171 }
172
173 /* Get a pixel: */
getpixel16(SDL_Surface * surface,int x,int y)174 Uint32 getpixel16(SDL_Surface * surface, int x, int y)
175 {
176 Uint8 *p;
177
178 /* get the X/Y values within the bounds of this surface */
179 if (unlikely((unsigned) x > (unsigned) surface->w - 1u))
180 x = (x < 0) ? 0 : surface->w - 1;
181 if (unlikely((unsigned) y > (unsigned) surface->h - 1u))
182 y = (y < 0) ? 0 : surface->h - 1;
183
184 /* Set a pointer to the exact location in memory of the pixel
185 in question: */
186
187 p = (Uint8 *) (((Uint8 *) surface->pixels) + /* Start at top of RAM */
188 (y * surface->pitch) + /* Go down Y lines */
189 (x * 2)); /* Go in X pixels */
190
191
192 /* Return the correctly-sized piece of data containing the
193 * pixel's value (an 8-bit palette value, or a 16-, 24- or 32-bit
194 * RGB value) */
195
196 return (*(Uint16 *) p);
197 }
198
199 /* Get a pixel: */
getpixel24(SDL_Surface * surface,int x,int y)200 Uint32 getpixel24(SDL_Surface * surface, int x, int y)
201 {
202 Uint8 *p;
203 Uint32 pixel;
204
205 /* get the X/Y values within the bounds of this surface */
206 if (unlikely((unsigned) x > (unsigned) surface->w - 1u))
207 x = (x < 0) ? 0 : surface->w - 1;
208 if (unlikely((unsigned) y > (unsigned) surface->h - 1u))
209 y = (y < 0) ? 0 : surface->h - 1;
210
211 /* Set a pointer to the exact location in memory of the pixel
212 in question: */
213
214 p = (Uint8 *) (((Uint8 *) surface->pixels) + /* Start at top of RAM */
215 (y * surface->pitch) + /* Go down Y lines */
216 (x * 3)); /* Go in X pixels */
217
218
219 /* Return the correctly-sized piece of data containing the
220 * pixel's value (an 8-bit palette value, or a 16-, 24- or 32-bit
221 * RGB value) */
222
223 /* Depending on the byte-order, it could be stored RGB or BGR! */
224
225 if (SDL_BYTEORDER == SDL_BIG_ENDIAN)
226 pixel = p[0] << 16 | p[1] << 8 | p[2];
227 else
228 pixel = p[0] | p[1] << 8 | p[2] << 16;
229
230 return pixel;
231 }
232
233 /* Get a pixel: */
getpixel32(SDL_Surface * surface,int x,int y)234 Uint32 getpixel32(SDL_Surface * surface, int x, int y)
235 {
236 Uint8 *p;
237
238 /* get the X/Y values within the bounds of this surface */
239 if (unlikely((unsigned) x > (unsigned) surface->w - 1u))
240 x = (x < 0) ? 0 : surface->w - 1;
241 if (unlikely((unsigned) y > (unsigned) surface->h - 1u))
242 y = (y < 0) ? 0 : surface->h - 1;
243
244 /* Set a pointer to the exact location in memory of the pixel
245 in question: */
246
247 p = (Uint8 *) (((Uint8 *) surface->pixels) + /* Start at top of RAM */
248 (y * surface->pitch) + /* Go down Y lines */
249 (x * 4)); /* Go in X pixels */
250
251
252 /* Return the correctly-sized piece of data containing the
253 * pixel's value (an 8-bit palette value, or a 16-, 24- or 32-bit
254 * RGB value) */
255
256 return *(Uint32 *) p; // 32-bit display
257 }
258
259 void (*putpixels[]) (SDL_Surface *, int, int, Uint32) =
260 {
261 putpixel8, putpixel8, putpixel16, putpixel24, putpixel32};
262
263
264 Uint32(*getpixels[])(SDL_Surface *, int, int) =
265 {
266 getpixel8, getpixel8, getpixel16, getpixel24, getpixel32};
267