tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

adler32.c (3290B)


      1 /*
      2 * Compute the Adler-32 checksum of a data stream.
      3 * This is a modified version based on adler32.c from the zlib library.
      4 *
      5 * Copyright (C) 1995 Mark Adler
      6 *
      7 * This software is provided 'as-is', without any express or implied
      8 * warranty.  In no event will the authors be held liable for any damages
      9 * arising from the use of this software.
     10 *
     11 * Permission is granted to anyone to use this software for any purpose,
     12 * including commercial applications, and to alter it and redistribute it
     13 * freely, subject to the following restrictions:
     14 *
     15 * 1. The origin of this software must not be misrepresented; you must not
     16 *    claim that you wrote the original software. If you use this software
     17 *    in a product, an acknowledgment in the product documentation would be
     18 *    appreciated but is not required.
     19 * 2. Altered source versions must be plainly marked as such, and must not be
     20 *    misrepresented as being the original software.
     21 * 3. This notice may not be removed or altered from any source distribution.
     22 */
     23 
     24 /**
     25 * @file
     26 * Computes the Adler-32 checksum of a data stream
     27 *
     28 * This is a modified version based on adler32.c from the zlib library.
     29 * @author Mark Adler
     30 * @ingroup lavu_adler32
     31 */
     32 
     33 #include "config.h"
     34 #include "adler32.h"
     35 #include "intreadwrite.h"
     36 #include "macros.h"
     37 
     38 #define BASE 65521L /* largest prime smaller than 65536 */
     39 
     40 #define DO1(buf)  { s1 += *buf++; s2 += s1; }
     41 #define DO4(buf)  DO1(buf); DO1(buf); DO1(buf); DO1(buf);
     42 #define DO16(buf) DO4(buf); DO4(buf); DO4(buf); DO4(buf);
     43 
     44 AVAdler av_adler32_update(AVAdler adler, const uint8_t *buf, size_t len)
     45 {
     46    unsigned long s1 = adler & 0xffff;
     47    unsigned long s2 = adler >> 16;
     48 
     49    while (len > 0) {
     50 #if HAVE_FAST_64BIT && HAVE_FAST_UNALIGNED && !CONFIG_SMALL
     51        unsigned len2 = FFMIN((len-1) & ~7, 23*8);
     52        if (len2) {
     53            uint64_t a1= 0;
     54            uint64_t a2= 0;
     55            uint64_t b1= 0;
     56            uint64_t b2= 0;
     57            len -= len2;
     58            s2 += s1*len2;
     59            while (len2 >= 8) {
     60                uint64_t v = AV_RN64(buf);
     61                a2 += a1;
     62                b2 += b1;
     63                a1 +=  v    &0x00FF00FF00FF00FF;
     64                b1 += (v>>8)&0x00FF00FF00FF00FF;
     65                len2 -= 8;
     66                buf+=8;
     67            }
     68 
     69            //We combine the 8 interleaved adler32 checksums without overflows
     70            //Decreasing the number of iterations would allow below code to be
     71            //simplified but would likely be slower due to the fewer iterations
     72            //of the inner loop
     73            s1 += ((a1+b1)*0x1000100010001)>>48;
     74            s2 += ((((a2&0xFFFF0000FFFF)+(b2&0xFFFF0000FFFF)+((a2>>16)&0xFFFF0000FFFF)+((b2>>16)&0xFFFF0000FFFF))*0x800000008)>>32)
     75 #if HAVE_BIGENDIAN
     76                 + 2*((b1*0x1000200030004)>>48)
     77                 +   ((a1*0x1000100010001)>>48)
     78                 + 2*((a1*0x0000100020003)>>48);
     79 #else
     80                 + 2*((a1*0x4000300020001)>>48)
     81                 +   ((b1*0x1000100010001)>>48)
     82                 + 2*((b1*0x3000200010000)>>48);
     83 #endif
     84        }
     85 #else
     86        while (len > 4  && s2 < (1U << 31)) {
     87            DO4(buf);
     88            len -= 4;
     89        }
     90 #endif
     91        DO1(buf); len--;
     92        s1 %= BASE;
     93        s2 %= BASE;
     94    }
     95    return (s2 << 16) | s1;
     96 }