Skip to content

Commit 5d499a1

Browse files
authored
Merge pull request opencv#19658 from alalek:update_libwebp
* 3rdparty: update libwebp 1.1.0 => 1.2.0 - https://github.com/webmproject/libwebp/releases/tag/v1.2.0 * 3rdparty(libwebp): re-apply OpenCV patches
1 parent 19865a2 commit 5d499a1

33 files changed

+630
-614
lines changed

3rdparty/libwebp/src/dec/io_dec.c

Lines changed: 24 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -25,29 +25,24 @@
2525
static int EmitYUV(const VP8Io* const io, WebPDecParams* const p) {
2626
WebPDecBuffer* output = p->output;
2727
const WebPYUVABuffer* const buf = &output->u.YUVA;
28-
uint8_t* const y_dst = buf->y + io->mb_y * buf->y_stride;
29-
uint8_t* const u_dst = buf->u + (io->mb_y >> 1) * buf->u_stride;
30-
uint8_t* const v_dst = buf->v + (io->mb_y >> 1) * buf->v_stride;
28+
uint8_t* const y_dst = buf->y + (size_t)io->mb_y * buf->y_stride;
29+
uint8_t* const u_dst = buf->u + (size_t)(io->mb_y >> 1) * buf->u_stride;
30+
uint8_t* const v_dst = buf->v + (size_t)(io->mb_y >> 1) * buf->v_stride;
3131
const int mb_w = io->mb_w;
3232
const int mb_h = io->mb_h;
3333
const int uv_w = (mb_w + 1) / 2;
3434
const int uv_h = (mb_h + 1) / 2;
35-
int j;
36-
for (j = 0; j < mb_h; ++j) {
37-
memcpy(y_dst + j * buf->y_stride, io->y + j * io->y_stride, mb_w);
38-
}
39-
for (j = 0; j < uv_h; ++j) {
40-
memcpy(u_dst + j * buf->u_stride, io->u + j * io->uv_stride, uv_w);
41-
memcpy(v_dst + j * buf->v_stride, io->v + j * io->uv_stride, uv_w);
42-
}
35+
WebPCopyPlane(io->y, io->y_stride, y_dst, buf->y_stride, mb_w, mb_h);
36+
WebPCopyPlane(io->u, io->uv_stride, u_dst, buf->u_stride, uv_w, uv_h);
37+
WebPCopyPlane(io->v, io->uv_stride, v_dst, buf->v_stride, uv_w, uv_h);
4338
return io->mb_h;
4439
}
4540

