Line data Source code
1 : /* 2 : * Copyright (c) 2016, Alliance for Open Media. All rights reserved 3 : * 4 : * This source code is subject to the terms of the BSD 2 Clause License and 5 : * the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License 6 : * was not distributed with this source code in the LICENSE file, you can 7 : * obtain it at www.aomedia.org/license/software. If the Alliance for Open 8 : * Media Patent License 1.0 was not distributed with this source code in the 9 : * PATENTS file, you can obtain it at www.aomedia.org/license/patent. 10 : */ 11 : 12 : #include "hash.h" 13 : 14 0 : static void crc_calculator_process_data(CRC_CALCULATOR *p_crc_calculator, 15 : uint8_t *pData, uint32_t dataLength) { 16 0 : for (uint32_t i = 0; i < dataLength; i++) { 17 0 : const uint8_t index = 18 0 : (p_crc_calculator->remainder >> (p_crc_calculator->bits - 8)) ^ 19 0 : pData[i]; 20 0 : p_crc_calculator->remainder <<= 8; 21 0 : p_crc_calculator->remainder ^= p_crc_calculator->table[index]; 22 : } 23 0 : } 24 : 25 0 : static void crc_calculator_reset(CRC_CALCULATOR *p_crc_calculator) { 26 0 : p_crc_calculator->remainder = 0; 27 0 : } 28 : 29 0 : static uint32_t crc_calculator_get_crc(CRC_CALCULATOR *p_crc_calculator) { 30 0 : return p_crc_calculator->remainder & p_crc_calculator->final_result_mask; 31 : } 32 : 33 0 : static void crc_calculator_init_table(CRC_CALCULATOR *p_crc_calculator) { 34 0 : const uint32_t high_bit = 1 << (p_crc_calculator->bits - 1); 35 0 : const uint32_t byte_high_bit = 1 << (8 - 1); 36 : 37 0 : for (uint32_t value = 0; value < 256; value++) { 38 0 : uint32_t remainder = 0; 39 0 : for (uint8_t mask = byte_high_bit; mask != 0; mask >>= 1) { 40 0 : if (value & mask) 41 0 : remainder ^= high_bit; 42 0 : if (remainder & high_bit) { 43 0 : remainder <<= 1; 44 0 : remainder ^= p_crc_calculator->trunc_poly; 45 : } else 46 0 : remainder <<= 1; 47 : } 48 0 : p_crc_calculator->table[value] = remainder; 49 : } 50 0 : } 51 : 52 0 : void av1_crc_calculator_init(CRC_CALCULATOR *p_crc_calculator, uint32_t bits, 53 : uint32_t truncPoly) { 54 0 : p_crc_calculator->remainder = 0; 55 0 : p_crc_calculator->bits = bits; 56 0 : p_crc_calculator->trunc_poly = truncPoly; 57 0 : p_crc_calculator->final_result_mask = (1 << bits) - 1; 58 0 : crc_calculator_init_table(p_crc_calculator); 59 0 : } 60 : 61 0 : uint32_t av1_get_crc_value(void *crc_calculator, uint8_t *p, int length) { 62 0 : CRC_CALCULATOR *p_crc_calculator = (CRC_CALCULATOR *)crc_calculator; 63 0 : crc_calculator_reset(p_crc_calculator); 64 0 : crc_calculator_process_data(p_crc_calculator, p, length); 65 0 : return crc_calculator_get_crc(p_crc_calculator); 66 : } 67 : 68 : /* CRC-32C (iSCSI) polynomial in reversed bit order. */ 69 : #define POLY 0x82f63b78 70 : 71 : /* Construct table for software CRC-32C calculation. */ 72 0 : void av1_crc32c_calculator_init(CRC32C *p_crc32c) { 73 : uint32_t crc; 74 : 75 0 : for (int n = 0; n < 256; n++) { 76 0 : crc = n; 77 0 : crc = crc & 1 ? (crc >> 1) ^ POLY : crc >> 1; 78 0 : crc = crc & 1 ? (crc >> 1) ^ POLY : crc >> 1; 79 0 : crc = crc & 1 ? (crc >> 1) ^ POLY : crc >> 1; 80 0 : crc = crc & 1 ? (crc >> 1) ^ POLY : crc >> 1; 81 0 : crc = crc & 1 ? (crc >> 1) ^ POLY : crc >> 1; 82 0 : crc = crc & 1 ? (crc >> 1) ^ POLY : crc >> 1; 83 0 : crc = crc & 1 ? (crc >> 1) ^ POLY : crc >> 1; 84 0 : crc = crc & 1 ? (crc >> 1) ^ POLY : crc >> 1; 85 0 : p_crc32c->table[0][n] = crc; 86 : } 87 0 : for (int n = 0; n < 256; n++) { 88 0 : crc = p_crc32c->table[0][n]; 89 0 : for (int k = 1; k < 8; k++) { 90 0 : crc = p_crc32c->table[0][crc & 0xff] ^ (crc >> 8); 91 0 : p_crc32c->table[k][n] = crc; 92 : } 93 : } 94 0 : } 95 : 96 : /* Table-driven software version as a fall-back. This is about 15 times slower 97 : than using the hardware instructions. This assumes little-endian integers, 98 : as is the case on Intel processors that the assembler code here is for. */ 99 0 : uint32_t av1_get_crc32c_value_c(CRC32C *p, uint8_t *buf, size_t len) { 100 0 : const uint8_t *next = (const uint8_t *)(buf); 101 : uint64_t crc; 102 : 103 0 : crc = 0 ^ 0xffffffff; 104 0 : while (len && ((uintptr_t)next & 7) != 0) { 105 0 : crc = p->table[0][(crc ^ *next++) & 0xff] ^ (crc >> 8); 106 0 : len--; 107 : } 108 0 : while (len >= 8) { 109 0 : crc ^= *(uint64_t *)next; 110 0 : crc = p->table[7][crc & 0xff] ^ p->table[6][(crc >> 8) & 0xff] ^ 111 0 : p->table[5][(crc >> 16) & 0xff] ^ p->table[4][(crc >> 24) & 0xff] ^ 112 0 : p->table[3][(crc >> 32) & 0xff] ^ p->table[2][(crc >> 40) & 0xff] ^ 113 0 : p->table[1][(crc >> 48) & 0xff] ^ p->table[0][crc >> 56]; 114 0 : next += 8; 115 0 : len -= 8; 116 : } 117 0 : while (len) { 118 0 : crc = p->table[0][(crc ^ *next++) & 0xff] ^ (crc >> 8); 119 0 : len--; 120 : } 121 0 : return (uint32_t)crc ^ 0xffffffff; 122 : }