Coverage Report

Created: 2026-07-16 06:32

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/work/svt-av1/Source/Lib/Codec/hash.c
Line
Count
Source
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 https://www.aomedia.org/license/software-license. 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 https://www.aomedia.org/license/patent-license.
10
 */
11
12
#include "hash.h"
13
14
/* CRC-32C (iSCSI) polynomial in reversed bit order. */
15
1.02k
#define POLY 0x82f63b78
16
17
/* Process-wide table for a quadword-at-a-time software crc. The only writer is
18
 * svt_av1_crc32c_table_init(), which runs from init_global_tables() under
19
 * svt_run_once() (pthread_once / InitOnce): the table is built exactly once per
20
 * process, before any encoder instance starts encoding, and is read-only after
21
 * that. The once-guard's release/acquire semantics make the completed table
22
 * visible to every thread and every concurrent encoder instance, so sharing one
23
 * copy across instances is safe (same lifetime as every other global lookup
24
 * table built in init_global_tables). */
25
static uint32_t crc32c_table[8][256];
26
27
/* Construct table for software CRC-32C calculation. */
28
1
void svt_av1_crc32c_table_init(void) {
29
1
    uint32_t crc;
30
31
257
    for (int n = 0; n < 256; n++) {
32
256
        crc                = n;
33
256
        crc                = (crc & 1) ? (crc >> 1) ^ POLY : crc >> 1;
34
256
        crc                = (crc & 1) ? (crc >> 1) ^ POLY : crc >> 1;
35
256
        crc                = (crc & 1) ? (crc >> 1) ^ POLY : crc >> 1;
36
256
        crc                = (crc & 1) ? (crc >> 1) ^ POLY : crc >> 1;
37
256
        crc                = (crc & 1) ? (crc >> 1) ^ POLY : crc >> 1;
38
256
        crc                = (crc & 1) ? (crc >> 1) ^ POLY : crc >> 1;
39
256
        crc                = (crc & 1) ? (crc >> 1) ^ POLY : crc >> 1;
40
256
        crc                = (crc & 1) ? (crc >> 1) ^ POLY : crc >> 1;
41
256
        crc32c_table[0][n] = crc;
42
256
    }
43
257
    for (int n = 0; n < 256; n++) {
44
256
        crc = crc32c_table[0][n];
45
2.04k
        for (int k = 1; k < 8; k++) {
46
1.79k
            crc                = crc32c_table[0][crc & 0xff] ^ (crc >> 8);
47
1.79k
            crc32c_table[k][n] = crc;
48
1.79k
        }
49
256
    }
50
1
}
51
52
/* Table-driven software version as a fall-back.  This is about 15 times slower
53
 than using the hardware instructions.  This assumes little-endian integers,
54
 as is the case on Intel processors that the assembler code here is for. */
55
0
uint32_t svt_av1_get_crc32c_value_c(const uint8_t* buf, size_t len) {
56
0
    const uint8_t* next = buf;
57
0
    uint64_t       crc;
58
0
    crc = 0 ^ 0xffffffff;
59
0
    while (len && ((uintptr_t)next & 7) != 0) {
60
0
        crc = crc32c_table[0][(crc ^ *next++) & 0xff] ^ (crc >> 8);
61
0
        len--;
62
0
    }
63
0
    while (len >= 8) {
64
0
        crc ^= *(uint64_t*)next;
65
0
        crc = crc32c_table[7][crc & 0xff] ^ crc32c_table[6][(crc >> 8) & 0xff] ^ crc32c_table[5][(crc >> 16) & 0xff] ^
66
0
            crc32c_table[4][(crc >> 24) & 0xff] ^ crc32c_table[3][(crc >> 32) & 0xff] ^
67
0
            crc32c_table[2][(crc >> 40) & 0xff] ^ crc32c_table[1][(crc >> 48) & 0xff] ^ crc32c_table[0][crc >> 56];
68
0
        next += 8;
69
0
        len -= 8;
70
0
    }
71
0
    while (len) {
72
0
        crc = crc32c_table[0][(crc ^ *next++) & 0xff] ^ (crc >> 8);
73
0
        len--;
74
0
    }
75
0
    return (uint32_t)crc ^ 0xffffffff;
76
0
}