diff options
-rw-r--r-- | lib/zlib/inffast.c | 51 | ||||
-rw-r--r-- | lib/zlib/zlib.h | 1 |
2 files changed, 40 insertions, 12 deletions
diff --git a/lib/zlib/inffast.c b/lib/zlib/inffast.c index 5e2a65ad4d2..b5a0adcce69 100644 --- a/lib/zlib/inffast.c +++ b/lib/zlib/inffast.c @@ -236,18 +236,47 @@ unsigned start; /* inflate()'s starting value for strm->avail_out */ } } else { + unsigned short *sout; + unsigned long loops; + from = out - dist; /* copy direct from output */ - do { /* minimum length is three */ - *out++ = *from++; - *out++ = *from++; - *out++ = *from++; - len -= 3; - } while (len > 2); - if (len) { - *out++ = *from++; - if (len > 1) - *out++ = *from++; - } + /* minimum length is three */ + /* Align out addr */ + if (!((long)(out - 1) & 1)) { + *out++ = *from++; + len--; + } + sout = (unsigned short *)out; + if (dist > 2 ) { + unsigned short *sfrom; + + sfrom = (unsigned short *)from; + loops = len >> 1; + do + *sout++ = get_unaligned(sfrom++); + while (--loops); + out = (unsigned char *)sout; + from = (unsigned char *)sfrom; + } else { /* dist == 1 or dist == 2 */ + unsigned short pat16; + + pat16 = *(sout - 1); + if (dist == 1) +#if defined(__BIG_ENDIAN) + pat16 = (pat16 & 0xff) | ((pat16 & 0xff ) << 8); +#elif defined(__LITTLE_ENDIAN) + pat16 = (pat16 & 0xff00) | ((pat16 & 0xff00 ) >> 8); +#else +#error __BIG_ENDIAN nor __LITTLE_ENDIAN is defined +#endif + loops = len >> 1; + do + *sout++ = pat16; + while (--loops); + out = (unsigned char *)sout; + } + if (len & 1) + *out++ = *from++; } } else if ((op & 64) == 0) { /* 2nd level distance code */ diff --git a/lib/zlib/zlib.h b/lib/zlib/zlib.h index 560e7be97d3..f9b2f69ac02 100644 --- a/lib/zlib/zlib.h +++ b/lib/zlib/zlib.h @@ -10,7 +10,6 @@ /* avoid conflicts */ #undef OFF #undef ASMINF -#undef POSTINC #undef NO_GZIP #define GUNZIP #undef STDC |