#include "image.h" #include typedef struct Src { char *name; int fd; ImgHdr; Biobuf; } Src; void usage(void) { fprint(2, "usage: %s image1 image2\n", argv0); exits("usage"); } void main(int argc, char **argv) { Src src1, src2; Biobuf bout; int c1, c2; ARGBEGIN { default: usage(); } ARGEND if(argc != 2) usage(); if(fmtinstall('H', Hfmt) < 0) sysfatal("fmtinstall"); src1.name = argv[0]; src2.name = argv[1]; if((src1.fd = open(src1.name, OREAD)) < 0) sysfatal("open %s: %r", src1.name); if((src2.fd = open(src2.name, OREAD)) < 0) sysfatal("open %s: %r", src2.name); if(readimghdr(src1.fd, &src1.ImgHdr) < 0) sysfatal("%s: read header: %r", src1.name); if(readimghdr(src2.fd, &src2.ImgHdr) < 0) sysfatal("%s: read header: %r", src2.name); if(!eqrect(src1.r, src2.r)) sysfatal("rect mismatch"); if(src1.chan == CMAP8) sysfatal("%s: color mapped", src1.name); if(src2.chan == CMAP8) sysfatal("%s: color mapped", src2.name); if(src1.compressed) sysfatal("%s: compressed", src1.name); if(src2.compressed) sysfatal("%s: compressed", src2.name); if(src1.chan != src2.chan) sysfatal("chan mismatch"); if(Binit(&src1.Biobuf, src1.fd, OREAD) < 0 || Binit(&src2.Biobuf, src2.fd, OREAD) < 0 || Binit(&bout, 1, OWRITE) < 0 ) sysfatal("Binit"); Bprint(&bout, "%H", src1.ImgHdr); for(;;) { c1 = Bgetc(&src1.Biobuf); c2 = Bgetc(&src2.Biobuf); if(c1 < 0 || c2 < 0) { if(c1 == Beof && c2 == Beof) break; sysfatal("read error: %d %d", c1, c2); } if(Bputc(&bout, c1^c2) < 0) sysfatal("write error"); } exits(nil); }