#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
#define __DEBUG
#define __WRITE
#define __VIEW
#endif
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);
}
void
putmbi (int i, void (*putout) (int c, void *out), void *out)
{
int cnt, l, accu;
cnt = 0;
accu = 0;
while (accu != i)
accu += i & 0x7f << 7 * cnt++;
for (l = cnt - 1; l > 0; l--)
putout (0x80 | (i & 0x7f << 7 * l) >> 7 * l, out);
putout (i & 0x7f, out);
}
int
skipheader (int (*getin) (void *in), void *in)
{
int i;
do
{
i = getin (in);
if (i < 0)
return (-1);
}
while (i & 0x80);
return (0);
}
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);
}
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))
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);
}
int
writewbmp (Wbmp * wbmp, void (*putout) (int c, void *out), void *out)
{
int row, col;
int bitpos, octet;
putout (0, out);
putout (0, out);
putmbi (wbmp->width, putout, out);
putmbi (wbmp->height, putout, out);
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);
}
void
freewbmp (Wbmp * wbmp)
{
gdFree (wbmp->bitmap);
gdFree (wbmp);
}
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
int
putout (int c, void *out)
{
return (putc (c, (FILE *) out));
}
int
getin (void *in)
{
return (getc ((FILE *) in));
}
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