diff --git a/src/opts/SkChecksum_opts.h b/src/opts/SkChecksum_opts.h index 48a8e36e1f..fe8aad903c 100644 --- a/src/opts/SkChecksum_opts.h +++ b/src/opts/SkChecksum_opts.h @@ -19,6 +19,7 @@ #if 1 && SK_CPU_SSE_LEVEL >= SK_CPU_SSE_LEVEL_SSE42 #include static uint32_t crc32c_1(uint32_t seed, uint8_t v) { return _mm_crc32_u8(seed, v); } + static uint32_t crc32c_4(uint32_t seed, uint32_t v) { return _mm_crc32_u32(seed, v); } static uint32_t crc32c_8(uint32_t seed, uint64_t v) { #if 1 && (defined(__x86_64__) || defined(_M_X64)) return _mm_crc32_u64(seed, v); @@ -30,6 +31,7 @@ #elif 1 && defined(SK_ARM_HAS_CRC32) #include static uint32_t crc32c_1(uint32_t seed, uint8_t v) { return __crc32cb(seed, v); } + static uint32_t crc32c_4(uint32_t seed, uint32_t v) { return __crc32cw(seed, v); } static uint32_t crc32c_8(uint32_t seed, uint64_t v) { return __crc32cd(seed, v); } #else // See https://www.w3.org/TR/PNG/#D-CRCAppendix, @@ -87,6 +89,14 @@ return crc32c_table[(seed ^ v) & 0xff] ^ (seed >> 8); } + static uint32_t crc32c_4(uint32_t seed, uint32_t v) { + // Nothing special... just crc32c_1() each byte. + for (int i = 0; i < 4; i++) { + seed = crc32c_1(seed, (uint8_t)v); + v >>= 8; + } + return seed; + } static uint32_t crc32c_8(uint32_t seed, uint64_t v) { // Nothing special... just crc32c_1() each byte. for (int i = 0; i < 8; i++) { @@ -115,7 +125,7 @@ namespace SK_OPTS_NS { ptr += 24; len -= 24; } - seed = crc32c_8(a, crc32c_8(b,c)); + seed = crc32c_4(a, crc32c_4(b,c)); } while (len >= 8) { seed = crc32c_8(seed, sk_unaligned_load(ptr)); diff --git a/tests/ChecksumTest.cpp b/tests/ChecksumTest.cpp index 4267d52d4c..a719741a99 100644 --- a/tests/ChecksumTest.cpp +++ b/tests/ChecksumTest.cpp @@ -82,9 +82,9 @@ DEF_TEST(ChecksumConsistent, r) { REPORTER_ASSERT(r, SkOpts::hash(bytes, 1) == 0x00000000, "%08x", SkOpts::hash(bytes, 1)); REPORTER_ASSERT(r, SkOpts::hash(bytes, 2) == 0xf26b8303, "%08x", SkOpts::hash(bytes, 2)); REPORTER_ASSERT(r, SkOpts::hash(bytes, 7) == 0x18678721, "%08x", SkOpts::hash(bytes, 7)); - REPORTER_ASSERT(r, SkOpts::hash(bytes, 32) == 0x2d3617af, "%08x", SkOpts::hash(bytes, 32)); - REPORTER_ASSERT(r, SkOpts::hash(bytes, 63) == 0xd482f6b1, "%08x", SkOpts::hash(bytes, 63)); - REPORTER_ASSERT(r, SkOpts::hash(bytes, 64) == 0x2e5a06a9, "%08x", SkOpts::hash(bytes, 64)); - REPORTER_ASSERT(r, SkOpts::hash(bytes, 99) == 0x5214485b, "%08x", SkOpts::hash(bytes, 99)); - REPORTER_ASSERT(r, SkOpts::hash(bytes,255) == 0xce206bd3, "%08x", SkOpts::hash(bytes,255)); + REPORTER_ASSERT(r, SkOpts::hash(bytes, 32) == 0x9d1ef96b, "%08x", SkOpts::hash(bytes, 32)); + REPORTER_ASSERT(r, SkOpts::hash(bytes, 63) == 0xc4b07d3a, "%08x", SkOpts::hash(bytes, 63)); + REPORTER_ASSERT(r, SkOpts::hash(bytes, 64) == 0x3535a461, "%08x", SkOpts::hash(bytes, 64)); + REPORTER_ASSERT(r, SkOpts::hash(bytes, 99) == 0x3f98a130, "%08x", SkOpts::hash(bytes, 99)); + REPORTER_ASSERT(r, SkOpts::hash(bytes,255) == 0x3b9ceab2, "%08x", SkOpts::hash(bytes,255)); }