#include #include #include #include bool test_header(FILE* f, int magic = 2){ bool r = false; char buf[5]; fread(buf, 1, 5, f); if(buf[0] == 'g' && buf[1] == 'g' && buf[2] == 'S' && !buf[3] && (buf[4] & magic)){ r = true; } fseek(f, -5, SEEK_CUR); return r; } void write_ogg(FILE* in, size_t sz, int* n){ char fname[32]; char* buf = new char[sz]; fread(buf, 1, sz, in); do { sprintf(fname, "%s%d.ogg", "extract_", (*n)++); } while(access(fname, F_OK) != -1); FILE* out = fopen(fname, "wb"); fwrite(buf, 1, sz, out); fclose(out); delete [] buf; } void do_extract(FILE* f, int* n){ int c = 0; long start = ftell(f), end = start; while(c = fgetc(f), !feof(f)){ if(c == 'O' && test_header(f, 4)){ fseek(f, 25, SEEK_CUR); int nsegs = fgetc(f), total = 0; unsigned char buf[nsegs]; fread(buf, 1, nsegs, f); total = std::accumulate(buf, buf+nsegs, 0); end = ftell(f) + total + 1; fseek(f, start-1, SEEK_SET); write_ogg(f, end - start, n); break; } } } inline void quit(const char* name, const char* msg){ fprintf(stderr, "%s: %s\n", name, msg); exit(1); } int main(int argc, char** argv){ if(argc < 2) quit(argv[0], "No argument given."); int c = 0, n = 0; for(int i = 1; i < argc; ++i){ FILE* f = fopen(argv[i], "rb"); if(!f) quit(argv[0], "File not found."); while(c = fgetc(f), !feof(f)){ if(c == 'O' && test_header(f)){ do_extract(f, &n); } } } return 0; }