Kannel: Open Source WAP and SMS gateway  $Revision: 5037 $
seewbmp.c
Go to the documentation of this file.
1 /* ====================================================================
2  * The Kannel Software License, Version 1.0
3  *
4  * Copyright (c) 2001-2016 Kannel Group
5  * Copyright (c) 1998-2001 WapIT Ltd.
6  * All rights reserved.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions
10  * are met:
11  *
12  * 1. Redistributions of source code must retain the above copyright
13  * notice, this list of conditions and the following disclaimer.
14  *
15  * 2. Redistributions in binary form must reproduce the above copyright
16  * notice, this list of conditions and the following disclaimer in
17  * the documentation and/or other materials provided with the
18  * distribution.
19  *
20  * 3. The end-user documentation included with the redistribution,
21  * if any, must include the following acknowledgment:
22  * "This product includes software developed by the
23  * Kannel Group (http://www.kannel.org/)."
24  * Alternately, this acknowledgment may appear in the software itself,
25  * if and wherever such third-party acknowledgments normally appear.
26  *
27  * 4. The names "Kannel" and "Kannel Group" must not be used to
28  * endorse or promote products derived from this software without
29  * prior written permission. For written permission, please
30  * contact org@kannel.org.
31  *
32  * 5. Products derived from this software may not be called "Kannel",
33  * nor may "Kannel" appear in their name, without prior written
34  * permission of the Kannel Group.
35  *
36  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
37  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
38  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
39  * DISCLAIMED. IN NO EVENT SHALL THE KANNEL GROUP OR ITS CONTRIBUTORS
40  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
41  * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
42  * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
43  * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
44  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
45  * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
46  * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
47  * ====================================================================
48  *
49  * This software consists of voluntary contributions made by many
50  * individuals on behalf of the Kannel Group. For more information on
51  * the Kannel Group, please see <http://www.kannel.org/>.
52  *
53  * Portions of this software are based upon software originally written at
54  * WapIT Ltd., Helsinki, Finland for the Kannel project.
55  */
56 
57 /* seebmp -- simple viewer for WBMP images (image/vnd.wap.wbmp) */
58 
59 /*
60  *
61  * Copyright (c) Richard Braakman <dark@xs4all.nl>
62  * All rights reserved.
63  *
64  * Redistribution and use in source and binary forms, with or without
65  * modification, are permitted provided that the following conditions
66  * are met:
67  * 1. Redistributions of source code must retain the above copyright
68  * notice, this list of conditions and the following disclaimer.
69  * 2. Redistributions in binary form must reproduce the above copyright
70  * notice, this list of conditions and the following disclaimer in the
71  * documentation and/or other materials provided with the distribution.
72  *
73  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
74  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
75  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
76  * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
77  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
78  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
79  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
80  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
81  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
82  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
83  * SUCH DAMAGE.
84  *
85  */
86 
87 
88 #include <stdio.h>
89 #include <stddef.h>
90 #include <stdlib.h>
91 #include <string.h>
92 
93 /* The spec includes a multi-byte integer format. For reasons of simplicity, we
94  * only handle integers that end up fitting in 31 bits. This limits picture
95  * sizes to about 2 billion pixels width or height, which I think we can live
96  * with. */
97 /* The function returns -1 in case of an error. */
98 static long get_mbi(FILE *infile) {
99  int c;
100  long result = 0;
101 
102  do {
103  c = getc(infile);
104  if (c < 0) return -1;
105  result = (result << 7) | (c & 0x7f);
106  } while (c & 0x80);
107 
108  return result;
109 }
110 
111 /* This function is like get_mbi, but it ignores the value of the result.
112  * So it's not limited to 31 bits, and it ends up skipping all bytes that
113  * have their high bit set. */
114 /* The function returns 0 for success, or -1 in case of an error. */
115 static int skip_mbi(FILE *infile) {
116  int c;
117 
118  do {
119  c = getc(infile);
120  if (c < 0) return -1;
121  } while (c & 0x80);
122 
123  return 0;
124 }
125 
126 static int show_image_from_file(char *bmpname, FILE *bmpfile,
127  long width, long height) {
128  long w, h;
129 
130  for (h = 0; h < height; h++) {
131  /* w is incremented in its inner loop */
132  for (w = 0; w < width; ) {
133  int c;
134  unsigned int bit;
135 
136  c = getc(bmpfile);
137  if (c < 0) {
138  perror(bmpname);
139  return -1;
140  }
141 
142  for (bit = 0x80; bit > 0 && w < width; bit >>= 1, w++) {
143  putc((c & bit) ? '*' : ' ', stdout);
144  }
145  }
146  putc('\n', stdout);
147  }
148 
149  return 0;
150 }
151 
152 /* These are global because that's easier. In a real parser they would
153  * be part of an image descriptor structure */
154 struct parm {
155  struct parm *next;
156  char *name;
157  char *value;
158 };
159 
160 struct parm *extparms = NULL;
161 
162 static void clear_extparms(void) {
163  while (extparms) {
164  struct parm *tmp = extparms;
165  extparms = extparms->next;
166  free(tmp->name);
167  free(tmp->value);
168  free(tmp);
169  }
170 }
171 
172 /* Record a new parameter. The name and value will be used directly,
173  * not copied. */
174 static int new_extparm(char *name, char *value) {
175  struct parm *new;
176  struct parm *p;
177 
178  /* Construct a new node */
179  new = (struct parm *)malloc(sizeof(struct parm));
180  if (!new)
181  return -1;
182 
183  new->name = name;
184  new->value = value;
185  new->next = NULL;
186 
187  /* Add it to the end of the list. */
188  if (!extparms) {
189  extparms = new;
190  } else {
191  p = extparms;
192  while (p->next) {
193  p = p->next;
194  }
195  p->next = new;
196  }
197 
198  return 0;
199 }
200 
201 static void print_extparms(FILE *outfile) {
202  struct parm *p;
203 
204  for (p = extparms; p; p = p->next) {
205  fprintf(outfile, "%s=%s\n", p->name, p->value);
206  }
207 }
208 
209 static int parse_headers(FILE *bmpfile) {
210  int c;
211  int exttype;
212 
213  clear_extparms();
214 
215  c = getc(bmpfile);
216  if (c < 0) return -1;
217  if (!(c & 0x80)) {
218  /* No extension headers follow */
219  return 0;
220  }
221  exttype = (c >> 5) & 0x03;
222  /* None of these headers do much at this time, but they
223  * might be meaningful with later specifications */
224  switch (exttype) {
225  case 0:
226  /* All we know of type 0 headers is that
227  * the high bit is a continuation bit.
228  * That makes them exactly like an MBI. */
229  if (skip_mbi(bmpfile) < 0) return -1;
230  break;
231  case 1: case 2:
232  /* We don't know what to do with these */
233  return -1;
234  case 3:
235  /* A sequence of parameter/value combinations */
236  do {
237  int namelen, valuelen;
238  char *name, *value;
239  c = getc(bmpfile);
240  if (c < 0) return -1;
241 
242  namelen = (c >> 4) & 0x07;
243  name = malloc(namelen + 1);
244  if (!name) return -1;
245  if (fread(name, namelen, 1, bmpfile) < (size_t) namelen)
246  return -1;
247 
248  valuelen = c & 0x0f;
249  value = malloc(valuelen + 1);
250  if (!value) { free(name); return -1; }
251  if (fread(value, valuelen, 1, bmpfile) < (size_t) valuelen)
252  return -1;
253 
254  new_extparm(name, value);
255  } while (c & 0x80);
256  break;
257  }
258  return 0;
259 }
260 
261 /* Return 0 for success, < 0 for failure */
262 static int show_wbmp_from_file(char *bmpname, FILE *bmpfile) {
263  long typefield;
264  long width, height;
265 
266  typefield = get_mbi(bmpfile);
267  if (typefield < 0) {
268  perror(bmpname);
269  return -1;
270  }
271 
272  if (parse_headers(bmpfile) < 0) {
273  fprintf(stderr, "%s: format error in headers\n", bmpname);
274  return -1;
275  }
276 
277  width = get_mbi(bmpfile);
278  height = get_mbi(bmpfile);
279  if (width < 0 || height < 0) {
280  fprintf(stderr, "%s: error reading height and width\n",
281  bmpname);
282  return -1;
283  }
284 
285  switch (typefield) {
286  case 0:
287  printf("%s, %ldx%ld B/W bitmap, no compression\n",
288  bmpname, width, height);
289  print_extparms(stdout);
290  if (show_image_from_file(bmpname, bmpfile,
291  width, height) < 0) {
292  return -1;
293  }
294  break;
295  default:
296  fprintf(stderr, "%s: cannot handle level %ld wbmp\n",
297  bmpname, typefield);
298  return -1;
299  }
300 
301  return 0;
302 }
303 
304 int main(int argc, char *argv[]) {
305  int i;
306  /* 1 means an I/O error. No other error values are used yet. */
307  int exitvalue = 0;
308 
309  if (argc > 1) {
310  for (i = 1; i < argc; i++) {
311  FILE *bmpfile;
312 
313  bmpfile = fopen(argv[i], "r");
314  if (bmpfile) {
315  if (show_wbmp_from_file(argv[i], bmpfile) < 0) {
316  /* We've already reported the error */
317  exitvalue = 1;
318  }
319  if (fclose(bmpfile) < 0) {
320  perror(argv[i]);
321  exitvalue = 1;
322  }
323  } else {
324  perror(argv[i]);
325  exitvalue = 1;
326  }
327  if (i < argc - 1) {
328  /* more files follow -- separate them */
329  printf("\n");
330  }
331  }
332  } else {
333  /* No files specified -- read from standard input */
334  if (show_wbmp_from_file("stdin", stdin)) {
335  exitvalue = 1;
336  }
337  }
338 
339  return exitvalue;
340 }
static void clear_extparms(void)
Definition: seewbmp.c:162
char * outfile
Definition: fakewap.c:248
static int new_extparm(char *name, char *value)
Definition: seewbmp.c:174
char * name
Definition: seewbmp.c:156
struct parm * extparms
Definition: seewbmp.c:160
static int show_image_from_file(char *bmpname, FILE *bmpfile, long width, long height)
Definition: seewbmp.c:126
static void print_extparms(FILE *outfile)
Definition: seewbmp.c:201
struct parm * next
Definition: seewbmp.c:155
char * value
Definition: seewbmp.c:157
#define free(p)
Definition: gwmem.h:194
char * name
Definition: smsc_cimd2.c:212
Definition: seewbmp.c:154
#define malloc(n)
Definition: gwmem.h:191
static int show_wbmp_from_file(char *bmpname, FILE *bmpfile)
Definition: seewbmp.c:262
static long get_mbi(FILE *infile)
Definition: seewbmp.c:98
char * infile
Definition: fakewap.c:247
int main(int argc, char *argv[])
Definition: seewbmp.c:304
static int parse_headers(FILE *bmpfile)
Definition: seewbmp.c:209
static int skip_mbi(FILE *infile)
Definition: seewbmp.c:115
See file LICENSE for details about the license agreement for using, modifying, copying or deriving work from this software.