diff options
Diffstat (limited to 'src/3rdparty/libwebp/src/dec/idec_dec.c')
-rw-r--r-- | src/3rdparty/libwebp/src/dec/idec_dec.c | 39 |
1 files changed, 25 insertions, 14 deletions
diff --git a/src/3rdparty/libwebp/src/dec/idec_dec.c b/src/3rdparty/libwebp/src/dec/idec_dec.c index 78fb2e7..9bc9166 100644 --- a/src/3rdparty/libwebp/src/dec/idec_dec.c +++ b/src/3rdparty/libwebp/src/dec/idec_dec.c @@ -15,10 +15,10 @@ #include <string.h> #include <stdlib.h> -#include "./alphai_dec.h" -#include "./webpi_dec.h" -#include "./vp8i_dec.h" -#include "../utils/utils.h" +#include "src/dec/alphai_dec.h" +#include "src/dec/webpi_dec.h" +#include "src/dec/vp8i_dec.h" +#include "src/utils/utils.h" // In append mode, buffer allocations increase as multiples of this value. // Needs to be a power of 2. @@ -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, @@ -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; @@ -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)) { @@ -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; } @@ -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; @@ -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) { @@ -673,12 +684,12 @@ void WebPIDelete(WebPIDecoder* idec) { //------------------------------------------------------------------------------ // Wrapper toward WebPINewDecoder -WebPIDecoder* WebPINewRGB(WEBP_CSP_MODE mode, uint8_t* output_buffer, +WebPIDecoder* WebPINewRGB(WEBP_CSP_MODE csp, uint8_t* output_buffer, size_t output_buffer_size, int output_stride) { const int is_external_memory = (output_buffer != NULL) ? 1 : 0; WebPIDecoder* idec; - if (mode >= MODE_YUV) return NULL; + if (csp >= MODE_YUV) return NULL; if (is_external_memory == 0) { // Overwrite parameters to sane values. output_buffer_size = 0; output_stride = 0; @@ -689,7 +700,7 @@ WebPIDecoder* WebPINewRGB(WEBP_CSP_MODE mode, uint8_t* output_buffer, } idec = WebPINewDecoder(NULL); if (idec == NULL) return NULL; - idec->output_.colorspace = mode; + idec->output_.colorspace = csp; idec->output_.is_external_memory = is_external_memory; idec->output_.u.RGBA.rgba = output_buffer; idec->output_.u.RGBA.stride = output_stride; |