/* aoi1.c - Don Yang (uguu.org) 08/18/02 */ #include #include #include static int ParseFile(FILE *infile, FILE *outfile, int *headersize, int *datasize); static int ParseChunk(FILE *infile, FILE *outfile, int *state, int *headersize, int *datasize); static int ParseList(FILE *infile, FILE *outfile, int listsize, int *state, int *headersize, int *datasize); int main(int argc, char **argv) { FILE *infile, *outfile; int headersize, datasize; if( argc < 3 ) return printf("%s \n", *argv); if( (infile = fopen(argv[1], "rb")) == NULL ) { printf("Can not open %s\n", argv[1]); return 1; } if( (outfile = fopen(argv[2], "wb+")) == NULL ) { fclose(infile); printf("Can not create %s\n", argv[2]); return 1; } headersize = datasize = 0; if( ParseFile(infile, outfile, &headersize, &datasize) == 0 ) { fseek(outfile, 16, 0); fwrite(&headersize, 4, 1, outfile); fseek(outfile, headersize + 4, 1); fwrite(&datasize, 4, 1, outfile); datasize += headersize + 20; fseek(outfile, 4, 0); fwrite(&datasize, 4, 1, outfile); } else { puts("failed"); } fclose(infile); fclose(outfile); return 0; } static int ParseFile(FILE *infile, FILE *outfile, int *headersize, int *datasize) { unsigned int tag; int size, rsize, state; fread(&tag, 4, 1, infile); fread(&size, 4, 1, infile); if( tag != 0x46464952 ) return 1; fread(&tag, 4, 1, infile); if( tag != 0x20495641 ) return 1; state = 0; do { rsize = ParseChunk(infile, outfile, &state, headersize, datasize); if( rsize == 0 ) return 1; } while( (state & 32) == 0 ); return 0; } static int ParseChunk(FILE *infile, FILE *outfile, int *state, int *headersize, int *datasize) { unsigned int tag; char *buffer; int size; fread(&tag, 4, 1, infile); fread(&size, 4, 1, infile); if( tag == 0x5453494c ) return ParseList(infile, outfile, size, state, headersize, datasize); if( (*state & 1) && tag == 0x68697661 ) { *state |= 2; fseek(infile, size, 1); } else if( (*state & 2) && tag == 0x68727473 ) { fread(&tag, 4, 1, infile); if( tag == 0x73647561 ) *state |= 4; fseek(infile, size - 4, 1); } else if( (*state & 4) && tag == 0x66727473 ) { fwrite("RIFF\0\0\0\0WAVEfmt \0\0\0\0", 20, 1, outfile); if( (buffer = (char*)alloca(size)) == NULL ) return 0; fread(buffer, size, 1, infile); fwrite(buffer, size, 1, outfile); *headersize = size; *state |= 16; } else if( (*state & 24) && (tag & 0xffff00ff) == 0x62770030 ) { if( (*state & 32) == 0 ) { fwrite("data\0\0\0\0", 8, 1, outfile); *state |= 32; } if( (buffer = (char*)alloca(size)) == NULL ) return 0; fread(buffer, size, 1, infile); fwrite(buffer, size, 1, outfile); *datasize += size; } else { fseek(infile, size, 1); } if( size & 1 ) { fgetc(infile); size++; } return size + 8; } static int ParseList(FILE *infile, FILE *outfile, int listsize, int *state, int *headersize, int *datasize) { int tag, chunksize; fread(&tag, 4, 1, infile); if( tag == 0x6c726468 ) { *state |= 1; } else if( tag == 0x69766f6d ) { *state |= 8; } chunksize = 0; while( listsize > chunksize ) { chunksize += (tag = ParseChunk(infile, outfile, state, headersize, datasize)); if( tag == 0 ) return 0; } return listsize; }