Back to index

plt-scheme  4.2.1
wbmp.c
Go to the documentation of this file.
00001 
00002 /* WBMP
00003    ** ----
00004    ** WBMP Level 0: B/W, Uncompressed
00005    ** This implements the WBMP format as specified in WAPSpec 1.1 and 1.2.
00006    ** It does not support ExtHeaders as defined in the spec. The spec states
00007    ** that a WAP client does not need to implement ExtHeaders.
00008    **
00009    ** (c) 2000 Johan Van den Brande <johan@vandenbrande.com>
00010  */
00011 
00012 #ifdef HAVE_CONFIG_H
00013 #include "config.h"
00014 #endif
00015 
00016 #include <stdio.h>
00017 #include <stddef.h>
00018 #include <stdlib.h>
00019 #include <string.h>
00020 
00021 #include "wbmp.h"
00022 #include "gd.h"
00023 #include "gdhelpers.h"
00024 
00025 #ifdef NOTDEF
00026 #define __TEST                     /* Compile with main function */
00027 #define __DEBUG                    /* Extra verbose when with __TEST */
00028 #define __WRITE                    /* readwbmp and writewbmp(stdout) */
00029 #define __VIEW                     /* view the wbmp on stdout */
00030 #endif
00031 
00032 /* getmbi
00033    ** ------
00034    ** Get a multibyte integer from a generic getin function 
00035    ** 'getin' can be getc, with in = NULL
00036    ** you can find getin as a function just above the main function
00037    ** This way you gain a lot of flexibilty about how this package
00038    ** reads a wbmp file.
00039  */
00040 int
00041 getmbi (int (*getin) (void *in), void *in)
00042 {
00043   int i, mbi = 0;
00044 
00045   do
00046     {
00047       i = getin (in);
00048       if (i < 0)
00049        return (-1);
00050       mbi = (mbi << 7) | (i & 0x7f);
00051     }
00052   while (i & 0x80);
00053 
00054   return (mbi);
00055 }
00056 
00057 
00058 /* putmbi
00059    ** ------
00060    ** Put a multibyte intgerer in some kind of output stream
00061    ** I work here with a function pointer, to make it as generic
00062    ** as possible. Look at this function as an iterator on the
00063    ** mbi integers it spits out.
00064    **
00065  */
00066 void
00067 putmbi (int i, void (*putout) (int c, void *out), void *out)
00068 {
00069   int cnt, l, accu;
00070 
00071   /* Get number of septets */
00072   cnt = 0;
00073   accu = 0;
00074   while (accu != i)
00075     accu += i & 0x7f << 7 * cnt++;
00076 
00077   /* Produce the multibyte output */
00078   for (l = cnt - 1; l > 0; l--)
00079     putout (0x80 | (i & 0x7f << 7 * l) >> 7 * l, out);
00080 
00081   putout (i & 0x7f, out);
00082 
00083 }
00084 
00085 
00086 
00087 /* skipheader
00088    ** ----------
00089    ** Skips the ExtHeader. Not needed for the moment
00090    **
00091  */
00092 int
00093 skipheader (int (*getin) (void *in), void *in)
00094 {
00095   int i;
00096 
00097   do
00098     {
00099       i = getin (in);
00100       if (i < 0)
00101        return (-1);
00102     }
00103   while (i & 0x80);
00104 
00105   return (0);
00106 }
00107 
00108 /* create wbmp
00109    ** -----------
00110    ** create an empty wbmp
00111    **
00112  */
00113 Wbmp *
00114 createwbmp (int width, int height, int color)
00115 {
00116   int i;
00117 
00118   Wbmp *wbmp;
00119   if ((wbmp = (Wbmp *) gdMalloc (sizeof (Wbmp))) == NULL)
00120     return (NULL);
00121 
00122   if ((wbmp->bitmap =
00123        (int *) gdMalloc (sizeof (int) * width * height)) == NULL)
00124     {
00125       gdFree (wbmp);
00126       return (NULL);
00127     }
00128 
00129   wbmp->width = width;
00130   wbmp->height = height;
00131 
00132   for (i = 0; i < width * height; wbmp->bitmap[i++] = color);
00133 
00134   return (wbmp);
00135 }
00136 
00137 
00138 
00139 /* readwbmp
00140    ** -------
00141    ** Actually reads the WBMP format from an open file descriptor
00142    ** It goes along by returning a pointer to a WBMP struct.
00143    **
00144  */
00145 int
00146 readwbmp (int (*getin) (void *in), void *in, Wbmp ** return_wbmp)
00147 {
00148   int row, col, byte, pel, pos;
00149   Wbmp *wbmp;
00150 
00151   if ((wbmp = (Wbmp *) gdMalloc (sizeof (Wbmp))) == NULL)
00152     return (-1);
00153 
00154   wbmp->type = getin (in);
00155   if (wbmp->type != 0)
00156     {
00157       gdFree (wbmp);
00158       return (-1);
00159     }
00160 
00161   if (skipheader (getin, in))
00162     return (-1);
00163 
00164 
00165   wbmp->width = getmbi (getin, in);
00166   if (wbmp->width == -1)
00167     {
00168       gdFree (wbmp);
00169       return (-1);
00170     }
00171 
00172   wbmp->height = getmbi (getin, in);
00173   if (wbmp->height == -1)
00174     {
00175       gdFree (wbmp);
00176       return (-1);
00177     }
00178 
00179 #ifdef __DEBUG
00180   printf ("W: %d, H: %d\n", wbmp->width, wbmp->height);
00181 #endif
00182 
00183   if ((wbmp->bitmap =
00184        (int *) gdMalloc (sizeof (int) * wbmp->width * wbmp->height)) == NULL)
00185     {
00186       gdFree (wbmp);
00187       return (-1);
00188     }
00189 
00190 #ifdef __DEBUG
00191   printf ("DATA CONSTRUCTED\n");
00192 #endif
00193 
00194   pos = 0;
00195   for (row = 0; row < wbmp->height; row++)
00196     {
00197       for (col = 0; col < wbmp->width;)
00198        {
00199          byte = getin (in);
00200 
00201          for (pel = 7; pel >= 0; pel--)
00202            {
00203              if (col++ < wbmp->width)
00204               {
00205                 if (byte & 1 << pel)
00206                   {
00207                     wbmp->bitmap[pos] = WBMP_WHITE;
00208                   }
00209                 else
00210                   {
00211                     wbmp->bitmap[pos] = WBMP_BLACK;
00212                   }
00213                 pos++;
00214               }
00215            }
00216        }
00217     }
00218 
00219   *return_wbmp = wbmp;
00220 
00221   return (0);
00222 }
00223 
00224 
00225 /* writewbmp
00226    ** ---------
00227    ** Write a wbmp to a file descriptor
00228    **
00229    ** Why not just giving a filedescriptor to this function?
00230    ** Well, the incentive to write this function was the complete
00231    ** integration in gd library from www.boutell.com. They use
00232    ** their own io functions, so the passing of a function seemed to be 
00233    ** a logic(?) decision ...
00234    **
00235  */
00236 int
00237 writewbmp (Wbmp * wbmp, void (*putout) (int c, void *out), void *out)
00238 {
00239   int row, col;
00240   int bitpos, octet;
00241 
00242   /* Generate the header */
00243   putout (0, out);          /* WBMP Type 0: B/W, Uncompressed bitmap */
00244   putout (0, out);          /* FixHeaderField */
00245 
00246 
00247 
00248   /* Size of the image */
00249   putmbi (wbmp->width, putout, out);      /* width */
00250   putmbi (wbmp->height, putout, out);     /* height */
00251 
00252 
00253   /* Image data */
00254   for (row = 0; row < wbmp->height; row++)
00255     {
00256       bitpos = 8;
00257       octet = 0;
00258       for (col = 0; col < wbmp->width; col++)
00259        {
00260          octet |=
00261            ((wbmp->bitmap[row * wbmp->width + col] ==
00262              1) ? WBMP_WHITE : WBMP_BLACK) << --bitpos;
00263          if (bitpos == 0)
00264            {
00265              bitpos = 8;
00266              putout (octet, out);
00267              octet = 0;
00268            }
00269        }
00270       if (bitpos != 8)
00271        putout (octet, out);
00272 
00273     }
00274   return (0);
00275 
00276 }
00277 
00278 
00279 /* freewbmp
00280    ** --------
00281    ** gdFrees up memory occupied by a WBMP structure
00282    **
00283  */
00284 void
00285 freewbmp (Wbmp * wbmp)
00286 {
00287   gdFree (wbmp->bitmap);
00288   gdFree (wbmp);
00289 }
00290 
00291 
00292 /* printwbmp
00293    ** ---------
00294    ** print a WBMP to stdout for visualisation
00295    **
00296  */
00297 void
00298 printwbmp (Wbmp * wbmp)
00299 {
00300   int row, col;
00301   for (row = 0; row < wbmp->height; row++)
00302     {
00303       for (col = 0; col < wbmp->width; col++)
00304        {
00305          if (wbmp->bitmap[wbmp->width * row + col] == WBMP_BLACK)
00306            {
00307              putchar ('#');
00308            }
00309          else
00310            {
00311              putchar (' ');
00312            }
00313        }
00314       putchar ('\n');
00315     }
00316 }
00317 
00318 #ifdef __TEST
00319 
00320 /* putout to file descriptor
00321    ** -------------------------
00322  */
00323 int
00324 putout (int c, void *out)
00325 {
00326   return (putc (c, (FILE *) out));
00327 }
00328 
00329 /* getin from file descriptor 
00330    ** --------------------------
00331  */
00332 int
00333 getin (void *in)
00334 {
00335   return (getc ((FILE *) in));
00336 }
00337 
00338 
00339 /* Main function
00340    ** -------------
00341    **
00342  */
00343 int
00344 main (int argc, char *argv[])
00345 {
00346   FILE *wbmp_file;
00347   Wbmp *wbmp;
00348 
00349   wbmp_file = fopen (argv[1], "rb");
00350   if (wbmp_file)
00351     {
00352       readwbmp (&getin, wbmp_file, &wbmp);
00353 
00354 #ifdef __VIEW
00355 
00356 #ifdef __DEBUG
00357       printf ("\nVIEWING IMAGE\n");
00358 #endif
00359 
00360       printwbmp (wbmp);
00361 #endif
00362 
00363 #ifdef __WRITE
00364 
00365 #ifdef __DEBUG
00366       printf ("\nDUMPING WBMP to STDOUT\n");
00367 #endif
00368 
00369       writewbmp (wbmp, &putout, stdout);
00370 #endif
00371 
00372       freewbmp (wbmp);
00373       fclose (wbmp_file);
00374     }
00375 }
00376 #endif