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