home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / gd201.zip / gd-2.0.1 / wbmp.c < prev    next >
C/C++ Source or Header  |  2001-04-03  |  7KB  |  370 lines

  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 ((wbmp->bitmap = (int *) gdMalloc (sizeof (int) * width * height)) == NULL)
  120.     {
  121.       gdFree (wbmp);
  122.       return (NULL);
  123.     }
  124.  
  125.   wbmp->width = width;
  126.   wbmp->height = height;
  127.  
  128.   for (i = 0; i < width * height; wbmp->bitmap[i++] = color);
  129.  
  130.   return (wbmp);
  131. }
  132.  
  133.  
  134.  
  135. /* readwbmp
  136.    ** -------
  137.    ** Actually reads the WBMP format from an open file descriptor
  138.    ** It goes along by returning a pointer to a WBMP struct.
  139.    **
  140.  */
  141. int
  142. readwbmp (int (*getin) (void *in), void *in, Wbmp ** return_wbmp)
  143. {
  144.   int row, col, byte, pel, pos;
  145.   Wbmp *wbmp;
  146.  
  147.   if ((wbmp = (Wbmp *) gdMalloc (sizeof (Wbmp))) == NULL)
  148.     return (-1);
  149.  
  150.   wbmp->type = getin (in);
  151.   if (wbmp->type != 0)
  152.     {
  153.       gdFree (wbmp);
  154.       return (-1);
  155.     }
  156.  
  157.   if (skipheader (getin, in))
  158.     return (-1);
  159.  
  160.  
  161.   wbmp->width = getmbi (getin, in);
  162.   if (wbmp->width == -1)
  163.     {
  164.       gdFree (wbmp);
  165.       return (-1);
  166.     }
  167.  
  168.   wbmp->height = getmbi (getin, in);
  169.   if (wbmp->height == -1)
  170.     {
  171.       gdFree (wbmp);
  172.       return (-1);
  173.     }
  174.  
  175. #ifdef __DEBUG
  176.   printf ("W: %d, H: %d\n", wbmp->width, wbmp->height);
  177. #endif
  178.  
  179.   if ((wbmp->bitmap = (int *) gdMalloc (sizeof (int) * wbmp->width * wbmp->height)) == NULL)
  180.     {
  181.       gdFree (wbmp);
  182.       return (-1);
  183.     }
  184.  
  185. #ifdef __DEBUG
  186.   printf ("DATA CONSTRUCTED\n");
  187. #endif
  188.  
  189.   pos = 0;
  190.   for (row = 0; row < wbmp->height; row++)
  191.     {
  192.       for (col = 0; col < wbmp->width;)
  193.     {
  194.       byte = getin (in);
  195.  
  196.       for (pel = 7; pel >= 0; pel--)
  197.         {
  198.           if (col++ < wbmp->width)
  199.         {
  200.           if (byte & 1 << pel)
  201.             {
  202.               wbmp->bitmap[pos] = WBMP_WHITE;
  203.             }
  204.           else
  205.             {
  206.               wbmp->bitmap[pos] = WBMP_BLACK;
  207.             }
  208.           pos++;
  209.         }
  210.         }
  211.     }
  212.     }
  213.  
  214.   *return_wbmp = wbmp;
  215.  
  216.   return (0);
  217. }
  218.  
  219.  
  220. /* writewbmp
  221.    ** ---------
  222.    ** Write a wbmp to a file descriptor
  223.    **
  224.    ** Why not just giving a filedescriptor to this function?
  225.    ** Well, the incentive to write this function was the complete
  226.    ** integration in gd library from www.boutell.com. They use
  227.    ** their own io functions, so the passing of a function seemed to be 
  228.    ** a logic(?) decision ...
  229.    **
  230.  */
  231. int
  232. writewbmp (Wbmp * wbmp, void (*putout) (int c, void *out), void *out)
  233. {
  234.   int row, col;
  235.   int bitpos, octet;
  236.  
  237.   /* Generate the header */
  238.   putout (0, out);        /* WBMP Type 0: B/W, Uncompressed bitmap */
  239.   putout (0, out);        /* FixHeaderField */
  240.  
  241.  
  242.  
  243.   /* Size of the image */
  244.   putmbi (wbmp->width, putout, out);    /* width */
  245.   putmbi (wbmp->height, putout, out);    /* height */
  246.  
  247.  
  248.   /* Image data */
  249.   for (row = 0; row < wbmp->height; row++)
  250.     {
  251.       bitpos = 8;
  252.       octet = 0;
  253.       for (col = 0; col < wbmp->width; col++)
  254.     {
  255.       octet |= ((wbmp->bitmap[row * wbmp->width + col] == 1) ? WBMP_WHITE : WBMP_BLACK) << --bitpos;
  256.       if (bitpos == 0)
  257.         {
  258.           bitpos = 8;
  259.           putout (octet, out);
  260.           octet = 0;
  261.         }
  262.     }
  263.       if (bitpos != 8)
  264.     putout (octet, out);
  265.  
  266.     }
  267.   return (0);
  268.  
  269. }
  270.  
  271.  
  272. /* freewbmp
  273.    ** --------
  274.    ** gdFrees up memory occupied by a WBMP structure
  275.    **
  276.  */
  277. void
  278. freewbmp (Wbmp * wbmp)
  279. {
  280.   gdFree (wbmp->bitmap);
  281.   gdFree (wbmp);
  282. }
  283.  
  284.  
  285. /* printwbmp
  286.    ** ---------
  287.    ** print a WBMP to stdout for visualisation
  288.    **
  289.  */
  290. void
  291. printwbmp (Wbmp * wbmp)
  292. {
  293.   int row, col;
  294.   for (row = 0; row < wbmp->height; row++)
  295.     {
  296.       for (col = 0; col < wbmp->width; col++)
  297.     {
  298.       if (wbmp->bitmap[wbmp->width * row + col] == WBMP_BLACK)
  299.         {
  300.           putchar ('#');
  301.         }
  302.       else
  303.         {
  304.           putchar (' ');
  305.         }
  306.     }
  307.       putchar ('\n');
  308.     }
  309. }
  310.  
  311. #ifdef __TEST
  312.  
  313. /* putout to file descriptor
  314.    ** -------------------------
  315.  */
  316. int
  317. putout (int c, void *out)
  318. {
  319.   return (putc (c, (FILE *) out));
  320. }
  321.  
  322. /* getin from file descriptor 
  323.    ** --------------------------
  324.  */
  325. int
  326. getin (void *in)
  327. {
  328.   return (getc ((FILE *) in));
  329. }
  330.  
  331.  
  332. /* Main function
  333.    ** -------------
  334.    **
  335.  */
  336. int
  337. main (int argc, char *argv[])
  338. {
  339.   FILE *wbmp_file;
  340.   Wbmp *wbmp;
  341.  
  342.   wbmp_file = fopen (argv[1], "rb");
  343.   if (wbmp_file)
  344.     {
  345.       readwbmp (&getin, wbmp_file, &wbmp);
  346.  
  347. #ifdef __VIEW
  348.  
  349. #ifdef __DEBUG
  350.       printf ("\nVIEWING IMAGE\n");
  351. #endif
  352.  
  353.       printwbmp (wbmp);
  354. #endif
  355.  
  356. #ifdef __WRITE
  357.  
  358. #ifdef __DEBUG
  359.       printf ("\nDUMPING WBMP to STDOUT\n");
  360. #endif
  361.  
  362.       writewbmp (wbmp, &putout, stdout);
  363. #endif
  364.  
  365.       freewbmp (wbmp);
  366.       fclose (wbmp_file);
  367.     }
  368. }
  369. #endif
  370.