php-internal-docs 8.4.8
Unofficial docs for php/php-src
Loading...
Searching...
No Matches
wbmp.c
Go to the documentation of this file.
1
2/* WBMP
3 ** ----
4 ** WBMP Level 0: B/W, Uncompressed
5 ** This implements the WBMP format as specified in WAPSpec 1.1 and 1.2.
6 ** It does not support ExtHeaders as defined in the spec. The spec states
7 ** that a WAP client does not need to implement ExtHeaders.
8 **
9 ** (c) 2000 Johan Van den Brande <johan@vandenbrande.com>
10 */
11
12
13#include <stdio.h>
14#include <stddef.h>
15#include <stdlib.h>
16#include <string.h>
17
18#include "wbmp.h"
19#include "gd.h"
20#include "gdhelpers.h"
21
22#ifdef NOTDEF
23#define __TEST /* Compile with main function */
24#define __DEBUG /* Extra verbose when with __TEST */
25#define __WRITE /* readwbmp and writewbmp(stdout) */
26#define __VIEW /* view the wbmp on stdout */
27#endif
28
29/* getmbi
30 ** ------
31 ** Get a multibyte integer from a generic getin function
32 ** 'getin' can be getc, with in = NULL
33 ** you can find getin as a function just above the main function
34 ** This way you gain a lot of flexibilty about how this package
35 ** reads a wbmp file.
36 */
37int
38getmbi (int (*getin) (void *in), void *in)
39{
40 unsigned int mbi = 0;
41 int i;
42
43 do
44 {
45 i = getin (in);
46 if (i < 0)
47 return (-1);
48 mbi = (mbi << 7) | (i & 0x7f);
49 }
50 while (i & 0x80);
51
52 return (mbi);
53}
54
55
56/* putmbi
57 ** ------
58 ** Put a multibyte intgerer in some kind of output stream
59 ** I work here with a function pointer, to make it as generic
60 ** as possible. Look at this function as an iterator on the
61 ** mbi integers it spits out.
62 **
63 */
64void
65putmbi (int i, void (*putout) (int c, void *out), void *out)
66{
67 int cnt, l, accu;
68
69 /* Get number of septets */
70 cnt = 0;
71 accu = 0;
72 while (accu != i)
73 accu += i & 0x7f << 7 * cnt++;
74
75 /* Produce the multibyte output */
76 for (l = cnt - 1; l > 0; l--)
77 putout (0x80 | (i & 0x7f << 7 * l) >> 7 * l, out);
78
79 putout (i & 0x7f, out);
80
81}
82
83
84
85/* skipheader
86 ** ----------
87 ** Skips the ExtHeader. Not needed for the moment
88 **
89 */
90int
91skipheader (int (*getin) (void *in), void *in)
92{
93 int i;
94
95 do
96 {
97 i = getin (in);
98 if (i < 0)
99 return (-1);
100 }
101 while (i & 0x80);
102
103 return (0);
104}
105
106/* create wbmp
107 ** -----------
108 ** create an empty wbmp
109 **
110 */
111Wbmp *
112createwbmp (int width, int height, int color)
113{
114 int i;
115
116 Wbmp *wbmp;
117 if ((wbmp = (Wbmp *) gdMalloc (sizeof (Wbmp))) == NULL)
118 return (NULL);
119
120 if (overflow2(sizeof (int), width)) {
121 gdFree(wbmp);
122 return NULL;
123 }
124 if (overflow2(sizeof (int) * width, height)) {
125 gdFree(wbmp);
126 return NULL;
127 }
128
129 if ((wbmp->bitmap = (int *) safe_emalloc(sizeof(int), width * height, 0)) == NULL)
130 {
131 gdFree (wbmp);
132 return (NULL);
133 }
134
135 wbmp->width = width;
136 wbmp->height = height;
137
138 for (i = 0; i < width * height; wbmp->bitmap[i++] = color);
139
140 return (wbmp);
141}
142
143
144
145/* readwbmp
146 ** -------
147 ** Actually reads the WBMP format from an open file descriptor
148 ** It goes along by returning a pointer to a WBMP struct.
149 **
150 */
151int
152readwbmp (int (*getin) (void *in), void *in, Wbmp ** return_wbmp)
153{
154 int row, col, byte, pel, pos;
155 Wbmp *wbmp;
156
157 if ((wbmp = (Wbmp *) gdMalloc (sizeof (Wbmp))) == NULL)
158 return (-1);
159
160 wbmp->type = getin (in);
161 if (wbmp->type != 0)
162 {
163 gdFree (wbmp);
164 return (-1);
165 }
166
167 if (skipheader (getin, in))
168 {
169 gdFree (wbmp);
170 return (-1);
171 }
172
173
174 wbmp->width = getmbi (getin, in);
175 if (wbmp->width == -1)
176 {
177 gdFree (wbmp);
178 return (-1);
179 }
180
181 wbmp->height = getmbi (getin, in);
182 if (wbmp->height == -1)
183 {
184 gdFree (wbmp);
185 return (-1);
186 }
187
188#ifdef __DEBUG
189 printf ("W: %d, H: %d\n", wbmp->width, wbmp->height);
190#endif
191
192 if (overflow2(sizeof (int), wbmp->width) ||
193 overflow2(sizeof (int) * wbmp->width, wbmp->height))
194 {
195 gdFree(wbmp);
196 return (-1);
197 }
198
199 if ((wbmp->bitmap = (int *) safe_emalloc((size_t)wbmp->width * wbmp->height, sizeof(int), 0)) == NULL)
200 {
201 gdFree (wbmp);
202 return (-1);
203 }
204
205#ifdef __DEBUG
206 printf ("DATA CONSTRUCTED\n");
207#endif
208
209 pos = 0;
210 for (row = 0; row < wbmp->height; row++)
211 {
212 for (col = 0; col < wbmp->width;)
213 {
214 byte = getin (in);
215
216 for (pel = 7; pel >= 0; pel--)
217 {
218 if (col++ < wbmp->width)
219 {
220 if (byte & 1 << pel)
221 {
222 wbmp->bitmap[pos] = WBMP_WHITE;
223 }
224 else
225 {
226 wbmp->bitmap[pos] = WBMP_BLACK;
227 }
228 pos++;
229 }
230 }
231 }
232 }
233
234 *return_wbmp = wbmp;
235
236 return (0);
237}
238
239
240/* writewbmp
241 ** ---------
242 ** Write a wbmp to a file descriptor
243 **
244 ** Why not just giving a filedescriptor to this function?
245 ** Well, the incentive to write this function was the complete
246 ** integration in gd library from www.boutell.com. They use
247 ** their own io functions, so the passing of a function seemed to be
248 ** a logic(?) decision ...
249 **
250 */
251int
252writewbmp (Wbmp * wbmp, void (*putout) (int c, void *out), void *out)
253{
254 int row, col;
255 int bitpos, octet;
256
257 /* Generate the header */
258 putout (0, out); /* WBMP Type 0: B/W, Uncompressed bitmap */
259 putout (0, out); /* FixHeaderField */
260
261
262
263 /* Size of the image */
264 putmbi (wbmp->width, putout, out); /* width */
265 putmbi (wbmp->height, putout, out); /* height */
266
267
268 /* Image data */
269 for (row = 0; row < wbmp->height; row++)
270 {
271 bitpos = 8;
272 octet = 0;
273 for (col = 0; col < wbmp->width; col++)
274 {
275 octet |= ((wbmp->bitmap[row * wbmp->width + col] == 1) ? WBMP_WHITE : WBMP_BLACK) << --bitpos;
276 if (bitpos == 0)
277 {
278 bitpos = 8;
279 putout (octet, out);
280 octet = 0;
281 }
282 }
283 if (bitpos != 8)
284 putout (octet, out);
285
286 }
287 return (0);
288
289}
290
291
292/* freewbmp
293 ** --------
294 ** gdFrees up memory occupied by a WBMP structure
295 **
296 */
297void
299{
300 gdFree (wbmp->bitmap);
301 gdFree (wbmp);
302}
303
304
305/* printwbmp
306 ** ---------
307 ** print a WBMP to stdout for visualisation
308 **
309 */
310void
312{
313 int row, col;
314 for (row = 0; row < wbmp->height; row++)
315 {
316 for (col = 0; col < wbmp->width; col++)
317 {
318 if (wbmp->bitmap[wbmp->width * row + col] == WBMP_BLACK)
319 {
320 putchar ('#');
321 }
322 else
323 {
324 putchar (' ');
325 }
326 }
327 putchar ('\n');
328 }
329}
330
331#ifdef __TEST
332
333/* putout to file descriptor
334 ** -------------------------
335 */
336int
337putout (int c, void *out)
338{
339 return (putc (c, (FILE *) out));
340}
341
342/* getin from file descriptor
343 ** --------------------------
344 */
345int
346getin (void *in)
347{
348 return (getc ((FILE *) in));
349}
350
351
352/* Main function
353 ** -------------
354 **
355 */
356int
357main (int argc, char *argv[])
358{
359 FILE *wbmp_file;
360 Wbmp *wbmp;
361
362 wbmp_file = fopen (argv[1], "rb");
363 if (wbmp_file)
364 {
365 readwbmp (&getin, wbmp_file, &wbmp);
366
367#ifdef __VIEW
368
369#ifdef __DEBUG
370 printf ("\nVIEWING IMAGE\n");
371#endif
372
373 printwbmp (wbmp);
374#endif
375
376#ifdef __WRITE
377
378#ifdef __DEBUG
379 printf ("\nDUMPING WBMP to STDOUT\n");
380#endif
381
382 writewbmp (wbmp, &putout, stdout);
383#endif
384
385 freewbmp (wbmp);
386 fclose (wbmp_file);
387 }
388}
389#endif
printf(string $format, mixed ... $values)
fclose($stream)
fopen(string $filename, string $mode, bool $use_include_path=false, $context=null)
int overflow2(int a, int b)
Definition gd_compat.c:10
#define NULL
Definition gdcache.h:45
int main(void)
Definition gddemo.c:7
#define gdFree(ptr)
Definition gdhelpers.h:19
#define gdMalloc(size)
Definition gdhelpers.h:16
short color
unsigned const char * pos
Definition php_ffi.h:52
int width
Definition wbmp.h:30
int * bitmap
Definition wbmp.h:32
int height
Definition wbmp.h:31
int type
Definition wbmp.h:29
Wbmp * createwbmp(int width, int height, int color)
Definition wbmp.c:112
int getmbi(int(*getin)(void *in), void *in)
Definition wbmp.c:38
int skipheader(int(*getin)(void *in), void *in)
Definition wbmp.c:91
int writewbmp(Wbmp *wbmp, void(*putout)(int c, void *out), void *out)
Definition wbmp.c:252
void printwbmp(Wbmp *wbmp)
Definition wbmp.c:311
int readwbmp(int(*getin)(void *in), void *in, Wbmp **return_wbmp)
Definition wbmp.c:152
void putmbi(int i, void(*putout)(int c, void *out), void *out)
Definition wbmp.c:65
void freewbmp(Wbmp *wbmp)
Definition wbmp.c:298
#define WBMP_WHITE
Definition wbmp.h:35
struct Wbmp_ Wbmp
#define WBMP_BLACK
Definition wbmp.h:36
#define safe_emalloc(nmemb, size, offset)
Definition zend_alloc.h:154
out($f, $s)