Path: utzoo!attcan!uunet!convex!killer!ames!vsi1!daver!athsys!jim From: jim@athsys.uucp (Jim Becker) Newsgroups: comp.windows.x Subject: XRdBitF.c: faster bitmap reading code for libX11.a Keywords: faster,faster! Message-ID: <129@tityus.UUCP> Date: 1 Sep 88 01:08:17 GMT Organization: Athena Systems, Inc., Sunnyvale, CA Lines: 254 Please excuse the following source posting to comp.windows.x, but my stuff isn't complex enough for comp.sources.x to accept it.. The following is new bitmap reading code that is considerably faster than the R2 release. It has been submitted for R3. It replaces the XRdBitF.c file in the "core.src/lib/X" directory on the distribution, for building the library libX11.a. You only need it if you read a lot of bitmaps from disk. -Jim Becker --skip or snip-- /* Copyright, 1987, Massachusetts Institute of Technology */ #include "copyright.h" /* * Code to read bitmaps from disk files. Interprets * data from X10 and X11 bitmap files and creates * Pixmap representations of files. Returns Pixmap * ID and specifics about image. * * Modified for speedup by Jim Becker, changed image * data parsing logic (removed some fscanf()s). * Aug 5, 1988 */ #include #include #include #include #include "Xlib.h" #include "Xutil.h" #include "Xlibint.h" #define MAX_SIZE 255 /* shared data for the image read/parse logic */ static FILE *fstream; /* file read handle */ static short HexVal[255]; /* conversion value */ static short HexSet = 0; /* initialized flag */ /* * Table index for the hex values. Initialized once, first time. * Used for translation value or delimiter significance lookup. */ static SetupHex() { /* set the translation entry values that are meaningful */ HexVal['0'] = 0; HexVal['1'] = 1; HexVal['2'] = 2; HexVal['3'] = 3; HexVal['4'] = 4; HexVal['5'] = 5; HexVal['6'] = 6; HexVal['7'] = 7; HexVal['8'] = 8; HexVal['9'] = 9; HexVal['A'] = 10; HexVal['B'] = 11; HexVal['C'] = 12; HexVal['D'] = 13; HexVal['E'] = 14; HexVal['F'] = 15; HexVal['a'] = 10; HexVal['b'] = 11; HexVal['c'] = 12; HexVal['d'] = 13; HexVal['e'] = 14; HexVal['f'] = 15; /* delimiters of significance are flagged w/ negative value */ HexVal[' '] = -1; HexVal[','] = -1; HexVal['}'] = -1; HexVal['\n'] = -1; HexVal['\t'] = -1; HexSet++; } /* * read next hex value in the input stream, return -1 if EOF */ static NextInt() { int ch; int value = 0; short gotone = 0; short done = 0; /* loop, accumulate hex value until find delimiter */ /* skip any initial delimiters found in read stream */ while( !done ) { ch = getc(fstream); if( ch == EOF ) { value = -1; done++; } else { /* trim high bits, check type and accumulate */ if( isxdigit( (ch &= 0xff) ) ) { value = (value << 4) + HexVal[ch]; gotone++; } else if( (HexVal[ch]) < 0 && gotone ) done++; } } return value; } int XReadBitmapFile( display, d, filename, width, height, pixmap, x_hot, y_hot ) Display *display; Drawable d; char *filename; unsigned int *width, *height; /* RETURNED */ Pixmap *pixmap; /* RETURNED */ int *x_hot, *y_hot; /* RETURNED */ { char *data = NULL; char *ptr; char line[MAX_SIZE]; int size, bytes; char name_and_type[MAX_SIZE]; char *type; int value; int version10p; int padding; int bytes_per_line; Pixmap pix; unsigned int ww = 0; unsigned int hh = 0; int hx = -1; int hy = -1; /* error cleanup and return macro */ #define RETURN(code) {if(data) free(data); \ fclose(fstream);\ return(code);} /* first time initialization */ if( !HexSet ) SetupHex(); if (!(fstream = fopen(filename, "r"))) return(BitmapOpenFailed); while(fgets(line, MAX_SIZE, fstream)) { if (strlen(line) == MAX_SIZE-1) RETURN(BitmapFileInvalid); if (sscanf(line, "#define %s %d", name_and_type, &value) == 2) { if (!(type = rindex(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 = rindex(name_and_type, '_'))) type = name_and_type; else type++; if (strcmp("bits[]", type)) continue; if (!ww || !hh) 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 = (char *)Xmalloc( size ); if (!data) RETURN(BitmapNoMemory); if (version10p) for (bytes=0, ptr=data; bytes> 8; } else for (bytes=0, ptr=data; bytes