home *** CD-ROM | disk | FTP | other *** search
- /****************************************************************************
- * *
- * io.c *
- * ==== *
- * *
- * I/O routines for image format conversion programs *
- * *
- * Version 1.00 (13-Aug-1993) *
- * 1.10 (20-Aug-1993) read_struct & write_struct added *
- * 1.20 (22-Aug-1993) new endian routines added *
- * 1.30 (23-Aug-1993) progess function added *
- * 1.41 (13-Oct-1993) progess start & finish functions added *
- * *
- * (C) 1993 DEEJ Technology PLC *
- * *
- ****************************************************************************/
-
- #include <stdlib.h>
- #include <stdio.h>
- #include <string.h>
- #include "io.h"
-
- #ifndef ENDIAN_MACROS
-
- /*
- * little-endian to big-endian
- */
-
- uint swap_endian(uint dword)
- {
- return( ((dword & 0xff000000)>>24) |
- ((dword & 0x00ff0000)>>8) |
- ((dword & 0x0000ff00)<<8) |
- ((dword & 0x000000ff)<<24) );
- }
-
- /*
- * little-endian to big-endian for 16 bit words
- */
-
- ushort swap_endian_word(ushort word)
- {
- return( ((ushort)(word & 0xff00)>>8) |
- ((ushort)(word & 0x00ff)<<8) );
- }
-
- /*
- * swaps endian of DWORD/WORD if type doesnot match machine type
- * type is LITTLE_ENDIAN (LE) or BIG_ENDIAN (BE)
- */
-
- uint endian(int type, uint dword)
- {
- if(type != ENDIAN_TYPE)
- return(swap_endian(dword));
- else
- return(dword);
- }
-
- ushort endian_w(int type, ushort word)
- {
- if(type != ENDIAN_TYPE)
- return(swap_endian_word(word));
- else
- return(word);
- }
-
- /*
- * reverses bit fields in byte
- */
-
- uint bit_swap(uint byte)
- {
- return( ((byte & 0x80)>>7) |
- ((byte & 0x40)>>5) |
- ((byte & 0x20)>>3) |
- ((byte & 0x10)>>1) |
- ((byte & 0x08)<<1) |
- ((byte & 0x04)<<3) |
- ((byte & 0x02)<<5) |
- ((byte & 0x01)<<7) );
- }
-
- uint bit2_swap(uint byte)
- {
- return( ((byte & 0xC0)>>6) |
- ((byte & 0x30)>>2) |
- ((byte & 0x0C)<<2) |
- ((byte & 0x03)<<6) );
- }
-
- uint bit4_swap(uint byte)
- {
- return( ((byte & 0xF0)>>4) |
- ((byte & 0x0F)<<4) );
- }
-
- #endif
-
- /* put/get word little endian */
-
- void fputwLE(ushort word, FILE *file)
- {
- word = endian_w(LE,word);
- fwrite((char*)&word, sizeof(ushort), 1, file);
- }
-
- ushort fgetwLE(FILE *file)
- {
- ushort word;
-
- word = endian_w(LE,word);
- fread((char*)&word, sizeof(ushort), 1, file);
-
- return(word);
- }
-
- /* put/get word big endian */
-
- void fputwBE(ushort word, FILE *file)
- {
- word = endian_w(BE,word);
- fwrite((char*)&word, sizeof(ushort), 1, file);
- }
-
- ushort fgetwBE(FILE *file)
- {
- ushort word;
-
- word = endian_w(BE,word);
- fread((char*)&word, sizeof(ushort), 1, file);
-
- return(word);
- }
-
- /* put/get double word little endian */
-
- void fputdLE(uint dword, FILE *file)
- {
- dword = endian(LE,dword);
- fwrite((char*)&dword, sizeof(dword), 1, file);
- }
-
- uint fgetdLE(FILE *file)
- {
- uint dword;
-
- dword = endian(LE,dword);
- fread((char*)&dword, sizeof(dword), 1, file);
-
- return(dword);
- }
-
- /* put/get word big endian */
-
- void fputdBE(uint dword, FILE *file)
- {
- dword = endian(BE,dword);
- fwrite((char*)&dword, sizeof(uint), 1, file);
- }
-
- uint fgetdBE(FILE *file)
- {
- uint dword;
-
- dword = endian(BE,dword);
- fread((char*)&dword, sizeof(uint), 1, file);
-
- return(dword);
- }
-
- /*
- * reads input, output & progress filenames from argv
- * and opens streams in, out & err. If names are not
- * given the streams default to stdin, stdout & stderr
- *
- * Can be used before arg processing if syntax is
- * [-in <file>] [-out <file>] [-err <file>]. If so any parts
- * found are removed from parameter list. If syntax is
- * [<flags>...] [<infile> [<outfile> [<errfile]]], must be
- * called after flags have been processed, and argc & argv
- * ajusted to after the last flag.
- */
-
- void file_args(int argc, char **argv, FILE **in, FILE **out, FILE **err)
- {
- char *infile, *outfile, *errfile;
- int o_argc = argc;
- char **o_argv = argv;
-
- infile = outfile = errfile = 0;
-
- argc--; argv++; /* skip program name */
-
- /* look for -in, -out, -err <file> */
-
- while(argc>0)
- {
- if(**argv=='-')
- {
- switch( (*argv)[1] )
- {
- case 'i':
- if(strcmp(*argv, "-in")==0)
- {
- **argv = 0; /* clear flag from parameters */
- argc--; argv++;
- infile = *argv;
- }
- break;
-
- case 'o':
- if(strcmp(*argv, "-out")==0)
- {
- **argv = 0;
- argc--; argv++;
- outfile = *argv;
- }
- break;
-
- case 'e':
- if(strcmp(*argv, "-err")==0)
- {
- **argv = 0;
- argc--; argv++;
- errfile = *argv;
- }
- break;
-
- default:
- break;
- }
- }
- /* next parameter */
- argc--; argv++;
- }
-
- /* if no filenames found try alternate syntax */
-
- if(infile==0 && outfile==0 && errfile==0)
- {
- if(o_argc>=2 && o_argv[1][0]!='-')
- {
- infile = o_argv[1];
- if(o_argc>=3 && o_argv[2][0]!='-')
- {
- outfile = o_argv[2];
- if(o_argc>=4 && o_argv[3][0]!='-')
- errfile = o_argv[3];
- }
- }
- }
-
- if(infile == 0)
- {
- *in = stdin;
- }
- else
- {
- if((*in = fopen(infile,"r")) == NULL)
- {
- fprintf(stderr, "Unable to open input file %s\n",
- infile);
- exit(1);
- }
- *infile = 0; /* remove from parameter list */
- }
- if(outfile == 0)
- {
- *out = stdout;
- }
- else
- {
- if((*out = fopen(outfile,"w")) == NULL)
- {
- fprintf(stderr, "Unable to open output file %s\n",
- outfile);
- exit(2);
- }
- *outfile = 0; /* remove from parameter list */
- }
- if(errfile == 0)
- {
- *err = stderr;
- }
- else
- {
- /*
- * open err file and ensure stderr from
- * libraries uses it as well
- */
-
- if((*err = freopen(errfile,"w",stderr)) == NULL)
- {
- /* dont use stderr as it will be closed */
- fprintf(stdout, "Unable to open error file %s\n",
- errfile);
- exit(3);
- }
- /* set no buffering of stderr file */
- setvbuf(*err, NULL, _IONBF, BUFSIZ);
- *errfile = 0; /* remove from parameter list */
- }
- }
-
- /*
- * reads in a structure from a file
- * correcting for endian'ness and arbitary alignment
- *
- * type : LITTLE_ENDIAN or BIG_ENDIAN
- * buffer : structure cast to uchar*
- * descrip : array of structure field sizes
- * (1=byte, 2=word, 4=dword, >4=string, -1=end of table)
- * file : file stream descriptor
- */
-
- void read_struct(int type, BYTE *buffer, int *descrip, FILE *file)
- {
- WORD word;
- DWORD dword;
-
- while(*descrip != -1)
- {
- switch(*descrip)
- {
- case 1: /* byte */
- *buffer++ = fgetc(file);
- break;
-
- case 2: /* word */
- fread(&word, sizeof(WORD), 1, file);
- word = endian_w(type,word);
-
- buffer = (BYTE*)
- (((int)buffer+ALIGN_WORD-1) & ~(ALIGN_WORD-1));
- memcpy(buffer, (char*)&word, sizeof(WORD));
- buffer += sizeof(WORD);
- break;
-
- case 4: /* double word */
- fread(&dword, sizeof(DWORD), 1, file);
- dword = endian(type,dword);
-
- buffer = (BYTE*)
- (((int)buffer+ALIGN_DWORD-1) & ~(ALIGN_DWORD-1));
- memcpy(buffer, (char*)&dword, sizeof(DWORD));
- buffer += sizeof(DWORD);
- break;
-
- default:
- if(*descrip > 0)
- {
- fread(buffer, *descrip, 1, file);
- buffer += *descrip;
- }
- break;
- }
-
- /* description pointer */
-
- descrip++;
- }
- }
-
- /*
- * writes a structure to a file
- * correcting for endian'ness and arbitary alignment
- */
-
- void write_struct(int type, BYTE *buffer, int *descrip, FILE *file)
- {
- WORD word;
- DWORD dword;
-
- while(*descrip != -1)
- {
- switch(*descrip)
- {
- case 1: /* byte */
- fputc(*buffer++,file);
- break;
-
- case 2: /* word */
- buffer = (BYTE*)
- (((int)buffer+ALIGN_WORD-1) & ~(ALIGN_WORD-1));
- memcpy((char*)&word, buffer, sizeof(WORD));
- buffer += sizeof(WORD);
-
- word = endian_w(type,word);
- fwrite(&word, sizeof(WORD), 1, file);
- break;
-
- case 4: /* double word */
- buffer = (BYTE*)
- (((int)buffer+ALIGN_DWORD-1) & ~(ALIGN_DWORD-1));
- memcpy((char*)&dword, buffer, sizeof(DWORD));
- buffer += sizeof(DWORD);
-
- dword = endian(type,dword);
- fwrite(&dword, sizeof(DWORD), 1, file);
- break;
-
- default:
- if(*descrip > 0)
- {
- fwrite(buffer, *descrip, 1, file);
- buffer += *descrip;
- }
- break;
- }
-
- /* advance description pointer */
-
- descrip++;
- }
- }
-
- /*
- * prints banner before calls to progress()
- * string should not contain newline
- */
-
- void progress_start(char *string)
- {
- fprintf(stderr, string);
- progress(0,100);
- }
-
- /*
- * displays progress of operation on stderr
- * by printing dots every 2% of completion
- * determined by value of current and max
- */
-
- void progress(int current, int max)
- {
- static old_percent = 0;
- int percent = (current*100)/max;
- int i;
-
- /* reset on for new progress indication */
-
- if(percent < old_percent) old_percent = 0;
-
- if(percent-old_percent>=2)
- {
- for(i=old_percent; i<percent; i+=2)
- fputc('.', stderr);
- old_percent = percent;
- }
- }
-
- /*
- * ensure display is correct after calls to progress()
- */
-
- void progress_finish(void)
- {
- progress(100,100);
- fprintf(stderr,"\n");
- }
-