#ifdef IMG3_SUPPORT #include #include #include #define BASE 65521L /* largest prime smaller than 65536 */ #define NMAX 5000 // NMAX (was 5521) the largest n such that 255n(n+1)/2 + (n+1)(BASE-1) <= 2^32-1 #define DO1(buf,i) {s1 += buf[i]; s2 += s1;} #define DO2(buf,i) DO1(buf,i); DO1(buf,i+1); #define DO4(buf,i) DO2(buf,i); DO2(buf,i+2); #define DO8(buf,i) DO4(buf,i); DO4(buf,i+4); #define DO16(buf) DO8(buf,0); DO8(buf,8); uint32_t lzadler32(uint8_t *buf, int32_t len) { unsigned long s1 = 1; // adler & 0xffff; unsigned long s2 = 0; // (adler >> 16) & 0xffff; int k; while (len > 0) { k = len < NMAX ? len : NMAX; len -= k; while (k >= 16) { DO16(buf); buf += 16; k -= 16; } if (k != 0) do { s1 += *buf++; s2 += s1; } while (--k); s1 %= BASE; s2 %= BASE; } return (s2 << 16) | s1; } /************************************************************** LZSS.C -- A Data Compression Program *************************************************************** 4/6/1989 Haruhiko Okumura Use, distribute, and modify this program freely. Please send me your improved versions. PC-VAN SCIENCE NIFTY-Serve PAF01022 CompuServe 74050,1022 **************************************************************/ #define N 4096 /* size of ring buffer - must be power of 2 */ #define F 18 /* upper limit for match_length */ #define THRESHOLD 2 /* encode string into position and length if match_length is greater than this */ int decompress_lzss(uint8_t *dst, uint8_t *src, uint32_t srclen) { /* ring buffer of size N, with extra F-1 bytes to aid string comparison */ uint8_t text_buf[N + F - 1]; uint8_t *dststart = dst; uint8_t *srcend = src + srclen; int i, j, k, r, c; unsigned int flags; dst = dststart; srcend = src + srclen; memset(text_buf, ' ', N - F); r = N - F; flags = 0; for ( ; ; ) { if (((flags >>= 1) & 0x100) == 0) { if (src < srcend) c = *src++; else break; flags = c | 0xFF00; /* uses higher byte cleverly */ } /* to count eight */ if (flags & 1) { if (src < srcend) c = *src++; else break; *dst++ = c; text_buf[r++] = c; r &= (N - 1); } else { if (src < srcend) i = *src++; else break; if (src < srcend) j = *src++; else break; i |= ((j & 0xF0) << 4); j = (j & 0x0F) + THRESHOLD; for (k = 0; k <= j; k++) { c = text_buf[(i + k) & (N - 1)]; *dst++ = c; text_buf[r++] = c; r &= (N - 1); } } } return dst - dststart; } #endif