#include #include #include #include static int lg2(ulong i) { int j; for(j = 0; (i >>= 1) != 0; j++) ; return j; } static ulong genmsk(ulong n) { ulong i; for(i = 0; n; n--) i = i<<1 | 1; return i; } static int expand(Tiff *t, ulong i, ulong o) { uchar *p, *e, *s, *op; ulong scale, mask, bits, nbits, shift, r, rb; long l; int c; shift = lg2(o/i); l = tiffimglen(t)<rawimg; e = t->rawimge; bits = 0; nbits = 0; r = 0; rb = 0; mask = genmsk(i); scale = genmsk(o)/mask; for(op = s; op < s+l; ){ while(nbits < i){ if(p >= e) sysfatal("p>e %uld %uld", (ulong)p, (ulong)e); //goto bad; c = *p++; bits = bits<<8|c; nbits += 8; } if(nbits= i){ nbits -= i; r = r<>nbits)&mask)*scale; rb += o; while(rb >= 8){ rb -= 8; *op++ = (r>>rb)&0xff; r >>= 8; } } bits &= mask; // delete used bits. } if(nbits != 0) goto bad; if(rb) *op = r&0xff; free(t->rawimg); t->rawimg = s; t->rawimge = s+l; return l; bad: free(s); return -1; } static int chanokay(int n) { if(n==0 || (n>8 && n%8) || (n<8 && 8%n)) return 0; return n; } static int cdepthequal(Tiff *t){ IFD *cdepth; int n, i; cdepth = lookifdptr(t, Tbitspersample); if(!cdepth) return 0; n = cdepth->sp[0]; for(i = 1; i < cdepth->n; i++) if(cdepth->sp[i] != n) return 0; return n; } static int setbitsps(Tiff *t, int o) { IFD *i; int j; i = lookifdptr(t, Tbitspersample); if(!i) return -1; for(j = 0; j < i->n; j++) i->sp[j] = o; t->bpp = o*i->n; return 0; } int tiffexpand(Tiff *t) { int n, m, i; if(chanokay(t->bpp)) return 0; if((n = cdepthequal(t)) == 0) return -1; // number theory. for(i = 1; i < 5; i++) if(chanokay(3*(n+i))) break; if(i>5) return -1; m = n+i; if(expand(t, n, m) == -1) return -1; if(setbitsps(t, m)) return -1; return 0; }