| Line | Branch | Exec | Source |
|---|---|---|---|
| 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 | 100849 | AVAdler av_adler32_update(AVAdler adler, const uint8_t *buf, size_t len) | |
| 45 | { | ||
| 46 | 100849 | unsigned long s1 = adler & 0xffff; | |
| 47 | 100849 | unsigned long s2 = adler >> 16; | |
| 48 | |||
| 49 |
2/2✓ Branch 0 taken 147662806 times.
✓ Branch 1 taken 100849 times.
|
147763655 | while (len > 0) { |
| 50 | #if HAVE_FAST_64BIT && HAVE_FAST_UNALIGNED && !CONFIG_SMALL | ||
| 51 | 147662806 | unsigned len2 = FFMIN((len-1) & ~7, 23*8); | |
| 52 |
2/2✓ Branch 0 taken 147306131 times.
✓ Branch 1 taken 356675 times.
|
147662806 | if (len2) { |
| 53 | 147306131 | uint64_t a1= 0; | |
| 54 | 147306131 | uint64_t a2= 0; | |
| 55 | 147306131 | uint64_t b1= 0; | |
| 56 | 147306131 | uint64_t b2= 0; | |
| 57 | 147306131 | len -= len2; | |
| 58 | 147306131 | s2 += s1*len2; | |
| 59 |
2/2✓ Branch 0 taken 3386974535 times.
✓ Branch 1 taken 147306131 times.
|
3534280666 | while (len2 >= 8) { |
| 60 | 3386974535 | uint64_t v = AV_RN64(buf); | |
| 61 | 3386974535 | a2 += a1; | |
| 62 | 3386974535 | b2 += b1; | |
| 63 | 3386974535 | a1 += v &0x00FF00FF00FF00FF; | |
| 64 | 3386974535 | b1 += (v>>8)&0x00FF00FF00FF00FF; | |
| 65 | 3386974535 | len2 -= 8; | |
| 66 | 3386974535 | 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 | 147306131 | s1 += ((a1+b1)*0x1000100010001)>>48; | |
| 74 | 147306131 | 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 | 147306131 | + 2*((a1*0x4000300020001)>>48) | |
| 81 | 147306131 | + ((b1*0x1000100010001)>>48) | |
| 82 | 147306131 | + 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 | 147662806 | DO1(buf); len--; | |
| 92 | 147662806 | s1 %= BASE; | |
| 93 | 147662806 | s2 %= BASE; | |
| 94 | } | ||
| 95 | 100849 | return (s2 << 16) | s1; | |
| 96 | } | ||
| 97 |