#include <u.h>#include <libc.h>#include <bio.h> static intBu16le(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 intBu32le(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 intBu64le(Biobuf *b, u64int *o){ int x, i; *o = 0; for(i = 0; i < 8; *o |= (uvlong)x<<(i*8), i++){ if((x = Bgetc(b)) < 0){ werrstr("failed to read 8 bytes"); return -1; } } return 0;} static voidusage(void){ fprint(2, "usage: %s [-h hxsz] [file.ivf] >file.raw\n", argv0); exits("usage");} voidmain(int argc, char **argv){ u64int timestamp, framenum; int n, bufsz, hxsz, fd; u32int tbnum, tbdenum; u16int w, h, hlen; Biobuf in, out; char tmp[6]; u8int *buf; u32int sz; hxsz = 0; ARGBEGIN{ case 'h': if((hxsz = atoi(EARGF(usage()))) > 0){ fmtinstall('H', encodefmt); break; } default: usage(); }ARGEND fd = 0; if(argc == 1){ if((fd = open(*argv, OREAD)) < 0) sysfatal("%r"); }else if(argc != 0) usage(); Binit(&in, fd, 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) < 0 || (int)sz < 0) break; if(bufsz < sz){ bufsz = sz; if((buf = realloc(buf, bufsz)) == nil) sysfatal("frame %llud is too big: %d bytes", framenum, bufsz); } if((n = Bread(&in, buf, sz)) != sz) sysfatal("short read (%d < %d) at %lld", n, sz, Boffset(&in)); if(hxsz < 1) Bwrite(&out, buf, sz); else Bprint(&out, "[%6llud %8llud %#7ux] %.*H\n", framenum, timestamp, sz, sz > hxsz ? hxsz : sz, buf); } Bterm(&in); Bterm(&out); exits(nil);}
#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 |= (uvlong)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 [-h hxsz] [file.ivf] >file.raw\n", argv0);
exits("usage");
}
void
main(int argc, char **argv)
{
u64int timestamp, framenum;
int n, bufsz, hxsz, fd;
u32int tbnum, tbdenum;
u16int w, h, hlen;
Biobuf in, out;
char tmp[6];
u8int *buf;
u32int sz;
hxsz = 0;
ARGBEGIN{
case 'h':
if((hxsz = atoi(EARGF(usage()))) > 0){
fmtinstall('H', encodefmt);
break;
}
default:
usage();
}ARGEND
fd = 0;
if(argc == 1){
if((fd = open(*argv, OREAD)) < 0)
sysfatal("%r");
}else if(argc != 0)
usage();
Binit(&in, fd, 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) < 0 || (int)sz < 0)
break;
if(bufsz < sz){
bufsz = sz;
if((buf = realloc(buf, bufsz)) == nil)
sysfatal("frame %llud is too big: %d bytes", framenum, bufsz);
}
if((n = Bread(&in, buf, sz)) != sz)
sysfatal("short read (%d < %d) at %lld", n, sz, Boffset(&in));
if(hxsz < 1)
Bwrite(&out, buf, sz);
else
Bprint(&out, "[%6llud %8llud %#7ux] %.*H\n", framenum, timestamp, sz, sz > hxsz ? hxsz : sz, buf);
}
Bterm(&in);
Bterm(&out);
exits(nil);
}