#ifndef WEBP_UTILS_BIT_WRITER_UTILS_H_
#define WEBP_UTILS_BIT_WRITER_UTILS_H_
#include "src/webp/types.h"
#ifdef __cplusplus
extern "C" {
#endif
typedef struct VP8BitWriter VP8BitWriter;
struct VP8BitWriter {
int32_t range_; int32_t value_;
int run_; int nb_bits_; uint8_t* buf_; size_t pos_;
size_t max_pos_;
int error_; };
int VP8BitWriterInit(VP8BitWriter* const bw, size_t expected_size);
uint8_t* VP8BitWriterFinish(VP8BitWriter* const bw);
void VP8BitWriterWipeOut(VP8BitWriter* const bw);
int VP8PutBit(VP8BitWriter* const bw, int bit, int prob);
int VP8PutBitUniform(VP8BitWriter* const bw, int bit);
void VP8PutBits(VP8BitWriter* const bw, uint32_t value, int nb_bits);
void VP8PutSignedBits(VP8BitWriter* const bw, int value, int nb_bits);
int VP8BitWriterAppend(VP8BitWriter* const bw,
const uint8_t* data, size_t size);
static WEBP_INLINE uint64_t VP8BitWriterPos(const VP8BitWriter* const bw) {
const uint64_t nb_bits = 8 + bw->nb_bits_; return (bw->pos_ + bw->run_) * 8 + nb_bits;
}
static WEBP_INLINE uint8_t* VP8BitWriterBuf(const VP8BitWriter* const bw) {
return bw->buf_;
}
static WEBP_INLINE size_t VP8BitWriterSize(const VP8BitWriter* const bw) {
return bw->pos_;
}
#if defined(__x86_64__) || defined(_M_X64) typedef uint64_t vp8l_atype_t; typedef uint32_t vp8l_wtype_t; #define WSWAP HToLE32
#define VP8L_WRITER_BYTES 4
#define VP8L_WRITER_BITS 32
#define VP8L_WRITER_MAX_BITS 64
#else
typedef uint32_t vp8l_atype_t;
typedef uint16_t vp8l_wtype_t;
#define WSWAP HToLE16
#define VP8L_WRITER_BYTES 2
#define VP8L_WRITER_BITS 16
#define VP8L_WRITER_MAX_BITS 32
#endif
typedef struct {
vp8l_atype_t bits_; int used_; uint8_t* buf_; uint8_t* cur_; uint8_t* end_;
int error_;
} VP8LBitWriter;
static WEBP_INLINE size_t VP8LBitWriterNumBytes(const VP8LBitWriter* const bw) {
return (bw->cur_ - bw->buf_) + ((bw->used_ + 7) >> 3);
}
int VP8LBitWriterInit(VP8LBitWriter* const bw, size_t expected_size);
int VP8LBitWriterClone(const VP8LBitWriter* const src,
VP8LBitWriter* const dst);
uint8_t* VP8LBitWriterFinish(VP8LBitWriter* const bw);
void VP8LBitWriterWipeOut(VP8LBitWriter* const bw);
void VP8LBitWriterReset(const VP8LBitWriter* const bw_init,
VP8LBitWriter* const bw);
void VP8LBitWriterSwap(VP8LBitWriter* const src, VP8LBitWriter* const dst);
void VP8LPutBitsFlushBits(VP8LBitWriter* const bw);
void VP8LPutBitsInternal(VP8LBitWriter* const bw, uint32_t bits, int n_bits);
static WEBP_INLINE void VP8LPutBits(VP8LBitWriter* const bw,
uint32_t bits, int n_bits) {
if (sizeof(vp8l_wtype_t) == 4) {
if (n_bits > 0) {
if (bw->used_ >= 32) {
VP8LPutBitsFlushBits(bw);
}
bw->bits_ |= (vp8l_atype_t)bits << bw->used_;
bw->used_ += n_bits;
}
} else {
VP8LPutBitsInternal(bw, bits, n_bits);
}
}
#ifdef __cplusplus
} #endif
#endif