/* * Ogg Extractor */ #include #include #include #pragma pack(1) typedef struct { unsigned long magic_number; unsigned char version; unsigned char header_type; unsigned short granule_position; long _padding1; short _padding2; unsigned short bitstream_serial_number; short _padding3; unsigned short page_sequence_number; short _padding4; unsigned short CRC_checksum; short _padding5; unsigned char page_segments; /* unsigned char segment_table[]; */ } ogg_header; #pragma pack() #define OGG_MAGIC 0x5367674F /* "OggS" */ #define OGG_TYPE_FIRST 2 #define OGG_TYPE_LAST 4 size_t min(size_t a, size_t b) { return a < b ? a : b; } void fcopy(FILE *dest, FILE *src, size_t len) { int buf[1024]; size_t n; for ( ; (n = fread(buf, 1, min(len, sizeof buf), src)) != 0; len -= n) fwrite(buf, 1, n, dest); } void ogg_extract(const char *filename) { FILE *fin; int out_i; ogg_header oh; if ((fin = fopen(filename, "rb")) == NULL) return; for (out_i = 0; fread(&oh, 1, sizeof oh, fin) == sizeof oh; out_i++) { char outname[FILENAME_MAX]; FILE *fout; int x; while (oh.magic_number != OGG_MAGIC || !(oh.header_type & OGG_TYPE_FIRST)) { if ((x = fgetc(fin)) == EOF) goto end; memmove(&oh, (char *)&oh + 1, sizeof oh - 1); ((char *)&oh)[sizeof oh - 1] = (char)x; } sprintf(outname, "%s.%04d.ogg", filename, out_i); printf("\rExtracting: %s -> %d", filename, out_i); if ((fout = fopen(outname, "wb")) == NULL) { printf("\n Failed to create file !!\n"); abort(); } do { unsigned char seg; size_t sum; fwrite(&oh, 1, sizeof oh, fout); for (seg = 0, sum = 0; seg < oh.page_segments; seg++) { if ((x = fgetc(fin)) == EOF) goto end; sum += (unsigned char)x; fputc(x, fout); } fcopy(fout, fin, sum); if (oh.header_type & OGG_TYPE_LAST) break; } while (fread(&oh, 1, sizeof oh, fin) == sizeof oh); fclose(fout); } end: fclose(fin); printf("\n"); } int main(int argc, char *argv[]) { int i; for (i = 1; i < argc; i++) ogg_extract(argv[i]); return 0; }