123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388 |
- /* WBMP
- ** ----
- ** WBMP Level 0: B/W, Uncompressed
- ** This implements the WBMP format as specified in WAPSpec 1.1 and 1.2.
- ** It does not support ExtHeaders as defined in the spec. The spec states
- ** that a WAP client does not need to implement ExtHeaders.
- **
- ** (c) 2000 Johan Van den Brande <johan@vandenbrande.com>
- */
- #include <stdio.h>
- #include <stddef.h>
- #include <stdlib.h>
- #include <string.h>
- #include "wbmp.h"
- #include "gd.h"
- #include "gdhelpers.h"
- #ifdef NOTDEF
- #define __TEST /* Compile with main function */
- #define __DEBUG /* Extra verbose when with __TEST */
- #define __WRITE /* readwbmp and writewbmp(stdout) */
- #define __VIEW /* view the wbmp on stdout */
- #endif
- /* getmbi
- ** ------
- ** Get a multibyte integer from a generic getin function
- ** 'getin' can be getc, with in = NULL
- ** you can find getin as a function just above the main function
- ** This way you gain a lot of flexibilty about how this package
- ** reads a wbmp file.
- */
- int
- getmbi (int (*getin) (void *in), void *in)
- {
- int i, mbi = 0;
- do
- {
- i = getin (in);
- if (i < 0)
- return (-1);
- mbi = (mbi << 7) | (i & 0x7f);
- }
- while (i & 0x80);
- return (mbi);
- }
- /* putmbi
- ** ------
- ** Put a multibyte intgerer in some kind of output stream
- ** I work here with a function pointer, to make it as generic
- ** as possible. Look at this function as an iterator on the
- ** mbi integers it spits out.
- **
- */
- void
- putmbi (int i, void (*putout) (int c, void *out), void *out)
- {
- int cnt, l, accu;
- /* Get number of septets */
- cnt = 0;
- accu = 0;
- while (accu != i)
- accu += i & 0x7f << 7 * cnt++;
- /* Produce the multibyte output */
- for (l = cnt - 1; l > 0; l--)
- putout (0x80 | (i & 0x7f << 7 * l) >> 7 * l, out);
- putout (i & 0x7f, out);
- }
- /* skipheader
- ** ----------
- ** Skips the ExtHeader. Not needed for the moment
- **
- */
- int
- skipheader (int (*getin) (void *in), void *in)
- {
- int i;
- do
- {
- i = getin (in);
- if (i < 0)
- return (-1);
- }
- while (i & 0x80);
- return (0);
- }
- /* create wbmp
- ** -----------
- ** create an empty wbmp
- **
- */
- Wbmp *
- createwbmp (int width, int height, int color)
- {
- int i;
- Wbmp *wbmp;
- if ((wbmp = (Wbmp *) gdMalloc (sizeof (Wbmp))) == NULL)
- return (NULL);
- if (overflow2(sizeof (int), width)) {
- gdFree(wbmp);
- return NULL;
- }
- if (overflow2(sizeof (int) * width, height)) {
- gdFree(wbmp);
- return NULL;
- }
- if ((wbmp->bitmap = (int *) safe_emalloc(sizeof(int), width * height, 0)) == NULL)
- {
- gdFree (wbmp);
- return (NULL);
- }
- wbmp->width = width;
- wbmp->height = height;
- for (i = 0; i < width * height; wbmp->bitmap[i++] = color);
- return (wbmp);
- }
- /* readwbmp
- ** -------
- ** Actually reads the WBMP format from an open file descriptor
- ** It goes along by returning a pointer to a WBMP struct.
- **
- */
- int
- readwbmp (int (*getin) (void *in), void *in, Wbmp ** return_wbmp)
- {
- int row, col, byte, pel, pos;
- Wbmp *wbmp;
- if ((wbmp = (Wbmp *) gdMalloc (sizeof (Wbmp))) == NULL)
- return (-1);
- wbmp->type = getin (in);
- if (wbmp->type != 0)
- {
- gdFree (wbmp);
- return (-1);
- }
- if (skipheader (getin, in))
- {
- gdFree (wbmp);
- return (-1);
- }
- wbmp->width = getmbi (getin, in);
- if (wbmp->width == -1)
- {
- gdFree (wbmp);
- return (-1);
- }
- wbmp->height = getmbi (getin, in);
- if (wbmp->height == -1)
- {
- gdFree (wbmp);
- return (-1);
- }
- #ifdef __DEBUG
- printf ("W: %d, H: %d\n", wbmp->width, wbmp->height);
- #endif
- if (overflow2(sizeof (int), wbmp->width) ||
- overflow2(sizeof (int) * wbmp->width, wbmp->height))
- {
- gdFree(wbmp);
- return (-1);
- }
- if ((wbmp->bitmap = (int *) safe_emalloc((size_t)wbmp->width * wbmp->height, sizeof(int), 0)) == NULL)
- {
- gdFree (wbmp);
- return (-1);
- }
- #ifdef __DEBUG
- printf ("DATA CONSTRUCTED\n");
- #endif
- pos = 0;
- for (row = 0; row < wbmp->height; row++)
- {
- for (col = 0; col < wbmp->width;)
- {
- byte = getin (in);
- for (pel = 7; pel >= 0; pel--)
- {
- if (col++ < wbmp->width)
- {
- if (byte & 1 << pel)
- {
- wbmp->bitmap[pos] = WBMP_WHITE;
- }
- else
- {
- wbmp->bitmap[pos] = WBMP_BLACK;
- }
- pos++;
- }
- }
- }
- }
- *return_wbmp = wbmp;
- return (0);
- }
- /* writewbmp
- ** ---------
- ** Write a wbmp to a file descriptor
- **
- ** Why not just giving a filedescriptor to this function?
- ** Well, the incentive to write this function was the complete
- ** integration in gd library from www.boutell.com. They use
- ** their own io functions, so the passing of a function seemed to be
- ** a logic(?) decision ...
- **
- */
- int
- writewbmp (Wbmp * wbmp, void (*putout) (int c, void *out), void *out)
- {
- int row, col;
- int bitpos, octet;
- /* Generate the header */
- putout (0, out); /* WBMP Type 0: B/W, Uncompressed bitmap */
- putout (0, out); /* FixHeaderField */
- /* Size of the image */
- putmbi (wbmp->width, putout, out); /* width */
- putmbi (wbmp->height, putout, out); /* height */
- /* Image data */
- for (row = 0; row < wbmp->height; row++)
- {
- bitpos = 8;
- octet = 0;
- for (col = 0; col < wbmp->width; col++)
- {
- octet |= ((wbmp->bitmap[row * wbmp->width + col] == 1) ? WBMP_WHITE : WBMP_BLACK) << --bitpos;
- if (bitpos == 0)
- {
- bitpos = 8;
- putout (octet, out);
- octet = 0;
- }
- }
- if (bitpos != 8)
- putout (octet, out);
- }
- return (0);
- }
- /* freewbmp
- ** --------
- ** gdFrees up memory occupied by a WBMP structure
- **
- */
- void
- freewbmp (Wbmp * wbmp)
- {
- gdFree (wbmp->bitmap);
- gdFree (wbmp);
- }
- /* printwbmp
- ** ---------
- ** print a WBMP to stdout for visualisation
- **
- */
- void
- printwbmp (Wbmp * wbmp)
- {
- int row, col;
- for (row = 0; row < wbmp->height; row++)
- {
- for (col = 0; col < wbmp->width; col++)
- {
- if (wbmp->bitmap[wbmp->width * row + col] == WBMP_BLACK)
- {
- putchar ('#');
- }
- else
- {
- putchar (' ');
- }
- }
- putchar ('\n');
- }
- }
- #ifdef __TEST
- /* putout to file descriptor
- ** -------------------------
- */
- int
- putout (int c, void *out)
- {
- return (putc (c, (FILE *) out));
- }
- /* getin from file descriptor
- ** --------------------------
- */
- int
- getin (void *in)
- {
- return (getc ((FILE *) in));
- }
- /* Main function
- ** -------------
- **
- */
- int
- main (int argc, char *argv[])
- {
- FILE *wbmp_file;
- Wbmp *wbmp;
- wbmp_file = fopen (argv[1], "rb");
- if (wbmp_file)
- {
- readwbmp (&getin, wbmp_file, &wbmp);
- #ifdef __VIEW
- #ifdef __DEBUG
- printf ("\nVIEWING IMAGE\n");
- #endif
- printwbmp (wbmp);
- #endif
- #ifdef __WRITE
- #ifdef __DEBUG
- printf ("\nDUMPING WBMP to STDOUT\n");
- #endif
- writewbmp (wbmp, &putout, stdout);
- #endif
- freewbmp (wbmp);
- fclose (wbmp_file);
- }
- }
- #endif
|