#include "xbcomm.h"
static VOIDPARM flipl( p )
byte *p;
{
byte t;
t = p[ 0 ];
p[ 0 ] = p[ 3 ];
p[ 3 ] = t;
t = p[ 1 ];
p[ 1 ] = p[ 2 ];
p[ 2 ] = t;
}
static int getbyte( fp )
FILE *fp;
{
return( (int)getc( fp ) );
}
static u_int getword( fp )
FILE *fp;
{
byte b1 = (byte)getc( fp );
byte b2 = (byte)getc( fp );
return( (u_int)(b1 + b2 * 256) );
}
static u_int getbeword( fp )
FILE *fp;
{
byte b1 = (byte)getc( fp );
byte b2 = (byte)getc( fp );
return( (u_int)(b2 + b1 * 256) );
}
static int getint( fp, gotGarbage )
FILE *fp;
boolean *gotGarbage;
{
int c, i;
boolean notDone;
/* skip forward to start of next number */
c = getc( fp );
notDone = TRUE;
*gotGarbage = FALSE;
while ( notDone )
{
/* eat comments */
if ( c IS POUNDSIGN )
/* if we're at a comment, read to end of line */
while ( c ISNT EOL AND c ISNT EOF)
c = getc( fp );
if ( c IS EOF )
return( 0 );
if ( c >= ZERO AND c <= NINE )
/* we've found what we were looking for */
notDone = FALSE;
else if ( NOT ( ( c IS SPACE ) OR ( c IS TAB ) OR ( c IS CR ) OR
( c IS EOL ) OR ( c IS COMMA ) ) )
/* see if we are getting garbage (non-whitespace) */
*gotGarbage = TRUE;
if ( notDone )
c = getc( fp );
}
/* we're at the start of a number, continue until we hit a non-number */
i = 0;
notDone = TRUE;
while ( notDone )
{
i = ( i * 10 ) + ( c - ZERO );
c = getc( fp );
if ( c IS EOF )
return( i );
if ( ( c < ZERO ) OR ( c > NINE ) )
notDone = FALSE;
}
return( i );
}
typedef struct
{
char type[ 6 ];
unsigned short width, height;
char planes;
} GIF_INFO;
static char *getGIFInfo( VOIDPARM )
{
FILE *fp;
GIF_INFO gi;
boolean swapEm=FALSE;
int cCnt;
char c, *d;
char resStr[ 32 ], tempStr[ 32 ];
union {
unsigned short theShort;
char theChars[ 2 ];
} byteOrder;
byteOrder.theShort = ( 'A' SHL_ 8 ) + 'B';
if ( byteOrder.theChars[ 0 ] IS 'A' )
swapEm = TRUE;
fp = fopen( theFile, "r" );
fread( (char *) &gi, sizeof( GIF_INFO ), 1, fp );
gi.type[ 5 ] = NULLTERM;
if ( swapEm )
{
d = (char *) &(gi.width);
c = d[ 1 ];
d[ 1 ] = d[ 0 ];
d[ 0 ] = c;
d = (char *) &(gi.height);
c = d[ 1 ];
d[ 1 ] = d[ 0 ];
d[ 0 ] = c;
}
gi.planes = ( gi.planes AND_ 0x07 );
sprintf( resStr, "[%dx%dx%dp]", gi.width, gi.height, gi.planes + 1 );
picRes = copyString( resStr );
sprintf( tempStr, "GIF {%s}", gi.type );
fclose( fp );
return( copyString( tempStr ) );
}
/*
> Scan through and look for 0xff followed by either 0xc0, 0xc1 or 0xc9.
> Once you find those, skip a couple bytes and you can then pick up
> the precision, height, width and number of components as 1 byte,
> 2 byte, 2 byte and 1 byte integers respectively and in that order
> (the 2 byte guys are in big endian order).
>
> The number of components roughly indiciates colour or grayscale (3 or 1).
> The precision is how big each component is (almost always 8 bits).
> Most files will have three, 8 bit components.
*/
static char *getJFIFInfo( VOIDPARM )
{
FILE *fp;
int oneByte;
boolean gotMarker;
int prec, comp, width, height;
char resStr[ 32 ], tempStr[ 32 ];
fp = fopen( theFile, "r" );
oneByte = getbyte( fp );
while ( oneByte ISNT EOF )
{
if ( (u_int)oneByte IS 0xff )
{
oneByte = (u_int)getbyte( fp );
if ( ( oneByte IS 0xc0 ) OR ( oneByte IS 0xc1 ) OR
( oneByte IS 0xc9 ) )
{
/* ...ignore one word... */
height = getword( fp );
/* Next byte should be precision... */
prec = (u_int)getbyte( fp );
/* Next two bytes should be height... */
height = getbeword( fp );
/* Next two bytes should be width... */
width = getbeword( fp );
/* Next byte should be number of components... */
comp = (u_int)getbyte( fp );
sprintf( resStr, "[%dx%dx%dp]", width, height,
( comp * prec ) );
break;
}
else if ( (u_int)oneByte ISNT 0xff )
oneByte = getbyte( fp );
}
else
oneByte = getbyte( fp );
}
fclose( fp );
picRes = copyString( resStr );
sprintf( tempStr, "JPEG/JFIF" );
return( copyString( tempStr ) );
}
typedef struct {
int id; /* Magic number for pm format files. */
int np; /* Number of planes. Normally 1. */
int nrow; /* Number of rows. 1 - MAXNELM. */
int ncol; /* Number of columns. 1 - MAXNELM. */
int nband; /* Number of bands. */
int form; /* Pixel format. */
} PM_INFO;
#define PM_MAGICNO 0x56494557 /* Hex for VIEW */
#define PM_A 0x8000
#define PM_C 0x8001
#define PM_S 0x8002
#define PM_I 0x8004
#define PM_F 0xc004
static char *getPMInfo( VOIDPARM )
{
FILE *fp;
PM_INFO pi;
boolean flipit;
char picType[ 5 ], resStr[ 32 ], tempStr[ 32 ];
fp = fopen( theFile, "r" );
flipit = FALSE;
fread( (char *) &pi, sizeof( PM_INFO ), 1, fp );
fclose( fp );
if ( pi.id ISNT PM_MAGICNO )
{
flipl( (byte *) &pi.id );
if ( pi.id IS PM_MAGICNO )
flipit = TRUE;
else
flipl( (byte *) &pi.id );
}
if ( pi.id ISNT PM_MAGICNO )
return( "INVALID PM FILE!" );
if ( flipit )
{
flipl( (byte *) &pi.np );
flipl( (byte *) &pi.nrow );
flipl( (byte *) &pi.ncol );
flipl( (byte *) &pi.nband );
flipl( (byte *) &pi.form );
}
if ( pi.form IS PM_A )
sprintf( picType, "PM_A" );
else if ( pi.form IS PM_C )
sprintf( picType, "PM_C" );
else if ( pi.form IS PM_S )
sprintf( picType, "PM_S" );
else if ( pi.form IS PM_I )
sprintf( picType, "PM_I" );
else if ( pi.form IS PM_F )
sprintf( picType, "PM_F" );
sprintf( resStr, "[%dx%dx%dp]", pi.ncol, pi.nrow, pi.np );
picRes = copyString( resStr );
sprintf( tempStr, "PM {%s}", picType );
return( copyString( tempStr ) );
}
static char *getPBMInfo( VOIDPARM )
{
FILE *fp;
/* char planes; */
char resStr[ 32 ], tempStr[ 32 ];
boolean garbage, intGarbage;
int c, c1;
int numBits, index;
int w, h, maxv, planes;
garbage = FALSE;
maxv = 0;
/* open the stream, if necesary */
fp = fopen( theFile, "r" );
/* read the first two bytes of the file to determine which format */
/* this file is. "P1" = ascii bitmap, "P2" = ascii greymap, */
/* "P3" = ascii pixmap, "P4" = raw bitmap, "P5" = raw greymap, */
/* "P6" = raw pixmap */
c = getc( fp );
c1 = getc( fp );
if ( ( c ISNT 'P' ) OR ( c1 < ONE ) OR ( c1 > SIX ) )
sprintf( tempStr, "CORRUPT PBM FILE!" );
else
{
/* read in header information */
w = getint( fp, &intGarbage );
garbage = ( garbage OR intGarbage );
h = getint( fp, &intGarbage );
garbage = ( garbage OR intGarbage );
/* if we're not reading a bitmap, read the 'max value' */
if ( NOT ( ( c1 IS ONE ) OR ( c1 IS FOUR ) ) )
{
maxv = getint( fp, &intGarbage );
garbage = ( garbage OR intGarbage );
if ( maxv < 1 )
garbage = TRUE; /* to avoid 'div by zero' probs */
}
if ( garbage )
sprintf( tempStr, "CORRUPT PBM FILE!" );
else
{
/* planes = ( ( maxv AND_ 0xfff0 ) SHR_ 4 ) + 1; */
numBits = 4 * sizeof( int );
planes = 1;
for ( index = 1; index <= numBits; index++ )
if ( ( maxv SHR_ index ) AND_ 0x0001 )
/* bit #index is used */
planes = index + 1;
sprintf( resStr, "[%dx%dx%dp]", w, h, planes );
picRes = copyString( resStr );
if ( c1 IS ONE )
sprintf( tempStr, "ASCII PBM" );
if ( c1 IS TWO )
sprintf( tempStr, "ASCII PGM" );
if ( c1 IS THREE )
sprintf( tempStr, "ASCII PPM" );
if ( c1 IS FOUR )
sprintf( tempStr, "RAW PBM" );
if ( c1 IS FIVE )
sprintf( tempStr, "RAW PGM" );
if ( c1 IS SIX )
sprintf( tempStr, "RAW PPM" );
}
}
fclose( fp );
return( copyString( tempStr ) );
}
static char *getXBMInfo( VOIDPARM )
{
FILE *fp;
boolean notDone, gotWidth;
int w, h;
char line[ 256 ], resStr[ 32 ], tempStr[ 32 ];
fp = fopen( theFile, "r" );
gotWidth = FALSE;
/* read width: skip lines until we hit a #define */
notDone = TRUE;
while ( notDone )
{
if ( NOT fgets( line, 256, fp ) )
{
sprintf( tempStr, "CORRUPT XBM FILE!" );
notDone = FALSE;
}
else if ( strncmp( line, "#define", 7 ) IS 0 )
{
if ( sscanf( line, "#define %*s %d", &w ) ISNT 1 )
sprintf( tempStr, "CORRUPT XBM FILE!" );
else
gotWidth = TRUE;
notDone = FALSE;
}
}
/* read height: skip lines until we hit another #define */
notDone = gotWidth;
while ( notDone )
{
if ( NOT fgets( line, 256, fp ) )
{
sprintf( tempStr, "CORRUPT XBM FILE!" );
notDone = FALSE;
}
else if ( strncmp( line, "#define", 7 ) IS 0 )
{
if ( sscanf( line, "#define %*s %d", &h ) ISNT 1 )
sprintf( tempStr, "CORRUPT XBM FILE!" );
else
{
sprintf( resStr, "[%dx%dx1p]", w, h );
picRes = copyString( resStr );
sprintf( tempStr, "XBM" );
}
notDone = FALSE;
}
}
fclose( fp );
return( copyString( tempStr ) );
}
static char *getPICInfo( VOIDPARM )
{
FILE *fp;
int magic, ignored;
byte bpp;
int w, h;
char planes;
char resStr[ 32 ], tempStr[ 32 ];
fp = fopen( theFile, "r" );
magic = getword( fp );
if (magic != 0x1234)
{
w = getword( fp );
h = getword( fp );
planes = 1;
}
else
{
w = getword( fp );
h = getword( fp );
ignored = getword( fp );
ignored = getword( fp );
bpp = (u_int)getbyte( fp );
planes = ( ( bpp AND_ 0xf0 ) SHR_ 4 ) + 1;
}
fclose( fp );
sprintf( resStr, "[%dx%dx%dp]", w, h, planes );
picRes = copyString( resStr );
sprintf( tempStr, "PIC" );
return( copyString( tempStr ) );
}
VOIDPARM getFileStats( VOIDPARM )
{
FILE *fp;
char magicno[ 8 ]; /* first 8 bytes of file */
char *infoStr;
fileType = UNKNOWN;
/* try to determine what type of file we've got by reading the */
/* first couple bytes and looking for a Magic Number */
fp = fopen( theFile, "r" );
if ( fp IS NULL )
{
if ( verboseOutput )
printf( "Can't open %s to determine file type!\n", theFile );
fileStats = copyString( "UNIDENTIFYABLE" );
return;
}
if ( verboseOutput )
{
printf( "...determining type/gathering statistics for %s...",
theFile );
fflush( stdout );
}
fread( magicno, 8, 1, fp );
fclose( fp );
if ( strncmp( magicno, "GIF", 3 ) IS 0 )
{
fileType = GIF;
fileStats = getGIFInfo();
}
else if ( strncmp( magicno, "hsi1", 4 ) IS 0 )
{
fileType = JFIF;
fileStats = copyString ( "HSI proprietary JPEG" );
picRes = copyString( "[unknown resolution]" );
}
else if ( magicno[ 0 ] IS (char) -1 AND
magicno[ 1 ] IS (char) -40 AND
magicno[ 2 ] IS (char) -1 )
{
fileType = JFIF;
fileStats = getJFIFInfo();
}
else if ( strncmp( magicno, "VIEW", 4) IS 0 OR
strncmp( magicno, "WEIV", 4) IS 0 )
{
fileType = PM;
fileStats = getPMInfo();
}
else if ( magicno[ 0 ] IS 'P' AND magicno[ 1 ] >= '1' AND
magicno[ 1 ] <= '6')
{
fileType = PBM;
fileStats = getPBMInfo();
}
else if ( strncmp( magicno, "#define", 7 ) IS 0 )
{
fileType = XBM;
fileStats = getXBMInfo();
}
else if ( ( (u_int) magicno[ 0 ] IS 0x34 ) AND
( (u_int) magicno[ 1 ] IS 0x12 ) )
{
fileType = PIC;
fileStats = getPICInfo();
}
else
fileStats = copyString( "UNKNOWN" );
if ( DEBUG_PROC )
printf( "File %s is of type %s...\n", theFile, fileStats );
if ( verboseOutput )
printf( "done.\n" );
}
syntax highlighted by Code2HTML, v. 0.9.1