root/ext/gd/libgd/wbmp.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. getmbi
  2. putmbi
  3. skipheader
  4. createwbmp
  5. readwbmp
  6. writewbmp
  7. freewbmp
  8. printwbmp
  9. putout
  10. getin
  11. main

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

/* [<][>][^][v][top][bottom][index][help] */