/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 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_ |