Skip to content

Commit

Permalink
Update libwebp to 1.0.1
Browse files Browse the repository at this point in the history
  • Loading branch information
volzhs committed Dec 10, 2018
1 parent bf59b73 commit d4133ac
Show file tree
Hide file tree
Showing 65 changed files with 583 additions and 872 deletions.
2 changes: 0 additions & 2 deletions modules/webp/SCsub
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,6 @@ if env['builtin_libwebp']:
"dsp/dec_neon.c",
"dsp/dec_sse2.c",
"dsp/dec_sse41.c",
"dsp/enc_avx2.c",
"dsp/enc.c",
"dsp/enc_mips32.c",
"dsp/enc_mips_dsp_r2.c",
Expand Down Expand Up @@ -90,7 +89,6 @@ if env['builtin_libwebp']:
"enc/backward_references_enc.c",
"enc/config_enc.c",
"enc/cost_enc.c",
"enc/delta_palettization_enc.c",
"enc/filter_enc.c",
"enc/frame_enc.c",
"enc/histogram_enc.c",
Expand Down
2 changes: 1 addition & 1 deletion thirdparty/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -233,7 +233,7 @@ Godot-made change marked with `// -- GODOT --` comments.
## libwebp

- Upstream: https://chromium.googlesource.com/webm/libwebp/
- Version: 1.0.0
- Version: 1.0.1
- License: BSD-3-Clause

Files extracted from upstream source:
Expand Down
2 changes: 1 addition & 1 deletion thirdparty/libwebp/src/dec/alphai_dec.h
Original file line number Diff line number Diff line change
Expand Up @@ -51,4 +51,4 @@ void WebPDeallocateAlphaMemory(VP8Decoder* const dec);
} // extern "C"
#endif

