]> mj.ucw.cz Git - libucw.git/commitdiff
taken much faster implementation of Adler32 and put into a separate source-code
authorRobert Spalek <robert@ucw.cz>
Fri, 16 Jul 2004 10:47:37 +0000 (10:47 +0000)
committerRobert Spalek <robert@ucw.cz>
Fri, 16 Jul 2004 10:47:37 +0000 (10:47 +0000)
lib/Makefile
lib/adler32.c [new file with mode: 0644]
lib/lizard-safe.c
lib/lizard.h

index 381190a07097d1fda79f4b45f00903215cd7fb70..f3e0529c2704c142ed7812b7158aa72e8fa6565e 100644 (file)
@@ -20,7 +20,7 @@ LIBSH_MODS= \
        db \
        url urlkey finger \
        mainloop exitstatus runcmd sighandler \
-       lizard lizard-safe \
+       lizard lizard-safe adler32 \
        md5 md5hex \
        base64 base224
 
diff --git a/lib/adler32.c b/lib/adler32.c
new file mode 100644 (file)
index 0000000..613ed72
--- /dev/null
@@ -0,0 +1,78 @@
+/*
+ *     adler32.c -- compute the Adler-32 checksum of a data stream
+ *
+ *     Copyright (C) 1995--2003 Mark Adler
+ *
+ *     Taken from zlib-1.2.1 and adjusted by Robert Spalek.  For conditions of
+ *     distribution and use, see copyright notice in zlib.h.
+ */
+
+#include "lib/lib.h"
+#include "lib/lizard.h"
+
+#define BASE 65521UL   /* largest prime smaller than 65536 */
+#define NMAX 5552      /* NMAX is 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);
+
+#ifdef NO_DIVIDE
+#  define MOD(a) \
+    do { \
+        if (a >= (BASE << 16)) a -= (BASE << 16); \
+        if (a >= (BASE << 15)) a -= (BASE << 15); \
+        if (a >= (BASE << 14)) a -= (BASE << 14); \
+        if (a >= (BASE << 13)) a -= (BASE << 13); \
+        if (a >= (BASE << 12)) a -= (BASE << 12); \
+        if (a >= (BASE << 11)) a -= (BASE << 11); \
+        if (a >= (BASE << 10)) a -= (BASE << 10); \
+        if (a >= (BASE << 9)) a -= (BASE << 9); \
+        if (a >= (BASE << 8)) a -= (BASE << 8); \
+        if (a >= (BASE << 7)) a -= (BASE << 7); \
+        if (a >= (BASE << 6)) a -= (BASE << 6); \
+        if (a >= (BASE << 5)) a -= (BASE << 5); \
+        if (a >= (BASE << 4)) a -= (BASE << 4); \
+        if (a >= (BASE << 3)) a -= (BASE << 3); \
+        if (a >= (BASE << 2)) a -= (BASE << 2); \
+        if (a >= (BASE << 1)) a -= (BASE << 1); \
+        if (a >= BASE) a -= BASE; \
+    } while (0)
+#else
+#  define MOD(a) a %= BASE
+#endif
+
+uns
+update_adler32(uns adler, byte *buf, uns len)
+{
+  uns s1 = adler & 0xffff;
+  uns s2 = (adler >> 16) & 0xffff;
+  int k;
+
+  if (!buf) return 1L;
+
+  while (len > 0) {
+    k = len < NMAX ? (int)len : NMAX;
+    len -= k;
+    while (k >= 16) {
+      DO16(buf);
+      buf += 16;
+      k -= 16;
+    }
+    if (k != 0) do {
+      s1 += *buf++;
+      s2 += s1;
+    } while (--k);
+    MOD(s1);
+    MOD(s2);
+  }
+  return (s2 << 16) | s1;
+}
+
+uns
+adler32(byte *buf, uns len)
+{
+  return update_adler32(1, buf, len);
+}
index 40a5aa3daf3da7dfef3efc72fff04359320bd860..88e9aebd4fc8070a1a97e239d487b8fd8a1b6963 100644 (file)
@@ -103,24 +103,3 @@ lizard_decompress_safe(byte *in, struct lizard_buffer *buf, uns expected_length)
   signal_handler[SIGSEGV] = old_handler;
   return ptr;
 }
-
-#define BASE 65521 /* largest prime smaller than 65536 */
-
-inline uns
-update_adler32(uns adler, byte *ptr, uns len)
-  /* taken from RFC1950 */
-{
-  uns s1 = adler & 0xffff;
-  uns s2 = (adler >> 16) & 0xffff;
-  for (uns n = 0; n < len; n++) {
-    s1 = (s1 + ptr[n]) % BASE;
-    s2 = (s2 + s1)     % BASE;
-  }
-  return (s2 << 16) + s1;
-}
-
-uns
-adler32(byte *ptr, uns len)
-{
-  return update_adler32(1, ptr, len);
-}
index 838d683f7849f30de68f797a467a676fc491f672..c701e6f2bcb589d2ecfa4fdaab86f1ebd988f976 100644 (file)
@@ -37,6 +37,7 @@ struct lizard_buffer *lizard_alloc(void);
 void lizard_free(struct lizard_buffer *buf);
 byte *lizard_decompress_safe(byte *in, struct lizard_buffer *buf, uns expected_length);
 
+/* adler32.c */
 uns update_adler32(uns adler, byte *ptr, uns len);
 uns adler32(byte *ptr, uns len);