/****************************************************************************** * Compilation instructions were originally in the e-mail containing this * * code; to compile: * * gcc -o uz2unpack -Wall uz2unpack.c -lz * * You're then left with a binary, "uz2unpack" in your current directory. * * All source below this comment block was written by Ryan C Gordon. * ******************************************************************************/ #include #include #define MAXUCOMPSIZE 32768 #define MAXCOMPSIZE 33096 // 32768 + 1% typedef unsigned int uint32; typedef unsigned char uint8; static int bigendian = 0; static uint8 ubuf[MAXUCOMPSIZE]; static uint8 cbuf[MAXCOMPSIZE]; static int readui32(FILE *in, uint32 *v) { if (fread(v, sizeof (uint32), 1, in) != 1) return(0); if (bigendian) { uint32 x = *v; *v = (((x)>>24) + (((x)>>8)&0xff00) + (((x)<<8)&0xff0000) + ((x)<<24)); } /* if */ return(1); } static int isBigendian(void) { uint32 x = 0x01000000; return(*((uint8 *) &x)); } /* isBigendian */ int main(int argc, char **argv) { const char *err = "Read failure"; FILE *in; FILE *out; uint32 usize; uint32 csize; uLongf x; if (argc != 3) { fprintf(stderr, "USAGE: %s \n", argv[0]); return(1); } /* if */ if ((sizeof (uint32) != 4) || (sizeof (uint8) != 1)) { fprintf(stderr, "ERROR: Program is miscompiled!\n"); return(2); } /* if */ bigendian = isBigendian(); remove(argv[2]); out = fopen(argv[2], "wb"); in = fopen(argv[1], "rb"); if ((!in) || (!out)) { fprintf(stderr, "Failed to open %s.\n", argv[in ? 1 : 2]); return(3); } /* if */ while (1) { if (!readui32(in, &csize)) { if (feof(in)) err = NULL; /* we're done! */ break; } /* if */ if (!readui32(in, &usize)) break; if ( (usize > sizeof (ubuf)) || (csize > sizeof (cbuf)) ) { err = "Bogus .uz2 file."; break; } /* if */ if (fread(cbuf, csize, 1, in) != 1) break; x = usize; if ((uncompress(ubuf, &x, cbuf, csize) != Z_OK) || (x != usize)) { err = "Decompression error."; break; } /* if */ if (fwrite(ubuf, usize, 1, out) != 1) { err = "Write error."; break; } /* if */ } /* while */ fclose(in); fclose(out); if (err != NULL) { remove(argv[2]); fprintf(stderr, "ERROR: %s\n", err); return(4); } /* if */ return(0); } /* main */ /* end of unpackuz2.c ... */