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