xenocara/app/xlockmore/xlock/xbm.c
2006-11-26 11:07:42 +00:00

143 lines
3.5 KiB
C

#if !defined( lint ) && !defined( SABER )
static const char sccsid[] = "@(#)xbm.c 4.00 97/01/01 xlockmore";
#endif
/*-
* Utilities for XBM processing
*
* See xlock.c for copying information.
*
* Revision History:
* 25-May-95: David Bagley "snarfed" xv's xvxbm.c
* John Bradley <bradley@central.cis.upenn.edu>
* code used here by permission
*/
#ifdef STANDALONE
#include "utils.h"
#else
#include "xlock.h"
#endif
#ifndef WIN32
#include <X11/Xutil.h>
#else
#include "Xapi.h"
#endif /* WIN32 */
extern int XbmReadFileToImage(char *filename,
int *width, int *height, unsigned char **bits);
extern FILE *my_fopen(char *, const char *);
int
XbmReadFileToImage(char *filename,
int *width, int *height, unsigned char **bits)
{
FILE *file;
int c, c1;
int i, j, k = 0;
unsigned char *pix;
char line[256], name[256];
unsigned char hex[256];
if ((file = my_fopen(filename, "r")) == NULL) {
/*(void) fprintf(stderr, "could not read file \"%s\"\n", filename); */
return BitmapOpenFailed;
}
/* read width: skip lines until we hit a #define */
for (;;) {
if (!fgets(line, 256, file)) {
/* not a xbm file */
(void) fclose(file);
return BitmapFileInvalid;
}
if (strncmp(line, "#define", (size_t) 7) == 0 &&
sscanf(line, "#define %s %d", name, width) == 2 &&
strcmp(name, "_width"))
break;
}
/* read height: skip lines until we hit another #define */
for (;;) {
if (!fgets(line, 256, file)) {
(void) fclose(file);
(void) fprintf(stderr, "EOF reached in header info.\n");
return BitmapFileInvalid;
}
if (strncmp(line, "#define", (size_t) 7) == 0 &&
sscanf(line, "#define %s %d", name, height) == 2 &&
strcmp(name, "_height"))
break;
}
/* scan forward until we see the first '0x' */
c = getc(file);
c1 = getc(file);
while (c1 != EOF && !(c == '0' && c1 == 'x')) {
c = c1;
c1 = getc(file);
}
if (c1 == EOF) {
(void) fclose(file);
(void) fprintf(stderr, "No bitmap data found\n");
return BitmapFileInvalid;
}
if (*width < 1 || *height < 1 || *width > 10000 || *height > 10000) {
(void) fclose(file);
(void) fprintf(stderr, "Not an xbm file");
return BitmapFileInvalid;
}
*bits = (unsigned char *) calloc((size_t) ((*width + 7) / 8) * (*height),
(size_t) 8);
if (!*bits) {
(void) fclose(file);
(void) fprintf(stderr, "couldn't malloc bits\n");
return BitmapNoMemory;
}
/* initialize the 'hex' array for zippy ASCII-hex -> int conversion */
for (i = 0; i < 256; i++)
hex[i] = 255; /* flag 'undefined' chars */
for (i = '0'; i <= '9'; i++)
hex[i] = i - '0';
for (i = 'a'; i <= 'f'; i++)
hex[i] = i + 10 - 'a';
for (i = 'A'; i <= 'F'; i++)
hex[i] = i + 10 - 'A';
/* read the image data */
for (i = 0, pix = *bits; i < *height; i++)
for (j = 0; j < (*width + 7) / 8; j++, pix++) {
/* get next byte from file. we're already positioned at it */
c = getc(file);
c1 = getc(file);
if (c < 0 || c1 < 0) {
/* EOF: break out of loop */
c = c1 = '0';
i = *height;
j = *width;
(void) fclose(file);
(void) fprintf(stderr, "The file would appear to be truncated.\n");
return BitmapFileInvalid;
}
if (hex[c1] == 255) {
if (hex[c] == 255)
k = 0; /* no digits after the '0x' ... */
else
k = hex[c];
} else
k = (hex[c] << 4) + hex[c1];
/* advance to next '0x' */
c = getc(file);
c1 = getc(file);
while (c1 != EOF && !(c == '0' && c1 == 'x')) {
c = c1;
c1 = getc(file);
}
*pix = k;
}
(void) fclose(file);
return BitmapSuccess;
}