Coverage Report

Created: 2026-11-12 07:35

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libwebp/src/utils/bit_writer_utils.h
Line
Count
Source
1
// Copyright 2011 Google Inc. All Rights Reserved.
2
//
3
// Use of this source code is governed by a BSD-style license
4
// that can be found in the COPYING file in the root of the source
5
// tree. An additional intellectual property rights grant can be found
6
// in the file PATENTS. All contributing project authors may
7
// be found in the AUTHORS file in the root of the source tree.
8
// -----------------------------------------------------------------------------
9
//
10
// Bit writing and boolean coder
11
//
12
// Author: Skal (pascal.massimino@gmail.com)
13
14
#ifndef WEBP_UTILS_BIT_WRITER_UTILS_H_
15
#define WEBP_UTILS_BIT_WRITER_UTILS_H_
16
17
#include <stddef.h>
18
19
#include "src/dsp/cpu.h"
20
#include "src/utils/bounds_safety.h"
21
#include "src/webp/types.h"
22
23
WEBP_ASSUME_UNSAFE_INDEXABLE_ABI
24
25
#ifdef __cplusplus
26
extern "C" {
27
#endif
28
29
//------------------------------------------------------------------------------
30
// Bit-writing
31
32
typedef struct VP8BitWriter VP8BitWriter;
33
struct VP8BitWriter {
34
  int32_t range;  // range-1
35
  int32_t value;
36
  int run;      // number of outstanding bits
37
  int nb_bits;  // number of pending bits
38
  // internal buffer. Re-allocated regularly. Not owned.
39
  uint8_t* WEBP_SIZED_BY_OR_NULL(max_pos) buf;
40
  size_t pos;
41
  size_t max_pos;
42
  int error;  // true in case of error
43
};
44
45
// Initialize the object. Allocates some initial memory based on expected_size.
46
WEBP_NODISCARD int VP8BitWriterInit(VP8BitWriter* const bw,
47
                                    size_t expected_size);
48
// Finalize the bitstream coding. Returns a pointer to the internal buffer.
49
uint8_t* VP8BitWriterFinish(VP8BitWriter* const bw);
50
// Release any pending memory and zeroes the object. Not a mandatory call.
51
// Only useful in case of error, when the internal buffer hasn't been grabbed!
52
void VP8BitWriterWipeOut(VP8BitWriter* const bw);
53
54
int VP8PutBit(VP8BitWriter* const bw, int bit, int prob);
55
int VP8PutBitUniform(VP8BitWriter* const bw, int bit);
56
void VP8PutBits(VP8BitWriter* const bw, uint32_t value, int nb_bits);
57
void VP8PutSignedBits(VP8BitWriter* const bw, int value, int nb_bits);
58
59
// Appends some bytes to the internal buffer. Data is copied.
60
WEBP_NODISCARD int VP8BitWriterAppend(VP8BitWriter* const bw,
61
                                      const uint8_t* data, size_t size);
62
63
// return approximate write position (in bits)
64
5.87k
static WEBP_INLINE uint64_t VP8BitWriterPos(const VP8BitWriter* const bw) {
65
5.87k
  const uint64_t nb_bits = 8 + bw->nb_bits;  // bw->nb_bits is <= 0, note
66
5.87k
  return (bw->pos + bw->run) * 8 + nb_bits;
67
5.87k
}
Unexecuted instantiation: picture_enc.c:VP8BitWriterPos
Unexecuted instantiation: picture_csp_enc.c:VP8BitWriterPos
Unexecuted instantiation: webp_enc.c:VP8BitWriterPos
Unexecuted instantiation: picture_tools_enc.c:VP8BitWriterPos
Unexecuted instantiation: vp8l_enc.c:VP8BitWriterPos
Unexecuted instantiation: backward_references_enc.c:VP8BitWriterPos
Unexecuted instantiation: histogram_enc.c:VP8BitWriterPos
Unexecuted instantiation: picture_rescale_enc.c:VP8BitWriterPos
Unexecuted instantiation: near_lossless_enc.c:VP8BitWriterPos
Unexecuted instantiation: predictor_enc.c:VP8BitWriterPos
Unexecuted instantiation: analysis_enc.c:VP8BitWriterPos
Unexecuted instantiation: iterator_enc.c:VP8BitWriterPos
Unexecuted instantiation: quant_enc.c:VP8BitWriterPos
Unexecuted instantiation: filter_enc.c:VP8BitWriterPos
Unexecuted instantiation: enc.c:VP8BitWriterPos
Unexecuted instantiation: enc_sse2.c:VP8BitWriterPos
Unexecuted instantiation: enc_sse41.c:VP8BitWriterPos
Unexecuted instantiation: cost_enc.c:VP8BitWriterPos
Unexecuted instantiation: cost.c:VP8BitWriterPos
Unexecuted instantiation: cost_sse2.c:VP8BitWriterPos
Unexecuted instantiation: alpha_enc.c:VP8BitWriterPos
Unexecuted instantiation: frame_enc.c:VP8BitWriterPos
syntax_enc.c:VP8BitWriterPos
Line
Count
Source
64
5.87k
static WEBP_INLINE uint64_t VP8BitWriterPos(const VP8BitWriter* const bw) {
65
5.87k
  const uint64_t nb_bits = 8 + bw->nb_bits;  // bw->nb_bits is <= 0, note
66
5.87k
  return (bw->pos + bw->run) * 8 + nb_bits;
67
5.87k
}
Unexecuted instantiation: tree_enc.c:VP8BitWriterPos
Unexecuted instantiation: token_enc.c:VP8BitWriterPos
Unexecuted instantiation: bit_writer_utils.c:VP8BitWriterPos
68
69
// Returns a pointer to the internal buffer.
70
5.31k
static WEBP_INLINE uint8_t* VP8BitWriterBuf(const VP8BitWriter* const bw) {
71
5.31k
  return bw->buf;
72
5.31k
}
Unexecuted instantiation: picture_enc.c:VP8BitWriterBuf
Unexecuted instantiation: picture_csp_enc.c:VP8BitWriterBuf
Unexecuted instantiation: webp_enc.c:VP8BitWriterBuf
Unexecuted instantiation: picture_tools_enc.c:VP8BitWriterBuf
Unexecuted instantiation: vp8l_enc.c:VP8BitWriterBuf
Unexecuted instantiation: backward_references_enc.c:VP8BitWriterBuf
Unexecuted instantiation: histogram_enc.c:VP8BitWriterBuf
Unexecuted instantiation: picture_rescale_enc.c:VP8BitWriterBuf
Unexecuted instantiation: near_lossless_enc.c:VP8BitWriterBuf
Unexecuted instantiation: predictor_enc.c:VP8BitWriterBuf
Unexecuted instantiation: analysis_enc.c:VP8BitWriterBuf
Unexecuted instantiation: iterator_enc.c:VP8BitWriterBuf
Unexecuted instantiation: quant_enc.c:VP8BitWriterBuf
Unexecuted instantiation: filter_enc.c:VP8BitWriterBuf
Unexecuted instantiation: enc.c:VP8BitWriterBuf
Unexecuted instantiation: enc_sse2.c:VP8BitWriterBuf
Unexecuted instantiation: enc_sse41.c:VP8BitWriterBuf
Unexecuted instantiation: cost_enc.c:VP8BitWriterBuf
Unexecuted instantiation: cost.c:VP8BitWriterBuf
Unexecuted instantiation: cost_sse2.c:VP8BitWriterBuf
alpha_enc.c:VP8BitWriterBuf
Line
Count
Source
70
1.39k
static WEBP_INLINE uint8_t* VP8BitWriterBuf(const VP8BitWriter* const bw) {
71
1.39k
  return bw->buf;
72
1.39k
}
Unexecuted instantiation: frame_enc.c:VP8BitWriterBuf
syntax_enc.c:VP8BitWriterBuf
Line
Count
Source
70
3.91k
static WEBP_INLINE uint8_t* VP8BitWriterBuf(const VP8BitWriter* const bw) {
71
3.91k
  return bw->buf;
72
3.91k
}
Unexecuted instantiation: tree_enc.c:VP8BitWriterBuf
Unexecuted instantiation: token_enc.c:VP8BitWriterBuf
Unexecuted instantiation: bit_writer_utils.c:VP8BitWriterBuf
73
// Returns the size of the internal buffer.
74
11.3k
static WEBP_INLINE size_t VP8BitWriterSize(const VP8BitWriter* const bw) {
75
11.3k
  return bw->pos;
76
11.3k
}
Unexecuted instantiation: picture_enc.c:VP8BitWriterSize
Unexecuted instantiation: picture_csp_enc.c:VP8BitWriterSize
Unexecuted instantiation: webp_enc.c:VP8BitWriterSize
Unexecuted instantiation: picture_tools_enc.c:VP8BitWriterSize
Unexecuted instantiation: vp8l_enc.c:VP8BitWriterSize
Unexecuted instantiation: backward_references_enc.c:VP8BitWriterSize
Unexecuted instantiation: histogram_enc.c:VP8BitWriterSize
Unexecuted instantiation: picture_rescale_enc.c:VP8BitWriterSize
Unexecuted instantiation: near_lossless_enc.c:VP8BitWriterSize
Unexecuted instantiation: predictor_enc.c:VP8BitWriterSize
Unexecuted instantiation: analysis_enc.c:VP8BitWriterSize
Unexecuted instantiation: iterator_enc.c:VP8BitWriterSize
Unexecuted instantiation: quant_enc.c:VP8BitWriterSize
Unexecuted instantiation: filter_enc.c:VP8BitWriterSize
Unexecuted instantiation: enc.c:VP8BitWriterSize
Unexecuted instantiation: enc_sse2.c:VP8BitWriterSize
Unexecuted instantiation: enc_sse41.c:VP8BitWriterSize
Unexecuted instantiation: cost_enc.c:VP8BitWriterSize
Unexecuted instantiation: cost.c:VP8BitWriterSize
Unexecuted instantiation: cost_sse2.c:VP8BitWriterSize
alpha_enc.c:VP8BitWriterSize
Line
Count
Source
74
3.48k
static WEBP_INLINE size_t VP8BitWriterSize(const VP8BitWriter* const bw) {
75
3.48k
  return bw->pos;
76
3.48k
}
Unexecuted instantiation: frame_enc.c:VP8BitWriterSize
syntax_enc.c:VP8BitWriterSize
Line
Count
Source
74
7.83k
static WEBP_INLINE size_t VP8BitWriterSize(const VP8BitWriter* const bw) {
75
7.83k
  return bw->pos;
76
7.83k
}
Unexecuted instantiation: tree_enc.c:VP8BitWriterSize
Unexecuted instantiation: token_enc.c:VP8BitWriterSize
Unexecuted instantiation: bit_writer_utils.c:VP8BitWriterSize
77
78
//------------------------------------------------------------------------------
79
// VP8LBitWriter
80
81
// 64bit
82
#if defined(__x86_64__) || defined(_M_X64) || WEBP_AARCH64 || defined(__wasm__)
83
typedef uint64_t vp8l_atype_t;  // accumulator type
84
typedef uint32_t vp8l_wtype_t;  // writing type
85
46.6M
#define WSWAP HToLE32
86
93.2M
#define VP8L_WRITER_BYTES 4      // sizeof(vp8l_wtype_t)
87
358M
#define VP8L_WRITER_BITS 32      // 8 * sizeof(vp8l_wtype_t)
88
#define VP8L_WRITER_MAX_BITS 64  // 8 * sizeof(vp8l_atype_t)
89
#else
90
typedef uint32_t vp8l_atype_t;
91
typedef uint16_t vp8l_wtype_t;
92
#define WSWAP HToLE16
93
#define VP8L_WRITER_BYTES 2
94
#define VP8L_WRITER_BITS 16
95
#define VP8L_WRITER_MAX_BITS 32
96
#endif
97
98
typedef struct {
99
  vp8l_atype_t bits;                   // bit accumulator
100
  int used;                            // number of bits used in accumulator
101
  uint8_t* WEBP_ENDED_BY(end) buf;     // start of buffer
102
  uint8_t* WEBP_UNSAFE_INDEXABLE cur;  // current write position
103
  uint8_t* end;                        // end of buffer
104
105
  // After all bits are written (VP8LBitWriterFinish()), the caller must observe
106
  // the state of 'error'. A value of 1 indicates that a memory allocation
107
  // failure has happened during bit writing. A value of 0 indicates successful
108
  // writing of bits.
109
  int error;
110
} VP8LBitWriter;
111
112
31.5k
static WEBP_INLINE size_t VP8LBitWriterNumBytes(const VP8LBitWriter* const bw) {
113
31.5k
  return (bw->cur - bw->buf) + ((bw->used + 7) >> 3);
114
31.5k
}
Unexecuted instantiation: picture_enc.c:VP8LBitWriterNumBytes
Unexecuted instantiation: picture_csp_enc.c:VP8LBitWriterNumBytes
Unexecuted instantiation: webp_enc.c:VP8LBitWriterNumBytes
Unexecuted instantiation: picture_tools_enc.c:VP8LBitWriterNumBytes
vp8l_enc.c:VP8LBitWriterNumBytes
Line
Count
Source
112
29.5k
static WEBP_INLINE size_t VP8LBitWriterNumBytes(const VP8LBitWriter* const bw) {
113
29.5k
  return (bw->cur - bw->buf) + ((bw->used + 7) >> 3);
114
29.5k
}
Unexecuted instantiation: backward_references_enc.c:VP8LBitWriterNumBytes
Unexecuted instantiation: histogram_enc.c:VP8LBitWriterNumBytes
Unexecuted instantiation: picture_rescale_enc.c:VP8LBitWriterNumBytes
Unexecuted instantiation: near_lossless_enc.c:VP8LBitWriterNumBytes
Unexecuted instantiation: predictor_enc.c:VP8LBitWriterNumBytes
Unexecuted instantiation: analysis_enc.c:VP8LBitWriterNumBytes
Unexecuted instantiation: iterator_enc.c:VP8LBitWriterNumBytes
Unexecuted instantiation: quant_enc.c:VP8LBitWriterNumBytes
Unexecuted instantiation: filter_enc.c:VP8LBitWriterNumBytes
Unexecuted instantiation: enc.c:VP8LBitWriterNumBytes
Unexecuted instantiation: enc_sse2.c:VP8LBitWriterNumBytes
Unexecuted instantiation: enc_sse41.c:VP8LBitWriterNumBytes
Unexecuted instantiation: cost_enc.c:VP8LBitWriterNumBytes
Unexecuted instantiation: cost.c:VP8LBitWriterNumBytes
Unexecuted instantiation: cost_sse2.c:VP8LBitWriterNumBytes
alpha_enc.c:VP8LBitWriterNumBytes
Line
Count
Source
112
2.08k
static WEBP_INLINE size_t VP8LBitWriterNumBytes(const VP8LBitWriter* const bw) {
113
2.08k
  return (bw->cur - bw->buf) + ((bw->used + 7) >> 3);
114
2.08k
}
Unexecuted instantiation: frame_enc.c:VP8LBitWriterNumBytes
Unexecuted instantiation: syntax_enc.c:VP8LBitWriterNumBytes
Unexecuted instantiation: tree_enc.c:VP8LBitWriterNumBytes
Unexecuted instantiation: token_enc.c:VP8LBitWriterNumBytes
Unexecuted instantiation: bit_writer_utils.c:VP8LBitWriterNumBytes
115
116
// Returns false in case of memory allocation error.
117
WEBP_NODISCARD int VP8LBitWriterInit(VP8LBitWriter* const bw,
118
                                     size_t expected_size);
119
// Returns false in case of memory allocation error.
120
WEBP_NODISCARD int VP8LBitWriterClone(const VP8LBitWriter* const src,
121
                                      VP8LBitWriter* const dst);
122
// Finalize the bitstream coding. Returns a pointer to the internal buffer.
123
uint8_t* VP8LBitWriterFinish(VP8LBitWriter* const bw);
124
// Release any pending memory and zeroes the object.
125
void VP8LBitWriterWipeOut(VP8LBitWriter* const bw);
126
// Resets the cursor of the BitWriter bw to when it was like in bw_init.
127
void VP8LBitWriterReset(const VP8LBitWriter* const bw_init,
128
                        VP8LBitWriter* const bw);
129
// Swaps the memory held by two BitWriters.
130
void VP8LBitWriterSwap(VP8LBitWriter* const src, VP8LBitWriter* const dst);
131
132
// Internal function for VP8LPutBits flushing VP8L_WRITER_BITS bits from the
133
// written state.
134
void VP8LPutBitsFlushBits(VP8LBitWriter* const bw, int* used,
135
                          vp8l_atype_t* bits);
136
137
#if VP8L_WRITER_BITS == 16
138
// PutBits internal function used in the 16 bit vp8l_wtype_t case.
139
void VP8LPutBitsInternal(VP8LBitWriter* const bw, uint32_t bits, int n_bits);
140
#endif
141
142
// This function writes bits into bytes in increasing addresses (little endian),
143
// and within a byte least-significant-bit first.
144
// This function can write up to VP8L_WRITER_MAX_BITS bits in one go, but
145
// VP8LBitReader can only read 24 bits max (VP8L_MAX_NUM_BIT_READ).
146
// VP8LBitWriter's 'error' flag is set in case of memory allocation error.
147
static WEBP_INLINE void VP8LPutBits(VP8LBitWriter* const bw, uint32_t bits,
148
451M
                                    int n_bits) {
149
451M
#if VP8L_WRITER_BYTES == 4
150
451M
  if (n_bits == 0) return;
151
264M
  if (bw->used >= VP8L_WRITER_BITS) {
152
46.6M
    VP8LPutBitsFlushBits(bw, &bw->used, &bw->bits);
153
46.6M
  }
154
264M
  bw->bits |= (vp8l_atype_t)bits << bw->used;
155
264M
  bw->used += n_bits;
156
#else
157
  VP8LPutBitsInternal(bw, bits, n_bits);
158
#endif
159
264M
}
Unexecuted instantiation: picture_enc.c:VP8LPutBits
Unexecuted instantiation: picture_csp_enc.c:VP8LPutBits
Unexecuted instantiation: webp_enc.c:VP8LPutBits
Unexecuted instantiation: picture_tools_enc.c:VP8LPutBits
vp8l_enc.c:VP8LPutBits
Line
Count
Source
148
451M
                                    int n_bits) {
149
451M
#if VP8L_WRITER_BYTES == 4
150
451M
  if (n_bits == 0) return;
151
264M
  if (bw->used >= VP8L_WRITER_BITS) {
152
46.6M
    VP8LPutBitsFlushBits(bw, &bw->used, &bw->bits);
153
46.6M
  }
154
264M
  bw->bits |= (vp8l_atype_t)bits << bw->used;
155
264M
  bw->used += n_bits;
156
#else
157
  VP8LPutBitsInternal(bw, bits, n_bits);
158
#endif
159
264M
}
Unexecuted instantiation: backward_references_enc.c:VP8LPutBits
Unexecuted instantiation: histogram_enc.c:VP8LPutBits
Unexecuted instantiation: picture_rescale_enc.c:VP8LPutBits
Unexecuted instantiation: near_lossless_enc.c:VP8LPutBits
Unexecuted instantiation: predictor_enc.c:VP8LPutBits
Unexecuted instantiation: analysis_enc.c:VP8LPutBits
Unexecuted instantiation: iterator_enc.c:VP8LPutBits
Unexecuted instantiation: quant_enc.c:VP8LPutBits
Unexecuted instantiation: filter_enc.c:VP8LPutBits
Unexecuted instantiation: enc.c:VP8LPutBits
Unexecuted instantiation: enc_sse2.c:VP8LPutBits
Unexecuted instantiation: enc_sse41.c:VP8LPutBits
Unexecuted instantiation: cost_enc.c:VP8LPutBits
Unexecuted instantiation: cost.c:VP8LPutBits
Unexecuted instantiation: cost_sse2.c:VP8LPutBits
Unexecuted instantiation: alpha_enc.c:VP8LPutBits
Unexecuted instantiation: frame_enc.c:VP8LPutBits
Unexecuted instantiation: syntax_enc.c:VP8LPutBits
Unexecuted instantiation: tree_enc.c:VP8LPutBits
Unexecuted instantiation: token_enc.c:VP8LPutBits
Unexecuted instantiation: bit_writer_utils.c:VP8LPutBits
160
161
//------------------------------------------------------------------------------
162
163
#ifdef __cplusplus
164
}  // extern "C"
165
#endif
166
167
#endif  // WEBP_UTILS_BIT_WRITER_UTILS_H_