Skip to content

Instantly share code, notes, and snippets.

@baines
Last active August 29, 2015 14:06
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save baines/a38e37d68adb79a59d83 to your computer and use it in GitHub Desktop.
Save baines/a38e37d68adb79a59d83 to your computer and use it in GitHub Desktop.
Extract OGGs from stuff
#include <cstdio>
#include <cstdlib>
#include <numeric>
#include <unistd.h>
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;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment