Hui Su | 1ddf231 | 2017-08-19 15:21:34 -0700 | [diff] [blame] | 1 | /* |
James Zern | b7c05bd | 2024-06-11 19:15:10 -0700 | [diff] [blame] | 2 | * Copyright (c) 2016, Alliance for Open Media. All rights reserved. |
Hui Su | 1ddf231 | 2017-08-19 15:21:34 -0700 | [diff] [blame] | 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 "av1/encoder/hash.h" |
James Zern | acf62fe | 2023-11-13 18:38:24 -0800 | [diff] [blame] | 13 | #include "config/av1_rtcd.h" |
Hui Su | 1ddf231 | 2017-08-19 15:21:34 -0700 | [diff] [blame] | 14 | |
| 15 | static void crc_calculator_process_data(CRC_CALCULATOR *p_crc_calculator, |
| 16 | uint8_t *pData, uint32_t dataLength) { |
| 17 | for (uint32_t i = 0; i < dataLength; i++) { |
clang-format | d652576 | 2024-08-06 18:52:58 -0700 | [diff] [blame] | 18 | const uint8_t index = (uint8_t)((p_crc_calculator->remainder >> |
| 19 | (p_crc_calculator->bits - 8)) ^ |
| 20 | pData[i]); |
Hui Su | 1ddf231 | 2017-08-19 15:21:34 -0700 | [diff] [blame] | 21 | p_crc_calculator->remainder <<= 8; |
| 22 | p_crc_calculator->remainder ^= p_crc_calculator->table[index]; |
| 23 | } |
| 24 | } |
| 25 | |
PENGBIN | ffda377 | 2018-02-26 17:36:37 +0800 | [diff] [blame] | 26 | static void crc_calculator_reset(CRC_CALCULATOR *p_crc_calculator) { |
Hui Su | 1ddf231 | 2017-08-19 15:21:34 -0700 | [diff] [blame] | 27 | p_crc_calculator->remainder = 0; |
| 28 | } |
| 29 | |
| 30 | static uint32_t crc_calculator_get_crc(CRC_CALCULATOR *p_crc_calculator) { |
| 31 | return p_crc_calculator->remainder & p_crc_calculator->final_result_mask; |
| 32 | } |
| 33 | |
| 34 | static void crc_calculator_init_table(CRC_CALCULATOR *p_crc_calculator) { |
| 35 | const uint32_t high_bit = 1 << (p_crc_calculator->bits - 1); |
| 36 | const uint32_t byte_high_bit = 1 << (8 - 1); |
| 37 | |
| 38 | for (uint32_t value = 0; value < 256; value++) { |
| 39 | uint32_t remainder = 0; |
| 40 | for (uint8_t mask = byte_high_bit; mask != 0; mask >>= 1) { |
| 41 | if (value & mask) { |
| 42 | remainder ^= high_bit; |
| 43 | } |
| 44 | |
| 45 | if (remainder & high_bit) { |
| 46 | remainder <<= 1; |
| 47 | remainder ^= p_crc_calculator->trunc_poly; |
| 48 | } else { |
| 49 | remainder <<= 1; |
| 50 | } |
| 51 | } |
| 52 | p_crc_calculator->table[value] = remainder; |
| 53 | } |
| 54 | } |
| 55 | |
| 56 | void av1_crc_calculator_init(CRC_CALCULATOR *p_crc_calculator, uint32_t bits, |
| 57 | uint32_t truncPoly) { |
| 58 | p_crc_calculator->remainder = 0; |
| 59 | p_crc_calculator->bits = bits; |
| 60 | p_crc_calculator->trunc_poly = truncPoly; |
| 61 | p_crc_calculator->final_result_mask = (1 << bits) - 1; |
| 62 | crc_calculator_init_table(p_crc_calculator); |
| 63 | } |
| 64 | |
chiyotsai | 82f36c9 | 2020-04-09 16:18:02 -0700 | [diff] [blame] | 65 | uint32_t av1_get_crc_value(CRC_CALCULATOR *p_crc_calculator, uint8_t *p, |
| 66 | int length) { |
Hui Su | 1ddf231 | 2017-08-19 15:21:34 -0700 | [diff] [blame] | 67 | crc_calculator_reset(p_crc_calculator); |
| 68 | crc_calculator_process_data(p_crc_calculator, p, length); |
| 69 | return crc_calculator_get_crc(p_crc_calculator); |
| 70 | } |
Peng Bin | 8a204cd | 2018-04-08 13:07:35 +0800 | [diff] [blame] | 71 | |
| 72 | /* CRC-32C (iSCSI) polynomial in reversed bit order. */ |
| 73 | #define POLY 0x82f63b78 |
| 74 | |
| 75 | /* Construct table for software CRC-32C calculation. */ |
| 76 | void av1_crc32c_calculator_init(CRC32C *p_crc32c) { |
| 77 | uint32_t crc; |
| 78 | |
| 79 | for (int n = 0; n < 256; n++) { |
| 80 | crc = n; |
| 81 | crc = crc & 1 ? (crc >> 1) ^ POLY : crc >> 1; |
| 82 | crc = crc & 1 ? (crc >> 1) ^ POLY : crc >> 1; |
| 83 | crc = crc & 1 ? (crc >> 1) ^ POLY : crc >> 1; |
| 84 | crc = crc & 1 ? (crc >> 1) ^ POLY : crc >> 1; |
| 85 | crc = crc & 1 ? (crc >> 1) ^ POLY : crc >> 1; |
| 86 | crc = crc & 1 ? (crc >> 1) ^ POLY : crc >> 1; |
| 87 | crc = crc & 1 ? (crc >> 1) ^ POLY : crc >> 1; |
| 88 | crc = crc & 1 ? (crc >> 1) ^ POLY : crc >> 1; |
| 89 | p_crc32c->table[0][n] = crc; |
| 90 | } |
| 91 | for (int n = 0; n < 256; n++) { |
| 92 | crc = p_crc32c->table[0][n]; |
| 93 | for (int k = 1; k < 8; k++) { |
| 94 | crc = p_crc32c->table[0][crc & 0xff] ^ (crc >> 8); |
| 95 | p_crc32c->table[k][n] = crc; |
| 96 | } |
| 97 | } |
| 98 | } |
| 99 | |
| 100 | /* Table-driven software version as a fall-back. This is about 15 times slower |
| 101 | than using the hardware instructions. This assumes little-endian integers, |
| 102 | as is the case on Intel processors that the assembler code here is for. */ |
Hien Ho | cfdbaee | 2019-05-02 11:01:05 -0700 | [diff] [blame] | 103 | uint32_t av1_get_crc32c_value_c(void *c, uint8_t *buf, size_t len) { |
Peng Bin | 8a204cd | 2018-04-08 13:07:35 +0800 | [diff] [blame] | 104 | const uint8_t *next = (const uint8_t *)(buf); |
| 105 | uint64_t crc; |
Hien Ho | cfdbaee | 2019-05-02 11:01:05 -0700 | [diff] [blame] | 106 | CRC32C *p = (CRC32C *)c; |
Peng Bin | 8a204cd | 2018-04-08 13:07:35 +0800 | [diff] [blame] | 107 | crc = 0 ^ 0xffffffff; |
| 108 | while (len && ((uintptr_t)next & 7) != 0) { |
| 109 | crc = p->table[0][(crc ^ *next++) & 0xff] ^ (crc >> 8); |
| 110 | len--; |
| 111 | } |
| 112 | while (len >= 8) { |
| 113 | crc ^= *(uint64_t *)next; |
| 114 | crc = p->table[7][crc & 0xff] ^ p->table[6][(crc >> 8) & 0xff] ^ |
| 115 | p->table[5][(crc >> 16) & 0xff] ^ p->table[4][(crc >> 24) & 0xff] ^ |
| 116 | p->table[3][(crc >> 32) & 0xff] ^ p->table[2][(crc >> 40) & 0xff] ^ |
| 117 | p->table[1][(crc >> 48) & 0xff] ^ p->table[0][crc >> 56]; |
| 118 | next += 8; |
| 119 | len -= 8; |
| 120 | } |
| 121 | while (len) { |
| 122 | crc = p->table[0][(crc ^ *next++) & 0xff] ^ (crc >> 8); |
| 123 | len--; |
| 124 | } |
| 125 | return (uint32_t)crc ^ 0xffffffff; |
| 126 | } |