diff options
author | Rémi Verschelde <rverschelde@gmail.com> | 2023-08-07 18:12:21 +0200 |
---|---|---|
committer | Rémi Verschelde <rverschelde@gmail.com> | 2023-08-07 18:12:39 +0200 |
commit | 2529ad6a6427a27f47c1ef8ce2aac608f6c20ed8 (patch) | |
tree | 979839c7347bbcedb9944c0060612399b5dfa25f /thirdparty/libwebp/src/enc | |
parent | f2acfb1ffc94d0e381064070108e7a773d86177d (diff) | |
download | redot-engine-2529ad6a6427a27f47c1ef8ce2aac608f6c20ed8.tar.gz |
libwebp: Sync with upstream 1.3.1
https://chromium.googlesource.com/webm/libwebp/+/1.3.1/NEWS
Diffstat (limited to 'thirdparty/libwebp/src/enc')
-rw-r--r-- | thirdparty/libwebp/src/enc/alpha_enc.c | 20 | ||||
-rw-r--r-- | thirdparty/libwebp/src/enc/analysis_enc.c | 4 | ||||
-rw-r--r-- | thirdparty/libwebp/src/enc/backward_references_enc.c | 9 | ||||
-rw-r--r-- | thirdparty/libwebp/src/enc/frame_enc.c | 8 | ||||
-rw-r--r-- | thirdparty/libwebp/src/enc/picture_csp_enc.c | 5 | ||||
-rw-r--r-- | thirdparty/libwebp/src/enc/picture_rescale_enc.c | 20 | ||||
-rw-r--r-- | thirdparty/libwebp/src/enc/syntax_enc.c | 6 | ||||
-rw-r--r-- | thirdparty/libwebp/src/enc/vp8i_enc.h | 2 | ||||
-rw-r--r-- | thirdparty/libwebp/src/enc/vp8l_enc.c | 38 | ||||
-rw-r--r-- | thirdparty/libwebp/src/enc/webp_enc.c | 10 |
10 files changed, 76 insertions, 46 deletions
diff --git a/thirdparty/libwebp/src/enc/alpha_enc.c b/thirdparty/libwebp/src/enc/alpha_enc.c index f7c02690e3..26f003485a 100644 --- a/thirdparty/libwebp/src/enc/alpha_enc.c +++ b/thirdparty/libwebp/src/enc/alpha_enc.c @@ -13,6 +13,7 @@ #include <assert.h> #include <stdlib.h> +#include <string.h> #include "src/enc/vp8i_enc.h" #include "src/dsp/dsp.h" @@ -140,6 +141,11 @@ static int EncodeAlphaInternal(const uint8_t* const data, int width, int height, !reduce_levels, &tmp_bw, &result->stats); if (ok) { output = VP8LBitWriterFinish(&tmp_bw); + if (tmp_bw.error_) { + VP8LBitWriterWipeOut(&tmp_bw); + memset(&result->bw, 0, sizeof(result->bw)); + return 0; + } output_size = VP8LBitWriterNumBytes(&tmp_bw); if (output_size > data_size) { // compressed size is larger than source! Revert to uncompressed mode. @@ -148,6 +154,7 @@ static int EncodeAlphaInternal(const uint8_t* const data, int width, int height, } } else { VP8LBitWriterWipeOut(&tmp_bw); + memset(&result->bw, 0, sizeof(result->bw)); return 0; } } @@ -162,7 +169,7 @@ static int EncodeAlphaInternal(const uint8_t* const data, int width, int height, header = method | (filter << 2); if (reduce_levels) header |= ALPHA_PREPROCESSED_LEVELS << 4; - VP8BitWriterInit(&result->bw, ALPHA_HEADER_LEN + output_size); + if (!VP8BitWriterInit(&result->bw, ALPHA_HEADER_LEN + output_size)) ok = 0; ok = ok && VP8BitWriterAppend(&result->bw, &header, ALPHA_HEADER_LEN); ok = ok && VP8BitWriterAppend(&result->bw, output, output_size); @@ -312,11 +319,11 @@ static int EncodeAlpha(VP8Encoder* const enc, assert(filter >= WEBP_FILTER_NONE && filter <= WEBP_FILTER_FAST); if (quality < 0 || quality > 100) { - return 0; + return WebPEncodingSetError(pic, VP8_ENC_ERROR_INVALID_CONFIGURATION); } if (method < ALPHA_NO_COMPRESSION || method > ALPHA_LOSSLESS_COMPRESSION) { - return 0; + return WebPEncodingSetError(pic, VP8_ENC_ERROR_INVALID_CONFIGURATION); } if (method == ALPHA_NO_COMPRESSION) { @@ -326,7 +333,7 @@ static int EncodeAlpha(VP8Encoder* const enc, quant_alpha = (uint8_t*)WebPSafeMalloc(1ULL, data_size); if (quant_alpha == NULL) { - return 0; + return WebPEncodingSetError(pic, VP8_ENC_ERROR_OUT_OF_MEMORY); } // Extract alpha data (width x height) from raw_data (stride x height). @@ -346,6 +353,9 @@ static int EncodeAlpha(VP8Encoder* const enc, ok = ApplyFiltersAndEncode(quant_alpha, width, height, data_size, method, filter, reduce_levels, effort_level, output, output_size, pic->stats); + if (!ok) { + WebPEncodingSetError(pic, VP8_ENC_ERROR_OUT_OF_MEMORY); // imprecise + } #if !defined(WEBP_DISABLE_STATS) if (pic->stats != NULL) { // need stats? pic->stats->coded_size += (int)(*output_size); @@ -405,7 +415,7 @@ int VP8EncStartAlpha(VP8Encoder* const enc) { WebPWorker* const worker = &enc->alpha_worker_; // Makes sure worker is good to go. if (!WebPGetWorkerInterface()->Reset(worker)) { - return 0; + return WebPEncodingSetError(enc->pic_, VP8_ENC_ERROR_OUT_OF_MEMORY); } WebPGetWorkerInterface()->Launch(worker); return 1; diff --git a/thirdparty/libwebp/src/enc/analysis_enc.c b/thirdparty/libwebp/src/enc/analysis_enc.c index a0001ac034..962eaa998f 100644 --- a/thirdparty/libwebp/src/enc/analysis_enc.c +++ b/thirdparty/libwebp/src/enc/analysis_enc.c @@ -474,6 +474,10 @@ int VP8EncAnalyze(VP8Encoder* const enc) { } else { // Use only one default segment. ResetAllMBInfo(enc); } + if (!ok) { + return WebPEncodingSetError(enc->pic_, + VP8_ENC_ERROR_OUT_OF_MEMORY); // imprecise + } return ok; } diff --git a/thirdparty/libwebp/src/enc/backward_references_enc.c b/thirdparty/libwebp/src/enc/backward_references_enc.c index 49a0fac034..dc98bf1719 100644 --- a/thirdparty/libwebp/src/enc/backward_references_enc.c +++ b/thirdparty/libwebp/src/enc/backward_references_enc.c @@ -283,8 +283,7 @@ int VP8LHashChainFill(VP8LHashChain* const p, int quality, hash_to_first_index = (int32_t*)WebPSafeMalloc(HASH_SIZE, sizeof(*hash_to_first_index)); if (hash_to_first_index == NULL) { - WebPEncodingSetError(pic, VP8_ENC_ERROR_OUT_OF_MEMORY); - return 0; + return WebPEncodingSetError(pic, VP8_ENC_ERROR_OUT_OF_MEMORY); } percent_range = remaining_percent / 2; @@ -1050,8 +1049,7 @@ int VP8LGetBackwardReferences( refs_best = GetBackwardReferencesLowEffort( width, height, argb, cache_bits_best, hash_chain, refs); if (refs_best == NULL) { - WebPEncodingSetError(pic, VP8_ENC_ERROR_OUT_OF_MEMORY); - return 0; + return WebPEncodingSetError(pic, VP8_ENC_ERROR_OUT_OF_MEMORY); } // Set it in first position. BackwardRefsSwap(refs_best, &refs[0]); @@ -1059,8 +1057,7 @@ int VP8LGetBackwardReferences( if (!GetBackwardReferences(width, height, argb, quality, lz77_types_to_try, cache_bits_max, do_no_cache, hash_chain, refs, cache_bits_best)) { - WebPEncodingSetError(pic, VP8_ENC_ERROR_OUT_OF_MEMORY); - return 0; + return WebPEncodingSetError(pic, VP8_ENC_ERROR_OUT_OF_MEMORY); } } diff --git a/thirdparty/libwebp/src/enc/frame_enc.c b/thirdparty/libwebp/src/enc/frame_enc.c index b93d9e5b99..9a98dc1f3e 100644 --- a/thirdparty/libwebp/src/enc/frame_enc.c +++ b/thirdparty/libwebp/src/enc/frame_enc.c @@ -689,7 +689,7 @@ static int PreLoopInitialize(VP8Encoder* const enc) { } if (!ok) { VP8EncFreeBitWriters(enc); // malloc error occurred - WebPEncodingSetError(enc->pic_, VP8_ENC_ERROR_OUT_OF_MEMORY); + return WebPEncodingSetError(enc->pic_, VP8_ENC_ERROR_OUT_OF_MEMORY); } return ok; } @@ -719,6 +719,7 @@ static int PostLoopFinalize(VP8EncIterator* const it, int ok) { } else { // Something bad happened -> need to do some memory cleanup. VP8EncFreeBitWriters(enc); + return WebPEncodingSetError(enc->pic_, VP8_ENC_ERROR_OUT_OF_MEMORY); } return ok; } @@ -754,6 +755,11 @@ int VP8EncLoop(VP8Encoder* const enc) { // *then* decide how to code the skip decision if there's one. if (!VP8Decimate(&it, &info, rd_opt) || dont_use_skip) { CodeResiduals(it.bw_, &it, &info); + if (it.bw_->error_) { + // enc->pic_->error_code is set in PostLoopFinalize(). + ok = 0; + break; + } } else { // reset predictors after a skip ResetAfterSkip(&it); } diff --git a/thirdparty/libwebp/src/enc/picture_csp_enc.c b/thirdparty/libwebp/src/enc/picture_csp_enc.c index 78c8ca479b..a9280e6c30 100644 --- a/thirdparty/libwebp/src/enc/picture_csp_enc.c +++ b/thirdparty/libwebp/src/enc/picture_csp_enc.c @@ -98,6 +98,7 @@ static int kLinearToGammaTab[GAMMA_TAB_SIZE + 1]; static uint16_t kGammaToLinearTab[256]; static volatile int kGammaTablesOk = 0; static void InitGammaTables(void); +extern VP8CPUInfo VP8GetCPUInfo; WEBP_DSP_INIT_FUNC(InitGammaTables) { if (!kGammaTablesOk) { @@ -534,7 +535,9 @@ static int ImportYUVAFromRGBA(const uint8_t* r_ptr, WebPInitConvertARGBToYUV(); InitGammaTables(); - if (tmp_rgb == NULL) return 0; // malloc error + if (tmp_rgb == NULL) { + return WebPEncodingSetError(picture, VP8_ENC_ERROR_OUT_OF_MEMORY); + } // Downsample Y/U/V planes, two rows at a time for (y = 0; y < (height >> 1); ++y) { diff --git a/thirdparty/libwebp/src/enc/picture_rescale_enc.c b/thirdparty/libwebp/src/enc/picture_rescale_enc.c index 839f91cacc..ea90d82548 100644 --- a/thirdparty/libwebp/src/enc/picture_rescale_enc.c +++ b/thirdparty/libwebp/src/enc/picture_rescale_enc.c @@ -137,7 +137,9 @@ int WebPPictureCrop(WebPPicture* pic, PictureGrabSpecs(pic, &tmp); tmp.width = width; tmp.height = height; - if (!WebPPictureAlloc(&tmp)) return 0; + if (!WebPPictureAlloc(&tmp)) { + return WebPEncodingSetError(pic, tmp.error_code); + } if (!pic->use_argb) { const int y_offset = top * pic->y_stride + left; @@ -212,26 +214,28 @@ int WebPPictureRescale(WebPPicture* picture, int width, int height) { prev_height = picture->height; if (!WebPRescalerGetScaledDimensions( prev_width, prev_height, &width, &height)) { - return 0; + return WebPEncodingSetError(picture, VP8_ENC_ERROR_BAD_DIMENSION); } PictureGrabSpecs(picture, &tmp); tmp.width = width; tmp.height = height; - if (!WebPPictureAlloc(&tmp)) return 0; + if (!WebPPictureAlloc(&tmp)) { + return WebPEncodingSetError(picture, tmp.error_code); + } if (!picture->use_argb) { work = (rescaler_t*)WebPSafeMalloc(2ULL * width, sizeof(*work)); if (work == NULL) { WebPPictureFree(&tmp); - return 0; + return WebPEncodingSetError(picture, VP8_ENC_ERROR_OUT_OF_MEMORY); } // If present, we need to rescale alpha first (for AlphaMultiplyY). if (picture->a != NULL) { WebPInitAlphaProcessing(); if (!RescalePlane(picture->a, prev_width, prev_height, picture->a_stride, tmp.a, width, height, tmp.a_stride, work, 1)) { - return 0; + return WebPEncodingSetError(picture, VP8_ENC_ERROR_BAD_DIMENSION); } } @@ -246,14 +250,14 @@ int WebPPictureRescale(WebPPicture* picture, int width, int height) { !RescalePlane(picture->v, HALVE(prev_width), HALVE(prev_height), picture->uv_stride, tmp.v, HALVE(width), HALVE(height), tmp.uv_stride, work, 1)) { - return 0; + return WebPEncodingSetError(picture, VP8_ENC_ERROR_BAD_DIMENSION); } AlphaMultiplyY(&tmp, 1); } else { work = (rescaler_t*)WebPSafeMalloc(2ULL * width * 4, sizeof(*work)); if (work == NULL) { WebPPictureFree(&tmp); - return 0; + return WebPEncodingSetError(picture, VP8_ENC_ERROR_OUT_OF_MEMORY); } // In order to correctly interpolate colors, we need to apply the alpha // weighting first (black-matting), scale the RGB values, and remove @@ -263,7 +267,7 @@ int WebPPictureRescale(WebPPicture* picture, int width, int height) { if (!RescalePlane((const uint8_t*)picture->argb, prev_width, prev_height, picture->argb_stride * 4, (uint8_t*)tmp.argb, width, height, tmp.argb_stride * 4, work, 4)) { - return 0; + return WebPEncodingSetError(picture, VP8_ENC_ERROR_BAD_DIMENSION); } AlphaMultiplyARGB(&tmp, 1); } diff --git a/thirdparty/libwebp/src/enc/syntax_enc.c b/thirdparty/libwebp/src/enc/syntax_enc.c index e18cf650ca..9b8f524d69 100644 --- a/thirdparty/libwebp/src/enc/syntax_enc.c +++ b/thirdparty/libwebp/src/enc/syntax_enc.c @@ -258,7 +258,10 @@ static int EmitPartitionsSize(const VP8Encoder* const enc, buf[3 * p + 1] = (part_size >> 8) & 0xff; buf[3 * p + 2] = (part_size >> 16) & 0xff; } - return p ? pic->writer(buf, 3 * p, pic) : 1; + if (p && !pic->writer(buf, 3 * p, pic)) { + return WebPEncodingSetError(pic, VP8_ENC_ERROR_BAD_WRITE); + } + return 1; } //------------------------------------------------------------------------------ @@ -381,6 +384,7 @@ int VP8EncWrite(VP8Encoder* const enc) { enc->coded_size_ = (int)(CHUNK_HEADER_SIZE + riff_size); ok = ok && WebPReportProgress(pic, final_percent, &enc->percent_); + if (!ok) WebPEncodingSetError(pic, VP8_ENC_ERROR_BAD_WRITE); return ok; } diff --git a/thirdparty/libwebp/src/enc/vp8i_enc.h b/thirdparty/libwebp/src/enc/vp8i_enc.h index c9927c47d8..19d9a6edb7 100644 --- a/thirdparty/libwebp/src/enc/vp8i_enc.h +++ b/thirdparty/libwebp/src/enc/vp8i_enc.h @@ -32,7 +32,7 @@ extern "C" { // version numbers #define ENC_MAJ_VERSION 1 #define ENC_MIN_VERSION 3 -#define ENC_REV_VERSION 0 +#define ENC_REV_VERSION 1 enum { MAX_LF_LEVELS = 64, // Maximum loop filter level MAX_VARIABLE_LEVEL = 67, // last (inclusive) level with variable cost diff --git a/thirdparty/libwebp/src/enc/vp8l_enc.c b/thirdparty/libwebp/src/enc/vp8l_enc.c index 0b07e529a9..3a8ec3dd1e 100644 --- a/thirdparty/libwebp/src/enc/vp8l_enc.c +++ b/thirdparty/libwebp/src/enc/vp8l_enc.c @@ -196,8 +196,7 @@ static int CoOccurrenceBuild(const WebPPicture* const pic, uint32_t palette_sorted[MAX_PALETTE_SIZE]; lines = (uint32_t*)WebPSafeMalloc(2 * pic->width, sizeof(*lines)); if (lines == NULL) { - WebPEncodingSetError(pic, VP8_ENC_ERROR_OUT_OF_MEMORY); - return 0; + return WebPEncodingSetError(pic, VP8_ENC_ERROR_OUT_OF_MEMORY); } line_top = &lines[0]; line_current = &lines[pic->width]; @@ -255,10 +254,10 @@ static int PaletteSortModifiedZeng( cooccurrence = (uint32_t*)WebPSafeCalloc(num_colors * num_colors, sizeof(*cooccurrence)); if (cooccurrence == NULL) { - WebPEncodingSetError(pic, VP8_ENC_ERROR_OUT_OF_MEMORY); - return 0; + return WebPEncodingSetError(pic, VP8_ENC_ERROR_OUT_OF_MEMORY); } if (!CoOccurrenceBuild(pic, palette_sorted, num_colors, cooccurrence)) { + WebPSafeFree(cooccurrence); return 0; } @@ -1012,8 +1011,7 @@ static int StoreImageToBitMask( VP8LRefsCursorNext(&c); } if (bw->error_) { - WebPEncodingSetError(pic, VP8_ENC_ERROR_OUT_OF_MEMORY); - return 0; + return WebPEncodingSetError(pic, VP8_ENC_ERROR_OUT_OF_MEMORY); } return 1; } @@ -1297,7 +1295,10 @@ static int EncodeImageInternal( } } tokens = (HuffmanTreeToken*)WebPSafeMalloc(max_tokens, sizeof(*tokens)); - if (tokens == NULL) goto Error; + if (tokens == NULL) { + WebPEncodingSetError(pic, VP8_ENC_ERROR_OUT_OF_MEMORY); + goto Error; + } for (i = 0; i < 5 * histogram_image_size; ++i) { HuffmanTreeCode* const codes = &huffman_codes[i]; StoreHuffmanCode(bw, huff_tree, tokens, codes); @@ -1448,18 +1449,21 @@ static int WriteImage(const WebPPicture* const pic, VP8LBitWriter* const bw, const size_t vp8l_size = VP8L_SIGNATURE_SIZE + webpll_size; const size_t pad = vp8l_size & 1; const size_t riff_size = TAG_SIZE + CHUNK_HEADER_SIZE + vp8l_size + pad; + *coded_size = 0; + + if (bw->error_) { + return WebPEncodingSetError(pic, VP8_ENC_ERROR_OUT_OF_MEMORY); + } if (!WriteRiffHeader(pic, riff_size, vp8l_size) || !pic->writer(webpll_data, webpll_size, pic)) { - WebPEncodingSetError(pic, VP8_ENC_ERROR_BAD_WRITE); - return 0; + return WebPEncodingSetError(pic, VP8_ENC_ERROR_BAD_WRITE); } if (pad) { const uint8_t pad_byte[1] = { 0 }; if (!pic->writer(pad_byte, 1, pic)) { - WebPEncodingSetError(pic, VP8_ENC_ERROR_BAD_WRITE); - return 0; + return WebPEncodingSetError(pic, VP8_ENC_ERROR_BAD_WRITE); } } *coded_size = CHUNK_HEADER_SIZE + riff_size; @@ -1504,8 +1508,7 @@ static int AllocateTransformBuffer(VP8LEncoder* const enc, int width, ClearTransformBuffer(enc); mem = (uint32_t*)WebPSafeMalloc(mem_size, sizeof(*mem)); if (mem == NULL) { - WebPEncodingSetError(enc->pic_, VP8_ENC_ERROR_OUT_OF_MEMORY); - return 0; + return WebPEncodingSetError(enc->pic_, VP8_ENC_ERROR_OUT_OF_MEMORY); } enc->transform_mem_ = mem; enc->transform_mem_size_ = (size_t)mem_size; @@ -1613,8 +1616,7 @@ static int ApplyPalette(const uint32_t* src, uint32_t src_stride, uint32_t* dst, int x, y; if (tmp_row == NULL) { - WebPEncodingSetError(pic, VP8_ENC_ERROR_OUT_OF_MEMORY); - return 0; + return WebPEncodingSetError(pic, VP8_ENC_ERROR_OUT_OF_MEMORY); } if (palette_size < APPLY_PALETTE_GREEDY_MAX) { @@ -1968,9 +1970,8 @@ int VP8LEncodeStream(const WebPConfig* const config, int ok_main; if (enc_main == NULL || !VP8LBitWriterInit(&bw_side, 0)) { - WebPEncodingSetError(picture, VP8_ENC_ERROR_OUT_OF_MEMORY); VP8LEncoderDelete(enc_main); - return 0; + return WebPEncodingSetError(picture, VP8_ENC_ERROR_OUT_OF_MEMORY); } // Avoid "garbage value" error from Clang's static analysis tool. @@ -2117,8 +2118,7 @@ int VP8LEncodeImage(const WebPConfig* const config, if (picture == NULL) return 0; if (config == NULL || picture->argb == NULL) { - WebPEncodingSetError(picture, VP8_ENC_ERROR_NULL_PARAMETER); - return 0; + return WebPEncodingSetError(picture, VP8_ENC_ERROR_NULL_PARAMETER); } width = picture->width; diff --git a/thirdparty/libwebp/src/enc/webp_enc.c b/thirdparty/libwebp/src/enc/webp_enc.c index 9620e05070..583fe6a8bb 100644 --- a/thirdparty/libwebp/src/enc/webp_enc.c +++ b/thirdparty/libwebp/src/enc/webp_enc.c @@ -307,7 +307,10 @@ int WebPEncodingSetError(const WebPPicture* const pic, WebPEncodingError error) { assert((int)error < VP8_ENC_ERROR_LAST); assert((int)error >= VP8_ENC_OK); - ((WebPPicture*)pic)->error_code = error; + // The oldest error reported takes precedence over the new one. + if (pic->error_code == VP8_ENC_OK) { + ((WebPPicture*)pic)->error_code = error; + } return 0; } @@ -317,8 +320,7 @@ int WebPReportProgress(const WebPPicture* const pic, *percent_store = percent; if (pic->progress_hook && !pic->progress_hook(percent, pic)) { // user abort requested - WebPEncodingSetError(pic, VP8_ENC_ERROR_USER_ABORT); - return 0; + return WebPEncodingSetError(pic, VP8_ENC_ERROR_USER_ABORT); } } return 1; // ok @@ -329,7 +331,7 @@ int WebPEncode(const WebPConfig* config, WebPPicture* pic) { int ok = 0; if (pic == NULL) return 0; - WebPEncodingSetError(pic, VP8_ENC_OK); // all ok so far + pic->error_code = VP8_ENC_OK; // all ok so far if (config == NULL) { // bad params return WebPEncodingSetError(pic, VP8_ENC_ERROR_NULL_PARAMETER); } |