ref: bbba27dbb73cf46b659a707a425be7d8fd8097fe
dir: /extra/ivf2raw.c/
#include <u.h> #include <libc.h> #include <bio.h> static int Bu16le(Biobuf *b, u16int *o) { int x; x = Bgetc(b); x |= Bgetc(b)<<8; *o = x; if(x < 0) werrstr("failed to read 2 bytes"); return x < 0 ? -1 : 0; } static int Bu32le(Biobuf *b, u32int *o) { int x, i; *o = 0; for(i = 0; i < 4; *o |= x<<(i*8), i++){ if((x = Bgetc(b)) < 0){ werrstr("failed to read 4 bytes"); return -1; } } return 0; } static int Bu64le(Biobuf *b, u64int *o) { int x, i; *o = 0; for(i = 0; i < 8; *o |= x<<(i*8), i++){ if((x = Bgetc(b)) < 0){ werrstr("failed to read 8 bytes"); return -1; } } return 0; } static void usage(void) { fprint(2, "usage: %s <file.ivf >file.raw\n", argv0); exits("usage"); } void main(int argc, char **argv) { int n, bufsz, framenum; u32int tbnum, tbdenum; u16int w, h, hlen; u64int timestamp; Biobuf in, out; char tmp[6]; u8int *buf; u32int sz; ARGBEGIN{ }ARGEND if(argc != 0) usage(); Binit(&in, 0, OREAD); Binit(&out, 1, OWRITE); if(Bread(&in, tmp, 6) != 6 || Bu16le(&in, &hlen) < 0) sysfatal("header read failed"); if(memcmp(tmp, "DKIF", 4) != 0) sysfatal("expected DKIF, got %02x%02x%02x%02x", tmp[0], tmp[1], tmp[2], tmp[3]); if(hlen < 0x20 || Bread(&in, tmp, 4) != 4) sysfatal("invalid header: hlen=%d", hlen); if(Bu16le(&in, &w) < 0 || Bu16le(&in, &h) < 0 || Bu32le(&in, &tbdenum) < 0 || Bu32le(&in, &tbnum) < 0) sysfatal("invalid header: %r"); if(Bseek(&in, hlen, 0) != hlen) sysfatal("invalid IVF stream"); bufsz = 0; buf = nil; for(framenum = 0;; framenum++){ if(Bu32le(&in, &sz) < 0 || Bu64le(&in, ×tamp) || (int)sz < 0) break; if(bufsz < sz){ bufsz = sz; if((buf = realloc(buf, bufsz)) == nil) sysfatal("frame %d is too big: %d bytes", framenum, bufsz); } if((n = Bread(&in, buf, sz)) != sz) sysfatal("short read (%d < %d)", n, sz); Bwrite(&out, buf, sz); } Bterm(&in); Bterm(&out); exits(nil); }