diff options
author | RĂ©mi Verschelde <rverschelde@gmail.com> | 2017-02-26 20:13:31 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2017-02-26 20:13:31 +0100 |
commit | 0f12d0a9243c17c08ef4a5e2a5beb4d82a9f048d (patch) | |
tree | c49dcb94c5ba42e4542586f5a01adced30204552 /thirdparty/libwebp/dec | |
parent | a78c314b0ec48ef03da66d5de893c07e03523b90 (diff) | |
parent | 6de3defe7271441f6e55e1a0ed5e115a92a72606 (diff) |
Merge pull request #7827 from volzhs/libwebp-0.6.0
Update libwebp to 0.6.0
Diffstat (limited to 'thirdparty/libwebp/dec')
-rw-r--r-- | thirdparty/libwebp/dec/alpha_dec.c (renamed from thirdparty/libwebp/dec/alpha.c) | 8 | ||||
-rw-r--r-- | thirdparty/libwebp/dec/alphai_dec.h (renamed from thirdparty/libwebp/dec/alphai.h) | 4 | ||||
-rw-r--r-- | thirdparty/libwebp/dec/buffer_dec.c (renamed from thirdparty/libwebp/dec/buffer.c) | 4 | ||||
-rw-r--r-- | thirdparty/libwebp/dec/common_dec.h (renamed from thirdparty/libwebp/dec/common.h) | 0 | ||||
-rw-r--r-- | thirdparty/libwebp/dec/frame_dec.c (renamed from thirdparty/libwebp/dec/frame.c) | 4 | ||||
-rw-r--r-- | thirdparty/libwebp/dec/idec_dec.c (renamed from thirdparty/libwebp/dec/idec.c) | 6 | ||||
-rw-r--r-- | thirdparty/libwebp/dec/io_dec.c (renamed from thirdparty/libwebp/dec/io.c) | 113 | ||||
-rw-r--r-- | thirdparty/libwebp/dec/quant_dec.c (renamed from thirdparty/libwebp/dec/quant.c) | 2 | ||||
-rw-r--r-- | thirdparty/libwebp/dec/tree_dec.c (renamed from thirdparty/libwebp/dec/tree.c) | 7 | ||||
-rw-r--r-- | thirdparty/libwebp/dec/vp8_dec.c (renamed from thirdparty/libwebp/dec/vp8.c) | 72 | ||||
-rw-r--r-- | thirdparty/libwebp/dec/vp8_dec.h (renamed from thirdparty/libwebp/dec/decode_vp8.h) | 0 | ||||
-rw-r--r-- | thirdparty/libwebp/dec/vp8i_dec.h (renamed from thirdparty/libwebp/dec/vp8i.h) | 14 | ||||
-rw-r--r-- | thirdparty/libwebp/dec/vp8l_dec.c (renamed from thirdparty/libwebp/dec/vp8l.c) | 37 | ||||
-rw-r--r-- | thirdparty/libwebp/dec/vp8li_dec.h (renamed from thirdparty/libwebp/dec/vp8li.h) | 8 | ||||
-rw-r--r-- | thirdparty/libwebp/dec/webp_dec.c (renamed from thirdparty/libwebp/dec/webp.c) | 17 | ||||
-rw-r--r-- | thirdparty/libwebp/dec/webpi_dec.h (renamed from thirdparty/libwebp/dec/webpi.h) | 17 |
16 files changed, 195 insertions, 118 deletions
diff --git a/thirdparty/libwebp/dec/alpha.c b/thirdparty/libwebp/dec/alpha_dec.c index d88f01d8de..83ffd4b609 100644 --- a/thirdparty/libwebp/dec/alpha.c +++ b/thirdparty/libwebp/dec/alpha_dec.c @@ -12,11 +12,11 @@ // Author: Skal (pascal.massimino@gmail.com) #include <stdlib.h> -#include "./alphai.h" -#include "./vp8i.h" -#include "./vp8li.h" +#include "./alphai_dec.h" +#include "./vp8i_dec.h" +#include "./vp8li_dec.h" #include "../dsp/dsp.h" -#include "../utils/quant_levels_dec.h" +#include "../utils/quant_levels_dec_utils.h" #include "../utils/utils.h" #include "../webp/format_constants.h" diff --git a/thirdparty/libwebp/dec/alphai.h b/thirdparty/libwebp/dec/alphai_dec.h index 69dd7c0f5d..561e8151ee 100644 --- a/thirdparty/libwebp/dec/alphai.h +++ b/thirdparty/libwebp/dec/alphai_dec.h @@ -14,8 +14,8 @@ #ifndef WEBP_DEC_ALPHAI_H_ #define WEBP_DEC_ALPHAI_H_ -#include "./webpi.h" -#include "../utils/filters.h" +#include "./webpi_dec.h" +#include "../utils/filters_utils.h" #ifdef __cplusplus extern "C" { diff --git a/thirdparty/libwebp/dec/buffer.c b/thirdparty/libwebp/dec/buffer_dec.c index 547e69b434..c685fd5646 100644 --- a/thirdparty/libwebp/dec/buffer.c +++ b/thirdparty/libwebp/dec/buffer_dec.c @@ -13,8 +13,8 @@ #include <stdlib.h> -#include "./vp8i.h" -#include "./webpi.h" +#include "./vp8i_dec.h" +#include "./webpi_dec.h" #include "../utils/utils.h" //------------------------------------------------------------------------------ diff --git a/thirdparty/libwebp/dec/common.h b/thirdparty/libwebp/dec/common_dec.h index 6961e22470..6961e22470 100644 --- a/thirdparty/libwebp/dec/common.h +++ b/thirdparty/libwebp/dec/common_dec.h diff --git a/thirdparty/libwebp/dec/frame.c b/thirdparty/libwebp/dec/frame_dec.c index 22d291d2cd..f91e27f7c8 100644 --- a/thirdparty/libwebp/dec/frame.c +++ b/thirdparty/libwebp/dec/frame_dec.c @@ -12,7 +12,7 @@ // Author: Skal (pascal.massimino@gmail.com) #include <stdlib.h> -#include "./vp8i.h" +#include "./vp8i_dec.h" #include "../utils/utils.h" //------------------------------------------------------------------------------ @@ -723,7 +723,7 @@ static int AllocateMemory(VP8Decoder* const dec) { return VP8SetError(dec, VP8_STATUS_OUT_OF_MEMORY, "no memory during frame initialization."); } - // down-cast is ok, thanks to WebPSafeAlloc() above. + // down-cast is ok, thanks to WebPSafeMalloc() above. dec->mem_size_ = (size_t)needed; } diff --git a/thirdparty/libwebp/dec/idec.c b/thirdparty/libwebp/dec/idec_dec.c index 8de131916e..78fb2e7186 100644 --- a/thirdparty/libwebp/dec/idec.c +++ b/thirdparty/libwebp/dec/idec_dec.c @@ -15,9 +15,9 @@ #include <string.h> #include <stdlib.h> -#include "./alphai.h" -#include "./webpi.h" -#include "./vp8i.h" +#include "./alphai_dec.h" +#include "./webpi_dec.h" +#include "./vp8i_dec.h" #include "../utils/utils.h" // In append mode, buffer allocations increase as multiples of this value. diff --git a/thirdparty/libwebp/dec/io.c b/thirdparty/libwebp/dec/io_dec.c index 8d5c43f325..8bfab86959 100644 --- a/thirdparty/libwebp/dec/io.c +++ b/thirdparty/libwebp/dec/io_dec.c @@ -13,8 +13,8 @@ #include <assert.h> #include <stdlib.h> -#include "../dec/vp8i.h" -#include "./webpi.h" +#include "../dec/vp8i_dec.h" +#include "./webpi_dec.h" #include "../dsp/dsp.h" #include "../dsp/yuv.h" #include "../utils/utils.h" @@ -256,7 +256,7 @@ static int Rescale(const uint8_t* src, int src_stride, static int EmitRescaledYUV(const VP8Io* const io, WebPDecParams* const p) { const int mb_h = io->mb_h; const int uv_mb_h = (mb_h + 1) >> 1; - WebPRescaler* const scaler = &p->scaler_y; + WebPRescaler* const scaler = p->scaler_y; int num_lines_out = 0; if (WebPIsAlphaMode(p->output->colorspace) && io->a != NULL) { // Before rescaling, we premultiply the luma directly into the io->y @@ -267,29 +267,28 @@ static int EmitRescaledYUV(const VP8Io* const io, WebPDecParams* const p) { io->a, io->width, io->mb_w, mb_h, 0); } num_lines_out = Rescale(io->y, io->y_stride, mb_h, scaler); - Rescale(io->u, io->uv_stride, uv_mb_h, &p->scaler_u); - Rescale(io->v, io->uv_stride, uv_mb_h, &p->scaler_v); + Rescale(io->u, io->uv_stride, uv_mb_h, p->scaler_u); + Rescale(io->v, io->uv_stride, uv_mb_h, p->scaler_v); return num_lines_out; } static int EmitRescaledAlphaYUV(const VP8Io* const io, WebPDecParams* const p, int expected_num_lines_out) { const WebPYUVABuffer* const buf = &p->output->u.YUVA; + uint8_t* const dst_a = buf->a + p->last_y * buf->a_stride; if (io->a != NULL) { - uint8_t* dst_y = buf->y + p->last_y * buf->y_stride; - const uint8_t* src_a = buf->a + p->last_y * buf->a_stride; - const int num_lines_out = Rescale(io->a, io->width, io->mb_h, &p->scaler_a); - (void)expected_num_lines_out; + uint8_t* const dst_y = buf->y + p->last_y * buf->y_stride; + const int num_lines_out = Rescale(io->a, io->width, io->mb_h, p->scaler_a); assert(expected_num_lines_out == num_lines_out); if (num_lines_out > 0) { // unmultiply the Y - WebPMultRows(dst_y, buf->y_stride, src_a, buf->a_stride, - p->scaler_a.dst_width, num_lines_out, 1); + WebPMultRows(dst_y, buf->y_stride, dst_a, buf->a_stride, + p->scaler_a->dst_width, num_lines_out, 1); } } else if (buf->a != NULL) { // the user requested alpha, but there is none, set it to opaque. assert(p->last_y + expected_num_lines_out <= io->scaled_height); - FillAlphaPlane(buf->a + p->last_y * buf->a_stride, - io->scaled_width, expected_num_lines_out, buf->a_stride); + FillAlphaPlane(dst_a, io->scaled_width, expected_num_lines_out, + buf->a_stride); } return 0; } @@ -305,31 +304,42 @@ static int InitYUVRescaler(const VP8Io* const io, WebPDecParams* const p) { const int uv_in_height = (io->mb_h + 1) >> 1; const size_t work_size = 2 * out_width; // scratch memory for luma rescaler const size_t uv_work_size = 2 * uv_out_width; // and for each u/v ones - size_t tmp_size; + size_t tmp_size, rescaler_size; rescaler_t* work; + WebPRescaler* scalers; + const int num_rescalers = has_alpha ? 4 : 3; tmp_size = (work_size + 2 * uv_work_size) * sizeof(*work); if (has_alpha) { tmp_size += work_size * sizeof(*work); } - p->memory = WebPSafeMalloc(1ULL, tmp_size); + rescaler_size = num_rescalers * sizeof(*p->scaler_y) + WEBP_ALIGN_CST; + + p->memory = WebPSafeMalloc(1ULL, tmp_size + rescaler_size); if (p->memory == NULL) { return 0; // memory error } work = (rescaler_t*)p->memory; - WebPRescalerInit(&p->scaler_y, io->mb_w, io->mb_h, + + scalers = (WebPRescaler*)WEBP_ALIGN((const uint8_t*)work + tmp_size); + p->scaler_y = &scalers[0]; + p->scaler_u = &scalers[1]; + p->scaler_v = &scalers[2]; + p->scaler_a = has_alpha ? &scalers[3] : NULL; + + WebPRescalerInit(p->scaler_y, io->mb_w, io->mb_h, buf->y, out_width, out_height, buf->y_stride, 1, work); - WebPRescalerInit(&p->scaler_u, uv_in_width, uv_in_height, + WebPRescalerInit(p->scaler_u, uv_in_width, uv_in_height, buf->u, uv_out_width, uv_out_height, buf->u_stride, 1, work + work_size); - WebPRescalerInit(&p->scaler_v, uv_in_width, uv_in_height, + WebPRescalerInit(p->scaler_v, uv_in_width, uv_in_height, buf->v, uv_out_width, uv_out_height, buf->v_stride, 1, work + work_size + uv_work_size); p->emit = EmitRescaledYUV; if (has_alpha) { - WebPRescalerInit(&p->scaler_a, io->mb_w, io->mb_h, + WebPRescalerInit(p->scaler_a, io->mb_w, io->mb_h, buf->a, out_width, out_height, buf->a_stride, 1, work + work_size + 2 * uv_work_size); p->emit_alpha = EmitRescaledAlphaYUV; @@ -349,15 +359,15 @@ static int ExportRGB(WebPDecParams* const p, int y_pos) { int num_lines_out = 0; // For RGB rescaling, because of the YUV420, current scan position // U/V can be +1/-1 line from the Y one. Hence the double test. - while (WebPRescalerHasPendingOutput(&p->scaler_y) && - WebPRescalerHasPendingOutput(&p->scaler_u)) { + while (WebPRescalerHasPendingOutput(p->scaler_y) && + WebPRescalerHasPendingOutput(p->scaler_u)) { assert(y_pos + num_lines_out < p->output->height); - assert(p->scaler_u.y_accum == p->scaler_v.y_accum); - WebPRescalerExportRow(&p->scaler_y); - WebPRescalerExportRow(&p->scaler_u); - WebPRescalerExportRow(&p->scaler_v); - convert(p->scaler_y.dst, p->scaler_u.dst, p->scaler_v.dst, - dst, p->scaler_y.dst_width); + assert(p->scaler_u->y_accum == p->scaler_v->y_accum); + WebPRescalerExportRow(p->scaler_y); + WebPRescalerExportRow(p->scaler_u); + WebPRescalerExportRow(p->scaler_v); + convert(p->scaler_y->dst, p->scaler_u->dst, p->scaler_v->dst, + dst, p->scaler_y->dst_width); dst += buf->stride; ++num_lines_out; } @@ -371,15 +381,15 @@ static int EmitRescaledRGB(const VP8Io* const io, WebPDecParams* const p) { int num_lines_out = 0; while (j < mb_h) { const int y_lines_in = - WebPRescalerImport(&p->scaler_y, mb_h - j, + WebPRescalerImport(p->scaler_y, mb_h - j, io->y + j * io->y_stride, io->y_stride); j += y_lines_in; - if (WebPRescaleNeededLines(&p->scaler_u, uv_mb_h - uv_j)) { + if (WebPRescaleNeededLines(p->scaler_u, uv_mb_h - uv_j)) { const int u_lines_in = - WebPRescalerImport(&p->scaler_u, uv_mb_h - uv_j, + WebPRescalerImport(p->scaler_u, uv_mb_h - uv_j, io->u + uv_j * io->uv_stride, io->uv_stride); const int v_lines_in = - WebPRescalerImport(&p->scaler_v, uv_mb_h - uv_j, + WebPRescalerImport(p->scaler_v, uv_mb_h - uv_j, io->v + uv_j * io->uv_stride, io->uv_stride); (void)v_lines_in; // remove a gcc warning assert(u_lines_in == v_lines_in); @@ -400,13 +410,13 @@ static int ExportAlpha(WebPDecParams* const p, int y_pos, int max_lines_out) { int num_lines_out = 0; const int is_premult_alpha = WebPIsPremultipliedMode(colorspace); uint32_t non_opaque = 0; - const int width = p->scaler_a.dst_width; + const int width = p->scaler_a->dst_width; - while (WebPRescalerHasPendingOutput(&p->scaler_a) && + while (WebPRescalerHasPendingOutput(p->scaler_a) && num_lines_out < max_lines_out) { assert(y_pos + num_lines_out < p->output->height); - WebPRescalerExportRow(&p->scaler_a); - non_opaque |= WebPDispatchAlpha(p->scaler_a.dst, 0, width, 1, dst, 0); + WebPRescalerExportRow(p->scaler_a); + non_opaque |= WebPDispatchAlpha(p->scaler_a->dst, 0, width, 1, dst, 0); dst += buf->stride; ++num_lines_out; } @@ -428,18 +438,18 @@ static int ExportAlphaRGBA4444(WebPDecParams* const p, int y_pos, #endif int num_lines_out = 0; const WEBP_CSP_MODE colorspace = p->output->colorspace; - const int width = p->scaler_a.dst_width; + const int width = p->scaler_a->dst_width; const int is_premult_alpha = WebPIsPremultipliedMode(colorspace); uint32_t alpha_mask = 0x0f; - while (WebPRescalerHasPendingOutput(&p->scaler_a) && + while (WebPRescalerHasPendingOutput(p->scaler_a) && num_lines_out < max_lines_out) { int i; assert(y_pos + num_lines_out < p->output->height); - WebPRescalerExportRow(&p->scaler_a); + WebPRescalerExportRow(p->scaler_a); for (i = 0; i < width; ++i) { // Fill in the alpha value (converted to 4 bits). - const uint32_t alpha_value = p->scaler_a.dst[i] >> 4; + const uint32_t alpha_value = p->scaler_a->dst[i] >> 4; alpha_dst[2 * i] = (alpha_dst[2 * i] & 0xf0) | alpha_value; alpha_mask &= alpha_value; } @@ -455,7 +465,7 @@ static int ExportAlphaRGBA4444(WebPDecParams* const p, int y_pos, static int EmitRescaledAlphaRGB(const VP8Io* const io, WebPDecParams* const p, int expected_num_out_lines) { if (io->a != NULL) { - WebPRescaler* const scaler = &p->scaler_a; + WebPRescaler* const scaler = p->scaler_a; int lines_left = expected_num_out_lines; const int y_end = p->last_y + lines_left; while (lines_left > 0) { @@ -477,7 +487,9 @@ static int InitRGBRescaler(const VP8Io* const io, WebPDecParams* const p) { const size_t work_size = 2 * out_width; // scratch memory for one rescaler rescaler_t* work; // rescalers work area uint8_t* tmp; // tmp storage for scaled YUV444 samples before RGB conversion - size_t tmp_size1, tmp_size2, total_size; + size_t tmp_size1, tmp_size2, total_size, rescaler_size; + WebPRescaler* scalers; + const int num_rescalers = has_alpha ? 4 : 3; tmp_size1 = 3 * work_size; tmp_size2 = 3 * out_width; @@ -486,26 +498,35 @@ static int InitRGBRescaler(const VP8Io* const io, WebPDecParams* const p) { tmp_size2 += out_width; } total_size = tmp_size1 * sizeof(*work) + tmp_size2 * sizeof(*tmp); - p->memory = WebPSafeMalloc(1ULL, total_size); + rescaler_size = num_rescalers * sizeof(*p->scaler_y) + WEBP_ALIGN_CST; + + p->memory = WebPSafeMalloc(1ULL, total_size + rescaler_size); if (p->memory == NULL) { return 0; // memory error } work = (rescaler_t*)p->memory; tmp = (uint8_t*)(work + tmp_size1); - WebPRescalerInit(&p->scaler_y, io->mb_w, io->mb_h, + + scalers = (WebPRescaler*)WEBP_ALIGN((const uint8_t*)work + total_size); + p->scaler_y = &scalers[0]; + p->scaler_u = &scalers[1]; + p->scaler_v = &scalers[2]; + p->scaler_a = has_alpha ? &scalers[3] : NULL; + + WebPRescalerInit(p->scaler_y, io->mb_w, io->mb_h, tmp + 0 * out_width, out_width, out_height, 0, 1, work + 0 * work_size); - WebPRescalerInit(&p->scaler_u, uv_in_width, uv_in_height, + WebPRescalerInit(p->scaler_u, uv_in_width, uv_in_height, tmp + 1 * out_width, out_width, out_height, 0, 1, work + 1 * work_size); - WebPRescalerInit(&p->scaler_v, uv_in_width, uv_in_height, + WebPRescalerInit(p->scaler_v, uv_in_width, uv_in_height, tmp + 2 * out_width, out_width, out_height, 0, 1, work + 2 * work_size); p->emit = EmitRescaledRGB; WebPInitYUV444Converters(); if (has_alpha) { - WebPRescalerInit(&p->scaler_a, io->mb_w, io->mb_h, + WebPRescalerInit(p->scaler_a, io->mb_w, io->mb_h, tmp + 3 * out_width, out_width, out_height, 0, 1, work + 3 * work_size); p->emit_alpha = EmitRescaledAlphaRGB; diff --git a/thirdparty/libwebp/dec/quant.c b/thirdparty/libwebp/dec/quant_dec.c index 5b648f942c..14e3198946 100644 --- a/thirdparty/libwebp/dec/quant.c +++ b/thirdparty/libwebp/dec/quant_dec.c @@ -11,7 +11,7 @@ // // Author: Skal (pascal.massimino@gmail.com) -#include "./vp8i.h" +#include "./vp8i_dec.h" static WEBP_INLINE int clip(int v, int M) { return v < 0 ? 0 : v > M ? M : v; diff --git a/thirdparty/libwebp/dec/tree.c b/thirdparty/libwebp/dec/tree_dec.c index c2007ea733..9e805f60f3 100644 --- a/thirdparty/libwebp/dec/tree.c +++ b/thirdparty/libwebp/dec/tree_dec.c @@ -11,10 +11,13 @@ // // Author: Skal (pascal.massimino@gmail.com) -#include "./vp8i.h" -#include "../utils/bit_reader_inl.h" +#include "./vp8i_dec.h" +#include "../utils/bit_reader_inl_utils.h" +#if !defined(__arm__) && !defined(_M_ARM) && !defined(__aarch64__) +// using a table is ~1-2% slower on ARM. Prefer the coded-tree approach then. #define USE_GENERIC_TREE +#endif #ifdef USE_GENERIC_TREE static const int8_t kYModesIntra4[18] = { diff --git a/thirdparty/libwebp/dec/vp8.c b/thirdparty/libwebp/dec/vp8_dec.c index 336680c38c..fad8d9cf35 100644 --- a/thirdparty/libwebp/dec/vp8.c +++ b/thirdparty/libwebp/dec/vp8_dec.c @@ -13,11 +13,11 @@ #include <stdlib.h> -#include "./alphai.h" -#include "./vp8i.h" -#include "./vp8li.h" -#include "./webpi.h" -#include "../utils/bit_reader_inl.h" +#include "./alphai_dec.h" +#include "./vp8i_dec.h" +#include "./vp8li_dec.h" +#include "./webpi_dec.h" +#include "../utils/bit_reader_inl_utils.h" #include "../utils/utils.h" //------------------------------------------------------------------------------ @@ -27,6 +27,16 @@ int WebPGetDecoderVersion(void) { } //------------------------------------------------------------------------------ +// Signature and pointer-to-function for GetCoeffs() variants below. + +typedef int (*GetCoeffsFunc)(VP8BitReader* const br, + const VP8BandProbas* const prob[], + int ctx, const quant_t dq, int n, int16_t* out); +static volatile GetCoeffsFunc GetCoeffs = NULL; + +static void InitGetCoeffs(void); + +//------------------------------------------------------------------------------ // VP8Decoder static void SetOk(VP8Decoder* const dec) { @@ -51,6 +61,7 @@ VP8Decoder* VP8New(void) { WebPGetWorkerInterface()->Init(&dec->worker_); dec->ready_ = 0; dec->num_parts_minus_one_ = 0; + InitGetCoeffs(); } return dec; } @@ -273,12 +284,14 @@ int VP8GetHeaders(VP8Decoder* const dec, VP8Io* const io) { frm_hdr->profile_ = (bits >> 1) & 7; frm_hdr->show_ = (bits >> 4) & 1; frm_hdr->partition_length_ = (bits >> 5); - if (frm_hdr->profile_ > 3) + if (frm_hdr->profile_ > 3) { return VP8SetError(dec, VP8_STATUS_BITSTREAM_ERROR, "Incorrect keyframe parameters."); - if (!frm_hdr->show_) + } + if (!frm_hdr->show_) { return VP8SetError(dec, VP8_STATUS_UNSUPPORTED_FEATURE, "Frame not displayable."); + } buf += 3; buf_size -= 3; } @@ -420,8 +433,9 @@ static int GetLargeValue(VP8BitReader* const br, const uint8_t* const p) { } // Returns the position of the last non-zero coeff plus one -static int GetCoeffs(VP8BitReader* const br, const VP8BandProbas* const prob[], - int ctx, const quant_t dq, int n, int16_t* out) { +static int GetCoeffsFast(VP8BitReader* const br, + const VP8BandProbas* const prob[], + int ctx, const quant_t dq, int n, int16_t* out) { const uint8_t* p = prob[n]->probas_[ctx]; for (; n < 16; ++n) { if (!VP8GetBit(br, p[0])) { @@ -447,6 +461,46 @@ static int GetCoeffs(VP8BitReader* const br, const VP8BandProbas* const prob[], return 16; } +// This version of GetCoeffs() uses VP8GetBitAlt() which is an alternate version +// of VP8GetBitAlt() targeting specific platforms. +static int GetCoeffsAlt(VP8BitReader* const br, + const VP8BandProbas* const prob[], + int ctx, const quant_t dq, int n, int16_t* out) { + const uint8_t* p = prob[n]->probas_[ctx]; + for (; n < 16; ++n) { + if (!VP8GetBitAlt(br, p[0])) { + return n; // previous coeff was last non-zero coeff + } + while (!VP8GetBitAlt(br, p[1])) { // sequence of zero coeffs + p = prob[++n]->probas_[0]; + if (n == 16) return 16; + } + { // non zero coeff + const VP8ProbaArray* const p_ctx = &prob[n + 1]->probas_[0]; + int v; + if (!VP8GetBitAlt(br, p[2])) { + v = 1; + p = p_ctx[1]; + } else { + v = GetLargeValue(br, p); + p = p_ctx[2]; + } + out[kZigzag[n]] = VP8GetSigned(br, v) * dq[n > 0]; + } + } + return 16; +} + +WEBP_TSAN_IGNORE_FUNCTION static void InitGetCoeffs(void) { + if (GetCoeffs == NULL) { + if (VP8GetCPUInfo != NULL && VP8GetCPUInfo(kSlowSSSE3)) { + GetCoeffs = GetCoeffsAlt; + } else { + GetCoeffs = GetCoeffsFast; + } + } +} + static WEBP_INLINE uint32_t NzCodeBits(uint32_t nz_coeffs, int nz, int dc_nz) { nz_coeffs <<= 2; nz_coeffs |= (nz > 3) ? 3 : (nz > 1) ? 2 : dc_nz; diff --git a/thirdparty/libwebp/dec/decode_vp8.h b/thirdparty/libwebp/dec/vp8_dec.h index b9337bbec0..b9337bbec0 100644 --- a/thirdparty/libwebp/dec/decode_vp8.h +++ b/thirdparty/libwebp/dec/vp8_dec.h diff --git a/thirdparty/libwebp/dec/vp8i.h b/thirdparty/libwebp/dec/vp8i_dec.h index 313d8a7b94..555853e8f8 100644 --- a/thirdparty/libwebp/dec/vp8i.h +++ b/thirdparty/libwebp/dec/vp8i_dec.h @@ -15,11 +15,11 @@ #define WEBP_DEC_VP8I_H_ #include <string.h> // for memcpy() -#include "./common.h" -#include "./vp8li.h" -#include "../utils/bit_reader.h" -#include "../utils/random.h" -#include "../utils/thread.h" +#include "./common_dec.h" +#include "./vp8li_dec.h" +#include "../utils/bit_reader_utils.h" +#include "../utils/random_utils.h" +#include "../utils/thread_utils.h" #include "../dsp/dsp.h" #ifdef __cplusplus @@ -31,8 +31,8 @@ extern "C" { // version numbers #define DEC_MAJ_VERSION 0 -#define DEC_MIN_VERSION 5 -#define DEC_REV_VERSION 2 +#define DEC_MIN_VERSION 6 +#define DEC_REV_VERSION 0 // YUV-cache parameters. Cache is 32-bytes wide (= one cacheline). // Constraints are: We need to store one 16x16 block of luma samples (y), diff --git a/thirdparty/libwebp/dec/vp8l.c b/thirdparty/libwebp/dec/vp8l_dec.c index cb2e3176b6..ef359a91f0 100644 --- a/thirdparty/libwebp/dec/vp8l.c +++ b/thirdparty/libwebp/dec/vp8l_dec.c @@ -14,13 +14,14 @@ #include <stdlib.h> -#include "./alphai.h" -#include "./vp8li.h" +#include "./alphai_dec.h" +#include "./vp8li_dec.h" #include "../dsp/dsp.h" #include "../dsp/lossless.h" +#include "../dsp/lossless_common.h" #include "../dsp/yuv.h" -#include "../utils/endian_inl.h" -#include "../utils/huffman.h" +#include "../utils/endian_inl_utils.h" +#include "../utils/huffman_utils.h" #include "../utils/utils.h" #define NUM_ARGB_CACHE_ROWS 16 @@ -547,11 +548,14 @@ static int EmitRescaledRowsRGBA(const VP8LDecoder* const dec, uint8_t* const row_out = out + num_lines_out * out_stride; const int lines_left = mb_h - num_lines_in; const int needed_lines = WebPRescaleNeededLines(dec->rescaler, lines_left); + int lines_imported; assert(needed_lines > 0 && needed_lines <= lines_left); WebPMultARGBRows(row_in, in_stride, dec->rescaler->src_width, needed_lines, 0); - WebPRescalerImport(dec->rescaler, lines_left, row_in, in_stride); - num_lines_in += needed_lines; + lines_imported = + WebPRescalerImport(dec->rescaler, lines_left, row_in, in_stride); + assert(lines_imported == needed_lines); + num_lines_in += lines_imported; num_lines_out += Export(dec->rescaler, colorspace, out_stride, row_out); } return num_lines_out; @@ -623,9 +627,12 @@ static int EmitRescaledRowsYUVA(const VP8LDecoder* const dec, while (num_lines_in < mb_h) { const int lines_left = mb_h - num_lines_in; const int needed_lines = WebPRescaleNeededLines(dec->rescaler, lines_left); + int lines_imported; WebPMultARGBRows(in, in_stride, dec->rescaler->src_width, needed_lines, 0); - WebPRescalerImport(dec->rescaler, lines_left, in, in_stride); - num_lines_in += needed_lines; + lines_imported = + WebPRescalerImport(dec->rescaler, lines_left, in, in_stride); + assert(lines_imported == needed_lines); + num_lines_in += lines_imported; in += needed_lines * in_stride; y_pos += ExportYUVA(dec, y_pos); } @@ -705,13 +712,15 @@ static void ApplyInverseTransforms(VP8LDecoder* const dec, int num_rows, uint32_t* const rows_out = dec->argb_cache_; // Inverse transforms. - // TODO: most transforms only need to operate on the cropped region only. - memcpy(rows_out, rows_in, cache_pixs * sizeof(*rows_out)); while (n-- > 0) { VP8LTransform* const transform = &dec->transforms_[n]; VP8LInverseTransform(transform, start_row, end_row, rows_in, rows_out); rows_in = rows_out; } + if (rows_in != rows_out) { + // No transform called, hence just copy. + memcpy(rows_out, rows_in, cache_pixs * sizeof(*rows_out)); + } } // Processes (transforms, scales & color-converts) the rows decoded after the @@ -1210,8 +1219,9 @@ static int ExpandColorMap(int num_colors, VP8LTransform* const transform) { // Equivalent to AddPixelEq(), on a byte-basis. new_data[i] = (data[i] + new_data[i - 4]) & 0xff; } - for (; i < 4 * final_num_colors; ++i) + for (; i < 4 * final_num_colors; ++i) { new_data[i] = 0; // black tail. + } WebPSafeFree(transform->data_); transform->data_ = new_color_map; } @@ -1482,9 +1492,8 @@ static void ExtractAlphaRows(VP8LDecoder* const dec, int last_row) { const int cache_pixs = width * num_rows_to_process; uint8_t* const dst = output + width * cur_row; const uint32_t* const src = dec->argb_cache_; - int i; ApplyInverseTransforms(dec, num_rows_to_process, in); - for (i = 0; i < cache_pixs; ++i) dst[i] = (src[i] >> 8) & 0xff; + WebPExtractGreen(src, dst, cache_pixs); AlphaApplyFilter(alph_dec, cur_row, cur_row + num_rows_to_process, dst, width); num_rows -= num_rows_to_process; @@ -1552,6 +1561,8 @@ int VP8LDecodeAlphaImageStream(ALPHDecoder* const alph_dec, int last_row) { return 1; // done } + if (!alph_dec->use_8b_decode_) WebPInitAlphaProcessing(); + // Decode (with special row processing). return alph_dec->use_8b_decode_ ? DecodeAlphaData(dec, (uint8_t*)dec->pixels_, dec->width_, dec->height_, diff --git a/thirdparty/libwebp/dec/vp8li.h b/thirdparty/libwebp/dec/vp8li_dec.h index 9313bdc0af..097a9d0589 100644 --- a/thirdparty/libwebp/dec/vp8li.h +++ b/thirdparty/libwebp/dec/vp8li_dec.h @@ -16,10 +16,10 @@ #define WEBP_DEC_VP8LI_H_ #include <string.h> // for memcpy() -#include "./webpi.h" -#include "../utils/bit_reader.h" -#include "../utils/color_cache.h" -#include "../utils/huffman.h" +#include "./webpi_dec.h" +#include "../utils/bit_reader_utils.h" +#include "../utils/color_cache_utils.h" +#include "../utils/huffman_utils.h" #ifdef __cplusplus extern "C" { diff --git a/thirdparty/libwebp/dec/webp.c b/thirdparty/libwebp/dec/webp_dec.c index d0b912f02f..a8e9c2c510 100644 --- a/thirdparty/libwebp/dec/webp.c +++ b/thirdparty/libwebp/dec/webp_dec.c @@ -13,9 +13,9 @@ #include <stdlib.h> -#include "./vp8i.h" -#include "./vp8li.h" -#include "./webpi.h" +#include "./vp8i_dec.h" +#include "./vp8li_dec.h" +#include "./webpi_dec.h" #include "../utils/utils.h" #include "../webp/mux_types.h" // ALPHA_FLAG @@ -39,8 +39,8 @@ // 20..23 VP8X flags bit-map corresponding to the chunk-types present. // 24..26 Width of the Canvas Image. // 27..29 Height of the Canvas Image. -// There can be extra chunks after the "VP8X" chunk (ICCP, FRGM, ANMF, VP8, -// VP8L, XMP, EXIF ...) +// There can be extra chunks after the "VP8X" chunk (ICCP, ANMF, VP8, VP8L, +// XMP, EXIF ...) // All sizes are in little-endian order. // Note: chunk data size must be padded to multiple of 2 when written. @@ -289,7 +289,6 @@ static VP8StatusCode ParseHeadersInternal(const uint8_t* data, int found_riff = 0; int found_vp8x = 0; int animation_present = 0; - int fragments_present = 0; const int have_all_data = (headers != NULL) ? headers->have_all_data : 0; VP8StatusCode status; @@ -318,7 +317,6 @@ static VP8StatusCode ParseHeadersInternal(const uint8_t* data, return status; // Wrong VP8X / insufficient data. } animation_present = !!(flags & ANIMATION_FLAG); - fragments_present = !!(flags & FRAGMENTS_FLAG); if (!found_riff && found_vp8x) { // Note: This restriction may be removed in the future, if it becomes // necessary to send VP8X chunk to the decoder. @@ -330,8 +328,7 @@ static VP8StatusCode ParseHeadersInternal(const uint8_t* data, image_width = canvas_width; image_height = canvas_height; - if (found_vp8x && (animation_present || fragments_present) && - headers == NULL) { + if (found_vp8x && animation_present && headers == NULL) { status = VP8_STATUS_OK; goto ReturnWidthHeight; // Just return features from VP8X header. } @@ -362,7 +359,7 @@ static VP8StatusCode ParseHeadersInternal(const uint8_t* data, return VP8_STATUS_BITSTREAM_ERROR; } - if (format != NULL && !(animation_present || fragments_present)) { + if (format != NULL && !animation_present) { *format = hdrs.is_lossless ? 2 : 1; } diff --git a/thirdparty/libwebp/dec/webpi.h b/thirdparty/libwebp/dec/webpi_dec.h index 991b194c22..696abc1958 100644 --- a/thirdparty/libwebp/dec/webpi.h +++ b/thirdparty/libwebp/dec/webpi_dec.h @@ -18,8 +18,8 @@ extern "C" { #endif -#include "../utils/rescaler.h" -#include "./decode_vp8.h" +#include "../utils/rescaler_utils.h" +#include "./vp8_dec.h" //------------------------------------------------------------------------------ // WebPDecParams: Decoding output parameters. Transient internal object. @@ -38,27 +38,18 @@ struct WebPDecParams { int last_y; // coordinate of the line that was last output const WebPDecoderOptions* options; // if not NULL, use alt decoding features - // rescalers - WebPRescaler scaler_y, scaler_u, scaler_v, scaler_a; + + WebPRescaler* scaler_y, *scaler_u, *scaler_v, *scaler_a; // rescalers void* memory; // overall scratch memory for the output work. OutputFunc emit; // output RGB or YUV samples OutputAlphaFunc emit_alpha; // output alpha channel OutputRowFunc emit_alpha_row; // output one line of rescaled alpha values - - WebPDecBuffer* final_output; // In case the user supplied a slow-memory - // output, we decode image in temporary buffer - // (this::output) and copy it here. - WebPDecBuffer tmp_buffer; // this::output will point to this one in case - // of slow memory. }; // Should be called first, before any use of the WebPDecParams object. void WebPResetDecParams(WebPDecParams* const params); -// Delete all memory (after an error occurred, for instance) -void WebPFreeDecParams(WebPDecParams* const params); - //------------------------------------------------------------------------------ // Header parsing helpers |