xref: /aosp_15_r20/external/webp/src/utils/bit_writer_utils.h (revision b2055c353e87c8814eb2b6b1b11112a1562253bd)
1*b2055c35SXin Li // Copyright 2011 Google Inc. All Rights Reserved.
2*b2055c35SXin Li //
3*b2055c35SXin Li // Use of this source code is governed by a BSD-style license
4*b2055c35SXin Li // that can be found in the COPYING file in the root of the source
5*b2055c35SXin Li // tree. An additional intellectual property rights grant can be found
6*b2055c35SXin Li // in the file PATENTS. All contributing project authors may
7*b2055c35SXin Li // be found in the AUTHORS file in the root of the source tree.
8*b2055c35SXin Li // -----------------------------------------------------------------------------
9*b2055c35SXin Li //
10*b2055c35SXin Li // Bit writing and boolean coder
11*b2055c35SXin Li //
12*b2055c35SXin Li // Author: Skal ([email protected])
13*b2055c35SXin Li 
14*b2055c35SXin Li #ifndef WEBP_UTILS_BIT_WRITER_UTILS_H_
15*b2055c35SXin Li #define WEBP_UTILS_BIT_WRITER_UTILS_H_
16*b2055c35SXin Li 
17*b2055c35SXin Li #include "src/webp/types.h"
18*b2055c35SXin Li 
19*b2055c35SXin Li #ifdef __cplusplus
20*b2055c35SXin Li extern "C" {
21*b2055c35SXin Li #endif
22*b2055c35SXin Li 
23*b2055c35SXin Li //------------------------------------------------------------------------------
24*b2055c35SXin Li // Bit-writing
25*b2055c35SXin Li 
26*b2055c35SXin Li typedef struct VP8BitWriter VP8BitWriter;
27*b2055c35SXin Li struct VP8BitWriter {
28*b2055c35SXin Li   int32_t  range_;      // range-1
29*b2055c35SXin Li   int32_t  value_;
30*b2055c35SXin Li   int      run_;        // number of outstanding bits
31*b2055c35SXin Li   int      nb_bits_;    // number of pending bits
32*b2055c35SXin Li   uint8_t* buf_;        // internal buffer. Re-allocated regularly. Not owned.
33*b2055c35SXin Li   size_t   pos_;
34*b2055c35SXin Li   size_t   max_pos_;
35*b2055c35SXin Li   int      error_;      // true in case of error
36*b2055c35SXin Li };
37*b2055c35SXin Li 
38*b2055c35SXin Li // Initialize the object. Allocates some initial memory based on expected_size.
39*b2055c35SXin Li int VP8BitWriterInit(VP8BitWriter* const bw, size_t expected_size);
40*b2055c35SXin Li // Finalize the bitstream coding. Returns a pointer to the internal buffer.
41*b2055c35SXin Li uint8_t* VP8BitWriterFinish(VP8BitWriter* const bw);
42*b2055c35SXin Li // Release any pending memory and zeroes the object. Not a mandatory call.
43*b2055c35SXin Li // Only useful in case of error, when the internal buffer hasn't been grabbed!
44*b2055c35SXin Li void VP8BitWriterWipeOut(VP8BitWriter* const bw);
45*b2055c35SXin Li 
46*b2055c35SXin Li int VP8PutBit(VP8BitWriter* const bw, int bit, int prob);
47*b2055c35SXin Li int VP8PutBitUniform(VP8BitWriter* const bw, int bit);
48*b2055c35SXin Li void VP8PutBits(VP8BitWriter* const bw, uint32_t value, int nb_bits);
49*b2055c35SXin Li void VP8PutSignedBits(VP8BitWriter* const bw, int value, int nb_bits);
50*b2055c35SXin Li 
51*b2055c35SXin Li // Appends some bytes to the internal buffer. Data is copied.
52*b2055c35SXin Li int VP8BitWriterAppend(VP8BitWriter* const bw,
53*b2055c35SXin Li                        const uint8_t* data, size_t size);
54*b2055c35SXin Li 
55*b2055c35SXin Li // return approximate write position (in bits)
VP8BitWriterPos(const VP8BitWriter * const bw)56*b2055c35SXin Li static WEBP_INLINE uint64_t VP8BitWriterPos(const VP8BitWriter* const bw) {
57*b2055c35SXin Li   const uint64_t nb_bits = 8 + bw->nb_bits_;   // bw->nb_bits_ is <= 0, note
58*b2055c35SXin Li   return (bw->pos_ + bw->run_) * 8 + nb_bits;
59*b2055c35SXin Li }
60*b2055c35SXin Li 
61*b2055c35SXin Li // Returns a pointer to the internal buffer.
VP8BitWriterBuf(const VP8BitWriter * const bw)62*b2055c35SXin Li static WEBP_INLINE uint8_t* VP8BitWriterBuf(const VP8BitWriter* const bw) {
63*b2055c35SXin Li   return bw->buf_;
64*b2055c35SXin Li }
65*b2055c35SXin Li // Returns the size of the internal buffer.
VP8BitWriterSize(const VP8BitWriter * const bw)66*b2055c35SXin Li static WEBP_INLINE size_t VP8BitWriterSize(const VP8BitWriter* const bw) {
67*b2055c35SXin Li   return bw->pos_;
68*b2055c35SXin Li }
69*b2055c35SXin Li 
70*b2055c35SXin Li //------------------------------------------------------------------------------
71*b2055c35SXin Li // VP8LBitWriter
72*b2055c35SXin Li 
73*b2055c35SXin Li #if defined(__x86_64__) || defined(_M_X64)   // 64bit
74*b2055c35SXin Li typedef uint64_t vp8l_atype_t;   // accumulator type
75*b2055c35SXin Li typedef uint32_t vp8l_wtype_t;   // writing type
76*b2055c35SXin Li #define WSWAP HToLE32
77*b2055c35SXin Li #define VP8L_WRITER_BYTES    4   // sizeof(vp8l_wtype_t)
78*b2055c35SXin Li #define VP8L_WRITER_BITS     32  // 8 * sizeof(vp8l_wtype_t)
79*b2055c35SXin Li #define VP8L_WRITER_MAX_BITS 64  // 8 * sizeof(vp8l_atype_t)
80*b2055c35SXin Li #else
81*b2055c35SXin Li typedef uint32_t vp8l_atype_t;
82*b2055c35SXin Li typedef uint16_t vp8l_wtype_t;
83*b2055c35SXin Li #define WSWAP HToLE16
84*b2055c35SXin Li #define VP8L_WRITER_BYTES    2
85*b2055c35SXin Li #define VP8L_WRITER_BITS     16
86*b2055c35SXin Li #define VP8L_WRITER_MAX_BITS 32
87*b2055c35SXin Li #endif
88*b2055c35SXin Li 
89*b2055c35SXin Li typedef struct {
90*b2055c35SXin Li   vp8l_atype_t bits_;   // bit accumulator
91*b2055c35SXin Li   int          used_;   // number of bits used in accumulator
92*b2055c35SXin Li   uint8_t*     buf_;    // start of buffer
93*b2055c35SXin Li   uint8_t*     cur_;    // current write position
94*b2055c35SXin Li   uint8_t*     end_;    // end of buffer
95*b2055c35SXin Li 
96*b2055c35SXin Li   // After all bits are written (VP8LBitWriterFinish()), the caller must observe
97*b2055c35SXin Li   // the state of error_. A value of 1 indicates that a memory allocation
98*b2055c35SXin Li   // failure has happened during bit writing. A value of 0 indicates successful
99*b2055c35SXin Li   // writing of bits.
100*b2055c35SXin Li   int error_;
101*b2055c35SXin Li } VP8LBitWriter;
102*b2055c35SXin Li 
VP8LBitWriterNumBytes(const VP8LBitWriter * const bw)103*b2055c35SXin Li static WEBP_INLINE size_t VP8LBitWriterNumBytes(const VP8LBitWriter* const bw) {
104*b2055c35SXin Li   return (bw->cur_ - bw->buf_) + ((bw->used_ + 7) >> 3);
105*b2055c35SXin Li }
106*b2055c35SXin Li 
107*b2055c35SXin Li // Returns false in case of memory allocation error.
108*b2055c35SXin Li int VP8LBitWriterInit(VP8LBitWriter* const bw, size_t expected_size);
109*b2055c35SXin Li // Returns false in case of memory allocation error.
110*b2055c35SXin Li int VP8LBitWriterClone(const VP8LBitWriter* const src,
111*b2055c35SXin Li                        VP8LBitWriter* const dst);
112*b2055c35SXin Li // Finalize the bitstream coding. Returns a pointer to the internal buffer.
113*b2055c35SXin Li uint8_t* VP8LBitWriterFinish(VP8LBitWriter* const bw);
114*b2055c35SXin Li // Release any pending memory and zeroes the object.
115*b2055c35SXin Li void VP8LBitWriterWipeOut(VP8LBitWriter* const bw);
116*b2055c35SXin Li // Resets the cursor of the BitWriter bw to when it was like in bw_init.
117*b2055c35SXin Li void VP8LBitWriterReset(const VP8LBitWriter* const bw_init,
118*b2055c35SXin Li                         VP8LBitWriter* const bw);
119*b2055c35SXin Li // Swaps the memory held by two BitWriters.
120*b2055c35SXin Li void VP8LBitWriterSwap(VP8LBitWriter* const src, VP8LBitWriter* const dst);
121*b2055c35SXin Li 
122*b2055c35SXin Li // Internal function for VP8LPutBits flushing 32 bits from the written state.
123*b2055c35SXin Li void VP8LPutBitsFlushBits(VP8LBitWriter* const bw);
124*b2055c35SXin Li 
125*b2055c35SXin Li // PutBits internal function used in the 16 bit vp8l_wtype_t case.
126*b2055c35SXin Li void VP8LPutBitsInternal(VP8LBitWriter* const bw, uint32_t bits, int n_bits);
127*b2055c35SXin Li 
128*b2055c35SXin Li // This function writes bits into bytes in increasing addresses (little endian),
129*b2055c35SXin Li // and within a byte least-significant-bit first.
130*b2055c35SXin Li // This function can write up to 32 bits in one go, but VP8LBitReader can only
131*b2055c35SXin Li // read 24 bits max (VP8L_MAX_NUM_BIT_READ).
132*b2055c35SXin Li // VP8LBitWriter's error_ flag is set in case of  memory allocation error.
VP8LPutBits(VP8LBitWriter * const bw,uint32_t bits,int n_bits)133*b2055c35SXin Li static WEBP_INLINE void VP8LPutBits(VP8LBitWriter* const bw,
134*b2055c35SXin Li                                     uint32_t bits, int n_bits) {
135*b2055c35SXin Li   if (sizeof(vp8l_wtype_t) == 4) {
136*b2055c35SXin Li     if (n_bits > 0) {
137*b2055c35SXin Li       if (bw->used_ >= 32) {
138*b2055c35SXin Li         VP8LPutBitsFlushBits(bw);
139*b2055c35SXin Li       }
140*b2055c35SXin Li       bw->bits_ |= (vp8l_atype_t)bits << bw->used_;
141*b2055c35SXin Li       bw->used_ += n_bits;
142*b2055c35SXin Li     }
143*b2055c35SXin Li   } else {
144*b2055c35SXin Li     VP8LPutBitsInternal(bw, bits, n_bits);
145*b2055c35SXin Li   }
146*b2055c35SXin Li }
147*b2055c35SXin Li 
148*b2055c35SXin Li //------------------------------------------------------------------------------
149*b2055c35SXin Li 
150*b2055c35SXin Li #ifdef __cplusplus
151*b2055c35SXin Li }    // extern "C"
152*b2055c35SXin Li #endif
153*b2055c35SXin Li 
154*b2055c35SXin Li #endif  // WEBP_UTILS_BIT_WRITER_UTILS_H_
155