dec/dsp/enc/utils,cosmetics: rm struct member '_' suffix

This is a follow up to:
ee8e8c62 Fix member naming for VP8LHistogram

This better matches Google style and clears some clang-tidy warnings.

This is the final change in this set. It is rather large due to the
shared dependencies between dec/enc.

Change-Id: I89de06b5653ae0bb627f904fa6060334831f7e3b
This commit is contained in:
James Zern
2025-04-11 12:48:18 -07:00
parent ed7cd6a7f3
commit ad52d5fc7e
66 changed files with 3054 additions and 3053 deletions

View File

@@ -53,33 +53,33 @@ void VP8LoadFinalBytes(VP8BitReader* const br);
//------------------------------------------------------------------------------
// Inlined critical functions
// makes sure br->value_ has at least BITS bits worth of data
// makes sure br->value has at least BITS bits worth of data
static WEBP_UBSAN_IGNORE_UNDEF WEBP_INLINE
void VP8LoadNewBytes(VP8BitReader* WEBP_RESTRICT const br) {
assert(br != NULL && br->buf_ != NULL);
assert(br != NULL && br->buf != NULL);
// Read 'BITS' bits at a time if possible.
if (br->buf_ < br->buf_max_) {
if (br->buf < br->buf_max) {
// convert memory type to register type (with some zero'ing!)
bit_t bits;
#if defined(WEBP_USE_MIPS32)
// This is needed because of un-aligned read.
lbit_t in_bits;
lbit_t* p_buf_ = (lbit_t*)br->buf_;
lbit_t* p_buf = (lbit_t*)br->buf;
__asm__ volatile(
".set push \n\t"
".set at \n\t"
".set macro \n\t"
"ulw %[in_bits], 0(%[p_buf_]) \n\t"
"ulw %[in_bits], 0(%[p_buf]) \n\t"
".set pop \n\t"
: [in_bits]"=r"(in_bits)
: [p_buf_]"r"(p_buf_)
: [p_buf]"r"(p_buf)
: "memory", "at"
);
#else
lbit_t in_bits;
memcpy(&in_bits, br->buf_, sizeof(in_bits));
memcpy(&in_bits, br->buf, sizeof(in_bits));
#endif
br->buf_ += BITS >> 3;
br->buf += BITS >> 3;
#if !defined(WORDS_BIGENDIAN)
#if (BITS > 32)
bits = BSwap64(in_bits);
@@ -96,8 +96,8 @@ void VP8LoadNewBytes(VP8BitReader* WEBP_RESTRICT const br) {
bits = (bit_t)in_bits;
if (BITS != 8 * sizeof(bit_t)) bits >>= (8 * sizeof(bit_t) - BITS);
#endif
br->value_ = bits | (br->value_ << BITS);
br->bits_ += BITS;
br->value = bits | (br->value << BITS);
br->bits += BITS;
} else {
VP8LoadFinalBytes(br); // no need to be inlined
}
@@ -108,28 +108,28 @@ static WEBP_INLINE int VP8GetBit(VP8BitReader* WEBP_RESTRICT const br,
int prob, const char label[]) {
// Don't move this declaration! It makes a big speed difference to store
// 'range' *before* calling VP8LoadNewBytes(), even if this function doesn't
// alter br->range_ value.
range_t range = br->range_;
if (br->bits_ < 0) {
// alter br->range value.
range_t range = br->range;
if (br->bits < 0) {
VP8LoadNewBytes(br);
}
{
const int pos = br->bits_;
const int pos = br->bits;
const range_t split = (range * prob) >> 8;
const range_t value = (range_t)(br->value_ >> pos);
const range_t value = (range_t)(br->value >> pos);
const int bit = (value > split);
if (bit) {
range -= split;
br->value_ -= (bit_t)(split + 1) << pos;
br->value -= (bit_t)(split + 1) << pos;
} else {
range = split + 1;
}
{
const int shift = 7 ^ BitsLog2Floor(range);
range <<= shift;
br->bits_ -= shift;
br->bits -= shift;
}
br->range_ = range - 1;
br->range = range - 1;
BT_TRACK(br);
return bit;
}
@@ -139,18 +139,18 @@ static WEBP_INLINE int VP8GetBit(VP8BitReader* WEBP_RESTRICT const br,
static WEBP_UBSAN_IGNORE_UNSIGNED_OVERFLOW WEBP_INLINE
int VP8GetSigned(VP8BitReader* WEBP_RESTRICT const br, int v,
const char label[]) {
if (br->bits_ < 0) {
if (br->bits < 0) {
VP8LoadNewBytes(br);
}
{
const int pos = br->bits_;
const range_t split = br->range_ >> 1;
const range_t value = (range_t)(br->value_ >> pos);
const int pos = br->bits;
const range_t split = br->range >> 1;
const range_t value = (range_t)(br->value >> pos);
const int32_t mask = (int32_t)(split - value) >> 31; // -1 or 0
br->bits_ -= 1;
br->range_ += (range_t)mask;
br->range_ |= 1;
br->value_ -= (bit_t)((split + 1) & (uint32_t)mask) << pos;
br->bits -= 1;
br->range += (range_t)mask;
br->range |= 1;
br->value -= (bit_t)((split + 1) & (uint32_t)mask) << pos;
BT_TRACK(br);
return (v ^ mask) - mask;
}
@@ -160,19 +160,19 @@ static WEBP_INLINE int VP8GetBitAlt(VP8BitReader* WEBP_RESTRICT const br,
int prob, const char label[]) {
// Don't move this declaration! It makes a big speed difference to store
// 'range' *before* calling VP8LoadNewBytes(), even if this function doesn't
// alter br->range_ value.
range_t range = br->range_;
if (br->bits_ < 0) {
// alter br->range value.
range_t range = br->range;
if (br->bits < 0) {
VP8LoadNewBytes(br);
}
{
const int pos = br->bits_;
const int pos = br->bits;
const range_t split = (range * prob) >> 8;
const range_t value = (range_t)(br->value_ >> pos);
const range_t value = (range_t)(br->value >> pos);
int bit; // Don't use 'const int bit = (value > split);", it's slower.
if (value > split) {
range -= split + 1;
br->value_ -= (bit_t)(split + 1) << pos;
br->value -= (bit_t)(split + 1) << pos;
bit = 1;
} else {
range = split;
@@ -181,9 +181,9 @@ static WEBP_INLINE int VP8GetBitAlt(VP8BitReader* WEBP_RESTRICT const br,
if (range <= (range_t)0x7e) {
const int shift = kVP8Log2Range[range];
range = kVP8NewRange[range];
br->bits_ -= shift;
br->bits -= shift;
}
br->range_ = range;
br->range = range;
BT_TRACK(br);
return bit;
}

View File

@@ -28,9 +28,9 @@ void VP8BitReaderSetBuffer(VP8BitReader* const br,
const uint8_t* const start,
size_t size) {
if (start != NULL) {
br->buf_ = start;
br->buf_end_ = start + size;
br->buf_max_ =
br->buf = start;
br->buf_end = start + size;
br->buf_max =
(size >= sizeof(lbit_t)) ? start + size - sizeof(lbit_t) + 1 : start;
}
}
@@ -40,19 +40,19 @@ void VP8InitBitReader(VP8BitReader* const br,
assert(br != NULL);
assert(start != NULL);
assert(size < (1u << 31)); // limit ensured by format and upstream checks
br->range_ = 255 - 1;
br->value_ = 0;
br->bits_ = -8; // to load the very first 8bits
br->eof_ = 0;
br->range = 255 - 1;
br->value = 0;
br->bits = -8; // to load the very first 8bits
br->eof = 0;
VP8BitReaderSetBuffer(br, start, size);
VP8LoadNewBytes(br);
}
void VP8RemapBitReader(VP8BitReader* const br, ptrdiff_t offset) {
if (br->buf_ != NULL) {
br->buf_ += offset;
br->buf_end_ += offset;
br->buf_max_ += offset;
if (br->buf != NULL) {
br->buf += offset;
br->buf_end += offset;
br->buf_max += offset;
}
}
@@ -89,17 +89,17 @@ const uint8_t kVP8NewRange[128] = {
};
void VP8LoadFinalBytes(VP8BitReader* const br) {
assert(br != NULL && br->buf_ != NULL);
assert(br != NULL && br->buf != NULL);
// Only read 8bits at a time
if (br->buf_ < br->buf_end_) {
br->bits_ += 8;
br->value_ = (bit_t)(*br->buf_++) | (br->value_ << 8);
} else if (!br->eof_) {
br->value_ <<= 8;
br->bits_ += 8;
br->eof_ = 1;
if (br->buf < br->buf_end) {
br->bits += 8;
br->value = (bit_t)(*br->buf++) | (br->value << 8);
} else if (!br->eof) {
br->value <<= 8;
br->bits += 8;
br->eof = 1;
} else {
br->bits_ = 0; // This is to avoid undefined behaviour with shifts.
br->bits = 0; // This is to avoid undefined behaviour with shifts.
}
}
@@ -150,20 +150,20 @@ void VP8LInitBitReader(VP8LBitReader* const br, const uint8_t* const start,
assert(start != NULL);
assert(length < 0xfffffff8u); // can't happen with a RIFF chunk.
br->len_ = length;
br->val_ = 0;
br->bit_pos_ = 0;
br->eos_ = 0;
br->len = length;
br->val = 0;
br->bit_pos = 0;
br->eos = 0;
if (length > sizeof(br->val_)) {
length = sizeof(br->val_);
if (length > sizeof(br->val)) {
length = sizeof(br->val);
}
for (i = 0; i < length; ++i) {
value |= (vp8l_val_t)start[i] << (8 * i);
}
br->val_ = value;
br->pos_ = length;
br->buf_ = start;
br->val = value;
br->pos = length;
br->buf = start;
}
void VP8LBitReaderSetBuffer(VP8LBitReader* const br,
@@ -171,24 +171,24 @@ void VP8LBitReaderSetBuffer(VP8LBitReader* const br,
assert(br != NULL);
assert(buf != NULL);
assert(len < 0xfffffff8u); // can't happen with a RIFF chunk.
br->buf_ = buf;
br->len_ = len;
// pos_ > len_ should be considered a param error.
br->eos_ = (br->pos_ > br->len_) || VP8LIsEndOfStream(br);
br->buf = buf;
br->len = len;
// 'pos' > 'len' should be considered a param error.
br->eos = (br->pos > br->len) || VP8LIsEndOfStream(br);
}
static void VP8LSetEndOfStream(VP8LBitReader* const br) {
br->eos_ = 1;
br->bit_pos_ = 0; // To avoid undefined behaviour with shifts.
br->eos = 1;
br->bit_pos = 0; // To avoid undefined behaviour with shifts.
}
// If not at EOS, reload up to VP8L_LBITS byte-by-byte
static void ShiftBytes(VP8LBitReader* const br) {
while (br->bit_pos_ >= 8 && br->pos_ < br->len_) {
br->val_ >>= 8;
br->val_ |= ((vp8l_val_t)br->buf_[br->pos_]) << (VP8L_LBITS - 8);
++br->pos_;
br->bit_pos_ -= 8;
while (br->bit_pos >= 8 && br->pos < br->len) {
br->val >>= 8;
br->val |= ((vp8l_val_t)br->buf[br->pos]) << (VP8L_LBITS - 8);
++br->pos;
br->bit_pos -= 8;
}
if (VP8LIsEndOfStream(br)) {
VP8LSetEndOfStream(br);
@@ -196,14 +196,14 @@ static void ShiftBytes(VP8LBitReader* const br) {
}
void VP8LDoFillBitWindow(VP8LBitReader* const br) {
assert(br->bit_pos_ >= VP8L_WBITS);
assert(br->bit_pos >= VP8L_WBITS);
#if defined(VP8L_USE_FAST_LOAD)
if (br->pos_ + sizeof(br->val_) < br->len_) {
br->val_ >>= VP8L_WBITS;
br->bit_pos_ -= VP8L_WBITS;
br->val_ |= (vp8l_val_t)HToLE32(WebPMemToUint32(br->buf_ + br->pos_)) <<
(VP8L_LBITS - VP8L_WBITS);
br->pos_ += VP8L_LOG8_WBITS;
if (br->pos + sizeof(br->val) < br->len) {
br->val >>= VP8L_WBITS;
br->bit_pos -= VP8L_WBITS;
br->val |= (vp8l_val_t)HToLE32(WebPMemToUint32(br->buf + br->pos)) <<
(VP8L_LBITS - VP8L_WBITS);
br->pos += VP8L_LOG8_WBITS;
return;
}
#endif
@@ -213,10 +213,10 @@ void VP8LDoFillBitWindow(VP8LBitReader* const br) {
uint32_t VP8LReadBits(VP8LBitReader* const br, int n_bits) {
assert(n_bits >= 0);
// Flag an error if end_of_stream or n_bits is more than allowed limit.
if (!br->eos_ && n_bits <= VP8L_MAX_NUM_BIT_READ) {
if (!br->eos && n_bits <= VP8L_MAX_NUM_BIT_READ) {
const uint32_t val = VP8LPrefetchBits(br) & kBitMask[n_bits];
const int new_bits = br->bit_pos_ + n_bits;
br->bit_pos_ = new_bits;
const int new_bits = br->bit_pos + n_bits;
br->bit_pos = new_bits;
ShiftBytes(br);
return val;
} else {
@@ -276,17 +276,17 @@ void BitTrace(const struct VP8BitReader* const br, const char label[]) {
if (!init_done) {
memset(kLabels, 0, sizeof(kLabels));
atexit(PrintBitTraces);
buf_start = br->buf_;
buf_start = br->buf;
init_done = 1;
}
pos = (int)(br->buf_ - buf_start) * 8 - br->bits_;
pos = (int)(br->buf - buf_start) * 8 - br->bits;
// if there's a too large jump, we've changed partition -> reset counter
if (abs(pos - last_pos) > 32) {
buf_start = br->buf_;
buf_start = br->buf;
pos = 0;
last_pos = 0;
}
if (br->range_ >= 0x7f) pos += kVP8Log2Range[br->range_ - 0x7f];
if (br->range >= 0x7f) pos += kVP8Log2Range[br->range - 0x7f];
for (i = 0; i < last_label; ++i) {
if (!strcmp(label, kLabels[i].label)) break;
}

View File

@@ -47,14 +47,14 @@ extern void BitTrace(const struct VP8BitReader* const br, const char label[]);
extern "C" {
#endif
// The Boolean decoder needs to maintain infinite precision on the value_ field.
// However, since range_ is only 8bit, we only need an active window of 8 bits
// for value_. Left bits (MSB) gets zeroed and shifted away when value_ falls
// below 128, range_ is updated, and fresh bits read from the bitstream are
// brought in as LSB. To avoid reading the fresh bits one by one (slow), we
// cache BITS of them ahead. The total of (BITS + 8) bits must fit into a
// natural register (with type bit_t). To fetch BITS bits from bitstream we
// use a type lbit_t.
// The Boolean decoder needs to maintain infinite precision on the 'value'
// field. However, since 'range' is only 8bit, we only need an active window of
// 8 bits for 'value". Left bits (MSB) gets zeroed and shifted away when
// 'value' falls below 128, 'range' is updated, and fresh bits read from the
// bitstream are brought in as LSB. To avoid reading the fresh bits one by one
// (slow), we cache BITS of them ahead. The total of (BITS + 8) bits must fit
// into a natural register (with type bit_t). To fetch BITS bits from bitstream
// we use a type lbit_t.
//
// BITS can be any multiple of 8 from 8 to 56 (inclusive).
// Pick values that fit natural register size.
@@ -77,8 +77,8 @@ extern "C" {
//------------------------------------------------------------------------------
// Derived types and constants:
// bit_t = natural register type for storing 'value_' (which is BITS+8 bits)
// range_t = register for 'range_' (which is 8bits only)
// bit_t = natural register type for storing 'value' (which is BITS+8 bits)
// range_t = register for 'range' (which is 8bits only)
#if (BITS > 24)
typedef uint64_t bit_t;
@@ -94,14 +94,14 @@ typedef uint32_t range_t;
typedef struct VP8BitReader VP8BitReader;
struct VP8BitReader {
// boolean decoder (keep the field ordering as is!)
bit_t value_; // current value
range_t range_; // current range minus 1. In [127, 254] interval.
int bits_; // number of valid bits left
bit_t value; // current value
range_t range; // current range minus 1. In [127, 254] interval.
int bits; // number of valid bits left
// read buffer
const uint8_t* buf_; // next byte to be read
const uint8_t* buf_end_; // end of read buffer
const uint8_t* buf_max_; // max packed-read position on buffer
int eof_; // true if input is exhausted
const uint8_t* buf; // next byte to be read
const uint8_t* buf_end; // end of read buffer
const uint8_t* buf_max; // max packed-read position on buffer
int eof; // true if input is exhausted
};
// Initialize the bit reader and the boolean decoder.
@@ -141,12 +141,12 @@ int32_t VP8GetSignedValue(VP8BitReader* const br, int num_bits,
typedef uint64_t vp8l_val_t; // right now, this bit-reader can only use 64bit.
typedef struct {
vp8l_val_t val_; // pre-fetched bits
const uint8_t* buf_; // input byte buffer
size_t len_; // buffer length
size_t pos_; // byte position in buf_
int bit_pos_; // current bit-reading position in val_
int eos_; // true if a bit was read past the end of buffer
vp8l_val_t val; // pre-fetched bits
const uint8_t* buf; // input byte buffer
size_t len; // buffer length
size_t pos; // byte position in buf
int bit_pos; // current bit-reading position in val
int eos; // true if a bit was read past the end of buffer
} VP8LBitReader;
void VP8LInitBitReader(VP8LBitReader* const br,
@@ -160,34 +160,34 @@ void VP8LBitReaderSetBuffer(VP8LBitReader* const br,
// Reads the specified number of bits from read buffer.
// Flags an error in case end_of_stream or n_bits is more than the allowed limit
// of VP8L_MAX_NUM_BIT_READ (inclusive).
// Flags eos_ if this read attempt is going to cross the read buffer.
// Flags 'eos' if this read attempt is going to cross the read buffer.
uint32_t VP8LReadBits(VP8LBitReader* const br, int n_bits);
// Return the prefetched bits, so they can be looked up.
static WEBP_INLINE uint32_t VP8LPrefetchBits(VP8LBitReader* const br) {
return (uint32_t)(br->val_ >> (br->bit_pos_ & (VP8L_LBITS - 1)));
return (uint32_t)(br->val >> (br->bit_pos & (VP8L_LBITS - 1)));
}
// Returns true if there was an attempt at reading bit past the end of
// the buffer. Doesn't set br->eos_ flag.
// the buffer. Doesn't set br->eos flag.
static WEBP_INLINE int VP8LIsEndOfStream(const VP8LBitReader* const br) {
assert(br->pos_ <= br->len_);
return br->eos_ || ((br->pos_ == br->len_) && (br->bit_pos_ > VP8L_LBITS));
assert(br->pos <= br->len);
return br->eos || ((br->pos == br->len) && (br->bit_pos > VP8L_LBITS));
}
// For jumping over a number of bits in the bit stream when accessed with
// VP8LPrefetchBits and VP8LFillBitWindow.
// This function does *not* set br->eos_, since it's speed-critical.
// This function does *not* set br->eos, since it's speed-critical.
// Use with extreme care!
static WEBP_INLINE void VP8LSetBitPos(VP8LBitReader* const br, int val) {
br->bit_pos_ = val;
br->bit_pos = val;
}
// Advances the read buffer by 4 bytes to make room for reading next 32 bits.
// Speed critical, but infrequent part of the code can be non-inlined.
extern void VP8LDoFillBitWindow(VP8LBitReader* const br);
static WEBP_INLINE void VP8LFillBitWindow(VP8LBitReader* const br) {
if (br->bit_pos_ >= VP8L_WBITS) VP8LDoFillBitWindow(br);
if (br->bit_pos >= VP8L_WBITS) VP8LDoFillBitWindow(br);
}
#ifdef __cplusplus

View File

@@ -26,54 +26,54 @@
static int BitWriterResize(VP8BitWriter* const bw, size_t extra_size) {
uint8_t* new_buf;
size_t new_size;
const uint64_t needed_size_64b = (uint64_t)bw->pos_ + extra_size;
const uint64_t needed_size_64b = (uint64_t)bw->pos + extra_size;
const size_t needed_size = (size_t)needed_size_64b;
if (needed_size_64b != needed_size) {
bw->error_ = 1;
bw->error = 1;
return 0;
}
if (needed_size <= bw->max_pos_) return 1;
if (needed_size <= bw->max_pos) return 1;
// If the following line wraps over 32bit, the test just after will catch it.
new_size = 2 * bw->max_pos_;
new_size = 2 * bw->max_pos;
if (new_size < needed_size) new_size = needed_size;
if (new_size < 1024) new_size = 1024;
new_buf = (uint8_t*)WebPSafeMalloc(1ULL, new_size);
if (new_buf == NULL) {
bw->error_ = 1;
bw->error = 1;
return 0;
}
if (bw->pos_ > 0) {
assert(bw->buf_ != NULL);
memcpy(new_buf, bw->buf_, bw->pos_);
if (bw->pos > 0) {
assert(bw->buf != NULL);
memcpy(new_buf, bw->buf, bw->pos);
}
WebPSafeFree(bw->buf_);
bw->buf_ = new_buf;
bw->max_pos_ = new_size;
WebPSafeFree(bw->buf);
bw->buf = new_buf;
bw->max_pos = new_size;
return 1;
}
static void Flush(VP8BitWriter* const bw) {
const int s = 8 + bw->nb_bits_;
const int32_t bits = bw->value_ >> s;
assert(bw->nb_bits_ >= 0);
bw->value_ -= bits << s;
bw->nb_bits_ -= 8;
const int s = 8 + bw->nb_bits;
const int32_t bits = bw->value >> s;
assert(bw->nb_bits >= 0);
bw->value -= bits << s;
bw->nb_bits -= 8;
if ((bits & 0xff) != 0xff) {
size_t pos = bw->pos_;
if (!BitWriterResize(bw, bw->run_ + 1)) {
size_t pos = bw->pos;
if (!BitWriterResize(bw, bw->run + 1)) {
return;
}
if (bits & 0x100) { // overflow -> propagate carry over pending 0xff's
if (pos > 0) bw->buf_[pos - 1]++;
if (pos > 0) bw->buf[pos - 1]++;
}
if (bw->run_ > 0) {
if (bw->run > 0) {
const int value = (bits & 0x100) ? 0x00 : 0xff;
for (; bw->run_ > 0; --bw->run_) bw->buf_[pos++] = value;
for (; bw->run > 0; --bw->run) bw->buf[pos++] = value;
}
bw->buf_[pos++] = bits & 0xff;
bw->pos_ = pos;
bw->buf[pos++] = bits & 0xff;
bw->pos = pos;
} else {
bw->run_++; // delay writing of bytes 0xff, pending eventual carry.
bw->run++; // delay writing of bytes 0xff, pending eventual carry.
}
}
@@ -106,36 +106,36 @@ static const uint8_t kNewRange[128] = {
};
int VP8PutBit(VP8BitWriter* const bw, int bit, int prob) {
const int split = (bw->range_ * prob) >> 8;
const int split = (bw->range * prob) >> 8;
if (bit) {
bw->value_ += split + 1;
bw->range_ -= split + 1;
bw->value += split + 1;
bw->range -= split + 1;
} else {
bw->range_ = split;
bw->range = split;
}
if (bw->range_ < 127) { // emit 'shift' bits out and renormalize
const int shift = kNorm[bw->range_];
bw->range_ = kNewRange[bw->range_];
bw->value_ <<= shift;
bw->nb_bits_ += shift;
if (bw->nb_bits_ > 0) Flush(bw);
if (bw->range < 127) { // emit 'shift' bits out and renormalize
const int shift = kNorm[bw->range];
bw->range = kNewRange[bw->range];
bw->value <<= shift;
bw->nb_bits += shift;
if (bw->nb_bits > 0) Flush(bw);
}
return bit;
}
int VP8PutBitUniform(VP8BitWriter* const bw, int bit) {
const int split = bw->range_ >> 1;
const int split = bw->range >> 1;
if (bit) {
bw->value_ += split + 1;
bw->range_ -= split + 1;
bw->value += split + 1;
bw->range -= split + 1;
} else {
bw->range_ = split;
bw->range = split;
}
if (bw->range_ < 127) {
bw->range_ = kNewRange[bw->range_];
bw->value_ <<= 1;
bw->nb_bits_ += 1;
if (bw->nb_bits_ > 0) Flush(bw);
if (bw->range < 127) {
bw->range = kNewRange[bw->range];
bw->value <<= 1;
bw->nb_bits += 1;
if (bw->nb_bits > 0) Flush(bw);
}
return bit;
}
@@ -160,37 +160,37 @@ void VP8PutSignedBits(VP8BitWriter* const bw, int value, int nb_bits) {
//------------------------------------------------------------------------------
int VP8BitWriterInit(VP8BitWriter* const bw, size_t expected_size) {
bw->range_ = 255 - 1;
bw->value_ = 0;
bw->run_ = 0;
bw->nb_bits_ = -8;
bw->pos_ = 0;
bw->max_pos_ = 0;
bw->error_ = 0;
bw->buf_ = NULL;
bw->range = 255 - 1;
bw->value = 0;
bw->run = 0;
bw->nb_bits = -8;
bw->pos = 0;
bw->max_pos = 0;
bw->error = 0;
bw->buf = NULL;
return (expected_size > 0) ? BitWriterResize(bw, expected_size) : 1;
}
uint8_t* VP8BitWriterFinish(VP8BitWriter* const bw) {
VP8PutBits(bw, 0, 9 - bw->nb_bits_);
bw->nb_bits_ = 0; // pad with zeroes
VP8PutBits(bw, 0, 9 - bw->nb_bits);
bw->nb_bits = 0; // pad with zeroes
Flush(bw);
return bw->buf_;
return bw->buf;
}
int VP8BitWriterAppend(VP8BitWriter* const bw,
const uint8_t* data, size_t size) {
assert(data != NULL);
if (bw->nb_bits_ != -8) return 0; // Flush() must have been called
if (bw->nb_bits != -8) return 0; // Flush() must have been called
if (!BitWriterResize(bw, size)) return 0;
memcpy(bw->buf_ + bw->pos_, data, size);
bw->pos_ += size;
memcpy(bw->buf + bw->pos, data, size);
bw->pos += size;
return 1;
}
void VP8BitWriterWipeOut(VP8BitWriter* const bw) {
if (bw != NULL) {
WebPSafeFree(bw->buf_);
WebPSafeFree(bw->buf);
memset(bw, 0, sizeof(*bw));
}
}
@@ -206,12 +206,12 @@ void VP8BitWriterWipeOut(VP8BitWriter* const bw) {
static int VP8LBitWriterResize(VP8LBitWriter* const bw, size_t extra_size) {
uint8_t* allocated_buf;
size_t allocated_size;
const size_t max_bytes = bw->end_ - bw->buf_;
const size_t current_size = bw->cur_ - bw->buf_;
const size_t max_bytes = bw->end - bw->buf;
const size_t current_size = bw->cur - bw->buf;
const uint64_t size_required_64b = (uint64_t)current_size + extra_size;
const size_t size_required = (size_t)size_required_64b;
if (size_required != size_required_64b) {
bw->error_ = 1;
bw->error = 1;
return 0;
}
if (max_bytes > 0 && size_required <= max_bytes) return 1;
@@ -221,16 +221,16 @@ static int VP8LBitWriterResize(VP8LBitWriter* const bw, size_t extra_size) {
allocated_size = (((allocated_size >> 10) + 1) << 10);
allocated_buf = (uint8_t*)WebPSafeMalloc(1ULL, allocated_size);
if (allocated_buf == NULL) {
bw->error_ = 1;
bw->error = 1;
return 0;
}
if (current_size > 0) {
memcpy(allocated_buf, bw->buf_, current_size);
memcpy(allocated_buf, bw->buf, current_size);
}
WebPSafeFree(bw->buf_);
bw->buf_ = allocated_buf;
bw->cur_ = bw->buf_ + current_size;
bw->end_ = bw->buf_ + allocated_size;
WebPSafeFree(bw->buf);
bw->buf = allocated_buf;
bw->cur = bw->buf + current_size;
bw->end = bw->buf + allocated_size;
return 1;
}
@@ -241,31 +241,31 @@ int VP8LBitWriterInit(VP8LBitWriter* const bw, size_t expected_size) {
int VP8LBitWriterClone(const VP8LBitWriter* const src,
VP8LBitWriter* const dst) {
const size_t current_size = src->cur_ - src->buf_;
assert(src->cur_ >= src->buf_ && src->cur_ <= src->end_);
const size_t current_size = src->cur - src->buf;
assert(src->cur >= src->buf && src->cur <= src->end);
if (!VP8LBitWriterResize(dst, current_size)) return 0;
memcpy(dst->buf_, src->buf_, current_size);
dst->bits_ = src->bits_;
dst->used_ = src->used_;
dst->error_ = src->error_;
dst->cur_ = dst->buf_ + current_size;
memcpy(dst->buf, src->buf, current_size);
dst->bits = src->bits;
dst->used = src->used;
dst->error = src->error;
dst->cur = dst->buf + current_size;
return 1;
}
void VP8LBitWriterWipeOut(VP8LBitWriter* const bw) {
if (bw != NULL) {
WebPSafeFree(bw->buf_);
WebPSafeFree(bw->buf);
memset(bw, 0, sizeof(*bw));
}
}
void VP8LBitWriterReset(const VP8LBitWriter* const bw_init,
VP8LBitWriter* const bw) {
bw->bits_ = bw_init->bits_;
bw->used_ = bw_init->used_;
bw->cur_ = bw->buf_ + (bw_init->cur_ - bw_init->buf_);
assert(bw->cur_ <= bw->end_);
bw->error_ = bw_init->error_;
bw->bits = bw_init->bits;
bw->used = bw_init->used;
bw->cur = bw->buf + (bw_init->cur - bw_init->buf);
assert(bw->cur <= bw->end);
bw->error = bw_init->error;
}
void VP8LBitWriterSwap(VP8LBitWriter* const src, VP8LBitWriter* const dst) {
@@ -276,19 +276,19 @@ void VP8LBitWriterSwap(VP8LBitWriter* const src, VP8LBitWriter* const dst) {
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 (bw->cur + VP8L_WRITER_BYTES > bw->end) {
const uint64_t extra_size = (bw->end - bw->buf) + MIN_EXTRA_SIZE;
if (!CheckSizeOverflow(extra_size) ||
!VP8LBitWriterResize(bw, (size_t)extra_size)) {
bw->cur_ = bw->buf_;
bw->error_ = 1;
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;
*(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) {
@@ -296,8 +296,8 @@ void VP8LPutBitsInternal(VP8LBitWriter* const bw, uint32_t bits, int n_bits) {
// That's the max we can handle:
assert(sizeof(vp8l_wtype_t) == 2);
if (n_bits > 0) {
vp8l_atype_t lbits = bw->bits_;
int used = bw->used_;
vp8l_atype_t lbits = bw->bits;
int used = bw->used;
// Special case of overflow handling for 32bit accumulator (2-steps flush).
#if VP8L_WRITER_BITS == 16
if (used + n_bits >= VP8L_WRITER_MAX_BITS) {
@@ -312,36 +312,36 @@ void VP8LPutBitsInternal(VP8LBitWriter* const bw, uint32_t bits, int n_bits) {
#endif
// If needed, make some room by flushing some bits out.
while (used >= VP8L_WRITER_BITS) {
if (bw->cur_ + VP8L_WRITER_BYTES > bw->end_) {
const uint64_t extra_size = (bw->end_ - bw->buf_) + MIN_EXTRA_SIZE;
if (bw->cur + VP8L_WRITER_BYTES > bw->end) {
const uint64_t extra_size = (bw->end - bw->buf) + MIN_EXTRA_SIZE;
if (!CheckSizeOverflow(extra_size) ||
!VP8LBitWriterResize(bw, (size_t)extra_size)) {
bw->cur_ = bw->buf_;
bw->error_ = 1;
bw->cur = bw->buf;
bw->error = 1;
return;
}
}
*(vp8l_wtype_t*)bw->cur_ = (vp8l_wtype_t)WSWAP((vp8l_wtype_t)lbits);
bw->cur_ += VP8L_WRITER_BYTES;
*(vp8l_wtype_t*)bw->cur = (vp8l_wtype_t)WSWAP((vp8l_wtype_t)lbits);
bw->cur += VP8L_WRITER_BYTES;
lbits >>= VP8L_WRITER_BITS;
used -= VP8L_WRITER_BITS;
}
bw->bits_ = lbits | ((vp8l_atype_t)bits << used);
bw->used_ = used + n_bits;
bw->bits = lbits | ((vp8l_atype_t)bits << used);
bw->used = used + n_bits;
}
}
uint8_t* VP8LBitWriterFinish(VP8LBitWriter* const bw) {
// flush leftover bits
if (VP8LBitWriterResize(bw, (bw->used_ + 7) >> 3)) {
while (bw->used_ > 0) {
*bw->cur_++ = (uint8_t)bw->bits_;
bw->bits_ >>= 8;
bw->used_ -= 8;
if (VP8LBitWriterResize(bw, (bw->used + 7) >> 3)) {
while (bw->used > 0) {
*bw->cur++ = (uint8_t)bw->bits;
bw->bits >>= 8;
bw->used -= 8;
}
bw->used_ = 0;
bw->used = 0;
}
return bw->buf_;
return bw->buf;
}
//------------------------------------------------------------------------------

View File

@@ -25,14 +25,14 @@ extern "C" {
typedef struct VP8BitWriter VP8BitWriter;
struct VP8BitWriter {
int32_t range_; // range-1
int32_t value_;
int run_; // number of outstanding bits
int nb_bits_; // number of pending bits
uint8_t* buf_; // internal buffer. Re-allocated regularly. Not owned.
size_t pos_;
size_t max_pos_;
int error_; // true in case of error
int32_t range; // range-1
int32_t value;
int run; // number of outstanding bits
int nb_bits; // number of pending bits
uint8_t* buf; // internal buffer. Re-allocated regularly. Not owned.
size_t pos;
size_t max_pos;
int error; // true in case of error
};
// Initialize the object. Allocates some initial memory based on expected_size.
@@ -54,17 +54,17 @@ int VP8BitWriterAppend(VP8BitWriter* const bw,
// return approximate write position (in bits)
static WEBP_INLINE uint64_t VP8BitWriterPos(const VP8BitWriter* const bw) {
const uint64_t nb_bits = 8 + bw->nb_bits_; // bw->nb_bits_ is <= 0, note
return (bw->pos_ + bw->run_) * 8 + nb_bits;
const uint64_t nb_bits = 8 + bw->nb_bits; // bw->nb_bits is <= 0, note
return (bw->pos + bw->run) * 8 + nb_bits;
}
// Returns a pointer to the internal buffer.
static WEBP_INLINE uint8_t* VP8BitWriterBuf(const VP8BitWriter* const bw) {
return bw->buf_;
return bw->buf;
}
// Returns the size of the internal buffer.
static WEBP_INLINE size_t VP8BitWriterSize(const VP8BitWriter* const bw) {
return bw->pos_;
return bw->pos;
}
//------------------------------------------------------------------------------
@@ -87,21 +87,21 @@ typedef uint16_t vp8l_wtype_t;
#endif
typedef struct {
vp8l_atype_t bits_; // bit accumulator
int used_; // number of bits used in accumulator
uint8_t* buf_; // start of buffer
uint8_t* cur_; // current write position
uint8_t* end_; // end of buffer
vp8l_atype_t bits; // bit accumulator
int used; // number of bits used in accumulator
uint8_t* buf; // start of buffer
uint8_t* cur; // current write position
uint8_t* end; // end of buffer
// After all bits are written (VP8LBitWriterFinish()), the caller must observe
// the state of error_. A value of 1 indicates that a memory allocation
// the state of 'error'. A value of 1 indicates that a memory allocation
// failure has happened during bit writing. A value of 0 indicates successful
// writing of bits.
int error_;
int error;
} VP8LBitWriter;
static WEBP_INLINE size_t VP8LBitWriterNumBytes(const VP8LBitWriter* const bw) {
return (bw->cur_ - bw->buf_) + ((bw->used_ + 7) >> 3);
return (bw->cur - bw->buf) + ((bw->used + 7) >> 3);
}
// Returns false in case of memory allocation error.
@@ -129,16 +129,16 @@ void VP8LPutBitsInternal(VP8LBitWriter* const bw, uint32_t bits, int n_bits);
// and within a byte least-significant-bit first.
// This function can write up to 32 bits in one go, but VP8LBitReader can only
// 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.
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) {
if (bw->used >= 32) {
VP8LPutBitsFlushBits(bw);
}
bw->bits_ |= (vp8l_atype_t)bits << bw->used_;
bw->used_ += n_bits;
bw->bits |= (vp8l_atype_t)bits << bw->used;
bw->used += n_bits;
}
} else {
VP8LPutBitsInternal(bw, bits, n_bits);

View File

@@ -24,18 +24,18 @@ int VP8LColorCacheInit(VP8LColorCache* const color_cache, int hash_bits) {
const int hash_size = 1 << hash_bits;
assert(color_cache != NULL);
assert(hash_bits > 0);
color_cache->colors_ = (uint32_t*)WebPSafeCalloc(
(uint64_t)hash_size, sizeof(*color_cache->colors_));
if (color_cache->colors_ == NULL) return 0;
color_cache->hash_shift_ = 32 - hash_bits;
color_cache->hash_bits_ = hash_bits;
color_cache->colors = (uint32_t*)WebPSafeCalloc(
(uint64_t)hash_size, sizeof(*color_cache->colors));
if (color_cache->colors == NULL) return 0;
color_cache->hash_shift = 32 - hash_bits;
color_cache->hash_bits = hash_bits;
return 1;
}
void VP8LColorCacheClear(VP8LColorCache* const color_cache) {
if (color_cache != NULL) {
WebPSafeFree(color_cache->colors_);
color_cache->colors_ = NULL;
WebPSafeFree(color_cache->colors);
color_cache->colors = NULL;
}
}
@@ -43,7 +43,7 @@ void VP8LColorCacheCopy(const VP8LColorCache* const src,
VP8LColorCache* const dst) {
assert(src != NULL);
assert(dst != NULL);
assert(src->hash_bits_ == dst->hash_bits_);
memcpy(dst->colors_, src->colors_,
((size_t)1u << dst->hash_bits_) * sizeof(*dst->colors_));
assert(src->hash_bits == dst->hash_bits);
memcpy(dst->colors, src->colors,
((size_t)1u << dst->hash_bits) * sizeof(*dst->colors));
}

View File

@@ -26,9 +26,9 @@ extern "C" {
// Main color cache struct.
typedef struct {
uint32_t* colors_; // color entries
int hash_shift_; // Hash shift: 32 - hash_bits_.
int hash_bits_;
uint32_t* colors; // color entries
int hash_shift; // Hash shift: 32 - 'hash_bits'.
int hash_bits;
} VP8LColorCache;
static const uint32_t kHashMul = 0x1e35a7bdu;
@@ -40,32 +40,32 @@ int VP8LHashPix(uint32_t argb, int shift) {
static WEBP_INLINE uint32_t VP8LColorCacheLookup(
const VP8LColorCache* const cc, uint32_t key) {
assert((key >> cc->hash_bits_) == 0u);
return cc->colors_[key];
assert((key >> cc->hash_bits) == 0u);
return cc->colors[key];
}
static WEBP_INLINE void VP8LColorCacheSet(const VP8LColorCache* const cc,
uint32_t key, uint32_t argb) {
assert((key >> cc->hash_bits_) == 0u);
cc->colors_[key] = argb;
assert((key >> cc->hash_bits) == 0u);
cc->colors[key] = argb;
}
static WEBP_INLINE void VP8LColorCacheInsert(const VP8LColorCache* const cc,
uint32_t argb) {
const int key = VP8LHashPix(argb, cc->hash_shift_);
cc->colors_[key] = argb;
const int key = VP8LHashPix(argb, cc->hash_shift);
cc->colors[key] = argb;
}
static WEBP_INLINE int VP8LColorCacheGetIndex(const VP8LColorCache* const cc,
uint32_t argb) {
return VP8LHashPix(argb, cc->hash_shift_);
return VP8LHashPix(argb, cc->hash_shift);
}
// Return the key if cc contains argb, and -1 otherwise.
static WEBP_INLINE int VP8LColorCacheContains(const VP8LColorCache* const cc,
uint32_t argb) {
const int key = VP8LHashPix(argb, cc->hash_shift_);
return (cc->colors_[key] == argb) ? key : -1;
const int key = VP8LHashPix(argb, cc->hash_shift);
return (cc->colors[key] == argb) ? key : -1;
}
//------------------------------------------------------------------------------

View File

@@ -29,9 +29,9 @@ typedef CRITICAL_SECTION pthread_mutex_t;
typedef CONDITION_VARIABLE pthread_cond_t;
#else
typedef struct {
HANDLE waiting_sem_;
HANDLE received_sem_;
HANDLE signal_event_;
HANDLE waiting_sem;
HANDLE received_sem;
HANDLE signal_event;
} pthread_cond_t;
#endif // _WIN32_WINNT >= 0x600
@@ -51,9 +51,9 @@ typedef struct {
#endif // _WIN32
typedef struct {
pthread_mutex_t mutex_;
pthread_cond_t condition_;
pthread_t thread_;
pthread_mutex_t mutex;
pthread_cond_t condition;
pthread_t thread;
} WebPWorkerImpl;
#if defined(_WIN32)
@@ -133,9 +133,9 @@ static int pthread_cond_destroy(pthread_cond_t* const condition) {
#ifdef USE_WINDOWS_CONDITION_VARIABLE
(void)condition;
#else
ok &= (CloseHandle(condition->waiting_sem_) != 0);
ok &= (CloseHandle(condition->received_sem_) != 0);
ok &= (CloseHandle(condition->signal_event_) != 0);
ok &= (CloseHandle(condition->waiting_sem) != 0);
ok &= (CloseHandle(condition->received_sem) != 0);
ok &= (CloseHandle(condition->signal_event) != 0);
#endif
return !ok;
}
@@ -145,12 +145,12 @@ static int pthread_cond_init(pthread_cond_t* const condition, void* cond_attr) {
#ifdef USE_WINDOWS_CONDITION_VARIABLE
InitializeConditionVariable(condition);
#else
condition->waiting_sem_ = CreateSemaphore(NULL, 0, 1, NULL);
condition->received_sem_ = CreateSemaphore(NULL, 0, 1, NULL);
condition->signal_event_ = CreateEvent(NULL, FALSE, FALSE, NULL);
if (condition->waiting_sem_ == NULL ||
condition->received_sem_ == NULL ||
condition->signal_event_ == NULL) {
condition->waiting_sem = CreateSemaphore(NULL, 0, 1, NULL);
condition->received_sem = CreateSemaphore(NULL, 0, 1, NULL);
condition->signal_event = CreateEvent(NULL, FALSE, FALSE, NULL);
if (condition->waiting_sem == NULL ||
condition->received_sem == NULL ||
condition->signal_event == NULL) {
pthread_cond_destroy(condition);
return 1;
}
@@ -163,12 +163,12 @@ static int pthread_cond_signal(pthread_cond_t* const condition) {
#ifdef USE_WINDOWS_CONDITION_VARIABLE
WakeConditionVariable(condition);
#else
if (WaitForSingleObject(condition->waiting_sem_, 0) == WAIT_OBJECT_0) {
if (WaitForSingleObject(condition->waiting_sem, 0) == WAIT_OBJECT_0) {
// a thread is waiting in pthread_cond_wait: allow it to be notified
ok = SetEvent(condition->signal_event_);
ok = SetEvent(condition->signal_event);
// wait until the event is consumed so the signaler cannot consume
// the event via its own pthread_cond_wait.
ok &= (WaitForSingleObject(condition->received_sem_, INFINITE) !=
ok &= (WaitForSingleObject(condition->received_sem, INFINITE) !=
WAIT_OBJECT_0);
}
#endif
@@ -183,12 +183,12 @@ static int pthread_cond_wait(pthread_cond_t* const condition,
#else
// note that there is a consumer available so the signal isn't dropped in
// pthread_cond_signal
if (!ReleaseSemaphore(condition->waiting_sem_, 1, NULL)) return 1;
if (!ReleaseSemaphore(condition->waiting_sem, 1, NULL)) return 1;
// now unlock the mutex so pthread_cond_signal may be issued
pthread_mutex_unlock(mutex);
ok = (WaitForSingleObject(condition->signal_event_, INFINITE) ==
ok = (WaitForSingleObject(condition->signal_event, INFINITE) ==
WAIT_OBJECT_0);
ok &= ReleaseSemaphore(condition->received_sem_, 1, NULL);
ok &= ReleaseSemaphore(condition->received_sem, 1, NULL);
pthread_mutex_lock(mutex);
#endif
return !ok;
@@ -203,17 +203,17 @@ static int pthread_cond_wait(pthread_cond_t* const condition,
static THREADFN ThreadLoop(void* ptr) {
WebPWorker* const worker = (WebPWorker*)ptr;
WebPWorkerImpl* const impl = (WebPWorkerImpl*)worker->impl_;
WebPWorkerImpl* const impl = (WebPWorkerImpl*)worker->impl;
int done = 0;
while (!done) {
pthread_mutex_lock(&impl->mutex_);
while (worker->status_ == OK) { // wait in idling mode
pthread_cond_wait(&impl->condition_, &impl->mutex_);
pthread_mutex_lock(&impl->mutex);
while (worker->status == OK) { // wait in idling mode
pthread_cond_wait(&impl->condition, &impl->mutex);
}
if (worker->status_ == WORK) {
if (worker->status == WORK) {
WebPGetWorkerInterface()->Execute(worker);
worker->status_ = OK;
} else if (worker->status_ == NOT_OK) { // finish the worker
worker->status = OK;
} else if (worker->status == NOT_OK) { // finish the worker
done = 1;
}
// signal to the main thread that we're done (for Sync())
@@ -221,8 +221,8 @@ static THREADFN ThreadLoop(void* ptr) {
// condition. Unlocking the mutex first may improve performance in some
// implementations, avoiding the case where the waiting thread can't
// reacquire the mutex when woken.
pthread_mutex_unlock(&impl->mutex_);
pthread_cond_signal(&impl->condition_);
pthread_mutex_unlock(&impl->mutex);
pthread_cond_signal(&impl->condition);
}
return THREAD_RETURN(NULL); // Thread is finished
}
@@ -230,30 +230,30 @@ static THREADFN ThreadLoop(void* ptr) {
// main thread state control
static void ChangeState(WebPWorker* const worker, WebPWorkerStatus new_status) {
// No-op when attempting to change state on a thread that didn't come up.
// Checking status_ without acquiring the lock first would result in a data
// Checking 'status' without acquiring the lock first would result in a data
// race.
WebPWorkerImpl* const impl = (WebPWorkerImpl*)worker->impl_;
WebPWorkerImpl* const impl = (WebPWorkerImpl*)worker->impl;
if (impl == NULL) return;
pthread_mutex_lock(&impl->mutex_);
if (worker->status_ >= OK) {
pthread_mutex_lock(&impl->mutex);
if (worker->status >= OK) {
// wait for the worker to finish
while (worker->status_ != OK) {
pthread_cond_wait(&impl->condition_, &impl->mutex_);
while (worker->status != OK) {
pthread_cond_wait(&impl->condition, &impl->mutex);
}
// assign new status and release the working thread if needed
if (new_status != OK) {
worker->status_ = new_status;
worker->status = new_status;
// Note the associated mutex does not need to be held when signaling the
// condition. Unlocking the mutex first may improve performance in some
// implementations, avoiding the case where the waiting thread can't
// reacquire the mutex when woken.
pthread_mutex_unlock(&impl->mutex_);
pthread_cond_signal(&impl->condition_);
pthread_mutex_unlock(&impl->mutex);
pthread_cond_signal(&impl->condition);
return;
}
}
pthread_mutex_unlock(&impl->mutex_);
pthread_mutex_unlock(&impl->mutex);
}
#endif // WEBP_USE_THREAD
@@ -262,54 +262,54 @@ static void ChangeState(WebPWorker* const worker, WebPWorkerStatus new_status) {
static void Init(WebPWorker* const worker) {
memset(worker, 0, sizeof(*worker));
worker->status_ = NOT_OK;
worker->status = NOT_OK;
}
static int Sync(WebPWorker* const worker) {
#ifdef WEBP_USE_THREAD
ChangeState(worker, OK);
#endif
assert(worker->status_ <= OK);
assert(worker->status <= OK);
return !worker->had_error;
}
static int Reset(WebPWorker* const worker) {
int ok = 1;
worker->had_error = 0;
if (worker->status_ < OK) {
if (worker->status < OK) {
#ifdef WEBP_USE_THREAD
WebPWorkerImpl* const impl =
(WebPWorkerImpl*)WebPSafeCalloc(1, sizeof(WebPWorkerImpl));
worker->impl_ = (void*)impl;
if (worker->impl_ == NULL) {
worker->impl = (void*)impl;
if (worker->impl == NULL) {
return 0;
}
if (pthread_mutex_init(&impl->mutex_, NULL)) {
if (pthread_mutex_init(&impl->mutex, NULL)) {
goto Error;
}
if (pthread_cond_init(&impl->condition_, NULL)) {
pthread_mutex_destroy(&impl->mutex_);
if (pthread_cond_init(&impl->condition, NULL)) {
pthread_mutex_destroy(&impl->mutex);
goto Error;
}
pthread_mutex_lock(&impl->mutex_);
ok = !pthread_create(&impl->thread_, NULL, ThreadLoop, worker);
if (ok) worker->status_ = OK;
pthread_mutex_unlock(&impl->mutex_);
pthread_mutex_lock(&impl->mutex);
ok = !pthread_create(&impl->thread, NULL, ThreadLoop, worker);
if (ok) worker->status = OK;
pthread_mutex_unlock(&impl->mutex);
if (!ok) {
pthread_mutex_destroy(&impl->mutex_);
pthread_cond_destroy(&impl->condition_);
pthread_mutex_destroy(&impl->mutex);
pthread_cond_destroy(&impl->condition);
Error:
WebPSafeFree(impl);
worker->impl_ = NULL;
worker->impl = NULL;
return 0;
}
#else
worker->status_ = OK;
worker->status = OK;
#endif
} else if (worker->status_ > OK) {
} else if (worker->status > OK) {
ok = Sync(worker);
}
assert(!ok || (worker->status_ == OK));
assert(!ok || (worker->status == OK));
return ok;
}
@@ -329,20 +329,20 @@ static void Launch(WebPWorker* const worker) {
static void End(WebPWorker* const worker) {
#ifdef WEBP_USE_THREAD
if (worker->impl_ != NULL) {
WebPWorkerImpl* const impl = (WebPWorkerImpl*)worker->impl_;
if (worker->impl != NULL) {
WebPWorkerImpl* const impl = (WebPWorkerImpl*)worker->impl;
ChangeState(worker, NOT_OK);
pthread_join(impl->thread_, NULL);
pthread_mutex_destroy(&impl->mutex_);
pthread_cond_destroy(&impl->condition_);
pthread_join(impl->thread, NULL);
pthread_mutex_destroy(&impl->mutex);
pthread_cond_destroy(&impl->condition);
WebPSafeFree(impl);
worker->impl_ = NULL;
worker->impl = NULL;
}
#else
worker->status_ = NOT_OK;
assert(worker->impl_ == NULL);
worker->status = NOT_OK;
assert(worker->impl == NULL);
#endif
assert(worker->status_ == NOT_OK);
assert(worker->status == NOT_OK);
}
//------------------------------------------------------------------------------

View File

@@ -37,8 +37,8 @@ typedef int (*WebPWorkerHook)(void*, void*);
// Synchronization object used to launch job in the worker thread
typedef struct {
void* impl_; // platform-dependent implementation worker details
WebPWorkerStatus status_;
void* impl; // platform-dependent implementation worker details
WebPWorkerStatus status;
WebPWorkerHook hook; // hook to call
void* data1; // first argument passed to 'hook'
void* data2; // second argument passed to 'hook'