#include "image.h" #include #include /* fd -> cat -> p[1] -> p[0] */ int hdrcat(int fd, ImgHdr h) { int p[2]; if(pipe(p) < 0) { werrstr("pipe: %r"); return -1; } switch(rfork(RFPROC|RFREND|RFFDG|RFNAMEG|RFNOWAIT)) { case -1: close(p[0]); close(p[1]); werrstr("fork: %r"); return -1; case 0: close(p[0]); dup(p[1], 1); dup(fd, 0); print("%H", h); execl("/bin/cat", "cat", nil); sysfatal("exec cat: %r"); } close(p[1]); return p[0]; } /* fd -> decompress -> p[1] -> p[0] */ int _decompress(int fd) { int p[2]; if(pipe(p) < 0) { werrstr("pipe: %r"); return -1; } switch(rfork(RFPROC|RFREND|RFFDG|RFNAMEG|RFNOWAIT)) { case -1: close(p[0]); close(p[1]); werrstr("fork: %r"); return -1; case 0: close(p[0]); dup(p[1], 1); dup(fd, 0); execl("/bin/image/decompress", "image/decompress", nil); sysfatal("exec decompress: %r"); } close(p[1]); return p[0]; } int decompress(int fd, ImgHdr *h) { if((fd = hdrcat(fd, *h)) < 0) { werrstr("decompress: hdrcat: %r"); return -1; } if((fd = _decompress(fd)) < 0) sysfatal("decompress: _: %r"); if(readimghdr(fd, h) < 0) sysfatal("decompress: header: %r"); return fd; } int linesz(ImgHdr h) { return Dx(h.r) * chantodepth(h.chan)/8; } void usage(void) { fprint(2, "usage: %s linesz(hsrc) ? linesz(hdst) : linesz(hsrc))) == nil) sysfatal("alloc buf: %r"); if(Binit(&bsrc, 0, OREAD) < 0 || Binit(&bdst, 1, OWRITE) < 0) sysfatal("Binit"); Bprint(&bdst, "%H", hdst); for(y = 0; y < Dy(hsrc.r); y++) { if((n = Bread(&bsrc, buf, linesz(hsrc))) != linesz(hsrc)) { if(n == 0) werrstr("eof"); sysfatal("read src: line %d/%d: %d/%d: %r", y, Dy(hsrc.r), n, linesz(hsrc)); } if(loadmemimage(srcline, srcline->r, buf, linesz(hsrc)) < 0) sysfatal("load src"); memimagedraw(dstline, dstline->r, srcline, ZP, nil, ZP, S); if(unloadmemimage(dstline, dstline->r, buf, linesz(hdst)) < 0) sysfatal("unload dst"); if(Bwrite(&bdst, buf, linesz(hdst)) != linesz(hdst)) sysfatal("write dst: %r"); } exits(nil); }