mirror of
https://github.com/webmproject/libwebp.git
synced 2024-12-27 22:28:22 +01:00
lossless: bit writer optimization
valgrind --tool=callgrind shows a 9 % speedup: 1021201984 ticks before vs. 927917709 after -q 0 -m 0 -lossless ~/alpi/1.png 22.040 MP/s before 24.796 MP/s after Change-Id: Iaab928167b3e20fb0d9401c6f8317a26c5a610b4
This commit is contained in:
parent
d97b9ff755
commit
f3a7a5bf76
@ -250,12 +250,28 @@ void VP8LBitWriterWipeOut(VP8LBitWriter* const bw) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void VP8LPutBits(VP8LBitWriter* const bw, uint32_t bits, int n_bits) {
|
void VP8LPutBitsFlushBits(VP8LBitWriter* const bw) {
|
||||||
|
// If needed, make some room by flushing some bits out.
|
||||||
|
if (bw->cur_ + VP8L_WRITER_BYTES > bw->end_) {
|
||||||
|
const uint64_t extra_size = (bw->end_ - bw->buf_) + MIN_EXTRA_SIZE;
|
||||||
|
if (extra_size != (size_t)extra_size ||
|
||||||
|
!VP8LBitWriterResize(bw, (size_t)extra_size)) {
|
||||||
|
bw->cur_ = bw->buf_;
|
||||||
|
bw->error_ = 1;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*(vp8l_wtype_t*)bw->cur_ = (vp8l_wtype_t)WSWAP((vp8l_wtype_t)bw->bits_);
|
||||||
|
bw->cur_ += VP8L_WRITER_BYTES;
|
||||||
|
bw->bits_ >>= VP8L_WRITER_BITS;
|
||||||
|
bw->used_ -= VP8L_WRITER_BITS;
|
||||||
|
}
|
||||||
|
|
||||||
|
void VP8LPutBitsInternal(VP8LBitWriter* const bw, uint32_t bits, int n_bits) {
|
||||||
assert(n_bits <= 32);
|
assert(n_bits <= 32);
|
||||||
// That's the max we can handle:
|
// That's the max we can handle:
|
||||||
assert(bw->used_ + n_bits <= 2 * VP8L_WRITER_MAX_BITS);
|
assert(sizeof(vp8l_wtype_t) == 2);
|
||||||
if (n_bits > 0) {
|
if (n_bits > 0) {
|
||||||
// Local field copy.
|
|
||||||
vp8l_atype_t lbits = bw->bits_;
|
vp8l_atype_t lbits = bw->bits_;
|
||||||
int used = bw->used_;
|
int used = bw->used_;
|
||||||
// Special case of overflow handling for 32bit accumulator (2-steps flush).
|
// Special case of overflow handling for 32bit accumulator (2-steps flush).
|
||||||
@ -286,7 +302,6 @@ void VP8LPutBits(VP8LBitWriter* const bw, uint32_t bits, int n_bits) {
|
|||||||
lbits >>= VP8L_WRITER_BITS;
|
lbits >>= VP8L_WRITER_BITS;
|
||||||
used -= VP8L_WRITER_BITS;
|
used -= VP8L_WRITER_BITS;
|
||||||
}
|
}
|
||||||
// Eventually, insert new bits.
|
|
||||||
bw->bits_ = lbits | ((vp8l_atype_t)bits << used);
|
bw->bits_ = lbits | ((vp8l_atype_t)bits << used);
|
||||||
bw->used_ = used + n_bits;
|
bw->used_ = used + n_bits;
|
||||||
}
|
}
|
||||||
|
@ -104,12 +104,31 @@ uint8_t* VP8LBitWriterFinish(VP8LBitWriter* const bw);
|
|||||||
// Release any pending memory and zeroes the object.
|
// Release any pending memory and zeroes the object.
|
||||||
void VP8LBitWriterWipeOut(VP8LBitWriter* const bw);
|
void VP8LBitWriterWipeOut(VP8LBitWriter* const bw);
|
||||||
|
|
||||||
|
// Internal function for VP8LPutBits flushing 32 bits from the written state.
|
||||||
|
void VP8LPutBitsFlushBits(VP8LBitWriter* const bw);
|
||||||
|
|
||||||
|
// PutBits internal function used in the 16 bit vp8l_wtype_t case.
|
||||||
|
void VP8LPutBitsInternal(VP8LBitWriter* const bw, uint32_t bits, int n_bits);
|
||||||
|
|
||||||
// This function writes bits into bytes in increasing addresses (little endian),
|
// This function writes bits into bytes in increasing addresses (little endian),
|
||||||
// and within a byte least-significant-bit first.
|
// and within a byte least-significant-bit first.
|
||||||
// This function can write up to 32 bits in one go, but VP8LBitReader can only
|
// This function can write up to 32 bits in one go, but VP8LBitReader can only
|
||||||
// read 24 bits max (VP8L_MAX_NUM_BIT_READ).
|
// read 24 bits max (VP8L_MAX_NUM_BIT_READ).
|
||||||
// VP8LBitWriter's error_ flag is set in case of memory allocation error.
|
// VP8LBitWriter's error_ flag is set in case of memory allocation error.
|
||||||
void VP8LPutBits(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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user