license header and line ending fixups
[pngwrite.git] / adler.pas
1 Unit Adler;\r
2 \r
3 {\r
4   adler32.c -- compute the Adler-32 checksum of a data stream\r
5   Copyright (C) 1995-1998 Mark Adler\r
6 \r
7   Pascal tranlastion\r
8   Copyright (C) 1998 by Jacques Nomssi Nzali\r
9   For conditions of distribution and use, see copyright notice in readme.paszlib\r
10 }\r
11 \r
12 interface\r
13 \r
14 {$I zconf.inc}\r
15 \r
16 uses\r
17   zutil;\r
18 \r
19 function adler32(adler : uLong; buf : pBytef; len : uInt) : uLong;\r
20 \r
21 {    Update a running Adler-32 checksum with the bytes buf[0..len-1] and\r
22    return the updated checksum. If buf is NIL, this function returns\r
23    the required initial value for the checksum.\r
24    An Adler-32 checksum is almost as reliable as a CRC32 but can be computed\r
25    much faster. Usage example:\r
26 \r
27    var\r
28      adler : uLong;\r
29    begin\r
30      adler := adler32(0, Z_NULL, 0);\r
31 \r
32      while (read_buffer(buffer, length) <> EOF) do\r
33        adler := adler32(adler, buffer, length);\r
34 \r
35      if (adler <> original_adler) then\r
36        error();\r
37    end;\r
38 }\r
39 \r
40 implementation\r
41 \r
42 const\r
43   BASE = uLong(65521); { largest prime smaller than 65536 }\r
44   {NMAX = 5552; original code with unsigned 32 bit integer }\r
45   { NMAX is the largest n such that 255n(n+1)/2 + (n+1)(BASE-1) <= 2^32-1 }\r
46   NMAX = 3854;        { code with signed 32 bit integer }\r
47   { NMAX is the largest n such that 255n(n+1)/2 + (n+1)(BASE-1) <= 2^31-1 }\r
48   { The penalty is the time loss in the extra MOD-calls. }\r
49 \r
50 \r
51 { ========================================================================= }\r
52 \r
53 function adler32(adler : uLong; buf : pBytef; len : uInt) : uLong;\r
54 var\r
55   s1, s2 : uLong;\r
56   k : int;\r
57 begin\r
58   s1 := adler and $ffff;\r
59   s2 := (adler shr 16) and $ffff;\r
60 \r
61   if not Assigned(buf) then\r
62   begin\r
63     adler32 := uLong(1);\r
64     exit;\r
65   end;\r
66 \r
67   while (len > 0) do\r
68   begin\r
69     if len < NMAX then\r
70       k := len\r
71     else\r
72       k := NMAX;\r
73     Dec(len, k);\r
74     {\r
75     while (k >= 16) do\r
76     begin\r
77       DO16(buf);\r
78       Inc(buf, 16);\r
79       Dec(k, 16);\r
80     end;\r
81     if (k <> 0) then\r
82     repeat\r
83       Inc(s1, buf^);\r
84       Inc(puf);\r
85       Inc(s2, s1);\r
86       Dec(k);\r
87     until (k = 0);\r
88     }\r
89     while (k > 0) do\r
90     begin\r
91       Inc(s1, buf^);\r
92       Inc(s2, s1);\r
93       Inc(buf);\r
94       Dec(k);\r
95     end;\r
96     s1 := s1 mod BASE;\r
97     s2 := s2 mod BASE;\r
98   end;\r
99   adler32 := (s2 shl 16) or s1;\r
100 end;\r
101 \r
102 {\r
103 #define DO1(buf,i)\r
104   begin\r
105     Inc(s1, buf[i]);\r
106     Inc(s2, s1);\r
107   end;\r
108 #define DO2(buf,i)  DO1(buf,i); DO1(buf,i+1);\r
109 #define DO4(buf,i)  DO2(buf,i); DO2(buf,i+2);\r
110 #define DO8(buf,i)  DO4(buf,i); DO4(buf,i+4);\r
111 #define DO16(buf)   DO8(buf,0); DO8(buf,8);\r
112 }\r
113 end.\r
114 \r