#include #include #include #include #include static int unZzero(Tiff * t, Biobuf *b, uchar *buf, int l) { switch(t->bpp){ case 16: return Btiffshorts(b, (short*)buf, l/2, t->order); case 32: return Btifflongs(b, (long*)buf, l/4, t->order); default: fprint(2, "l = %d\n", l); return Bread(b, buf, l); } } static int unZccitt(Tiff *t, Biobuf *b, uchar *buf, int l) { return tiffhuff(b, buf, l, lookifd(t, Tphotometric), lookifd(t, Twidth)); } static int unZpack(Tiff *, Biobuf *b, uchar* buf, int l) { int c, n; for(n = 0; n != l; ){ c = Bgetc(b); if(c < 128) Bread(b, buf+n, c+1); else if(c > 128){ c = 256-c; memset(buf+n, Bgetc(b), c+1); } else continue; n += c+1; } return n; } #ifdef nosabe static int unZlzw(Tiff *, Biobuf *b, uchar *buf, int l) { uchar block[8*1024], *p, *e; static int didinit; int c, s, r; if(!didinit++) inflateinit(); s = iounit(Bfildes(b)); if(s < 100 || s > sizeof block) s = sizeof block; fprint(2, "s=%d\n", s); for(p = buf, e = p+l; e != p; p += r){ c = Bread(b, block, s); if(c < 0) break; r = inflateblock(p, e-p, block, c); if(r < 0){ fprint(2, "%d: %r\n", r); break; } fprint(2, "buf=%011uld: p %011uld e %011uld r=%d\n", (ulong)buf, (ulong)p, (ulong)e, r); } return p-buf; } #endif typedef struct { uchar *a; long offset; long l; } A; static int dmemcpy(void *t, void *s, int n){ A *a; a = t; fprint(2, "x %lx n=%d\n", a->offset, n); if(a->offset+n >= a->l) return -1; memcpy(a->a + a->offset, s, n); a->offset += n; return n; } extern int inflatelzw(void *wr, int (*w)(void*, void*, int), void *getr, int (*get)(void*)); static int unZlzw(Tiff *, Biobuf *b, uchar *buf, int l) { A a; a.a = buf; a.offset = 0; a.l = l; return inflatelzw(&a, dmemcpy, b, (int (*)(void*))Bgetc); } int unbad(Tiff*, Biobuf*, uchar*, int) { return -1; } typedef struct { Ztype z; int (*f)(Tiff*, Biobuf*, uchar*, int); char *s; } Ztab; Ztab tab[] = { {Zzero, unZzero, "none" }, {Zccitt, unZccitt, "ccitt", }, {Zgroup3, unZccitt, "group3", }, {Zgroup4, unZccitt, "group4", }, {Zlzw, unZlzw, "lzw", }, {Zjpeg, unbad, "jpg", }, {Zpack, unZpack, "packbits", }, {0, unbad, "unknown", } }; char* tiffzstr(ushort ztype) { Ztab *z, *e; for(z = tab, e = tab+nelem(tab); z < e; z++) if(z->z == ztype) return z->s; return 0; } int tiffunz(Tiff *t, ushort ztype, Biobuf* b, int l) { Ztab *z, *e; for(z = tab, e = tab+nelem(tab)-1; z < e; z++) if(z->z == ztype) break; return z->f(t, b, t->rawimge, l); }