4641
// Point-sampling U/V sampler.
4742
static int EmitSampledRGB(const VP8Io* const io, WebPDecParams* const p) {
4843
WebPDecBuffer* const output = p->output;
4944
WebPRGBABuffer* const buf = &output->u.RGBA;
50-
uint8_t* const dst = buf->rgba + io->mb_y * buf->stride;
45+
uint8_t* const dst = buf->rgba + (size_t)io->mb_y * buf->stride;
5146
WebPSamplerProcessPlane(io->y, io->y_stride,
5247
io->u, io->v, io->uv_stride,
5348
dst, buf->stride, io->mb_w, io->mb_h,
@@ -62,7 +57,7 @@ static int EmitSampledRGB(const VP8Io* const io, WebPDecParams* const p) {
6257
static int EmitFancyRGB(const VP8Io* const io, WebPDecParams* const p) {
6358
int num_lines_out = io->mb_h; // a priori guess
6459
const WebPRGBABuffer* const buf = &p->output->u.RGBA;
65-
uint8_t* dst = buf->rgba + io->mb_y * buf->stride;
60+
uint8_t* dst = buf->rgba + (size_t)io->mb_y * buf->stride;
6661
WebPUpsampleLinePairFunc upsample = WebPUpsamplers[p->output->colorspace];
6762
const uint8_t* cur_y = io->y;
6863
const uint8_t* cur_u = io->u;
@@ -133,7 +128,7 @@ static int EmitAlphaYUV(const VP8Io* const io, WebPDecParams* const p,
133128
const WebPYUVABuffer* const buf = &p->output->u.YUVA;
134129
const int mb_w = io->mb_w;
135130
const int mb_h = io->mb_h;
136-
uint8_t* dst = buf->a + io->mb_y * buf->a_stride;
131+
uint8_t* dst = buf->a + (size_t)io->mb_y * buf->a_stride;
137132
int j;
138133
(void)expected_num_lines_out;
139134
assert(expected_num_lines_out == mb_h);
@@ -186,7 +181,7 @@ static int EmitAlphaRGB(const VP8Io* const io, WebPDecParams* const p,
186181
(colorspace == MODE_ARGB || colorspace == MODE_Argb);
187182
const WebPRGBABuffer* const buf = &p->output->u.RGBA;
188183
int num_rows;
189-
const int start_y = GetAlphaSourceRow(io, &alpha, &num_rows);
184+
const size_t start_y = GetAlphaSourceRow(io, &alpha, &num_rows);
190185
uint8_t* const base_rgba = buf->rgba + start_y * buf->stride;
191186
uint8_t* const dst = base_rgba + (alpha_first ? 0 : 3);
192187
const int has_alpha = WebPDispatchAlpha(alpha, io->width, mb_w,
@@ -210,7 +205,7 @@ static int EmitAlphaRGBA4444(const VP8Io* const io, WebPDecParams* const p,
210205
const WEBP_CSP_MODE colorspace = p->output->colorspace;
211206
const WebPRGBABuffer* const buf = &p->output->u.RGBA;
212207
int num_rows;
213-
const int start_y = GetAlphaSourceRow(io, &alpha, &num_rows);
208+
const size_t start_y = GetAlphaSourceRow(io, &alpha, &num_rows);
214209
uint8_t* const base_rgba = buf->rgba + start_y * buf->stride;
215210
#if (WEBP_SWAP_16BIT_CSP == 1)
216211
uint8_t* alpha_dst = base_rgba;
@@ -276,9 +271,9 @@ static int EmitRescaledYUV(const VP8Io* const io, WebPDecParams* const p) {
276271
static int EmitRescaledAlphaYUV(const VP8Io* const io, WebPDecParams* const p,
277272
int expected_num_lines_out) {
278273
const WebPYUVABuffer* const buf = &p->output->u.YUVA;
279-
uint8_t* const dst_a = buf->a + p->last_y * buf->a_stride;
274+
uint8_t* const dst_a = buf->a + (size_t)p->last_y * buf->a_stride;
280275
if (io->a != NULL) {
281-
uint8_t* const dst_y = buf->y + p->last_y * buf->y_stride;
276+
uint8_t* const dst_y = buf->y + (size_t)p->last_y * buf->y_stride;
282277
const int num_lines_out = Rescale(io->a, io->width, io->mb_h, p->scaler_a);
283278
assert(expected_num_lines_out == num_lines_out);
284279
if (num_lines_out > 0) { // unmultiply the Y
@@ -356,7 +351,7 @@ static int ExportRGB(WebPDecParams* const p, int y_pos) {
356351
const WebPYUV444Converter convert =
357352
WebPYUV444Converters[p->output->colorspace];
358353
const WebPRGBABuffer* const buf = &p->output->u.RGBA;
359-
uint8_t* dst = buf->rgba + y_pos * buf->stride;
354+
uint8_t* dst = buf->rgba + (size_t)y_pos * buf->stride;
360355
int num_lines_out = 0;
361356
// For RGB rescaling, because of the YUV420, current scan position
362357
// U/V can be +1/-1 line from the Y one. Hence the double test.
@@ -383,15 +378,15 @@ static int EmitRescaledRGB(const VP8Io* const io, WebPDecParams* const p) {
383378
while (j < mb_h) {
384379
const int y_lines_in =
385380
WebPRescalerImport(p->scaler_y, mb_h - j,
386-
io->y + j * io->y_stride, io->y_stride);
381+
io->y + (size_t)j * io->y_stride, io->y_stride);
387382
j += y_lines_in;
388383
if (WebPRescaleNeededLines(p->scaler_u, uv_mb_h - uv_j)) {
389-
const int u_lines_in =
390-
WebPRescalerImport(p->scaler_u, uv_mb_h - uv_j,
391-
io->u + uv_j * io->uv_stride, io->uv_stride);
392-
const int v_lines_in =
393-
WebPRescalerImport(p->scaler_v, uv_mb_h - uv_j,
394-
io->v + uv_j * io->uv_stride, io->uv_stride);
384+
const int u_lines_in = WebPRescalerImport(
385+
p->scaler_u, uv_mb_h - uv_j, io->u + (size_t)uv_j * io->uv_stride,
386+
io->uv_stride);
387+
const int v_lines_in = WebPRescalerImport(
388+
p->scaler_v, uv_mb_h - uv_j, io->v + (size_t)uv_j * io->uv_stride,
389+
io->uv_stride);
395390
(void)v_lines_in; // remove a gcc warning
396391
assert(u_lines_in == v_lines_in);
397392
uv_j += u_lines_in;
@@ -403,7 +398,7 @@ static int EmitRescaledRGB(const VP8Io* const io, WebPDecParams* const p) {
403398

404399
static int ExportAlpha(WebPDecParams* const p, int y_pos, int max_lines_out) {
405400
const WebPRGBABuffer* const buf = &p->output->u.RGBA;
406-
uint8_t* const base_rgba = buf->rgba + y_pos * buf->stride;
401+
uint8_t* const base_rgba = buf->rgba + (size_t)y_pos * buf->stride;
407402
const WEBP_CSP_MODE colorspace = p->output->colorspace;
408403
const int alpha_first =
409404
(colorspace == MODE_ARGB || colorspace == MODE_Argb);
@@ -431,7 +426,7 @@ static int ExportAlpha(WebPDecParams* const p, int y_pos, int max_lines_out) {
431426
static int ExportAlphaRGBA4444(WebPDecParams* const p, int y_pos,
432427
int max_lines_out) {
433428
const WebPRGBABuffer* const buf = &p->output->u.RGBA;
434-
uint8_t* const base_rgba = buf->rgba + y_pos * buf->stride;
429+
uint8_t* const base_rgba = buf->rgba + (size_t)y_pos * buf->stride;
435430
#if (WEBP_SWAP_16BIT_CSP == 1)
436431
uint8_t* alpha_dst = base_rgba;
437432
#else
@@ -470,7 +465,7 @@ static int EmitRescaledAlphaRGB(const VP8Io* const io, WebPDecParams* const p,
470465
int lines_left = expected_num_out_lines;
471466
const int y_end = p->last_y + lines_left;
472467
while (lines_left > 0) {
473-
const int row_offset = scaler->src_y - io->mb_y;
468+
const int64_t row_offset = (int64_t)scaler->src_y - io->mb_y;
474469
WebPRescalerImport(scaler, io->mb_h + io->mb_y - scaler->src_y,
475470
io->a + row_offset * io->width, io->width);
476471
lines_left -= p->emit_alpha_row(p, y_end - lines_left, lines_left);

3rdparty/libwebp/src/dec/vp8_dec.c

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -494,13 +494,11 @@ static int GetCoeffsAlt(VP8BitReader* const br,
494494
return 16;
495495
}
496496

497-
static WEBP_TSAN_IGNORE_FUNCTION void InitGetCoeffs(void) {
498-
if (GetCoeffs == NULL) {
499-
if (VP8GetCPUInfo != NULL && VP8GetCPUInfo(kSlowSSSE3)) {
500-
GetCoeffs = GetCoeffsAlt;
501-
} else {
502-
GetCoeffs = GetCoeffsFast;
503-
}
497+
WEBP_DSP_INIT_FUNC(InitGetCoeffs) {
498+
if (VP8GetCPUInfo != NULL && VP8GetCPUInfo(kSlowSSSE3)) {
499+
GetCoeffs = GetCoeffsAlt;
500+
} else {
501+
GetCoeffs = GetCoeffsFast;
504502
}
505503
}
506504

3rdparty/libwebp/src/dec/vp8i_dec.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ extern "C" {
3131

3232
// version numbers
3333
#define DEC_MAJ_VERSION 1
34-
#define DEC_MIN_VERSION 1
34+
#define DEC_MIN_VERSION 2
3535
#define DEC_REV_VERSION 0
3636

3737
// YUV-cache parameters. Cache is 32-bytes wide (= one cacheline).

3rdparty/libwebp/src/dec/vp8l_dec.c

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -947,7 +947,6 @@ static WEBP_INLINE void CopyBlock8b(uint8_t* const dst, int dist, int length) {
947947
break;
948948
default:
949949
goto Copy;
950-
break;
951950
}
952951
CopySmallPattern8b(src, dst, length, pattern);
953952
return;

3rdparty/libwebp/src/demux/anim_decode.c

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -346,12 +346,15 @@ int WebPAnimDecoderGetNext(WebPAnimDecoder* dec,
346346
{
347347
const uint8_t* in = iter.fragment.bytes;
348348
const size_t in_size = iter.fragment.size;
349-
const size_t out_offset =
350-
(iter.y_offset * width + iter.x_offset) * NUM_CHANNELS;
349+
const uint32_t stride = width * NUM_CHANNELS; // at most 25 + 2 bits
350+
const uint64_t out_offset = (uint64_t)iter.y_offset * stride +
351+
(uint64_t)iter.x_offset * NUM_CHANNELS; // 53b
352+
const uint64_t size = (uint64_t)iter.height * stride; // at most 25 + 27b
351353
WebPDecoderConfig* const config = &dec->config_;
352354
WebPRGBABuffer* const buf = &config->output.u.RGBA;
353-
buf->stride = NUM_CHANNELS * width;
354-
buf->size = buf->stride * iter.height;
355+
if ((size_t)size != size) goto Error;
356+
buf->stride = (int)stride;
357+
buf->size = (size_t)size;
355358
buf->rgba = dec->curr_frame_ + out_offset;
356359

357360
if (WebPDecode(in, in_size, config) != VP8_STATUS_OK) {

3rdparty/libwebp/src/demux/demux.c

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@
2424
#include "src/webp/format_constants.h"
2525

2626
#define DMUX_MAJ_VERSION 1
27-
#define DMUX_MIN_VERSION 1
27+
#define DMUX_MIN_VERSION 2
2828
#define DMUX_REV_VERSION 0
2929

3030
typedef struct {
@@ -312,6 +312,7 @@ static ParseStatus ParseAnimationFrame(
312312
int bits;
313313
MemBuffer* const mem = &dmux->mem_;
314314
Frame* frame;
315+
size_t start_offset;
315316
ParseStatus status =
316317
NewFrame(mem, ANMF_CHUNK_SIZE, frame_chunk_size, &frame);
317318
if (status != PARSE_OK) return status;
@@ -332,7 +333,11 @@ static ParseStatus ParseAnimationFrame(
332333

333334
// Store a frame only if the animation flag is set there is some data for
334335
// this frame is available.
336+
start_offset = mem->start_;
335337
status = StoreFrame(dmux->num_frames_ + 1, anmf_payload_size, mem, frame);
338+
if (status != PARSE_ERROR && mem->start_ - start_offset > anmf_payload_size) {
339+
status = PARSE_ERROR;
340+
}
336341
if (status != PARSE_ERROR && is_animation && frame->frame_num_ > 0) {
337342
added_frame = AddFrame(dmux, frame);
338343
if (added_frame) {

3rdparty/libwebp/src/dsp/alpha_processing.c

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -359,6 +359,11 @@ static int HasAlpha32b_C(const uint8_t* src, int length) {
359359
return 0;
360360
}
361361

362+
static void AlphaReplace_C(uint32_t* src, int length, uint32_t color) {
363+
int x;
364+
for (x = 0; x < length; ++x) if ((src[x] >> 24) == 0) src[x] = color;
365+
}
366+
362367
//------------------------------------------------------------------------------
363368
// Simple channel manipulations.
364369

@@ -400,6 +405,7 @@ void (*WebPPackRGB)(const uint8_t* r, const uint8_t* g, const uint8_t* b,
400405

401406
int (*WebPHasAlpha8b)(const uint8_t* src, int length);
402407
int (*WebPHasAlpha32b)(const uint8_t* src, int length);
408+
void (*WebPAlphaReplace)(uint32_t* src, int length, uint32_t color);
403409

404410
//------------------------------------------------------------------------------
405411
// Init function
@@ -428,6 +434,7 @@ WEBP_DSP_INIT_FUNC(WebPInitAlphaProcessing) {
428434

429435
WebPHasAlpha8b = HasAlpha8b_C;
430436
WebPHasAlpha32b = HasAlpha32b_C;
437+
WebPAlphaReplace = AlphaReplace_C;
431438

432439
// If defined, use CPUInfo() to overwrite some pointers with faster versions.
433440
if (VP8GetCPUInfo != NULL) {
@@ -469,4 +476,5 @@ WEBP_DSP_INIT_FUNC(WebPInitAlphaProcessing) {
469476
assert(WebPPackRGB != NULL);
470477
assert(WebPHasAlpha8b != NULL);
471478
assert(WebPHasAlpha32b != NULL);
479+
assert(WebPAlphaReplace != NULL);
472480
}

3rdparty/libwebp/src/dsp/alpha_processing_sse2.c

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -265,6 +265,27 @@ static int HasAlpha32b_SSE2(const uint8_t* src, int length) {
265265
return 0;
266266
}
267267

268+
static void AlphaReplace_SSE2(uint32_t* src, int length, uint32_t color) {
269+
const __m128i m_color = _mm_set1_epi32(color);
270+
const __m128i zero = _mm_setzero_si128();
271+
int i = 0;
272+
for (; i + 8 <= length; i += 8) {
273+
const __m128i a0 = _mm_loadu_si128((const __m128i*)(src + i + 0));
274+
const __m128i a1 = _mm_loadu_si128((const __m128i*)(src + i + 4));
275+
const __m128i b0 = _mm_srai_epi32(a0, 24);
276+
const __m128i b1 = _mm_srai_epi32(a1, 24);
277+
const __m128i c0 = _mm_cmpeq_epi32(b0, zero);
278+
const __m128i c1 = _mm_cmpeq_epi32(b1, zero);
279+
const __m128i d0 = _mm_and_si128(c0, m_color);
280+
const __m128i d1 = _mm_and_si128(c1, m_color);
281+
const __m128i e0 = _mm_andnot_si128(c0, a0);
282+
const __m128i e1 = _mm_andnot_si128(c1, a1);
283+
_mm_storeu_si128((__m128i*)(src + i + 0), _mm_or_si128(d0, e0));
284+
_mm_storeu_si128((__m128i*)(src + i + 4), _mm_or_si128(d1, e1));
285+
}
286+
for (; i < length; ++i) if ((src[i] >> 24) == 0) src[i] = color;
287+
}
288+
268289
// -----------------------------------------------------------------------------
269290
// Apply alpha value to rows
270291

@@ -334,6 +355,7 @@ WEBP_TSAN_IGNORE_FUNCTION void WebPInitAlphaProcessingSSE2(void) {
334355

335356
WebPHasAlpha8b = HasAlpha8b_SSE2;
336357
WebPHasAlpha32b = HasAlpha32b_SSE2;
358+
WebPAlphaReplace = AlphaReplace_SSE2;
337359
}
338360

339361
#else // !WEBP_USE_SSE2

3rdparty/libwebp/src/dsp/cpu.c

Lines changed: 34 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -55,12 +55,18 @@ static WEBP_INLINE void GetCPUInfo(int cpu_info[4], int info_type) {
5555
: "=a"(cpu_info[0]), "=b"(cpu_info[1]), "=c"(cpu_info[2]), "=d"(cpu_info[3])
5656
: "a"(info_type), "c"(0));
5757
}
58-
#elif (defined(_M_X64) || defined(_M_IX86)) && \
59-
defined(_MSC_FULL_VER) && _MSC_FULL_VER >= 150030729 // >= VS2008 SP1
58+
#elif defined(_MSC_VER) && (defined(_M_X64) || defined(_M_IX86))
59+
60+
#if defined(_MSC_FULL_VER) && _MSC_FULL_VER >= 150030729 // >= VS2008 SP1
6061
#include <intrin.h>
6162
#define GetCPUInfo(info, type) __cpuidex(info, type, 0) // set ecx=0
62-
#elif defined(WEBP_MSC_SSE2)
63+
#define WEBP_HAVE_MSC_CPUID
64+
#elif _MSC_VER > 1310
65+
#include <intrin.h>
6366
#define GetCPUInfo __cpuid
67+
#define WEBP_HAVE_MSC_CPUID
68+
#endif
69+
6470
#endif
6571

6672
// NaCl has no support for xgetbv or the raw opcode.
@@ -94,7 +100,7 @@ static WEBP_INLINE uint64_t xgetbv(void) {
94100
#define xgetbv() 0U // no AVX for older x64 or unrecognized toolchains.
95101
#endif
96102

97-
#if defined(__i386__) || defined(__x86_64__) || defined(WEBP_MSC_SSE2)
103+
#if defined(__i386__) || defined(__x86_64__) || defined(WEBP_HAVE_MSC_CPUID)
98104

99105
// helper function for run-time detection of slow SSSE3 platforms
100106
static int CheckSlowModel(int info) {
@@ -179,6 +185,30 @@ static int AndroidCPUInfo(CPUFeature feature) {
179185
return 0;
180186
}
181187
VP8CPUInfo VP8GetCPUInfo = AndroidCPUInfo;
188+
#elif defined(EMSCRIPTEN) // also needs to be before generic NEON test
189+
// Use compile flags as an indicator of SIMD support instead of a runtime check.
190+
static int wasmCPUInfo(CPUFeature feature) {
191+
switch (feature) {
192+
#ifdef WEBP_USE_SSE2
193+
case kSSE2:
194+
return 1;
195+
#endif
196+
#ifdef WEBP_USE_SSE41
197+
case kSSE3:
198+
case kSlowSSSE3:
199+
case kSSE4_1:
200+
return 1;
201+
#endif
202+
#ifdef WEBP_USE_NEON
203+
case kNEON:
204+
return 1;
205+
#endif
206+
default:
207+
break;
208+
}
209+
return 0;
210+
}
211+
VP8CPUInfo VP8GetCPUInfo = wasmCPUInfo;
182212
#elif defined(WEBP_USE_NEON)
183213
// define a dummy function to enable turning off NEON at runtime by setting
184214
// VP8DecGetCPUInfo = NULL

0 commit comments

Comments
 (0)