GCC Code Coverage Report
Directory: ../../../ffmpeg/ Exec Total Coverage
File: src/libavcodec/rangecoder.h Lines: 54 54 100.0 %
Date: 2020-09-25 23:16:12 Branches: 22 22 100.0 %

Line Branch Exec Source
1
/*
2
 * Range coder
3
 * Copyright (c) 2004 Michael Niedermayer <michaelni@gmx.at>
4
 *
5
 * This file is part of FFmpeg.
6
 *
7
 * FFmpeg is free software; you can redistribute it and/or
8
 * modify it under the terms of the GNU Lesser General Public
9
 * License as published by the Free Software Foundation; either
10
 * version 2.1 of the License, or (at your option) any later version.
11
 *
12
 * FFmpeg is distributed in the hope that it will be useful,
13
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15
 * Lesser General Public License for more details.
16
 *
17
 * You should have received a copy of the GNU Lesser General Public
18
 * License along with FFmpeg; if not, write to the Free Software
19
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20
 */
21
22
/**
23
 * @file
24
 * Range coder.
25
 */
26
27
#ifndef AVCODEC_RANGECODER_H
28
#define AVCODEC_RANGECODER_H
29
30
#include <stdint.h>
31
32
#include "libavutil/common.h"
33
#include "libavutil/avassert.h"
34
35
typedef struct RangeCoder {
36
    int low;
37
    int range;
38
    int outstanding_count;
39
    int outstanding_byte;
40
    uint8_t zero_state[256];
41
    uint8_t one_state[256];
42
    uint8_t *bytestream_start;
43
    uint8_t *bytestream;
44
    uint8_t *bytestream_end;
45
    int overread;
46
#define MAX_OVERREAD 2
47
} RangeCoder;
48
49
void ff_init_range_encoder(RangeCoder *c, uint8_t *buf, int buf_size);
50
void ff_init_range_decoder(RangeCoder *c, const uint8_t *buf, int buf_size);
51
52
/**
53
 * Terminates the range coder
54
 * @param version version 0 requires the decoder to know the data size in bytes
55
 *                version 1 needs about 1 bit more space but does not need to
56
 *                          carry the size from encoder to decoder
57
 */
58
int ff_rac_terminate(RangeCoder *c, int version);
59
60
/**
61
 * Check if at the current position there is a valid looking termination
62
 * @param version version 0 requires the decoder to know the data size in bytes
63
 *                version 1 needs about 1 bit more space but does not need to
64
 *                          carry the size from encoder to decoder
65
 * @returns negative AVERROR code on error or non negative.
66
 */
67
int ff_rac_check_termination(RangeCoder *c, int version);
68
69
void ff_build_rac_states(RangeCoder *c, int factor, int max_p);
70
71
1362078737
static inline void renorm_encoder(RangeCoder *c)
72
{
73
    // FIXME: optimize
74
1446355023
    while (c->range < 0x100) {
75
84276286
        if (c->outstanding_byte < 0) {
76
8395
            c->outstanding_byte = c->low >> 8;
77
84267891
        } else if (c->low <= 0xFF00) {
78
55156256
            *c->bytestream++ = c->outstanding_byte;
79
55678641
            for (; c->outstanding_count; c->outstanding_count--)
80
522385
                *c->bytestream++ = 0xFF;
81
55156256
            c->outstanding_byte = c->low >> 8;
82
29111635
        } else if (c->low >= 0x10000) {
83
28478363
            *c->bytestream++ = c->outstanding_byte + 1;
84
28589165
            for (; c->outstanding_count; c->outstanding_count--)
85
110802
                *c->bytestream++ = 0x00;
86
28478363
            c->outstanding_byte = (c->low >> 8) & 0xFF;
87
        } else {
88
633272
            c->outstanding_count++;
89
        }
90
91
84276286
        c->low     = (c->low & 0xFF) << 8;
92
84276286
        c->range <<= 8;
93
    }
94
1362078737
}
95
96
1673460
static inline int get_rac_count(RangeCoder *c)
97
{
98
1673460
    int x = c->bytestream - c->bytestream_start + c->outstanding_count;
99
1673460
    if (c->outstanding_byte >= 0)
100
1672998
        x++;
101
1673460
    return 8 * x - av_log2(c->range);
102
}
103
104
1362063573
static inline void put_rac(RangeCoder *c, uint8_t *const state, int bit)
105
{
106
1362063573
    int range1 = (c->range * (*state)) >> 8;
107
108
    av_assert2(*state);
109
    av_assert2(range1 < c->range);
110
    av_assert2(range1 > 0);
111
1362063573
    if (!bit) {
112
581766013
        c->range -= range1;
113
581766013
        *state    = c->zero_state[*state];
114
    } else {
115
780297560
        c->low  += c->range - range1;
116
780297560
        c->range = range1;
117
780297560
        *state   = c->one_state[*state];
118
    }
119
120
1362063573
    renorm_encoder(c);
121
1362063573
}
122
123
1371689831
static inline void refill(RangeCoder *c)
124
{
125
1371689831
    if (c->range < 0x100) {
126
83731125
        c->range <<= 8;
127
83731125
        c->low   <<= 8;
128
83731125
        if (c->bytestream < c->bytestream_end) {
129
83729463
            c->low += c->bytestream[0];
130
83729463
            c->bytestream++;
131
        } else
132
1662
            c->overread ++;
133
    }
134
1371689831
}
135
136
1371689831
static inline int get_rac(RangeCoder *c, uint8_t *const state)
137
{
138
1371689831
    int range1 = (c->range * (*state)) >> 8;
139
140
1371689831
    c->range -= range1;
141
1371689831
    if (c->low < c->range) {
142
585236152
        *state = c->zero_state[*state];
143
585236152
        refill(c);
144
585236152
        return 0;
145
    } else {
146
786453679
        c->low  -= c->range;
147
786453679
        *state   = c->one_state[*state];
148
786453679
        c->range = range1;
149
786453679
        refill(c);
150
786453679
        return 1;
151
    }
152
}
153
154
#endif /* AVCODEC_RANGECODER_H */