143 lines
3.5 KiB
C
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;
|
|
}
|