Back to index

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