/* * The data returned by the following routine is always in left-most byte * first and left-most bit first. If it doesn't return BitmapSuccess then * its arguments won't have been touched. This routine should look as much * like the Xlib routine XReadBitmapfile as possible. */ int XmuReadBitmapData(FILE *fstream, unsigned int *width, unsigned int *height, unsigned char **datap, int *x_hot, int *y_hot) { unsigned char *data = NULL; /* working variable */ char line[MAX_SIZE]; /* input line from file */ int size; /* number of bytes of data */ char name_and_type[MAX_SIZE]; /* an input line */ char *type; /* for parsing */ int value; /* from an input line */ int version10p; /* boolean, old format */ int padding; /* to handle alignment */ int bytes_per_line; /* per scanline of data */ unsigned int ww = 0; /* width */ unsigned int hh = 0; /* height */ int hx = -1; /* x hotspot */ int hy = -1; /* y hotspot */ #undef Xmalloc /* see MALLOC_0_RETURNS_NULL in Xlibint.h */ #define Xmalloc(size) malloc(size) /* first time initialization */ if (initialized == False) initHexTable(); while (fgets(line, MAX_SIZE, fstream)) { if (strlen(line) == MAX_SIZE-1) { free (data); return BitmapFileInvalid; } if (sscanf(line,"#define %s %d",name_and_type,&value) == 2) { if (!(type = strrchr(name_and_type, '_'))) type = name_and_type; else type++; if (!strcmp("width", type)) ww = (unsigned int) value; if (!strcmp("height", type)) hh = (unsigned int) value; if (!strcmp("hot", type)) { if (type-- == name_and_type || type-- == name_and_type) continue; if (!strcmp("x_hot", type)) hx = value; if (!strcmp("y_hot", type)) hy = value; } continue; } if (sscanf(line, "static short %s = {", name_and_type) == 1) version10p = 1; else if (sscanf(line,"static unsigned char %s = {",name_and_type) == 1) version10p = 0; else if (sscanf(line, "static char %s = {", name_and_type) == 1) version10p = 0; else continue; if (!(type = strrchr(name_and_type, '_'))) type = name_and_type; else type++; if (strcmp("bits[]", type)) continue; if (!ww || !hh){ free (data); return BitmapFileInvalid; } if ((ww % 16) && ((ww % 16) < 9) && version10p) padding = 1; else padding = 0; bytes_per_line = (ww+7)/8 + padding; size = bytes_per_line * hh; data = (unsigned char *) Xmalloc ((unsigned int) size); if (!data) return BitmapNoMemory; if (version10p) { unsigned char *ptr; int bytes; for (bytes=0, ptr=data; bytes<size; (bytes += 2)) { if ((value = NextInt(fstream)) < 0) { free(data); return BitmapFileInvalid; } *(ptr++) = value; if (!padding || ((bytes+2) % bytes_per_line)) *(ptr++) = value >> 8; } } else { unsigned char *ptr; int bytes; for (bytes=0, ptr=data; bytes<size; bytes++, ptr++) { if ((value = NextInt(fstream)) < 0){ free(data); return BitmapFileInvalid; } *ptr=value; } } break; } /* end while */
static unsigned char * read_x11_bitmap_file(IOSTREAM *fd, int *w, int *h) { unsigned char *data = NULL; char line[LINESIZE]; int size = 0; char name_and_type[LINESIZE]; /* an input line */ char *type; /* for parsing */ int value; /* from an input line */ int version10p; /* bool, old format */ int padding; /* to handle alignment */ int bytes_per_line; /* per scanline of data */ unsigned int ww = 0; /* width */ unsigned int hh = 0; /* height */ int hx = -1; /* x hotspot */ int hy = -1; /* y hotspot */ if (initialized == FALSE) initHexTable(); #define RETURN_ERROR { if (data) XFree(data); return NULL; } while (Sfgets(line, LINESIZE, fd)) { if ( sscanf(line,"#define %s %d",name_and_type,&value) == 2) { if (!(type = strrchr(name_and_type, '_'))) type = name_and_type; else type++; if (!strcmp("width", type)) ww = (unsigned int) value; if (!strcmp("height", type)) hh = (unsigned int) value; if (!strcmp("hot", type)) { if (type-- == name_and_type || type-- == name_and_type) continue; if (!strcmp("x_hot", type)) hx = value; if (!strcmp("y_hot", type)) hy = value; } continue; } if (sscanf(line, "static short %s = {", name_and_type) == 1) version10p = 1; else if (sscanf(line,"static unsigned char %s = {",name_and_type) == 1) version10p = 0; else if (sscanf(line, "static char %s = {", name_and_type) == 1) version10p = 0; else continue; if (!(type = strrchr(name_and_type, '_'))) type = name_and_type; else type++; if (strcmp("bits[]", type)) continue; if (!ww || !hh) RETURN_ERROR; if ((ww % 16) && ((ww % 16) < 9) && version10p) padding = 1; else padding = 0; bytes_per_line = (ww+7)/8 + padding; size = bytes_per_line * hh; data = (unsigned char *) malloc(size); if (version10p) { unsigned char *ptr; int bytes; for (bytes=0, ptr=data; bytes<size; (bytes += 2)) { if ((value = NextInt(fd)) < 0) RETURN_ERROR; *(ptr++) = value; if (!padding || ((bytes+2) % bytes_per_line)) *(ptr++) = value >> 8; } } else { unsigned char *ptr; int bytes; for (bytes=0, ptr=data; bytes<size; bytes++, ptr++) { if ((value = NextInt(fd)) < 0) RETURN_ERROR; *ptr=value; } } }