Coverage Report

Created: 2026-05-16 06:41

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/work/svt-av1/Source/Lib/Codec/random.h
Line
Count
Source
1
/*
2
 * Copyright (c) 2017, 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
#ifndef AOM_AV1_ENCODER_RANDOM_H_
13
#define AOM_AV1_ENCODER_RANDOM_H_
14
15
#ifdef __cplusplus
16
extern "C" {
17
#endif
18
19
// Advance the generator to its next state, and generate the next 32-bit output.
20
// Note that the low bits of this output are comparatively low-quality, so users
21
// of this function should ensure that the high bits factor through to their
22
// outputs.
23
0
static INLINE uint32_t lcg_next(uint32_t* state) {
24
0
    *state = (uint32_t)(*state * 1103515245ULL + 12345);
25
0
    return *state;
26
0
}
Unexecuted instantiation: palette.c:lcg_next
Unexecuted instantiation: resize.c:lcg_next
Unexecuted instantiation: ransac.c:lcg_next
27
28
// Generate a random number in the range [0, 32768).
29
0
static INLINE uint32_t lcg_rand16(uint32_t* state) {
30
0
    return (lcg_next(state) / 65536) % 32768;
31
0
}
32
33
// Generate a random number in the range [0, n)
34
// This is implemented as (rand() * n) / <range of RNG> rather than
35
// rand() % n, for a few reasons: This implementation is faster and less biased,
36
// and if is a power of 2, this uses the higher-quality top bits from the RNG
37
// output rather than the lower-quality bottom bits.
38
0
static INLINE uint32_t lcg_randint(uint32_t* state, uint32_t n) {
39
0
    uint64_t v = ((uint64_t)lcg_next(state) * n) >> 32;
40
0
    return (uint32_t)v;
41
0
}
Unexecuted instantiation: palette.c:lcg_randint
Unexecuted instantiation: resize.c:lcg_randint
Unexecuted instantiation: ransac.c:lcg_randint
42
43
// Generate a random number in the range [lo, hi)
44
0
static INLINE uint32_t lcg_randrange(uint32_t* state, uint32_t lo, uint32_t hi) {
45
0
    assert(lo < hi);
46
0
    return lo + lcg_randint(state, hi - lo);
47
0
}
Unexecuted instantiation: palette.c:lcg_randrange
Unexecuted instantiation: resize.c:lcg_randrange
Unexecuted instantiation: ransac.c:lcg_randrange
48
49
// Pick k distinct numbers from the set {0, ..., n-1}
50
// All possible sets of k numbers, and all possible orderings of those numbers,
51
// are equally likely.
52
//
53
// Note: The algorithm used here uses resampling to avoid choosing repeated
54
// values. This works well as long as n >> k, but can potentially lead to many
55
// resampling attempts if n is equal to or only slightly larger than k.
56
0
static INLINE void lcg_pick(int n, int k, int* out, unsigned int* seed) {
57
0
    assert(0 <= k && k <= n);
58
0
    for (int i = 0; i < k; i++) {
59
0
        int v;
60
61
        // Inner resampling loop
62
        // We have to use a goto here because C does not have a multi-level continue
63
        // statement
64
0
    resample:
65
0
        v = (int)lcg_randint(seed, n);
66
0
        for (int j = 0; j < i; j++) {
67
0
            if (v == out[j]) {
68
                // Repeated v, resample
69
0
                goto resample;
70
0
            }
71
0
        }
72
73
        // New v, accept
74
0
        out[i] = v;
75
0
    }
76
0
}
Unexecuted instantiation: palette.c:lcg_pick
Unexecuted instantiation: resize.c:lcg_pick
Unexecuted instantiation: ransac.c:lcg_pick
77
78
#ifdef __cplusplus
79
} // extern "C"
80
#endif
81
82
#endif // AOM_AV1_ENCODER_RANDOM_H_