Coverage Report

Created: 2026-09-28 06:47

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
int VP8BitWriterInit(VP8BitWriter* const bw, size_t expected_size);
47
// Finalize the bitstream coding. Returns a pointer to the internal buffer.
48
uint8_t* VP8BitWriterFinish(VP8BitWriter* const bw);
49
// Release any pending memory and zeroes the object. Not a mandatory call.
50
// Only useful in case of error, when the internal buffer hasn't been grabbed!
51
void VP8BitWriterWipeOut(VP8BitWriter* const bw);
52
53
int VP8PutBit(VP8BitWriter* const bw, int bit, int prob);
54
int VP8PutBitUniform(VP8BitWriter* const bw, int bit);
55
void VP8PutBits(VP8BitWriter* const bw, uint32_t value, int nb_bits);
56
void VP8PutSignedBits(VP8BitWriter* const bw, int value, int nb_bits);
57
58
// Appends some bytes to the internal buffer. Data is copied.
59
int VP8BitWriterAppend(VP8BitWriter* const bw, const uint8_t* data,
60
                       size_t size);
61
62
// return approximate write position (in bits)
63
0
static WEBP_INLINE uint64_t VP8BitWriterPos(const VP8BitWriter* const bw) {
64
0
  const uint64_t nb_bits = 8 + bw->nb_bits;  // bw->nb_bits is <= 0, note
65
0
  return (bw->pos + bw->run) * 8 + nb_bits;
66
0
}
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
Unexecuted instantiation: syntax_enc.c:VP8BitWriterPos
Unexecuted instantiation: tree_enc.c:VP8BitWriterPos
Unexecuted instantiation: token_enc.c:VP8BitWriterPos
Unexecuted instantiation: bit_writer_utils.c:VP8BitWriterPos
67
68
// Returns a pointer to the internal buffer.
69
0
static WEBP_INLINE uint8_t* VP8BitWriterBuf(const VP8BitWriter* const bw) {
70
0
  return bw->buf;
71
0
}
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
Unexecuted instantiation: alpha_enc.c:VP8BitWriterBuf
Unexecuted instantiation: frame_enc.c:VP8BitWriterBuf
Unexecuted instantiation: syntax_enc.c:VP8BitWriterBuf
Unexecuted instantiation: tree_enc.c:VP8BitWriterBuf
Unexecuted instantiation: token_enc.c:VP8BitWriterBuf
Unexecuted instantiation: bit_writer_utils.c:VP8BitWriterBuf
72
// Returns the size of the internal buffer.
73
0
static WEBP_INLINE size_t VP8BitWriterSize(const VP8BitWriter* const bw) {
74
0
  return bw->pos;
75
0
}
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
Unexecuted instantiation: alpha_enc.c:VP8BitWriterSize
Unexecuted instantiation: frame_enc.c:VP8BitWriterSize
Unexecuted instantiation: syntax_enc.c:VP8BitWriterSize
Unexecuted instantiation: tree_enc.c:VP8BitWriterSize
Unexecuted instantiation: token_enc.c:VP8BitWriterSize
Unexecuted instantiation: bit_writer_utils.c:VP8BitWriterSize
76
77
//------------------------------------------------------------------------------
78
// VP8LBitWriter
79
80
// 64bit
81
#if defined(__x86_64__) || defined(_M_X64) || WEBP_AARCH64 || defined(__wasm__)
82
typedef uint64_t vp8l_atype_t;  // accumulator type
83
typedef uint32_t vp8l_wtype_t;  // writing type
84
0
#define WSWAP HToLE32
85
0
#define VP8L_WRITER_BYTES 4      // sizeof(vp8l_wtype_t)
86
0
#define VP8L_WRITER_BITS 32      // 8 * sizeof(vp8l_wtype_t)
87
#define VP8L_WRITER_MAX_BITS 64  // 8 * sizeof(vp8l_atype_t)
88
#else
89
typedef uint32_t vp8l_atype_t;
90
typedef uint16_t vp8l_wtype_t;
91
#define WSWAP HToLE16
92
#define VP8L_WRITER_BYTES 2
93
#define VP8L_WRITER_BITS 16
94
#define VP8L_WRITER_MAX_BITS 32
95
#endif
96
97
typedef struct {
98
  vp8l_atype_t bits;                   // bit accumulator
99
  int used;                            // number of bits used in accumulator
100
  uint8_t* WEBP_ENDED_BY(end) buf;     // start of buffer
101
  uint8_t* WEBP_UNSAFE_INDEXABLE cur;  // current write position
102
  uint8_t* end;                        // end of buffer
103
104
  // After all bits are written (VP8LBitWriterFinish()), the caller must observe
105
  // the state of 'error'. A value of 1 indicates that a memory allocation
106
  // failure has happened during bit writing. A value of 0 indicates successful
107
  // writing of bits.
108
  int error;
109
} VP8LBitWriter;
110
111
0
static WEBP_INLINE size_t VP8LBitWriterNumBytes(const VP8LBitWriter* const bw) {
112
0
  return (bw->cur - bw->buf) + ((bw->used + 7) >> 3);
113
0
}
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
Unexecuted instantiation: vp8l_enc.c:VP8LBitWriterNumBytes
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
Unexecuted instantiation: alpha_enc.c:VP8LBitWriterNumBytes
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
114
115
// Returns false in case of memory allocation error.
116
int VP8LBitWriterInit(VP8LBitWriter* const bw, size_t expected_size);
117
// Returns false in case of memory allocation error.
118
int VP8LBitWriterClone(const VP8LBitWriter* const src,
119
                       VP8LBitWriter* const dst);
