adler32_c.c 1.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354
  1. /* adler32.c -- compute the Adler-32 checksum of a data stream
  2. * Copyright (C) 1995-2011, 2016 Mark Adler
  3. * For conditions of distribution and use, see copyright notice in zlib.h
  4. */
  5. #include "zbuild.h"
  6. #include "functable.h"
  7. #include "adler32_p.h"
  8. /* ========================================================================= */
  9. Z_INTERNAL uint32_t adler32_c(uint32_t adler, const uint8_t *buf, size_t len) {
  10. uint32_t sum2;
  11. unsigned n;
  12. /* split Adler-32 into component sums */
  13. sum2 = (adler >> 16) & 0xffff;
  14. adler &= 0xffff;
  15. /* in case user likes doing a byte at a time, keep it fast */
  16. if (UNLIKELY(len == 1))
  17. return adler32_len_1(adler, buf, sum2);
  18. /* initial Adler-32 value (deferred check for len == 1 speed) */
  19. if (UNLIKELY(buf == NULL))
  20. return 1L;
  21. /* in case short lengths are provided, keep it somewhat fast */
  22. if (UNLIKELY(len < 16))
  23. return adler32_len_16(adler, buf, len, sum2);
  24. /* do length NMAX blocks -- requires just one modulo operation */
  25. while (len >= NMAX) {
  26. len -= NMAX;
  27. #ifdef UNROLL_MORE
  28. n = NMAX / 16; /* NMAX is divisible by 16 */
  29. #else
  30. n = NMAX / 8; /* NMAX is divisible by 8 */
  31. #endif
  32. do {
  33. #ifdef UNROLL_MORE
  34. DO16(adler, sum2, buf); /* 16 sums unrolled */
  35. buf += 16;
  36. #else
  37. DO8(adler, sum2, buf, 0); /* 8 sums unrolled */
  38. buf += 8;
  39. #endif
  40. } while (--n);
  41. adler %= BASE;
  42. sum2 %= BASE;
  43. }
  44. /* do remaining bytes (less than NMAX, still just one modulo) */
  45. return adler32_len_64(adler, buf, len, sum2);
  46. }