readtif, writetif: remove multiplication in inner loops of predict functions

This commit is contained in:
ppatience0 2013-07-21 10:56:11 -04:00
parent 176569ca4d
commit 776056dcd0
2 changed files with 36 additions and 53 deletions

View file

@ -442,8 +442,8 @@ static void listadd(Lzw *, Code *);
static Code *tabadd(Lzw *, Code *, Code *); static Code *tabadd(Lzw *, Code *, Code *);
static int getcode(Lzw *); static int getcode(Lzw *);
static int wstr(uchar *, ulong, ulong *, Code *, long *); static int wstr(uchar *, ulong, ulong *, Code *, long *);
static int predict1(Tif *, uchar *, ulong); static void predict1(Tif *, uchar *);
static int predict8(Tif *, uchar *, ulong); static void predict8(Tif *, uchar *);
static int lzwstrip(Lzw *, uchar *, ulong, ulong *, long); static int lzwstrip(Lzw *, uchar *, ulong, ulong *, long);
static uchar *lzw(Tif *); static uchar *lzw(Tif *);
static uchar *packbits(Tif *); static uchar *packbits(Tif *);
@ -1096,61 +1096,45 @@ wstr(uchar *data, ulong size, ulong *i, Code *p, long *striplen)
return 0; return 0;
} }
static int static void
predict1(Tif *t, uchar *data, ulong ndata) predict1(Tif *t, uchar *data)
{ {
int bpl, pix, b[8], d, m, n, j; int bpl, pix, b[8], d, m, n, j;
ulong i, x, y; ulong x, y;
bpl = bytesperline(Rect(0, 0, t->dx, t->dy), t->depth);
d = t->depth; d = t->depth;
bpl = bytesperline(Rect(0, 0, t->dx, t->dy), d);
m = (1 << d) - 1; m = (1 << d) - 1;
n = 8 / d; n = 8 / d;
for(y = 0; y < t->dy; y++) { for(y = 0; y < t->dy; y++) {
for(x = 0; x < bpl; x++) { for(x = 0; x < bpl; x++, data++) {
i = y*bpl + x; pix = *data;
if(i >= ndata) {
werrstr("pred4 overflow");
return -1;
}
pix = data[i];
b[n-1] = (pix >> d*(n-1)) & m; b[n-1] = (pix >> d*(n-1)) & m;
if(x > 0) if(x > 0)
b[n-1] += data[i-1] & m; b[n-1] += *(data-1) & m;
for(j = n-2; j >= 0; j--) { for(j = n-2; j >= 0; j--) {
b[j] = (pix >> d*j) & m; b[j] = (pix >> d*j) & m;
b[j] += b[j+1]; b[j] += b[j+1];
} }
for(j = pix = 0; j < n; j++) for(j = pix = 0; j < n; j++)
pix |= (b[j] & m) << d*j; pix |= (b[j] & m) << d*j;
data[i] = pix; *data = pix;
} }
} }
return 0;
} }
static int static void
predict8(Tif *t, uchar *data, ulong ndata) predict8(Tif *t, uchar *data)
{ {
char a, b; ulong j, s, x, y;
ulong i, j, s, x, y;
s = t->samples; s = t->samples;
for(y = 0; y < t->dy; y++) { for(y = 0; y < t->dy; y++) {
for(x = 1; x < t->dx; x++) { for(x = 1, data += s; x < t->dx; x++) {
i = (y*t->dx + x) * s; for(j = 0; j < s; j++, data++)
if(i+s-1 >= ndata) { *data += *(data-s);
werrstr("pred8 overflow");
return -1;
}
for(j = 0; j < s; i++, j++) {
a = (char)data[i];
b = (char)data[i-s];
data[i] = (uchar)(a + b);
}
} }
} }
return 0;
} }
static int static int
@ -1215,7 +1199,6 @@ lzw(Tif *t)
uchar *data; uchar *data;
Lzw l; Lzw l;
Code *p, *q; Code *p, *q;
int (*predict)(Tif *, uchar *, ulong);
size = ((t->dx*t->dy*t->depth + 7) / 8) * sizeof *data; size = ((t->dx*t->dy*t->depth + 7) / 8) * sizeof *data;
if((data = malloc(size)) == nil) { if((data = malloc(size)) == nil) {
@ -1259,13 +1242,9 @@ lzw(Tif *t)
free(t->data); free(t->data);
if(data != nil && t->predictor == 2) { if(data != nil && t->predictor == 2) {
if(t->depth < 8) if(t->depth < 8)
predict = predict1; predict1(t, data);
else else
predict = predict8; predict8(t, data);
if((*predict)(t, data, size) < 0) {
free(data);
return nil;
}
} }
return data; return data;
} }

View file

@ -792,27 +792,27 @@ static void
predict1(Tif *t) predict1(Tif *t)
{ {
int pix, b[8], d, m, n, j; int pix, b[8], d, m, n, j;
ulong i, x, y; ulong x, y;
uchar *data, *p;
p = t->data;
d = *t->depth; d = *t->depth;
m = (1 << d) - 1; m = (1 << d) - 1;
n = 8 / d; n = 8 / d;
for(y = 0; y < t->dy; y++) { for(y = 0; y < t->dy; y++) {
for(x = t->bpl-1;; x--) { data = p += t->bpl;
i = y*t->bpl + x; for(x = t->bpl; x > 0; x--) {
pix = t->data[i]; pix = *--data;
for(j = 0; j < n; j++) { for(j = 0; j < n; j++) {
b[j] = (pix >> d*j) & m; b[j] = (pix >> d*j) & m;
if(j > 0) if(j > 0)
b[j-1] -= b[j]; b[j-1] -= b[j];
} }
if(x > 0) if(x > 1)
b[n-1] -= t->data[i-1] & m; b[n-1] -= *(data-1) & m;
for(j = pix = 0; j < n; j++) for(j = pix = 0; j < n; j++)
pix |= (b[j] & m) << d*j; pix |= (b[j] & m) << d*j;
t->data[i] = pix; *data = pix;
if(x == 0)
break;
} }
} }
} }
@ -820,14 +820,18 @@ predict1(Tif *t)
static void static void
predict8(Tif *t) predict8(Tif *t)
{ {
ulong i, j, s, x, y; ulong j, s, x, y;
uchar *data, *p;
p = t->data;
s = t->samples; s = t->samples;
for(y = 0; y < t->dy; y++) { for(y = 0; y < t->dy; y++) {
for(x = t->dx-1; x >= 1; x--) { data = p += t->dx * s;
i = (y*t->dx + x) * s; for(x = t->dx; x > 1; x--) {
for(j = 0; j < s; i++, j++) for(j = 0; j < s; j++) {
t->data[i] -= t->data[i-s]; data--;
*data -= *(data-s);
}
} }
} }
} }