120
// Finalize the bitstream coding. Returns a pointer to the internal buffer.
121
uint8_t* VP8LBitWriterFinish(VP8LBitWriter* const bw);
122
// Release any pending memory and zeroes the object.
123
void VP8LBitWriterWipeOut(VP8LBitWriter* const bw);
124
// Resets the cursor of the BitWriter bw to when it was like in bw_init.
125
void VP8LBitWriterReset(const VP8LBitWriter* const bw_init,
126
                        VP8LBitWriter* const bw);
127
// Swaps the memory held by two BitWriters.
128
void VP8LBitWriterSwap(VP8LBitWriter* const src, VP8LBitWriter* const dst);
129
130
// Internal function for VP8LPutBits flushing VP8L_WRITER_BITS bits from the
131
// written state.
132
void VP8LPutBitsFlushBits(VP8LBitWriter* const bw, int* used,
133
                          vp8l_atype_t* bits);
134
135
#if VP8L_WRITER_BITS == 16
136
// PutBits internal function used in the 16 bit vp8l_wtype_t case.
137
void VP8LPutBitsInternal(VP8LBitWriter* const bw, uint32_t bits, int n_bits);
138
#endif
139
140
// This function writes bits into bytes in increasing addresses (little endian),
141
// and within a byte least-significant-bit first.
142
// This function can write up to VP8L_WRITER_MAX_BITS bits in one go, but
143
// VP8LBitReader can only read 24 bits max (VP8L_MAX_NUM_BIT_READ).
144
// VP8LBitWriter's 'error' flag is set in case of memory allocation error.
145
static WEBP_INLINE void VP8LPutBits(VP8LBitWriter* const bw, uint32_t bits,
146
0
                                    int n_bits) {
147
0
#if VP8L_WRITER_BYTES == 4
148
0
  if (n_bits == 0) return;
149
0
  if (bw->used >= VP8L_WRITER_BITS) {
150
0
    VP8LPutBitsFlushBits(bw, &bw->used, &bw->bits);
151
0
  }
152
0
  bw->bits |= (vp8l_atype_t)bits << bw->used;
153
0
  bw->used += n_bits;
154
#else
155
  VP8LPutBitsInternal(bw, bits, n_bits);
156
#endif
157
0
}
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
Unexecuted instantiation: vp8l_enc.c:VP8LPutBits
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
158
159
//------------------------------------------------------------------------------
160
161
#ifdef __cplusplus
162
}  // extern "C"
163
#endif
164
165
#endif  // WEBP_UTILS_BIT_WRITER_UTILS_H_