bit_writer_utils.h 5.8 KB

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