File size: 21,410 Bytes
9375c9a |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 |
<html><!-- Created using the cpp_pretty_printer from the dlib C++ library. See http://dlib.net for updates. --><head><title>dlib C++ Library - adler32.c</title></head><body bgcolor='white'><pre>
<font color='#009900'>/* adler32.c -- compute the Adler-32 checksum of a data stream
* Copyright (C) 1995-2011 Mark Adler
* For conditions of distribution and use, see copyright notice in zlib.h
*/</font>
<font color='#009900'>/* @(#) $Id$ */</font>
<font color='#0000FF'>#include</font> "<a style='text-decoration:none' href='zutil.h.html'>zutil.h</a>"
<font color='#0000FF'>#define</font> local <font color='#0000FF'>static</font>
local uLong adler32_combine_ <b><a name='OF'></a>OF</b><font face='Lucida Console'>(</font><font face='Lucida Console'>(</font>uLong adler1, uLong adler2, z_off64_t len2<font face='Lucida Console'>)</font><font face='Lucida Console'>)</font>;
<font color='#0000FF'>#define</font> BASE <font color='#979000'>65521</font> <font color='#009900'>/* largest prime smaller than 65536 */</font>
<font color='#0000FF'>#define</font> NMAX <font color='#979000'>5552</font>
<font color='#009900'>/* NMAX is the largest n such that 255n(n+1)/2 + (n+1)(BASE-1) <= 2^32-1 */</font>
<font color='#0000FF'>#define</font> DO1<font face='Lucida Console'>(</font>buf,i<font face='Lucida Console'>)</font> <b>{</b>adler <font color='#5555FF'>+</font><font color='#5555FF'>=</font> <font face='Lucida Console'>(</font>buf<font face='Lucida Console'>)</font>[i]; sum2 <font color='#5555FF'>+</font><font color='#5555FF'>=</font> adler;<b>}</b>
<font color='#0000FF'>#define</font> DO2<font face='Lucida Console'>(</font>buf,i<font face='Lucida Console'>)</font> DO1<font face='Lucida Console'>(</font>buf,i<font face='Lucida Console'>)</font>; DO1<font face='Lucida Console'>(</font>buf,i<font color='#5555FF'>+</font><font color='#979000'>1</font><font face='Lucida Console'>)</font>;
<font color='#0000FF'>#define</font> DO4<font face='Lucida Console'>(</font>buf,i<font face='Lucida Console'>)</font> DO2<font face='Lucida Console'>(</font>buf,i<font face='Lucida Console'>)</font>; DO2<font face='Lucida Console'>(</font>buf,i<font color='#5555FF'>+</font><font color='#979000'>2</font><font face='Lucida Console'>)</font>;
<font color='#0000FF'>#define</font> DO8<font face='Lucida Console'>(</font>buf,i<font face='Lucida Console'>)</font> DO4<font face='Lucida Console'>(</font>buf,i<font face='Lucida Console'>)</font>; DO4<font face='Lucida Console'>(</font>buf,i<font color='#5555FF'>+</font><font color='#979000'>4</font><font face='Lucida Console'>)</font>;
<font color='#0000FF'>#define</font> DO16<font face='Lucida Console'>(</font>buf<font face='Lucida Console'>)</font> DO8<font face='Lucida Console'>(</font>buf,<font color='#979000'>0</font><font face='Lucida Console'>)</font>; DO8<font face='Lucida Console'>(</font>buf,<font color='#979000'>8</font><font face='Lucida Console'>)</font>;
<font color='#009900'>/* use NO_DIVIDE if your processor does not do division in hardware --
try it both ways to see which is faster */</font>
<font color='#0000FF'>#ifdef</font> NO_DIVIDE
<font color='#009900'>/* note that this assumes BASE is 65521, where 65536 % 65521 == 15
(thank you to John Reiser for pointing this out) */</font>
# define <b><a name='CHOP'></a>CHOP</b><font face='Lucida Console'>(</font>a<font face='Lucida Console'>)</font> \
<font color='#0000FF'>do</font> <b>{</b> \
<font color='#0000FF'><u>unsigned</u></font> <font color='#0000FF'><u>long</u></font> tmp <font color='#5555FF'>=</font> a <font color='#5555FF'>></font><font color='#5555FF'>></font> <font color='#979000'>16</font>; \
a <font color='#5555FF'>&</font><font color='#5555FF'>=</font> <font color='#979000'>0xffffUL</font>; \
a <font color='#5555FF'>+</font><font color='#5555FF'>=</font> <font face='Lucida Console'>(</font>tmp <font color='#5555FF'><</font><font color='#5555FF'><</font> <font color='#979000'>4</font><font face='Lucida Console'>)</font> <font color='#5555FF'>-</font> tmp; \
<b>}</b> <font color='#0000FF'>while</font> <font face='Lucida Console'>(</font><font color='#979000'>0</font><font face='Lucida Console'>)</font>
# define <b><a name='MOD28'></a>MOD28</b><font face='Lucida Console'>(</font>a<font face='Lucida Console'>)</font> \
<font color='#0000FF'>do</font> <b>{</b> \
<font color='#BB00BB'>CHOP</font><font face='Lucida Console'>(</font>a<font face='Lucida Console'>)</font>; \
<font color='#0000FF'>if</font> <font face='Lucida Console'>(</font>a <font color='#5555FF'>></font><font color='#5555FF'>=</font> BASE<font face='Lucida Console'>)</font> a <font color='#5555FF'>-</font><font color='#5555FF'>=</font> BASE; \
<b>}</b> <font color='#0000FF'>while</font> <font face='Lucida Console'>(</font><font color='#979000'>0</font><font face='Lucida Console'>)</font>
# define <b><a name='MOD'></a>MOD</b><font face='Lucida Console'>(</font>a<font face='Lucida Console'>)</font> \
<font color='#0000FF'>do</font> <b>{</b> \
<font color='#BB00BB'>CHOP</font><font face='Lucida Console'>(</font>a<font face='Lucida Console'>)</font>; \
<font color='#BB00BB'>MOD28</font><font face='Lucida Console'>(</font>a<font face='Lucida Console'>)</font>; \
<b>}</b> <font color='#0000FF'>while</font> <font face='Lucida Console'>(</font><font color='#979000'>0</font><font face='Lucida Console'>)</font>
# define <b><a name='MOD63'></a>MOD63</b><font face='Lucida Console'>(</font>a<font face='Lucida Console'>)</font> \
<font color='#0000FF'>do</font> <b>{</b> <font color='#009900'>/* this assumes a is not negative */</font> \
z_off64_t tmp <font color='#5555FF'>=</font> a <font color='#5555FF'>></font><font color='#5555FF'>></font> <font color='#979000'>32</font>; \
a <font color='#5555FF'>&</font><font color='#5555FF'>=</font> <font color='#979000'>0xffffffffL</font>; \
a <font color='#5555FF'>+</font><font color='#5555FF'>=</font> <font face='Lucida Console'>(</font>tmp <font color='#5555FF'><</font><font color='#5555FF'><</font> <font color='#979000'>8</font><font face='Lucida Console'>)</font> <font color='#5555FF'>-</font> <font face='Lucida Console'>(</font>tmp <font color='#5555FF'><</font><font color='#5555FF'><</font> <font color='#979000'>5</font><font face='Lucida Console'>)</font> <font color='#5555FF'>+</font> tmp; \
tmp <font color='#5555FF'>=</font> a <font color='#5555FF'>></font><font color='#5555FF'>></font> <font color='#979000'>16</font>; \
a <font color='#5555FF'>&</font><font color='#5555FF'>=</font> <font color='#979000'>0xffffL</font>; \
a <font color='#5555FF'>+</font><font color='#5555FF'>=</font> <font face='Lucida Console'>(</font>tmp <font color='#5555FF'><</font><font color='#5555FF'><</font> <font color='#979000'>4</font><font face='Lucida Console'>)</font> <font color='#5555FF'>-</font> tmp; \
tmp <font color='#5555FF'>=</font> a <font color='#5555FF'>></font><font color='#5555FF'>></font> <font color='#979000'>16</font>; \
a <font color='#5555FF'>&</font><font color='#5555FF'>=</font> <font color='#979000'>0xffffL</font>; \
a <font color='#5555FF'>+</font><font color='#5555FF'>=</font> <font face='Lucida Console'>(</font>tmp <font color='#5555FF'><</font><font color='#5555FF'><</font> <font color='#979000'>4</font><font face='Lucida Console'>)</font> <font color='#5555FF'>-</font> tmp; \
<font color='#0000FF'>if</font> <font face='Lucida Console'>(</font>a <font color='#5555FF'>></font><font color='#5555FF'>=</font> BASE<font face='Lucida Console'>)</font> a <font color='#5555FF'>-</font><font color='#5555FF'>=</font> BASE; \
<b>}</b> <font color='#0000FF'>while</font> <font face='Lucida Console'>(</font><font color='#979000'>0</font><font face='Lucida Console'>)</font>
<font color='#0000FF'>#else</font>
# define <b><a name='MOD'></a>MOD</b><font face='Lucida Console'>(</font>a<font face='Lucida Console'>)</font> a <font color='#5555FF'>%</font><font color='#5555FF'>=</font> BASE
# define <b><a name='MOD28'></a>MOD28</b><font face='Lucida Console'>(</font>a<font face='Lucida Console'>)</font> a <font color='#5555FF'>%</font><font color='#5555FF'>=</font> BASE
# define <b><a name='MOD63'></a>MOD63</b><font face='Lucida Console'>(</font>a<font face='Lucida Console'>)</font> a <font color='#5555FF'>%</font><font color='#5555FF'>=</font> BASE
<font color='#0000FF'>#endif</font>
<font color='#009900'>/* ========================================================================= */</font>
uLong ZEXPORT <b><a name='adler32'></a>adler32</b><font face='Lucida Console'>(</font>adler, buf, len<font face='Lucida Console'>)</font>
uLong adler;
<font color='#0000FF'>const</font> Bytef <font color='#5555FF'>*</font>buf;
uInt len;
<b>{</b>
<font color='#0000FF'><u>unsigned</u></font> <font color='#0000FF'><u>long</u></font> sum2;
<font color='#0000FF'><u>unsigned</u></font> n;
<font color='#009900'>/* split Adler-32 into component sums */</font>
sum2 <font color='#5555FF'>=</font> <font face='Lucida Console'>(</font>adler <font color='#5555FF'>></font><font color='#5555FF'>></font> <font color='#979000'>16</font><font face='Lucida Console'>)</font> <font color='#5555FF'>&</font> <font color='#979000'>0xffff</font>;
adler <font color='#5555FF'>&</font><font color='#5555FF'>=</font> <font color='#979000'>0xffff</font>;
<font color='#009900'>/* in case user likes doing a byte at a time, keep it fast */</font>
<font color='#0000FF'>if</font> <font face='Lucida Console'>(</font>len <font color='#5555FF'>=</font><font color='#5555FF'>=</font> <font color='#979000'>1</font><font face='Lucida Console'>)</font> <b>{</b>
adler <font color='#5555FF'>+</font><font color='#5555FF'>=</font> buf[<font color='#979000'>0</font>];
<font color='#0000FF'>if</font> <font face='Lucida Console'>(</font>adler <font color='#5555FF'>></font><font color='#5555FF'>=</font> BASE<font face='Lucida Console'>)</font>
adler <font color='#5555FF'>-</font><font color='#5555FF'>=</font> BASE;
sum2 <font color='#5555FF'>+</font><font color='#5555FF'>=</font> adler;
<font color='#0000FF'>if</font> <font face='Lucida Console'>(</font>sum2 <font color='#5555FF'>></font><font color='#5555FF'>=</font> BASE<font face='Lucida Console'>)</font>
sum2 <font color='#5555FF'>-</font><font color='#5555FF'>=</font> BASE;
<font color='#0000FF'>return</font> adler <font color='#5555FF'>|</font> <font face='Lucida Console'>(</font>sum2 <font color='#5555FF'><</font><font color='#5555FF'><</font> <font color='#979000'>16</font><font face='Lucida Console'>)</font>;
<b>}</b>
<font color='#009900'>/* initial Adler-32 value (deferred check for len == 1 speed) */</font>
<font color='#0000FF'>if</font> <font face='Lucida Console'>(</font>buf <font color='#5555FF'>=</font><font color='#5555FF'>=</font> Z_NULL<font face='Lucida Console'>)</font>
<font color='#0000FF'>return</font> <font color='#979000'>1</font>L;
<font color='#009900'>/* in case short lengths are provided, keep it somewhat fast */</font>
<font color='#0000FF'>if</font> <font face='Lucida Console'>(</font>len <font color='#5555FF'><</font> <font color='#979000'>16</font><font face='Lucida Console'>)</font> <b>{</b>
<font color='#0000FF'>while</font> <font face='Lucida Console'>(</font>len<font color='#5555FF'>-</font><font color='#5555FF'>-</font><font face='Lucida Console'>)</font> <b>{</b>
adler <font color='#5555FF'>+</font><font color='#5555FF'>=</font> <font color='#5555FF'>*</font>buf<font color='#5555FF'>+</font><font color='#5555FF'>+</font>;
sum2 <font color='#5555FF'>+</font><font color='#5555FF'>=</font> adler;
<b>}</b>
<font color='#0000FF'>if</font> <font face='Lucida Console'>(</font>adler <font color='#5555FF'>></font><font color='#5555FF'>=</font> BASE<font face='Lucida Console'>)</font>
adler <font color='#5555FF'>-</font><font color='#5555FF'>=</font> BASE;
<font color='#BB00BB'>MOD28</font><font face='Lucida Console'>(</font>sum2<font face='Lucida Console'>)</font>; <font color='#009900'>/* only added so many BASE's */</font>
<font color='#0000FF'>return</font> adler <font color='#5555FF'>|</font> <font face='Lucida Console'>(</font>sum2 <font color='#5555FF'><</font><font color='#5555FF'><</font> <font color='#979000'>16</font><font face='Lucida Console'>)</font>;
<b>}</b>
<font color='#009900'>/* do length NMAX blocks -- requires just one modulo operation */</font>
<font color='#0000FF'>while</font> <font face='Lucida Console'>(</font>len <font color='#5555FF'>></font><font color='#5555FF'>=</font> NMAX<font face='Lucida Console'>)</font> <b>{</b>
len <font color='#5555FF'>-</font><font color='#5555FF'>=</font> NMAX;
n <font color='#5555FF'>=</font> NMAX <font color='#5555FF'>/</font> <font color='#979000'>16</font>; <font color='#009900'>/* NMAX is divisible by 16 */</font>
<font color='#0000FF'>do</font> <b>{</b>
<font color='#BB00BB'>DO16</font><font face='Lucida Console'>(</font>buf<font face='Lucida Console'>)</font>; <font color='#009900'>/* 16 sums unrolled */</font>
buf <font color='#5555FF'>+</font><font color='#5555FF'>=</font> <font color='#979000'>16</font>;
<b>}</b> <font color='#0000FF'>while</font> <font face='Lucida Console'>(</font><font color='#5555FF'>-</font><font color='#5555FF'>-</font>n<font face='Lucida Console'>)</font>;
<font color='#BB00BB'>MOD</font><font face='Lucida Console'>(</font>adler<font face='Lucida Console'>)</font>;
<font color='#BB00BB'>MOD</font><font face='Lucida Console'>(</font>sum2<font face='Lucida Console'>)</font>;
<b>}</b>
<font color='#009900'>/* do remaining bytes (less than NMAX, still just one modulo) */</font>
<font color='#0000FF'>if</font> <font face='Lucida Console'>(</font>len<font face='Lucida Console'>)</font> <b>{</b> <font color='#009900'>/* avoid modulos if none remaining */</font>
<font color='#0000FF'>while</font> <font face='Lucida Console'>(</font>len <font color='#5555FF'>></font><font color='#5555FF'>=</font> <font color='#979000'>16</font><font face='Lucida Console'>)</font> <b>{</b>
len <font color='#5555FF'>-</font><font color='#5555FF'>=</font> <font color='#979000'>16</font>;
<font color='#BB00BB'>DO16</font><font face='Lucida Console'>(</font>buf<font face='Lucida Console'>)</font>;
buf <font color='#5555FF'>+</font><font color='#5555FF'>=</font> <font color='#979000'>16</font>;
<b>}</b>
<font color='#0000FF'>while</font> <font face='Lucida Console'>(</font>len<font color='#5555FF'>-</font><font color='#5555FF'>-</font><font face='Lucida Console'>)</font> <b>{</b>
adler <font color='#5555FF'>+</font><font color='#5555FF'>=</font> <font color='#5555FF'>*</font>buf<font color='#5555FF'>+</font><font color='#5555FF'>+</font>;
sum2 <font color='#5555FF'>+</font><font color='#5555FF'>=</font> adler;
<b>}</b>
<font color='#BB00BB'>MOD</font><font face='Lucida Console'>(</font>adler<font face='Lucida Console'>)</font>;
<font color='#BB00BB'>MOD</font><font face='Lucida Console'>(</font>sum2<font face='Lucida Console'>)</font>;
<b>}</b>
<font color='#009900'>/* return recombined sums */</font>
<font color='#0000FF'>return</font> adler <font color='#5555FF'>|</font> <font face='Lucida Console'>(</font>sum2 <font color='#5555FF'><</font><font color='#5555FF'><</font> <font color='#979000'>16</font><font face='Lucida Console'>)</font>;
<b>}</b>
<font color='#009900'>/* ========================================================================= */</font>
local uLong <b><a name='adler32_combine_'></a>adler32_combine_</b><font face='Lucida Console'>(</font>adler1, adler2, len2<font face='Lucida Console'>)</font>
uLong adler1;
uLong adler2;
z_off64_t len2;
<b>{</b>
<font color='#0000FF'><u>unsigned</u></font> <font color='#0000FF'><u>long</u></font> sum1;
<font color='#0000FF'><u>unsigned</u></font> <font color='#0000FF'><u>long</u></font> sum2;
<font color='#0000FF'><u>unsigned</u></font> rem;
<font color='#009900'>/* for negative len, return invalid adler32 as a clue for debugging */</font>
<font color='#0000FF'>if</font> <font face='Lucida Console'>(</font>len2 <font color='#5555FF'><</font> <font color='#979000'>0</font><font face='Lucida Console'>)</font>
<font color='#0000FF'>return</font> <font color='#979000'>0xffffffffUL</font>;
<font color='#009900'>/* the derivation of this formula is left as an exercise for the reader */</font>
<font color='#BB00BB'>MOD63</font><font face='Lucida Console'>(</font>len2<font face='Lucida Console'>)</font>; <font color='#009900'>/* assumes len2 >= 0 */</font>
rem <font color='#5555FF'>=</font> <font face='Lucida Console'>(</font><font color='#0000FF'><u>unsigned</u></font><font face='Lucida Console'>)</font>len2;
sum1 <font color='#5555FF'>=</font> adler1 <font color='#5555FF'>&</font> <font color='#979000'>0xffff</font>;
sum2 <font color='#5555FF'>=</font> rem <font color='#5555FF'>*</font> sum1;
<font color='#BB00BB'>MOD</font><font face='Lucida Console'>(</font>sum2<font face='Lucida Console'>)</font>;
sum1 <font color='#5555FF'>+</font><font color='#5555FF'>=</font> <font face='Lucida Console'>(</font>adler2 <font color='#5555FF'>&</font> <font color='#979000'>0xffff</font><font face='Lucida Console'>)</font> <font color='#5555FF'>+</font> BASE <font color='#5555FF'>-</font> <font color='#979000'>1</font>;
sum2 <font color='#5555FF'>+</font><font color='#5555FF'>=</font> <font face='Lucida Console'>(</font><font face='Lucida Console'>(</font>adler1 <font color='#5555FF'>></font><font color='#5555FF'>></font> <font color='#979000'>16</font><font face='Lucida Console'>)</font> <font color='#5555FF'>&</font> <font color='#979000'>0xffff</font><font face='Lucida Console'>)</font> <font color='#5555FF'>+</font> <font face='Lucida Console'>(</font><font face='Lucida Console'>(</font>adler2 <font color='#5555FF'>></font><font color='#5555FF'>></font> <font color='#979000'>16</font><font face='Lucida Console'>)</font> <font color='#5555FF'>&</font> <font color='#979000'>0xffff</font><font face='Lucida Console'>)</font> <font color='#5555FF'>+</font> BASE <font color='#5555FF'>-</font> rem;
<font color='#0000FF'>if</font> <font face='Lucida Console'>(</font>sum1 <font color='#5555FF'>></font><font color='#5555FF'>=</font> BASE<font face='Lucida Console'>)</font> sum1 <font color='#5555FF'>-</font><font color='#5555FF'>=</font> BASE;
<font color='#0000FF'>if</font> <font face='Lucida Console'>(</font>sum1 <font color='#5555FF'>></font><font color='#5555FF'>=</font> BASE<font face='Lucida Console'>)</font> sum1 <font color='#5555FF'>-</font><font color='#5555FF'>=</font> BASE;
<font color='#0000FF'>if</font> <font face='Lucida Console'>(</font>sum2 <font color='#5555FF'>></font><font color='#5555FF'>=</font> <font face='Lucida Console'>(</font>BASE <font color='#5555FF'><</font><font color='#5555FF'><</font> <font color='#979000'>1</font><font face='Lucida Console'>)</font><font face='Lucida Console'>)</font> sum2 <font color='#5555FF'>-</font><font color='#5555FF'>=</font> <font face='Lucida Console'>(</font>BASE <font color='#5555FF'><</font><font color='#5555FF'><</font> <font color='#979000'>1</font><font face='Lucida Console'>)</font>;
<font color='#0000FF'>if</font> <font face='Lucida Console'>(</font>sum2 <font color='#5555FF'>></font><font color='#5555FF'>=</font> BASE<font face='Lucida Console'>)</font> sum2 <font color='#5555FF'>-</font><font color='#5555FF'>=</font> BASE;
<font color='#0000FF'>return</font> sum1 <font color='#5555FF'>|</font> <font face='Lucida Console'>(</font>sum2 <font color='#5555FF'><</font><font color='#5555FF'><</font> <font color='#979000'>16</font><font face='Lucida Console'>)</font>;
<b>}</b>
<font color='#009900'>/* ========================================================================= */</font>
uLong ZEXPORT <b><a name='adler32_combine'></a>adler32_combine</b><font face='Lucida Console'>(</font>adler1, adler2, len2<font face='Lucida Console'>)</font>
uLong adler1;
uLong adler2;
z_off_t len2;
<b>{</b>
<font color='#0000FF'>return</font> <font color='#BB00BB'>adler32_combine_</font><font face='Lucida Console'>(</font>adler1, adler2, len2<font face='Lucida Console'>)</font>;
<b>}</b>
uLong ZEXPORT <b><a name='adler32_combine64'></a>adler32_combine64</b><font face='Lucida Console'>(</font>adler1, adler2, len2<font face='Lucida Console'>)</font>
uLong adler1;
uLong adler2;
z_off64_t len2;
<b>{</b>
<font color='#0000FF'>return</font> <font color='#BB00BB'>adler32_combine_</font><font face='Lucida Console'>(</font>adler1, adler2, len2<font face='Lucida Console'>)</font>;
<b>}</b>
</pre></body></html> |