diff options
Diffstat (limited to 'thirdparty/libwebp/src/dec/alpha_dec.c')
-rw-r--r-- | thirdparty/libwebp/src/dec/alpha_dec.c | 61 |
1 files changed, 34 insertions, 27 deletions
diff --git a/thirdparty/libwebp/src/dec/alpha_dec.c b/thirdparty/libwebp/src/dec/alpha_dec.c index 0b93a30b32..b6c874fb84 100644 --- a/thirdparty/libwebp/src/dec/alpha_dec.c +++ b/thirdparty/libwebp/src/dec/alpha_dec.c @@ -13,18 +13,20 @@ #include <stdlib.h> #include "src/dec/alphai_dec.h" +#include "src/dec/vp8_dec.h" #include "src/dec/vp8i_dec.h" #include "src/dec/vp8li_dec.h" #include "src/dsp/dsp.h" #include "src/utils/quant_levels_dec_utils.h" #include "src/utils/utils.h" #include "src/webp/format_constants.h" +#include "src/webp/types.h" //------------------------------------------------------------------------------ // ALPHDecoder object. // Allocates a new alpha decoder instance. -static ALPHDecoder* ALPHNew(void) { +WEBP_NODISCARD static ALPHDecoder* ALPHNew(void) { ALPHDecoder* const dec = (ALPHDecoder*)WebPSafeCalloc(1ULL, sizeof(*dec)); return dec; } @@ -45,9 +47,9 @@ static void ALPHDelete(ALPHDecoder* const dec) { // header for alpha data stored using lossless compression. // Returns false in case of error in alpha header (data too short, invalid // compression method or filter, error in lossless header data etc). -static int ALPHInit(ALPHDecoder* const dec, const uint8_t* data, - size_t data_size, const VP8Io* const src_io, - uint8_t* output) { +WEBP_NODISCARD static int ALPHInit(ALPHDecoder* const dec, const uint8_t* data, + size_t data_size, const VP8Io* const src_io, + uint8_t* output) { int ok = 0; const uint8_t* const alpha_data = data + ALPHA_HEADER_LEN; const size_t alpha_data_size = data_size - ALPHA_HEADER_LEN; @@ -79,7 +81,9 @@ static int ALPHInit(ALPHDecoder* const dec, const uint8_t* data, } // Copy the necessary parameters from src_io to io - VP8InitIo(io); + if (!VP8InitIo(io)) { + return 0; + } WebPInitCustomIo(NULL, io); io->opaque = dec; io->width = src_io->width; @@ -107,7 +111,8 @@ static int ALPHInit(ALPHDecoder* const dec, const uint8_t* data, // starting from row number 'row'. It assumes that rows up to (row - 1) have // already been decoded. // Returns false in case of bitstream error. -static int ALPHDecode(VP8Decoder* const dec, int row, int num_rows) { +WEBP_NODISCARD static int ALPHDecode(VP8Decoder* const dec, int row, + int num_rows) { ALPHDecoder* const alph_dec = dec->alph_dec_; const int width = alph_dec->width_; const int height = alph_dec->io_.crop_bottom; @@ -117,21 +122,12 @@ static int ALPHDecode(VP8Decoder* const dec, int row, int num_rows) { const uint8_t* deltas = dec->alpha_data_ + ALPHA_HEADER_LEN + row * width; uint8_t* dst = dec->alpha_plane_ + row * width; assert(deltas <= &dec->alpha_data_[dec->alpha_data_size_]); - if (alph_dec->filter_ != WEBP_FILTER_NONE) { - assert(WebPUnfilters[alph_dec->filter_] != NULL); - for (y = 0; y < num_rows; ++y) { - WebPUnfilters[alph_dec->filter_](prev_line, deltas, dst, width); - prev_line = dst; - dst += width; - deltas += width; - } - } else { - for (y = 0; y < num_rows; ++y) { - memcpy(dst, deltas, width * sizeof(*dst)); - prev_line = dst; - dst += width; - deltas += width; - } + assert(WebPUnfilters[alph_dec->filter_] != NULL); + for (y = 0; y < num_rows; ++y) { + WebPUnfilters[alph_dec->filter_](prev_line, deltas, dst, width); + prev_line = dst; + dst += width; + deltas += width; } dec->alpha_prev_line_ = prev_line; } else { // alph_dec->method_ == ALPHA_LOSSLESS_COMPRESSION @@ -147,7 +143,8 @@ static int ALPHDecode(VP8Decoder* const dec, int row, int num_rows) { return 1; } -static int AllocateAlphaPlane(VP8Decoder* const dec, const VP8Io* const io) { +WEBP_NODISCARD static int AllocateAlphaPlane(VP8Decoder* const dec, + const VP8Io* const io) { const int stride = io->width; const int height = io->crop_bottom; const uint64_t alpha_size = (uint64_t)stride * height; @@ -155,7 +152,8 @@ static int AllocateAlphaPlane(VP8Decoder* const dec, const VP8Io* const io) { dec->alpha_plane_mem_ = (uint8_t*)WebPSafeMalloc(alpha_size, sizeof(*dec->alpha_plane_)); if (dec->alpha_plane_mem_ == NULL) { - return 0; + return VP8SetError(dec, VP8_STATUS_OUT_OF_MEMORY, + "Alpha decoder initialization failed."); } dec->alpha_plane_ = dec->alpha_plane_mem_; dec->alpha_prev_line_ = NULL; @@ -174,9 +172,9 @@ void WebPDeallocateAlphaMemory(VP8Decoder* const dec) { //------------------------------------------------------------------------------ // Main entry point. -const uint8_t* VP8DecompressAlphaRows(VP8Decoder* const dec, - const VP8Io* const io, - int row, int num_rows) { +WEBP_NODISCARD const uint8_t* VP8DecompressAlphaRows(VP8Decoder* const dec, + const VP8Io* const io, + int row, int num_rows) { const int width = io->width; const int height = io->crop_bottom; @@ -189,10 +187,19 @@ const uint8_t* VP8DecompressAlphaRows(VP8Decoder* const dec, if (!dec->is_alpha_decoded_) { if (dec->alph_dec_ == NULL) { // Initialize decoder. dec->alph_dec_ = ALPHNew(); - if (dec->alph_dec_ == NULL) return NULL; + if (dec->alph_dec_ == NULL) { + VP8SetError(dec, VP8_STATUS_OUT_OF_MEMORY, + "Alpha decoder initialization failed."); + return NULL; + } if (!AllocateAlphaPlane(dec, io)) goto Error; if (!ALPHInit(dec->alph_dec_, dec->alpha_data_, dec->alpha_data_size_, io, dec->alpha_plane_)) { + VP8LDecoder* const vp8l_dec = dec->alph_dec_->vp8l_dec_; + VP8SetError(dec, + (vp8l_dec == NULL) ? VP8_STATUS_OUT_OF_MEMORY + : vp8l_dec->status_, + "Alpha decoder initialization failed."); goto Error; } // if we allowed use of alpha dithering, check whether it's needed at all |