Index: third_party/libwebp/dec/webp.c |
diff --git a/third_party/libwebp/dec/webp.c b/third_party/libwebp/dec/webp.c |
index 78220433777f69f12d11d84f428f0ee964ab4c1c..90d8a45d230ff94d0c29452874581b49a7ba2e61 100644 |
--- a/third_party/libwebp/dec/webp.c |
+++ b/third_party/libwebp/dec/webp.c |
@@ -403,7 +403,8 @@ static VP8StatusCode ParseHeadersInternal(const uint8_t* data, |
} |
VP8StatusCode WebPParseHeaders(WebPHeaderStructure* const headers) { |
- VP8StatusCode status; |
+ // status is marked volatile as a workaround for a clang-3.8 (aarch64) bug |
+ volatile VP8StatusCode status; |
int has_animation = 0; |
assert(headers != NULL); |
// fill out headers, ignore width/height/has_alpha. |
@@ -500,10 +501,12 @@ static VP8StatusCode DecodeInto(const uint8_t* const data, size_t data_size, |
if (status != VP8_STATUS_OK) { |
WebPFreeDecBuffer(params->output); |
- } |
- |
- if (params->options != NULL && params->options->flip) { |
- status = WebPFlipBuffer(params->output); |
+ } else { |
+ if (params->options != NULL && params->options->flip) { |
+ // This restores the original stride values if options->flip was used |
+ // during the call to WebPAllocateDecBuffer above. |
+ status = WebPFlipBuffer(params->output); |
+ } |
} |
return status; |
} |
@@ -746,9 +749,24 @@ VP8StatusCode WebPDecode(const uint8_t* data, size_t data_size, |
} |
WebPResetDecParams(¶ms); |
- params.output = &config->output; |
params.options = &config->options; |
- status = DecodeInto(data, data_size, ¶ms); |
+ params.output = &config->output; |
+ if (WebPAvoidSlowMemory(params.output, &config->input)) { |
+ // decoding to slow memory: use a temporary in-mem buffer to decode into. |
+ WebPDecBuffer in_mem_buffer; |
+ WebPInitDecBuffer(&in_mem_buffer); |
+ in_mem_buffer.colorspace = config->output.colorspace; |
+ in_mem_buffer.width = config->input.width; |
+ in_mem_buffer.height = config->input.height; |
+ params.output = &in_mem_buffer; |
+ status = DecodeInto(data, data_size, ¶ms); |
+ if (status == VP8_STATUS_OK) { // do the slow-copy |
+ status = WebPCopyDecBufferPixels(&in_mem_buffer, &config->output); |
+ } |
+ WebPFreeDecBuffer(&in_mem_buffer); |
+ } else { |
+ status = DecodeInto(data, data_size, ¶ms); |
+ } |
return status; |
} |
@@ -797,7 +815,7 @@ int WebPIoInitFromOptions(const WebPDecoderOptions* const options, |
} |
// Filter |
- io->bypass_filtering = options && options->bypass_filtering; |
+ io->bypass_filtering = (options != NULL) && options->bypass_filtering; |
// Fancy upsampler |
#ifdef FANCY_UPSAMPLING |
@@ -814,4 +832,3 @@ int WebPIoInitFromOptions(const WebPDecoderOptions* const options, |
} |
//------------------------------------------------------------------------------ |
- |