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