1 /*
2 * file w32_image.c - image conversion (rgb to pixel)
3 *
4 * $Id: w32_image.c,v 1.5 2006/02/19 13:33:01 lodott Exp $
5 *
6 * Program XBLAST
7 * (C) by Oliver Vogel (e-mail: m.vogel@ndh.net)
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published
11 * by the Free Software Foundation; either version 2; or (at your option)
12 * any later version
13 *
14 * This program is distributed in the hope that it will be entertaining,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILTY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
17 * Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License along
20 * with this program; if not, write to the Free Software Foundation, Inc.
21 * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 */
23 #include "xblast.h"
24 #include "w32_image.h"
25
26 #include "gui.h"
27 #include "util.h"
28
29 /*
30 * local variables
31 */
32 static unsigned char *bitConvTable = NULL;
33
34 /*
35 * library function: InitImages
36 * description: initializes data structure neede for image conversion
37 * parameters: none
38 * return value: 0 on success, -1 on failure
39 */
40 XBBool
InitImages(void)41 InitImages (void)
42 {
43 unsigned i, j;
44 unsigned char tmp;
45
46 /* create translation tables between pbm bits and windows mask */
47 bitConvTable = malloc (256);
48 if (NULL == bitConvTable) {
49 return XBFalse;
50 }
51 for (i = 0; i < 256; i++) {
52 tmp = 0;
53 for (j = 0; j < 8; j++) {
54 if (i & (1 << j)) {
55 tmp |= (1 << (7 - j));
56 }
57 }
58 bitConvTable[i] = ~tmp;
59 }
60 return XBTrue;
61 } /* InitImages */
62
63 /*
64 *
65 */
66 void
FinishImages(void)67 FinishImages (void)
68 {
69 if (NULL != bitConvTable) {
70 free (bitConvTable);
71 }
72 } /* FinishImages */
73
74 /*
75 * local function: BitmapFromRGBPixel
76 * description: creates bitmap from pixel data in 24 bit RGB format
77 * parameters: data - 24 bit pixel data (b,g,r!)
78 * width - width of bitmap
79 * height - height of bitmap
80 * return value: handle of bitmap, or NULL on failure
81 */
82 static HBITMAP
BitmapFromRGBPixel(unsigned char * data,int width,int height)83 BitmapFromRGBPixel (unsigned char *data, int width, int height)
84 {
85 BITMAPINFO info;
86 HDC hdc;
87 HBITMAP bitmap;
88 HPALETTE oldPal = NULL;
89 unsigned char swap;
90 int i, len;
91
92 /* turn r,g,b around */
93 len = 3 * width * height;
94 for (i = 0; i < len; i += 3) {
95 swap = data[i];
96 data[i] = data[i + 2];
97 data[i + 2] = swap;
98 }
99 /* set bitmap map info */
100 info.bmiHeader.biSize = sizeof (info.bmiHeader);
101 info.bmiHeader.biWidth = width;
102 info.bmiHeader.biHeight = -height;
103 info.bmiHeader.biPlanes = 1;
104 info.bmiHeader.biBitCount = 24;
105 info.bmiHeader.biCompression = BI_RGB;
106 info.bmiHeader.biSizeImage = 0;
107 info.bmiHeader.biYPelsPerMeter = 2834;
108 info.bmiHeader.biXPelsPerMeter = 2834;
109 info.bmiHeader.biClrUsed = 0;
110 info.bmiHeader.biClrImportant = 0;
111 /* get dvice context of window */
112 hdc = GetDC (window);
113 if (NULL == hdc) {
114 return NULL;
115 }
116 /* select palette to use */
117 if (NULL != palette) {
118 oldPal = SelectPalette (hdc, palette, FALSE);
119 }
120 /* create bitmap */
121 bitmap = CreateDIBitmap (hdc, &info.bmiHeader, CBM_INIT, data, &info, 0);
122 ReleaseDC (window, hdc);
123 if (NULL != palette) {
124 SelectPalette (hdc, oldPal, FALSE);
125 }
126 /* that's all */
127 return bitmap;
128 } /* BitmapFromRGBPixel */
129
130 /*
131 * library function: ReadPbmBitmap
132 * description: create a bitmap from a given pbm-file
133 * parameters: path - relative path for image
134 * filename - name of image file
135 * return value: handle of bitmap, or NULL on failure
136 */
137 HBITMAP
ReadPbmBitmap(const char * path,const char * filename)138 ReadPbmBitmap (const char *path, const char *filename)
139 {
140 int width;
141 int height;
142 unsigned char *pbm;
143 HBITMAP bitmap;
144 int pbmLineLength;
145 int w32LineLength;
146 int i;
147 int pbmSize;
148
149 /* load pbm file */
150 if (NULL == (pbm = ReadPbmFile (path, filename, &width, &height))) {
151 GUI_ErrorMessage ("Failed to load bitmap %s\n", filename);
152 return NULL;
153 }
154 pbmLineLength = (width + 7) / 8;
155 w32LineLength = 2 * ((width + 15) / 16);
156 pbmSize = pbmLineLength * height;
157 for (i = 0; i < pbmSize; i++) {
158 pbm[i] = bitConvTable[pbm[i]];
159 }
160 /* pbm data is byte aligned while bitmap data must be word aligned */
161 if (pbmLineLength != w32LineLength) {
162 int y;
163 unsigned char *tmp;
164 /* --- */
165 tmp = calloc (height * w32LineLength, sizeof (unsigned char));
166 assert (tmp != NULL);
167 for (y = 0; y < height; y++) {
168 memcpy (tmp + y * w32LineLength, pbm + y * pbmLineLength, pbmLineLength);
169 }
170 /* --- */
171 free (pbm);
172 pbm = tmp;
173 }
174 /* create monochrome bitmap */
175 bitmap = CreateBitmap (width, height, 1, 1, pbm);
176 /* free data */
177 free (pbm);
178 /* that's all */
179 return bitmap;
180 } /* ReadPbmBitmap */
181
182 /*
183 * library function: ReadRgbPixmap
184 * description: create a bitmap from a ppm file (using rgb values)
185 * parameters: path - relative path for image
186 * filename - name of image file
187 * return value: handle of bitmap, or NULL on failure
188 */
189 HBITMAP
ReadRgbPixmap(const char * path,const char * filename)190 ReadRgbPixmap (const char *path, const char *filename)
191 {
192 int width;
193 int height;
194 unsigned char *ppm;
195 HBITMAP bitmap;
196
197 /* load ppm file */
198 if (NULL == (ppm = ReadPpmFile (path, filename, &width, &height))) {
199 GUI_ErrorMessage ("Failed to load pixmap %s\n", filename);
200 return NULL;
201 }
202 /* now create bitmap */
203 bitmap = BitmapFromRGBPixel (ppm, width, height);
204 /* free pixel data */
205 free (ppm);
206 /* that's all */
207 return bitmap;
208 } /* ReadRgbPixmap */
209
210 /*
211 * library function: ReadCchPixmap
212 * description: create a bitmap from a ppm file (using red as bg, green as add
213 * and white as highlight)
214 * parameters: path - relative path for image
215 * filename - name of image file
216 * fg - base color (black most of the time)
217 * bg - first color (for red pixels)
218 * add - seconed color (for green pixels)
219 * return value: handle of bitmap, or NULL on failure
220 */
221 HBITMAP
ReadCchPixmap(const char * path,const char * filename,XBColor fg,XBColor bg,XBColor add)222 ReadCchPixmap (const char *path, const char *filename, XBColor fg, XBColor bg, XBColor add)
223 {
224 int width;
225 int height;
226 unsigned char *ppm;
227 HBITMAP bitmap;
228
229 /* load ppm file */
230 if (NULL == (ppm = ReadPpmFile (path, filename, &width, &height))) {
231 GUI_ErrorMessage ("Failed to load pixmap %s\n", filename);
232 return NULL;
233 }
234 /* convert color */
235 CchToPpm (ppm, width, height, fg, bg, add);
236 /* now create bitmap */
237 bitmap = BitmapFromRGBPixel (ppm, width, height);
238 /* free pixel data */
239 free (ppm);
240 /* that's all */
241 return bitmap;
242 } /* ReadCchPixmap */
243
244 /*
245 * library function: ReadEpmPixmap
246 * description: create a bitmap from a ppm file (using red as bg, green as add
247 * and white as highlight)
248 * parameters: path - relative path for image
249 * filename - name of image file
250 * n_colors - number of color layers
251 * color - arrays with colors foreach layer
252 * return value: handle of bitmap, or NULL on failure
253 */
254 HBITMAP
ReadEpmPixmap(const char * path,const char * filename,int n_colors,const XBColor * color)255 ReadEpmPixmap (const char *path, const char *filename, int n_colors, const XBColor * color)
256 {
257 int width;
258 int height;
259 int depth;
260 unsigned char *epm;
261 unsigned char *ppm;
262 HBITMAP bitmap;
263
264 assert (NULL != color);
265 assert (NULL != path);
266 assert (NULL != filename);
267 /* load ppm file */
268 if (NULL == (epm = ReadEpmFile (path, filename, &width, &height, &depth))) {
269 GUI_ErrorMessage ("Failed to load pixmap %s\n", filename);
270 return NULL;
271 }
272 /* check depth */
273 if (depth < n_colors) {
274 n_colors = depth;
275 }
276 /* create ppm array */
277 ppm = malloc (width * height * 3);
278 assert (ppm != NULL);
279 /* convert color */
280 EpmToPpm (epm, ppm, width, height, n_colors, color);
281 /* now create bitmap */
282 bitmap = BitmapFromRGBPixel (ppm, width, height);
283 /* free pixel data */
284 free (epm);
285 free (ppm);
286 /* that's all */
287 return bitmap;
288 } /* ReadEpmPixmap */
289
290 /*
291 * convert colorname to value (not supported for win32)
292 */
293 XBColor
GUI_ParseColor(const char * name)294 GUI_ParseColor (const char *name)
295 {
296 return COLOR_INVALID;
297 } /* GUI_ParseColor */
298
299 /*
300 * end of file w32_image.c
301 */
302