#endif /* WEBP_DEC_ALPHAI_DEC_H_ */
#endif // WEBP_DEC_ALPHAI_DEC_H_
3 changes: 2 additions & 1 deletion thirdparty/libwebp/src/dec/buffer_dec.c
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,8 @@ static VP8StatusCode CheckDecBuffer(const WebPDecBuffer* const buffer) {
} else { // RGB checks
const WebPRGBABuffer* const buf = &buffer->u.RGBA;
const int stride = abs(buf->stride);
const uint64_t size = MIN_BUFFER_SIZE(width, height, stride);
const uint64_t size =
MIN_BUFFER_SIZE(width * kModeBpp[mode], height, stride);
ok &= (size <= buf->size);
ok &= (stride >= width * kModeBpp[mode]);
ok &= (buf->rgba != NULL);
Expand Down
2 changes: 1 addition & 1 deletion thirdparty/libwebp/src/dec/common_dec.h
Original file line number Diff line number Diff line change
Expand Up @@ -51,4 +51,4 @@ enum { MB_FEATURE_TREE_PROBS = 3,
NUM_PROBAS = 11
};

#endif // WEBP_DEC_COMMON_DEC_H_
#endif // WEBP_DEC_COMMON_DEC_H_
9 changes: 1 addition & 8 deletions thirdparty/libwebp/src/dec/frame_dec.c
Original file line number Diff line number Diff line change
Expand Up @@ -338,7 +338,6 @@ void VP8InitDithering(const WebPDecoderOptions* const options,
for (s = 0; s < NUM_MB_SEGMENTS; ++s) {
VP8QuantMatrix* const dqm = &dec->dqm_[s];
if (dqm->uv_quant_ < DITHER_AMP_TAB_SIZE) {
// TODO(skal): should we specially dither more for uv_quant_ < 0?
const int idx = (dqm->uv_quant_ < 0) ? 0 : dqm->uv_quant_;
dqm->dither_ = (f * kQuantToDitherAmp[idx]) >> 3;
}
Expand Down Expand Up @@ -669,15 +668,9 @@ int VP8GetThreadMethod(const WebPDecoderOptions* const options,
(void)height;
assert(headers == NULL || !headers->is_lossless);
#if defined(WEBP_USE_THREAD)
if (width < MIN_WIDTH_FOR_THREADS) return 0;
// TODO(skal): tune the heuristic further
#if 0
if (height < 2 * width) return 2;
if (width >= MIN_WIDTH_FOR_THREADS) return 2;
#endif
return 2;
#else // !WEBP_USE_THREAD
return 0;
#endif
}

#undef MT_CACHE_LINES
Expand Down
25 changes: 18 additions & 7 deletions thirdparty/libwebp/src/dec/idec_dec.c
Original file line number Diff line number Diff line change
Expand Up @@ -140,10 +140,9 @@ static void DoRemap(WebPIDecoder* const idec, ptrdiff_t offset) {
if (NeedCompressedAlpha(idec)) {
ALPHDecoder* const alph_dec = dec->alph_dec_;
dec->alpha_data_ += offset;
if (alph_dec != NULL) {
if (alph_dec != NULL && alph_dec->vp8l_dec_ != NULL) {
if (alph_dec->method_ == ALPHA_LOSSLESS_COMPRESSION) {
VP8LDecoder* const alph_vp8l_dec = alph_dec->vp8l_dec_;
assert(alph_vp8l_dec != NULL);
assert(dec->alpha_data_size_ >= ALPHA_HEADER_LEN);
VP8LBitReaderSetBuffer(&alph_vp8l_dec->br_,
dec->alpha_data_ + ALPHA_HEADER_LEN,
Expand Down Expand Up @@ -283,10 +282,8 @@ static void RestoreContext(const MBContext* context, VP8Decoder* const dec,

static VP8StatusCode IDecError(WebPIDecoder* const idec, VP8StatusCode error) {
if (idec->state_ == STATE_VP8_DATA) {
VP8Io* const io = &idec->io_;
if (io->teardown != NULL) {
io->teardown(io);
}
// Synchronize the thread, clean-up and check for errors.
VP8ExitCritical((VP8Decoder*)idec->dec_, &idec->io_);
}
idec->state_ = STATE_ERROR;
return error;
Expand Down Expand Up @@ -451,7 +448,10 @@ static VP8StatusCode DecodeRemaining(WebPIDecoder* const idec) {
VP8Decoder* const dec = (VP8Decoder*)idec->dec_;
VP8Io* const io = &idec->io_;

assert(dec->ready_);
// Make sure partition #0 has been read before, to set dec to ready_.
if (!dec->ready_) {
return IDecError(idec, VP8_STATUS_BITSTREAM_ERROR);
}
for (; dec->mb_y_ < dec->mb_h_; ++dec->mb_y_) {
if (idec->last_mb_y_ != dec->mb_y_) {
if (!VP8ParseIntraModeRow(&dec->br_, dec)) {
Expand All @@ -473,6 +473,12 @@ static VP8StatusCode DecodeRemaining(WebPIDecoder* const idec) {
MemDataSize(&idec->mem_) > MAX_MB_SIZE) {
return IDecError(idec, VP8_STATUS_BITSTREAM_ERROR);
}
// Synchronize the threads.
if (dec->mt_method_ > 0) {
if (!WebPGetWorkerInterface()->Sync(&dec->worker_)) {
return IDecError(idec, VP8_STATUS_BITSTREAM_ERROR);
}
}
RestoreContext(&context, dec, token_br);
return VP8_STATUS_SUSPENDED;
}
Expand All @@ -491,6 +497,7 @@ static VP8StatusCode DecodeRemaining(WebPIDecoder* const idec) {
}
// Synchronize the thread and check for errors.
if (!VP8ExitCritical(dec, io)) {
idec->state_ = STATE_ERROR; // prevent re-entry in IDecError
return IDecError(idec, VP8_STATUS_USER_ABORT);
}
dec->ready_ = 0;
Expand Down Expand Up @@ -571,6 +578,10 @@ static VP8StatusCode IDecode(WebPIDecoder* idec) {
status = DecodePartition0(idec);
}
if (idec->state_ == STATE_VP8_DATA) {
const VP8Decoder* const dec = (VP8Decoder*)idec->dec_;
if (dec == NULL) {
return VP8_STATUS_SUSPENDED; // can't continue if we have no decoder.
}
status = DecodeRemaining(idec);
}
if (idec->state_ == STATE_VP8L_HEADER) {
Expand Down
2 changes: 1 addition & 1 deletion thirdparty/libwebp/src/dec/vp8_dec.h
Original file line number Diff line number Diff line change
Expand Up @@ -182,4 +182,4 @@ WEBP_EXTERN int VP8LGetInfo(
} // extern "C"
#endif

#endif /* WEBP_DEC_VP8_DEC_H_ */
#endif // WEBP_DEC_VP8_DEC_H_
4 changes: 2 additions & 2 deletions thirdparty/libwebp/src/dec/vp8i_dec.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ extern "C" {
// version numbers
#define DEC_MAJ_VERSION 1
#define DEC_MIN_VERSION 0
#define DEC_REV_VERSION 0
#define DEC_REV_VERSION 1

// YUV-cache parameters. Cache is 32-bytes wide (= one cacheline).
// Constraints are: We need to store one 16x16 block of luma samples (y),
Expand Down Expand Up @@ -316,4 +316,4 @@ const uint8_t* VP8DecompressAlphaRows(VP8Decoder* const dec,
} // extern "C"
#endif

#endif /* WEBP_DEC_VP8I_DEC_H_ */
#endif // WEBP_DEC_VP8I_DEC_H_
103 changes: 78 additions & 25 deletions thirdparty/libwebp/src/dec/vp8l_dec.c
Original file line number Diff line number Diff line change
Expand Up @@ -362,12 +362,19 @@ static int ReadHuffmanCodes(VP8LDecoder* const dec, int xsize, int ysize,
VP8LMetadata* const hdr = &dec->hdr_;
uint32_t* huffman_image = NULL;
HTreeGroup* htree_groups = NULL;
// When reading htrees, some might be unused, as the format allows it.
// We will still read them but put them in this htree_group_bogus.
HTreeGroup htree_group_bogus;
HuffmanCode* huffman_tables = NULL;
HuffmanCode* huffman_tables_bogus = NULL;
HuffmanCode* next = NULL;
int num_htree_groups = 1;
int num_htree_groups_max = 1;
int max_alphabet_size = 0;
int* code_lengths = NULL;
const int table_size = kTableSize[color_cache_bits];
int* mapping = NULL;
int ok = 0;

if (allow_recursion && VP8LReadBits(br, 1)) {
// use meta Huffman codes.
Expand All @@ -384,9 +391,41 @@ static int ReadHuffmanCodes(VP8LDecoder* const dec, int xsize, int ysize,
// The huffman data is stored in red and green bytes.
const int group = (huffman_image[i] >> 8) & 0xffff;
huffman_image[i] = group;
if (group >= num_htree_groups) {
num_htree_groups = group + 1;
if (group >= num_htree_groups_max) {
num_htree_groups_max = group + 1;
}
}
// Check the validity of num_htree_groups_max. If it seems too big, use a
// smaller value for later. This will prevent big memory allocations to end
// up with a bad bitstream anyway.
// The value of 1000 is totally arbitrary. We know that num_htree_groups_max
// is smaller than (1 << 16) and should be smaller than the number of pixels
// (though the format allows it to be bigger).
if (num_htree_groups_max > 1000 || num_htree_groups_max > xsize * ysize) {
// Create a mapping from the used indices to the minimal set of used
// values [0, num_htree_groups)
mapping = (int*)WebPSafeMalloc(num_htree_groups_max, sizeof(*mapping));
if (mapping == NULL) {
dec->status_ = VP8_STATUS_OUT_OF_MEMORY;
goto Error;
}
// -1 means a value is unmapped, and therefore unused in the Huffman
// image.
memset(mapping, 0xff, num_htree_groups_max * sizeof(*mapping));
for (num_htree_groups = 0, i = 0; i < huffman_pixs; ++i) {
// Get the current mapping for the group and remap the Huffman image.
int* const mapped_group = &mapping[huffman_image[i]];
if (*mapped_group == -1) *mapped_group = num_htree_groups++;
huffman_image[i] = *mapped_group;
}
huffman_tables_bogus = (HuffmanCode*)WebPSafeMalloc(
table_size, sizeof(*huffman_tables_bogus));
if (huffman_tables_bogus == NULL) {
dec->status_ = VP8_STATUS_OUT_OF_MEMORY;
goto Error;
}
} else {
num_htree_groups = num_htree_groups_max;
}
}

Expand All @@ -403,40 +442,47 @@ static int ReadHuffmanCodes(VP8LDecoder* const dec, int xsize, int ysize,
}
}

code_lengths = (int*)WebPSafeCalloc((uint64_t)max_alphabet_size,
sizeof(*code_lengths));
huffman_tables = (HuffmanCode*)WebPSafeMalloc(num_htree_groups * table_size,
sizeof(*huffman_tables));
htree_groups = VP8LHtreeGroupsNew(num_htree_groups);
code_lengths = (int*)WebPSafeCalloc((uint64_t)max_alphabet_size,
sizeof(*code_lengths));

if (htree_groups == NULL || code_lengths == NULL || huffman_tables == NULL) {
dec->status_ = VP8_STATUS_OUT_OF_MEMORY;
goto Error;
}

next = huffman_tables;
for (i = 0; i < num_htree_groups; ++i) {
HTreeGroup* const htree_group = &htree_groups[i];
for (i = 0; i < num_htree_groups_max; ++i) {
// If the index "i" is unused in the Huffman image, read the coefficients
// but store them to a bogus htree_group.
const int is_bogus = (mapping != NULL && mapping[i] == -1);
HTreeGroup* const htree_group =
is_bogus ? &htree_group_bogus :
&htree_groups[(mapping == NULL) ? i : mapping[i]];
HuffmanCode** const htrees = htree_group->htrees;
HuffmanCode* huffman_tables_i = is_bogus ? huffman_tables_bogus : next;
int size;
int total_size = 0;
int is_trivial_literal = 1;
int max_bits = 0;
for (j = 0; j < HUFFMAN_CODES_PER_META_CODE; ++j) {
int alphabet_size = kAlphabetSize[j];
htrees[j] = next;
htrees[j] = huffman_tables_i;
if (j == 0 && color_cache_bits > 0) {
alphabet_size += 1 << color_cache_bits;
}
size = ReadHuffmanCode(alphabet_size, dec, code_lengths, next);
size =
ReadHuffmanCode(alphabet_size, dec, code_lengths, huffman_tables_i);
if (size == 0) {
goto Error;
}
if (is_trivial_literal && kLiteralMap[j] == 1) {
is_trivial_literal = (next->bits == 0);
is_trivial_literal = (huffman_tables_i->bits == 0);
}
total_size += next->bits;
next += size;
total_size += huffman_tables_i->bits;
huffman_tables_i += size;
if (j <= ALPHA) {
int local_max_bits = code_lengths[0];
int k;
Expand All @@ -448,38 +494,41 @@ static int ReadHuffmanCodes(VP8LDecoder* const dec, int xsize, int ysize,
max_bits += local_max_bits;
}
}
if (!is_bogus) next = huffman_tables_i;
htree_group->is_trivial_literal = is_trivial_literal;
htree_group->is_trivial_code = 0;
if (is_trivial_literal) {
const int red = htrees[RED][0].value;
const int blue = htrees[BLUE][0].value;
const int alpha = htrees[ALPHA][0].value;
htree_group->literal_arb =
((uint32_t)alpha << 24) | (red << 16) | blue;
htree_group->literal_arb = ((uint32_t)alpha << 24) | (red << 16) | blue;
if (total_size == 0 && htrees[GREEN][0].value < NUM_LITERAL_CODES) {
htree_group->is_trivial_code = 1;
htree_group->literal_arb |= htrees[GREEN][0].value << 8;
}
}
htree_group->use_packed_table = !htree_group->is_trivial_code &&
(max_bits < HUFFMAN_PACKED_BITS);
htree_group->use_packed_table =
!htree_group->is_trivial_code && (max_bits < HUFFMAN_PACKED_BITS);
if (htree_group->use_packed_table) BuildPackedTable(htree_group);
}
WebPSafeFree(code_lengths);
ok = 1;

// All OK. Finalize pointers and return.
// All OK. Finalize pointers.
hdr->huffman_image_ = huffman_image;
hdr->num_htree_groups_ = num_htree_groups;
hdr->htree_groups_ = htree_groups;
hdr->huffman_tables_ = huffman_tables;
return 1;

Error:
WebPSafeFree(code_lengths);
WebPSafeFree(huffman_image);
WebPSafeFree(huffman_tables);
VP8LHtreeGroupsFree(htree_groups);
return 0;
WebPSafeFree(huffman_tables_bogus);
WebPSafeFree(mapping);
if (!ok) {
WebPSafeFree(huffman_image);
WebPSafeFree(huffman_tables);
VP8LHtreeGroupsFree(htree_groups);
}
return ok;
}

//------------------------------------------------------------------------------
Expand Down Expand Up @@ -884,7 +933,11 @@ static WEBP_INLINE void CopyBlock8b(uint8_t* const dst, int dist, int length) {
#endif
break;
case 2:
#if !defined(WORDS_BIGENDIAN)
memcpy(&pattern, src, sizeof(uint16_t));
#else
pattern = ((uint32_t)src[0] << 8) | src[1];
#endif
#if defined(__arm__) || defined(_M_ARM)
pattern |= pattern << 16;
#elif defined(WEBP_USE_MIPS_DSP_R2)
Expand Down Expand Up @@ -1523,7 +1576,6 @@ int VP8LDecodeAlphaHeader(ALPHDecoder* const alph_dec,
if (dec == NULL) return 0;

assert(alph_dec != NULL);
alph_dec->vp8l_dec_ = dec;

dec->width_ = alph_dec->width_;
dec->height_ = alph_dec->height_;
Expand Down Expand Up @@ -1555,11 +1607,12 @@ int VP8LDecodeAlphaHeader(ALPHDecoder* const alph_dec,

if (!ok) goto Err;

// Only set here, once we are sure it is valid (to avoid thread races).
alph_dec->vp8l_dec_ = dec;
return 1;

Err:
VP8LDelete(alph_dec->vp8l_dec_);
alph_dec->vp8l_dec_ = NULL;
VP8LDelete(dec);
return 0;
}

Expand Down
2 changes: 1 addition & 1 deletion thirdparty/libwebp/src/dec/vp8li_dec.h
Original file line number Diff line number Diff line change
Expand Up @@ -132,4 +132,4 @@ void VP8LDelete(VP8LDecoder* const dec);
} // extern "C"
#endif

#endif /* WEBP_DEC_VP8LI_DEC_H_ */
#endif // WEBP_DEC_VP8LI_DEC_H_
2 changes: 1 addition & 1 deletion thirdparty/libwebp/src/dec/webpi_dec.h
Original file line number Diff line number Diff line change
Expand Up @@ -130,4 +130,4 @@ int WebPAvoidSlowMemory(const WebPDecBuffer* const output,
} // extern "C"
#endif

#endif /* WEBP_DEC_WEBPI_DEC_H_ */
#endif // WEBP_DEC_WEBPI_DEC_H_
2 changes: 1 addition & 1 deletion thirdparty/libwebp/src/demux/demux.c
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@

#define DMUX_MAJ_VERSION 1
#define DMUX_MIN_VERSION 0
#define DMUX_REV_VERSION 0
#define DMUX_REV_VERSION 1

typedef struct {
size_t start_; // start location of the data
Expand Down
Loading

0 comments on commit d4133ac

Please sign in to comment.