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