Duplicated code in DecompressZip and DecompressRLE
jeffatrad opened this issue · 2 comments
jeffatrad commented
There is a chunk of code at the end of both decompresszip and decompressrle that is just cut and pasted.
If you split this out into and undo_predictor and undo_reorder and then just call them, and then do a little IPC unrolling, this will simplify the code and run about 10% faster for 4K RLE loads:
static void undo_predictor( unsigned char * t, unsigned long uncompressed_size )
{
unsigned char *stop = t + uncompressed_size;
int tm1 = 128;
if ( uncompressed_size >= 16 ) // for some minimum size
{
unsigned char *stop4 = t + (uncompressed_size&~3);
while (t < stop4) {
int t0 = t[0];
int t1 = t[1];
int t2 = t[2];
int t3 = t[3];
t[0] = static_cast<unsigned char>(tm1+t0-128);
t[1] = static_cast<unsigned char>(tm1+t0-128+t1-128);
t[2] = static_cast<unsigned char>(tm1+t0-128+t1-128+t2-128);
t[3] = tm1 = static_cast<unsigned char>(tm1+t0-128+t1-128+t2-128+t3-128);
t += 4;
}
}
while (t < stop) {
int d = tm1 + int(t[0]) - 128;
t[0] = tm1 = static_cast<unsigned char>(d);
++t;
}
}
static void undo_reorder( unsigned char *dst, unsigned char *t, unsigned long uncompressed_size )
{
const char *t1 = reinterpret_cast<const char *>(t);
const char *t2 = reinterpret_cast<const char *>(t) +
(uncompressed_size + 1) / 2;
char *s = reinterpret_cast<char *>(dst);
char *stop = s + (uncompressed_size);
char *stop8 = s + (uncompressed_size&~7);
while( s < stop8 )
{
s[0]=t1[0];
s[1]=t2[0];
s[2]=t1[1];
s[3]=t2[1];
s[4]=t1[2];
s[5]=t2[2];
s[6]=t1[3];
s[7]=t2[3];
t1 += 4;
t2 += 4;
s += 8;
}
for (;;) {
if (s < stop)
*(s++) = *(t1++);
else
break;
if (s < stop)
*(s++) = *(t2++);
else
break;
}
}
Even if you don't do initial unrolled loop, it would be good to deduplicate this code.
Thanks!
syoyo commented
Please send PR of this change.
syoyo commented
Close the issue since there is no PR has been submitted