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