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