compute CRC32 (Slicing-by-16 algorithm)
| 330 | #ifdef CRC32_USE_LOOKUP_TABLE_SLICING_BY_16 |
| 331 | /// compute CRC32 (Slicing-by-16 algorithm) |
| 332 | uint32_t crc32_16bytes(const void* data, size_t length, uint32_t previousCrc32) |
| 333 | { |
| 334 | uint32_t crc = ~previousCrc32; // same as previousCrc32 ^ 0xFFFFFFFF |
| 335 | const uint32_t* current = (const uint32_t*)data; |
| 336 | |
| 337 | // enabling optimization (at least -O2) automatically unrolls the inner for-loop |
| 338 | const size_t Unroll = 4; |
| 339 | const size_t BytesAtOnce = 16 * Unroll; |
| 340 | |
| 341 | while (length >= BytesAtOnce) |
| 342 | { |
| 343 | for (size_t unrolling = 0; unrolling < Unroll; unrolling++) |
| 344 | { |
| 345 | #if __BYTE_ORDER == __BIG_ENDIAN |
| 346 | uint32_t one = *current++ ^ swap(crc); |
| 347 | uint32_t two = *current++; |
| 348 | uint32_t three = *current++; |
| 349 | uint32_t four = *current++; |
| 350 | crc = Crc32Lookup[0][four & 0xFF] ^ Crc32Lookup[1][(four >> 8) & 0xFF] ^ Crc32Lookup[2][(four >> 16) & 0xFF] ^ Crc32Lookup[3][(four >> 24) & 0xFF] ^ |
| 351 | Crc32Lookup[4][three & 0xFF] ^ Crc32Lookup[5][(three >> 8) & 0xFF] ^ Crc32Lookup[6][(three >> 16) & 0xFF] ^ Crc32Lookup[7][(three >> 24) & 0xFF] ^ |
| 352 | Crc32Lookup[8][two & 0xFF] ^ Crc32Lookup[9][(two >> 8) & 0xFF] ^ Crc32Lookup[10][(two >> 16) & 0xFF] ^ Crc32Lookup[11][(two >> 24) & 0xFF] ^ |
| 353 | Crc32Lookup[12][one & 0xFF] ^ Crc32Lookup[13][(one >> 8) & 0xFF] ^ Crc32Lookup[14][(one >> 16) & 0xFF] ^ Crc32Lookup[15][(one >> 24) & 0xFF]; |
| 354 | #else |
| 355 | uint32_t one = *current++ ^ crc; |
| 356 | uint32_t two = *current++; |
| 357 | uint32_t three = *current++; |
| 358 | uint32_t four = *current++; |
| 359 | crc = Crc32Lookup[0][(four >> 24) & 0xFF] ^ Crc32Lookup[1][(four >> 16) & 0xFF] ^ Crc32Lookup[2][(four >> 8) & 0xFF] ^ Crc32Lookup[3][four & 0xFF] ^ |
| 360 | Crc32Lookup[4][(three >> 24) & 0xFF] ^ Crc32Lookup[5][(three >> 16) & 0xFF] ^ Crc32Lookup[6][(three >> 8) & 0xFF] ^ Crc32Lookup[7][three & 0xFF] ^ |
| 361 | Crc32Lookup[8][(two >> 24) & 0xFF] ^ Crc32Lookup[9][(two >> 16) & 0xFF] ^ Crc32Lookup[10][(two >> 8) & 0xFF] ^ Crc32Lookup[11][two & 0xFF] ^ |
| 362 | Crc32Lookup[12][(one >> 24) & 0xFF] ^ Crc32Lookup[13][(one >> 16) & 0xFF] ^ Crc32Lookup[14][(one >> 8) & 0xFF] ^ Crc32Lookup[15][one & 0xFF]; |
| 363 | #endif |
| 364 | } |
| 365 | |
| 366 | length -= BytesAtOnce; |
| 367 | } |
| 368 | |
| 369 | const uint8_t* currentChar = (const uint8_t*)current; |
| 370 | // remaining 1 to 63 bytes (standard algorithm) |
| 371 | while (length-- != 0) |
| 372 | crc = (crc >> 8) ^ Crc32Lookup[0][(crc & 0xFF) ^ *currentChar++]; |
| 373 | |
| 374 | return ~crc; // same as crc ^ 0xFFFFFFFF |
| 375 | } |
| 376 | |
| 377 | /// compute CRC32 (Slicing-by-16 algorithm, prefetch upcoming data blocks) |
| 378 | uint32_t crc32_16bytes_prefetch(const void* data, size_t length, uint32_t previousCrc32, size_t prefetchAhead) |
no test coverage detected