1 /*
2    WBMP: Wireless Bitmap Type 0: B/W, Uncompressed Bitmap
3    Specification of the WBMP format can be found in the file:
4    SPEC-WAESpec-19990524.pdf
5    You can download the WAP specification on: http://www.wapforum.com/
6 
7    gd_wbmp.c
8 
9    Copyright (C) Johan Van den Brande (johan@vandenbrande.com)
10 
11    Fixed: gdImageWBMPPtr, gdImageWBMP
12 
13    Recoded: gdImageWBMPCtx for use with my wbmp library
14    (wbmp library included, but you can find the latest distribution
15    at http://www.vandenbrande.com/wbmp)
16 
17    Implemented: gdImageCreateFromWBMPCtx, gdImageCreateFromWBMP
18 
19    ---------------------------------------------------------------------------
20 
21    Parts of this code are from Maurice Smurlo.
22 
23 
24    ** Copyright (C) Maurice Szmurlo --- T-SIT --- January 2000
25    ** (Maurice.Szmurlo@info.unicaen.fr)
26 
27    ** Permission to use, copy, modify, and distribute this software and its
28    ** documentation for any purpose and without fee is hereby granted, provided
29    ** that the above copyright notice appear in all copies and that both that
30    ** copyright notice and this permission notice appear in supporting
31    ** documentation.  This software is provided "as is" without express or
32    ** implied warranty.
33 
34    ---------------------------------------------------------------------------
35    Parts od this code are inspired by  'pbmtowbmp.c' and 'wbmptopbm.c' by
36    Terje Sannum <terje@looplab.com>.
37    **
38    ** Permission to use, copy, modify, and distribute this software and its
39    ** documentation for any purpose and without fee is hereby granted, provided
40    ** that the above copyright notice appear in all copies and that both that
41    ** copyright notice and this permission notice appear in supporting
42    ** documentation.  This software is provided "as is" without express or
43    ** implied warranty.
44    **
45    ---------------------------------------------------------------------------
46 
47    Todo:
48 
49    gdCreateFromWBMP function for reading WBMP files
50 
51    ----------------------------------------------------------------------------
52  */
53 
54 #include <stdio.h>
55 #include <stdlib.h>
56 #include <limits.h>
57 
58 #include "gd.h"
59 #include "gdfonts.h"
60 #include "gd_errors.h"
61 #include "wbmp.h"
62 
63 
64 /* gd_putout
65    ** ---------
66    ** Wrapper around gdPutC for use with writewbmp
67    **
68  */
gd_putout(int i,void * out)69 void gd_putout (int i, void *out)
70 {
71 	gdPutC(i, (gdIOCtx *) out);
72 }
73 
74 
75 /* gd_getin
76    ** --------
77    ** Wrapper around gdGetC for use with readwbmp
78    **
79  */
gd_getin(void * in)80 int gd_getin (void *in)
81 {
82 	return (gdGetC((gdIOCtx *) in));
83 }
84 
85 static int _gdImageWBMPCtx(gdImagePtr image, int fg, gdIOCtx *out);
86 
87 /*      gdImageWBMPCtx
88    **  --------------
89    **  Write the image as a wbmp file
90    **  Parameters are:
91    **  image:  gd image structure;
92    **  fg:     the index of the foreground color. any other value will be
93    **          considered as background and will not be written
94    **  out:    the stream where to write
95  */
gdImageWBMPCtx(gdImagePtr image,int fg,gdIOCtx * out)96 void gdImageWBMPCtx (gdImagePtr image, int fg, gdIOCtx * out)
97 {
98 	_gdImageWBMPCtx(image, fg, out);
99 }
100 
101 /* returns 0 on success, 1 on failure */
_gdImageWBMPCtx(gdImagePtr image,int fg,gdIOCtx * out)102 static int _gdImageWBMPCtx(gdImagePtr image, int fg, gdIOCtx *out)
103 {
104 	int x, y, pos;
105 	Wbmp *wbmp;
106 
107 	/* create the WBMP */
108 	if ((wbmp = createwbmp (gdImageSX (image), gdImageSY (image), WBMP_WHITE)) == NULL) {
109 		gd_error("Could not create WBMP");
110 		return 1;
111 	}
112 
113 	/* fill up the WBMP structure */
114 	pos = 0;
115 	for (y = 0; y < gdImageSY(image); y++) {
116 		for (x = 0; x < gdImageSX(image); x++) {
117 			if (gdImageGetPixel (image, x, y) == fg) {
118 				wbmp->bitmap[pos] = WBMP_BLACK;
119 			}
120 			pos++;
121 		}
122 	}
123 
124 	/* write the WBMP to a gd file descriptor */
125 	if (writewbmp (wbmp, &gd_putout, out)) {
126 		freewbmp(wbmp);
127 		gd_error("Could not save WBMP");
128 		return 1;
129 	}
130 
131 	/* des submitted this bugfix: gdFree the memory. */
132 	freewbmp(wbmp);
133 
134 	return 0;
135 }
136 
137 /* gdImageCreateFromWBMPCtx
138    ** ------------------------
139    ** Create a gdImage from a WBMP file input from an gdIOCtx
140  */
gdImageCreateFromWBMPCtx(gdIOCtx * infile)141 gdImagePtr gdImageCreateFromWBMPCtx (gdIOCtx * infile)
142 {
143 	/* FILE *wbmp_file; */
144 	Wbmp *wbmp;
145 	gdImagePtr im = NULL;
146 	int black, white;
147 	int col, row, pos;
148 
149 	if (readwbmp (&gd_getin, infile, &wbmp)) {
150 		return NULL;
151 	}
152 
153 	if (!(im = gdImageCreate (wbmp->width, wbmp->height))) {
154 		freewbmp (wbmp);
155 		return NULL;
156 	}
157 
158 	/* create the background color */
159 	white = gdImageColorAllocate(im, 255, 255, 255);
160 	/* create foreground color */
161 	black = gdImageColorAllocate(im, 0, 0, 0);
162 
163 	/* fill in image (in a wbmp 1 = white/ 0 = black) */
164 	pos = 0;
165 	for (row = 0; row < wbmp->height; row++) {
166 		for (col = 0; col < wbmp->width; col++) {
167 			if (wbmp->bitmap[pos++] == WBMP_WHITE) {
168 				gdImageSetPixel(im, col, row, white);
169 			} else {
170 				gdImageSetPixel(im, col, row, black);
171 			}
172 		}
173 	}
174 
175 	freewbmp(wbmp);
176 
177 	return im;
178 }
179 
180 /* gdImageCreateFromWBMP
181    ** ---------------------
182  */
gdImageCreateFromWBMP(FILE * inFile)183 gdImagePtr gdImageCreateFromWBMP (FILE * inFile)
184 {
185 	gdImagePtr im;
186 	gdIOCtx *in = gdNewFileCtx(inFile);
187 	im = gdImageCreateFromWBMPCtx(in);
188 	in->gd_free(in);
189 
190 	return im;
191 }
192 
gdImageCreateFromWBMPPtr(int size,void * data)193 gdImagePtr gdImageCreateFromWBMPPtr (int size, void *data)
194 {
195 	gdImagePtr im;
196 	gdIOCtx *in = gdNewDynamicCtxEx(size, data, 0);
197 	im = gdImageCreateFromWBMPCtx(in);
198 	in->gd_free(in);
199 	return im;
200 }
201 
202 /* gdImageWBMP
203    ** -----------
204  */
gdImageWBMP(gdImagePtr im,int fg,FILE * outFile)205 void gdImageWBMP (gdImagePtr im, int fg, FILE * outFile)
206 {
207 	gdIOCtx *out = gdNewFileCtx(outFile);
208 	gdImageWBMPCtx(im, fg, out);
209 	out->gd_free(out);
210 }
211 
212 /* gdImageWBMPPtr
213    ** --------------
214  */
gdImageWBMPPtr(gdImagePtr im,int * size,int fg)215 void * gdImageWBMPPtr (gdImagePtr im, int *size, int fg)
216 {
217 	void *rv;
218 	gdIOCtx *out = gdNewDynamicCtx(2048, NULL);
219 	if (!_gdImageWBMPCtx(im, fg, out)) {
220 		rv = gdDPExtractData(out, size);
221 	} else {
222 		rv = NULL;
223 	}
224 	out->gd_free(out);
225 
226 	return rv;
227 }
228