github.com/Schaudge/grailbase@v0.0.0-20240223061707-44c758a471c0/compress/libdeflate/adler32.c (about) 1 /* 2 * adler32.c - Adler-32 checksum algorithm 3 * 4 * Copyright 2016 Eric Biggers 5 * 6 * Permission is hereby granted, free of charge, to any person 7 * obtaining a copy of this software and associated documentation 8 * files (the "Software"), to deal in the Software without 9 * restriction, including without limitation the rights to use, 10 * copy, modify, merge, publish, distribute, sublicense, and/or sell 11 * copies of the Software, and to permit persons to whom the 12 * Software is furnished to do so, subject to the following 13 * conditions: 14 * 15 * The above copyright notice and this permission notice shall be 16 * included in all copies or substantial portions of the Software. 17 * 18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 19 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 20 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 21 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 22 * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 23 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 24 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 25 * OTHER DEALINGS IN THE SOFTWARE. 26 */ 27 28 #include "lib_common.h" 29 #include "libdeflate.h" 30 31 /* The Adler-32 divisor, or "base", value. */ 32 #define DIVISOR 65521 33 34 /* 35 * MAX_CHUNK_SIZE is the most bytes that can be processed without the 36 * possibility of s2 overflowing when it is represented as an unsigned 32-bit 37 * integer. This value was computed using the following Python script: 38 * 39 * divisor = 65521 40 * count = 0 41 * s1 = divisor - 1 42 * s2 = divisor - 1 43 * while True: 44 * s1 += 0xFF 45 * s2 += s1 46 * if s2 > 0xFFFFFFFF: 47 * break 48 * count += 1 49 * print(count) 50 * 51 * Note that to get the correct worst-case value, we must assume that every byte 52 * has value 0xFF and that s1 and s2 started with the highest possible values 53 * modulo the divisor. 54 */ 55 #define MAX_CHUNK_SIZE 5552 56 57 typedef u32 (*adler32_func_t)(u32, const u8 *, size_t); 58 59 /* Include architecture-specific implementations if available */ 60 #undef DEFAULT_IMPL 61 #undef DISPATCH 62 #if defined(__arm__) || defined(__aarch64__) 63 # include "arm/adler32_impl.h" 64 #elif defined(__i386__) || defined(__x86_64__) 65 # include "adler32_impl.h" 66 #endif 67 68 /* Define a generic implementation if needed */ 69 #ifndef DEFAULT_IMPL 70 #define DEFAULT_IMPL adler32_generic 71 static u32 adler32_generic(u32 adler, const u8 *p, size_t size) 72 { 73 u32 s1 = adler & 0xFFFF; 74 u32 s2 = adler >> 16; 75 const u8 * const end = p + size; 76 77 while (p != end) { 78 size_t chunk_size = MIN(end - p, MAX_CHUNK_SIZE); 79 const u8 *chunk_end = p + chunk_size; 80 size_t num_unrolled_iterations = chunk_size / 4; 81 82 while (num_unrolled_iterations--) { 83 s1 += *p++; 84 s2 += s1; 85 s1 += *p++; 86 s2 += s1; 87 s1 += *p++; 88 s2 += s1; 89 s1 += *p++; 90 s2 += s1; 91 } 92 while (p != chunk_end) { 93 s1 += *p++; 94 s2 += s1; 95 } 96 s1 %= DIVISOR; 97 s2 %= DIVISOR; 98 } 99 100 return (s2 << 16) | s1; 101 } 102 #endif /* !DEFAULT_IMPL */ 103 104 #ifdef DISPATCH 105 static u32 dispatch(u32, const u8 *, size_t); 106 107 static volatile adler32_func_t adler32_impl = dispatch; 108 109 /* Choose the fastest implementation at runtime */ 110 static u32 dispatch(u32 adler, const u8 *buffer, size_t size) 111 { 112 adler32_func_t f = arch_select_adler32_func(); 113 114 if (f == NULL) 115 f = DEFAULT_IMPL; 116 117 adler32_impl = f; 118 return adler32_impl(adler, buffer, size); 119 } 120 #else 121 # define adler32_impl DEFAULT_IMPL /* only one implementation, use it */ 122 #endif 123 124 LIBDEFLATEAPI u32 125 libdeflate_adler32(u32 adler, const void *buffer, size_t size) 126 { 127 if (buffer == NULL) /* return initial value */ 128 return 1; 129 return adler32_impl(adler, buffer, size); 130 }