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