#include <u.h>
#include <libc.h>
#include <bio.h>
#include <flate.h>
#include <tiff.h>
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);
}
|