/* aoi6.c - Don Yang (uguu.org) 08/25/02 */ #include #include static FILE *infile, *outfile; static int s, t, state, size, headersize, datasize, tag; void r(void *d) { fread(d, s, 1, infile); } void w(void *d) { fwrite(d, s, 1, outfile); } void k(int p) { fseek(infile, p, 1); } void K(int p) { fseek(outfile, p, 0); } int ParseChunk(); int ParseList(int listsize) { int chunksize; r(&tag); state |= (tag == 0x6c726468) ? 1 : (tag == 0x69766f6d) ? 8 : 0; for(chunksize = 0; listsize > chunksize && (t = ParseChunk()); chunksize += t); return listsize; } int ParseChunk() { void *buffer; r(&tag); r(&size); if( tag == 0x5453494c ) return ParseList(size); if( (state & 1) && tag == 0x68697661 ) { state |= 2; k(size); } else if( (state & 2) && tag == 0x68727473 ) { r(&tag); if( tag == 0x73647561 ) state |= 4; k(size - 4); } else if( ((state & 4) && tag == 0x66727473) || ((state & 24) && (tag & 0xffff00ff) == 0x62770030) ) { if( tag & 1 ) { s = 20; w("RIFF....WAVEfmt ...."); state |= 16; headersize = size; } else { if( !(state & 32) ) { s = 8; w("data...."); state |= 32; } datasize += size; } if( (buffer = alloca(s = size)) ) { r(buffer); w(buffer); } else { size = -8; } s = 4; } else { k(size); } if( (size += 8) & 1 ) { fgetc(infile); size++; } return size; } int main(int argc, char **argv) { if( argc < 3 ) { printf("%s \n", *argv); } else { headersize = datasize = state = 0; if( (infile = fopen(argv[1], "rb")) ) { if( (outfile = fopen(argv[2], "wb+")) ) { s = 4; r(&tag); r(&size); if( tag == 0x46464952 ) { r(&tag); if( tag == 0x20495641 ) for(; !(state & 32) && ParseChunk();); } if( (state & 32) ) { K(16); w(&headersize); K(headersize + 24); w(&datasize); datasize += headersize + 20; K(4); w(&datasize); } fclose(outfile); } fclose(infile); } puts((state & 32) ? "success" : "fail"); } return 0; }