blob: f938e6290077c3f3ca0d2db906ce4cf5196844be [file]
// Copyright 2024 The Wuffs Authors.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// https://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
//
// SPDX-License-Identifier: Apache-2.0 OR MIT
// ----------------
/*
This test program is typically run indirectly, by the "wuffs test" or "wuffs
bench" commands. These commands take an optional "-mimic" flag to check that
Wuffs' output mimics (i.e. exactly matches) other libraries' output, such as
giflib for GIF, libpng for PNG, etc.
To manually run this test:
for CC in clang gcc; do
$CC -std=c99 -Wall -Werror webp.c && ./a.out
rm -f a.out
done
Each edition should print "PASS", amongst other information, and exit(0).
Add the "wuffs mimic cflags" (everything after the colon below) to the C
compiler flags (after the .c file) to run the mimic tests.
To manually run the benchmarks, replace "-Wall -Werror" with "-O3" and replace
the first "./a.out" with "./a.out -bench". Combine these changes with the
"wuffs mimic cflags" to run the mimic benchmarks.
*/
// ¿ wuffs mimic cflags: -DWUFFS_MIMIC -lwebp
// Wuffs ships as a "single file C library" or "header file library" as per
// https://github.com/nothings/stb/blob/master/docs/stb_howto.txt
//
// To use that single file as a "foo.c"-like implementation, instead of a
// "foo.h"-like header, #define WUFFS_IMPLEMENTATION before #include'ing or
// compiling it.
#define WUFFS_IMPLEMENTATION
// Defining the WUFFS_CONFIG__MODULE* macros are optional, but it lets users of
// release/c/etc.c choose which parts of Wuffs to build. That file contains the
// entire Wuffs standard library, implementing a variety of codecs and file
// formats. Without this macro definition, an optimizing compiler or linker may
// very well discard Wuffs code for unused codecs, but listing the Wuffs
// modules we use makes that process explicit. Preprocessing means that such
// code simply isn't compiled.
#define WUFFS_CONFIG__MODULES
#define WUFFS_CONFIG__MODULE__BASE
#define WUFFS_CONFIG__MODULE__VP8
#define WUFFS_CONFIG__MODULE__WEBP
// If building this program in an environment that doesn't easily accommodate
// relative includes, you can use the script/inline-c-relative-includes.go
// program to generate a stand-alone C file.
#include "../../../release/c/wuffs-unsupported-snapshot.c"
#include "../testlib/testlib.c"
#ifdef WUFFS_MIMIC
#include "../mimiclib/webp.c"
#endif
static wuffs_webp__decoder g_webp_decoder;
// ---------------- WebP Tests
const char* //
wuffs_webp_decode(uint64_t* n_bytes_out,
wuffs_base__io_buffer* dst,
uint32_t wuffs_initialize_flags,
wuffs_base__pixel_format pixfmt,
uint32_t* quirks_ptr,
size_t quirks_len,
wuffs_base__io_buffer* src) {
wuffs_webp__decoder* dec = &g_webp_decoder;
CHECK_STATUS("initialize",
wuffs_webp__decoder__initialize(dec, sizeof *dec, WUFFS_VERSION,
wuffs_initialize_flags));
return do_run__wuffs_base__image_decoder(
wuffs_webp__decoder__upcast_as__wuffs_base__image_decoder(dec),
n_bytes_out, dst, pixfmt, quirks_ptr, quirks_len, src);
}
// --------
const char* //
test_wuffs_webp_decode_interface_lossless() {
CHECK_FOCUS(__func__);
wuffs_webp__decoder* dec = &g_webp_decoder;
CHECK_STATUS("initialize",
wuffs_webp__decoder__initialize(
dec, sizeof *dec, WUFFS_VERSION,
WUFFS_INITIALIZE__LEAVE_INTERNAL_BUFFERS_UNINITIALIZED));
return do_test__wuffs_base__image_decoder(
wuffs_webp__decoder__upcast_as__wuffs_base__image_decoder(dec),
"test/data/bricks-color.lossless.webp", 0, SIZE_MAX, 160, 120,
0xFF022460);
}
const char* //
test_wuffs_webp_decode_interface_lossy() {
CHECK_FOCUS(__func__);
wuffs_webp__decoder* dec = &g_webp_decoder;
CHECK_STATUS("initialize",
wuffs_webp__decoder__initialize(
dec, sizeof *dec, WUFFS_VERSION,
WUFFS_INITIALIZE__LEAVE_INTERNAL_BUFFERS_UNINITIALIZED));
return do_test__wuffs_base__image_decoder(
wuffs_webp__decoder__upcast_as__wuffs_base__image_decoder(dec),
"test/data/bricks-color.lossy.webp", 0, SIZE_MAX, 160, 120, 0xFF032665);
}
const char* //
test_wuffs_webp_decode_interface_vp8x_alpha_lossy() {
CHECK_FOCUS(__func__);
wuffs_webp__decoder* dec = &g_webp_decoder;
CHECK_STATUS("initialize",
wuffs_webp__decoder__initialize(
dec, sizeof *dec, WUFFS_VERSION,
WUFFS_INITIALIZE__LEAVE_INTERNAL_BUFFERS_UNINITIALIZED));
return do_test__wuffs_base__image_decoder(
wuffs_webp__decoder__upcast_as__wuffs_base__image_decoder(dec),
"test/data/hippopotamus.masked-with-muybridge.lossy.webp", 0, SIZE_MAX,
36, 28, 0x7D787878);
}
const char* //
test_wuffs_webp_decode_many_small_reads() {
CHECK_FOCUS(__func__);
wuffs_webp__decoder* dec = &g_webp_decoder;
CHECK_STATUS("initialize",
wuffs_webp__decoder__initialize(
dec, sizeof *dec, WUFFS_VERSION,
WUFFS_INITIALIZE__LEAVE_INTERNAL_BUFFERS_UNINITIALIZED));
wuffs_base__io_buffer src = ((wuffs_base__io_buffer){
.data = g_src_slice_u8,
});
CHECK_STRING(read_file(&src, "test/data/mona-lisa.21x32.q0.lossy.webp"));
wuffs_base__image_config ic = ((wuffs_base__image_config){});
CHECK_STATUS("decode_image_config",
wuffs_webp__decoder__decode_image_config(dec, &ic, &src));
const uint32_t w = 21;
if (wuffs_base__pixel_config__width(&ic.pixcfg) != 21) {
RETURN_FAIL("width: have %" PRIu32 ", want 21",
wuffs_base__pixel_config__width(&ic.pixcfg));
}
const uint32_t h = 32;
if (wuffs_base__pixel_config__height(&ic.pixcfg) != 32) {
RETURN_FAIL("height: have %" PRIu32 ", want 32",
wuffs_base__pixel_config__height(&ic.pixcfg));
}
if (wuffs_base__pixel_config__pixel_format(&ic.pixcfg).repr !=
WUFFS_BASE__PIXEL_FORMAT__BGRX) {
RETURN_FAIL("pixel_format: have %" PRIu32
", want WUFFS_BASE__PIXEL_FORMAT__BGRX",
wuffs_base__pixel_config__pixel_format(&ic.pixcfg).repr);
}
// 30 is 12 for the RIFF container header, 8 for the RIFF chunk header and
// 10 for the VP8 header.
if (wuffs_base__image_config__first_frame_io_position(&ic) != 30) {
RETURN_FAIL("first_frame_io_position: have %" PRIu64 ", want 30",
wuffs_base__image_config__first_frame_io_position(&ic));
}
wuffs_base__pixel_buffer pb = ((wuffs_base__pixel_buffer){});
CHECK_STATUS("set_from_slice", wuffs_base__pixel_buffer__set_from_slice(
&pb, &ic.pixcfg, g_pixel_slice_u8));
wuffs_base__pixel_buffer__set_color_u32_argb_premul_fill_rect(
&pb, wuffs_base__make_rect_ie_u32(0, 0, w, h), 0xFF234567);
uint64_t m = wuffs_webp__decoder__workbuf_len(dec).min_incl;
wuffs_base__slice_u8 workbuf = g_work_slice_u8;
if (workbuf.len > m) {
workbuf.len = m;
}
const uint64_t rlimit = 10;
int num_iters = 0;
while (true) {
num_iters++;
wuffs_base__io_buffer limited_src = make_limited_reader(src, rlimit);
size_t old_ri = src.meta.ri;
wuffs_base__status status = wuffs_webp__decoder__decode_frame(
dec, &pb, &limited_src, WUFFS_BASE__PIXEL_BLEND__SRC, workbuf, NULL);
src.meta.ri += limited_src.meta.ri;
if (wuffs_base__status__is_ok(&status)) {
break;
}
if (status.repr != wuffs_base__suspension__short_read) {
RETURN_FAIL("decode_frame: have \"%s\", want \"%s\"", status.repr,
wuffs_base__suspension__short_read);
}
if (src.meta.ri < old_ri) {
RETURN_FAIL("read index src.meta.ri went backwards");
} else if (src.meta.ri == old_ri) {
RETURN_FAIL("no progress was made");
}
}
if (num_iters <= 1) {
RETURN_FAIL("num_iters: have %d, want > 1", num_iters);
}
wuffs_base__color_u32_argb_premul last_pixel =
wuffs_base__pixel_buffer__color_u32_at(&pb, w - 1, h - 1);
if (last_pixel != 0xFF210A1B) {
RETURN_FAIL("last_pixel: have 0x%" PRIX32 ", want 0xFF210A1B", last_pixel);
}
return NULL;
}
const char* //
test_wuffs_webp_decode_filter_alph() {
CHECK_FOCUS(__func__);
const int width = 41;
const int height = 6;
// src is arbitrary bytes, a subset of a noise texture.
const uint8_t src[1][246] = {
{
0x3C, 0xD4, 0xB6, 0x77, 0x64, 0xAB, 0xEF, 0x03, 0x7D, 0x2F, 0xC0,
0x24, 0x79, 0x3E, 0x87, 0x9A, 0x36, 0x7F, 0xBC, 0xF0, 0x42, 0xAF,
0x2D, 0x63, 0x22, 0xC3, 0x4E, 0x33, 0xE9, 0x67, 0x9C, 0x01, 0xA9,
0x23, 0x50, 0xDD, 0x36, 0x26, 0x4B, 0x94, 0xDC,
0x14, 0xFB, 0x47, 0x5F, 0xF2, 0x13, 0x53, 0xE7, 0xD7, 0x28, 0x8A,
0x07, 0xC6, 0x54, 0xE5, 0xB5, 0x0E, 0x78, 0xAE, 0x14, 0x84, 0xC0,
0x20, 0x7D, 0x95, 0xEA, 0x06, 0x8A, 0xFA, 0xC3, 0x70, 0x5C, 0xA6,
0x88, 0xCC, 0x09, 0xBA, 0xA6, 0x68, 0x1E, 0xB3,
0x5A, 0xA5, 0x68, 0xFD, 0x18, 0x90, 0x70, 0x3A, 0xF0, 0x5F, 0xCA,
0x44, 0x2B, 0x58, 0x12, 0xBD, 0x43, 0x61, 0xB0, 0x9D, 0x0E, 0x3F,
0xEC, 0xB6, 0x36, 0x6E, 0x94, 0xDE, 0x2F, 0xCE, 0x77, 0x92, 0x11,
0xE2, 0x37, 0x81, 0xA0, 0x46, 0xCD, 0xDF, 0xA3,
0x05, 0x97, 0xDC, 0x73, 0xE4, 0x35, 0x6D, 0xF2, 0xC7, 0x1D, 0x56,
0x7B, 0xCE, 0x2A, 0x17, 0x54, 0xE9, 0x21, 0x7E, 0x4E, 0xEB, 0x3B,
0xF9, 0x47, 0xCA, 0x75, 0xB9, 0xD9, 0x0B, 0x5A, 0x27, 0x8A, 0x4D,
0xF5, 0x1F, 0xB7, 0x8E, 0xD0, 0xA4, 0x28, 0x81,
0xD9, 0x32, 0xE4, 0xA3, 0x8F, 0x65, 0xD8, 0x9B, 0x42, 0xB2, 0x04,
0x8B, 0x19, 0xBE, 0x9B, 0x00, 0x51, 0x22, 0x31, 0xF6, 0x7C, 0xBF,
0x1A, 0x6C, 0xB0, 0x3C, 0x63, 0x0A, 0xF9, 0x53, 0x15, 0x93, 0x67,
0xB8, 0x4B, 0x01, 0xF4, 0x82, 0xBE, 0x11, 0xFD,
0x61, 0xC4, 0xA4, 0x57, 0x6D, 0x2C, 0xDD, 0xED, 0xB1, 0x92, 0x63,
0xA8, 0xE2, 0x35, 0xC8, 0x7F, 0xD5, 0x9D, 0x49, 0x85, 0xAE, 0xE2,
0x41, 0x0C, 0xFE, 0x76, 0xC5, 0x20, 0x45, 0xAC, 0x30, 0xCB, 0x73,
0x24, 0xEF, 0xDA, 0x80, 0xAB, 0x5E, 0x89, 0x6E,
},
};
const uint8_t wants[3][246] = {
{
0x3C, 0x10, 0xC6, 0x3D, 0xA1, 0x4C, 0x3B, 0x3E, 0xBB, 0xEA, 0xAA,
0xCE, 0x47, 0x85, 0x0C, 0xA6, 0xDC, 0x5B, 0x17, 0x07, 0x49, 0xF8,
0x25, 0x88, 0xAA, 0x6D, 0xBB, 0xEE, 0xD7, 0x3E, 0xDA, 0xDB, 0x84,
0xA7, 0xF7, 0xD4, 0x0A, 0x30, 0x7B, 0x0F, 0xEB,
0x50, 0x4B, 0x92, 0xF1, 0xE3, 0xF6, 0x49, 0x30, 0x07, 0x2F, 0xB9,
0xC0, 0x86, 0xDA, 0xBF, 0x74, 0x82, 0xFA, 0xA8, 0xBC, 0x40, 0x00,
0x20, 0x9D, 0x32, 0x1C, 0x22, 0xAC, 0xA6, 0x69, 0xD9, 0x35, 0xDB,
0x63, 0x2F, 0x38, 0xF2, 0x98, 0x00, 0x1E, 0xD1,
0xAA, 0x4F, 0xB7, 0xB4, 0xCC, 0x5C, 0xCC, 0x06, 0xF6, 0x55, 0x1F,
0x63, 0x8E, 0xE6, 0xF8, 0xB5, 0xF8, 0x59, 0x09, 0xA6, 0xB4, 0xF3,
0xDF, 0x95, 0xCB, 0x39, 0xCD, 0xAB, 0xDA, 0xA8, 0x1F, 0xB1, 0xC2,
0xA4, 0xDB, 0x5C, 0xFC, 0x42, 0x0F, 0xEE, 0x91,
0xAF, 0x46, 0x22, 0x95, 0x79, 0xAE, 0x1B, 0x0D, 0xD4, 0xF1, 0x47,
0xC2, 0x90, 0xBA, 0xD1, 0x25, 0x0E, 0x2F, 0xAD, 0xFB, 0xE6, 0x21,
0x1A, 0x61, 0x2B, 0xA0, 0x59, 0x32, 0x3D, 0x97, 0xBE, 0x48, 0x95,
0x8A, 0xA9, 0x60, 0xEE, 0xBE, 0x62, 0x8A, 0x0B,
0x88, 0xBA, 0x9E, 0x41, 0xD0, 0x35, 0x0D, 0xA8, 0xEA, 0x9C, 0xA0,
0x2B, 0x44, 0x02, 0x9D, 0x9D, 0xEE, 0x10, 0x41, 0x37, 0xB3, 0x72,
0x8C, 0xF8, 0xA8, 0xE4, 0x47, 0x51, 0x4A, 0x9D, 0xB2, 0x45, 0xAC,
0x64, 0xAF, 0xB0, 0xA4, 0x26, 0xE4, 0xF5, 0xF2,
0xE9, 0xAD, 0x51, 0xA8, 0x15, 0x41, 0x1E, 0x0B, 0xBC, 0x4E, 0xB1,
0x59, 0x3B, 0x70, 0x38, 0xB7, 0x8C, 0x29, 0x72, 0xF7, 0xA5, 0x87,
0xC8, 0xD4, 0xD2, 0x48, 0x0D, 0x2D, 0x72, 0x1E, 0x4E, 0x19, 0x8C,
0xB0, 0x9F, 0x79, 0xF9, 0xA4, 0x02, 0x8B, 0xF9,
},
{
0x3C, 0x10, 0xC6, 0x3D, 0xA1, 0x4C, 0x3B, 0x3E, 0xBB, 0xEA, 0xAA,
0xCE, 0x47, 0x85, 0x0C, 0xA6, 0xDC, 0x5B, 0x17, 0x07, 0x49, 0xF8,
0x25, 0x88, 0xAA, 0x6D, 0xBB, 0xEE, 0xD7, 0x3E, 0xDA, 0xDB, 0x84,
0xA7, 0xF7, 0xD4, 0x0A, 0x30, 0x7B, 0x0F, 0xEB,
0x50, 0x0B, 0x0D, 0x9C, 0x93, 0x5F, 0x8E, 0x25, 0x92, 0x12, 0x34,
0xD5, 0x0D, 0xD9, 0xF1, 0x5B, 0xEA, 0xD3, 0xC5, 0x1B, 0xCD, 0xB8,
0x45, 0x05, 0x3F, 0x57, 0xC1, 0x78, 0xD1, 0x01, 0x4A, 0x37, 0x2A,
0x2F, 0xC3, 0xDD, 0xC4, 0xD6, 0xE3, 0x2D, 0x9E,
0xAA, 0xB0, 0x75, 0x99, 0xAB, 0xEF, 0xFE, 0x5F, 0x82, 0x71, 0xFE,
0x19, 0x38, 0x31, 0x03, 0x18, 0x2D, 0x34, 0x75, 0xB8, 0xDB, 0xF7,
0x31, 0xBB, 0x75, 0xC5, 0x55, 0x56, 0x00, 0xCF, 0xC1, 0xC9, 0x3B,
0x11, 0xFA, 0x5E, 0x64, 0x1C, 0xB0, 0x0C, 0x41,
0xAF, 0x47, 0x51, 0x0C, 0x8F, 0x24, 0x6B, 0x51, 0x49, 0x8E, 0x54,
0x94, 0x06, 0x5B, 0x1A, 0x6C, 0x16, 0x55, 0xF3, 0x06, 0xC6, 0x32,
0x2A, 0x02, 0x3F, 0x3A, 0x0E, 0x2F, 0x0B, 0x29, 0xE8, 0x53, 0x88,
0x06, 0x19, 0x15, 0xF2, 0xEC, 0x54, 0x34, 0xC2,
0x88, 0x79, 0x35, 0xAF, 0x1E, 0x89, 0x43, 0xEC, 0x8B, 0x40, 0x58,
0x1F, 0x1F, 0x19, 0xB5, 0x6C, 0x67, 0x77, 0x24, 0xFC, 0x42, 0xF1,
0x44, 0x6E, 0xEF, 0x76, 0x71, 0x39, 0x04, 0x7C, 0xFD, 0xE6, 0xEF,
0xBE, 0x64, 0x16, 0xE6, 0x6E, 0x12, 0x45, 0xBF,
0xE9, 0x3D, 0xD9, 0x06, 0x8B, 0xB5, 0x20, 0xD9, 0x3C, 0xD2, 0xBB,
0xC7, 0x01, 0x4E, 0x7D, 0xEB, 0x3C, 0x14, 0x6D, 0x81, 0xF0, 0xD3,
0x85, 0x7A, 0xED, 0xEC, 0x36, 0x59, 0x49, 0x28, 0x2D, 0xB1, 0x62,
0xE2, 0x53, 0xF0, 0x66, 0x19, 0x70, 0xCE, 0x2D,
},
{
0x3C, 0x10, 0xC6, 0x3D, 0xA1, 0x4C, 0x3B, 0x3E, 0xBB, 0xEA, 0xAA,
0xCE, 0x47, 0x85, 0x0C, 0xA6, 0xDC, 0x5B, 0x17, 0x07, 0x49, 0xF8,
0x25, 0x88, 0xAA, 0x6D, 0xBB, 0xEE, 0xD7, 0x3E, 0xDA, 0xDB, 0x84,
0xA7, 0xF7, 0xD4, 0x0A, 0x30, 0x7B, 0x0F, 0xEB,
0x50, 0x1F, 0x1C, 0x5F, 0xB5, 0x73, 0xB5, 0x9F, 0xD6, 0x27, 0x8A,
0xB5, 0xF4, 0x53, 0xE5, 0xB4, 0xF8, 0xEF, 0x59, 0x5D, 0x23, 0x92,
0x20, 0x00, 0xB7, 0x64, 0xB8, 0x75, 0x58, 0xC3, 0x6F, 0xCC, 0x1B,
0xC6, 0xCB, 0xB1, 0xBA, 0x86, 0x39, 0x1E, 0xAD,
0xAA, 0x1E, 0x83, 0xC3, 0x17, 0x90, 0x42, 0x66, 0x8D, 0x5F, 0x8C,
0xFB, 0x2A, 0x58, 0xFC, 0x88, 0x0F, 0x67, 0xB0, 0x51, 0x25, 0xD3,
0x4D, 0xE3, 0x35, 0x6E, 0x56, 0xF1, 0x03, 0x3C, 0x77, 0x66, 0x11,
0x9E, 0xDA, 0x41, 0xEA, 0xFC, 0x7C, 0x40, 0x72,
0xAF, 0xBA, 0xDB, 0x72, 0xE4, 0x34, 0x6D, 0x83, 0x71, 0x60, 0xE3,
0x7A, 0xCE, 0x26, 0xE1, 0xC1, 0x31, 0xAA, 0x71, 0x60, 0x1F, 0x08,
0xF9, 0x46, 0xCA, 0x74, 0x15, 0x89, 0x0B, 0x9E, 0x00, 0x8A, 0x82,
0xF4, 0x1E, 0xB7, 0x8D, 0x6F, 0xA4, 0x90, 0x43,
0x88, 0xC5, 0xCA, 0x04, 0x05, 0x65, 0x76, 0x27, 0x57, 0xF8, 0x03,
0x8B, 0xF8, 0x0E, 0x64, 0x44, 0x51, 0xEC, 0xE4, 0xC9, 0x04, 0xBF,
0x19, 0x6C, 0xA0, 0x86, 0x8A, 0x08, 0xF9, 0x52, 0x15, 0x32, 0x91,
0xB7, 0x4B, 0xE5, 0xAF, 0x13, 0x06, 0x11, 0xFD,
0xE9, 0xC3, 0x6C, 0x57, 0xC5, 0x2B, 0x19, 0xED, 0xB0, 0x91, 0x63,
0x93, 0xE1, 0x35, 0x53, 0xB2, 0x94, 0x9C, 0xDD, 0x47, 0xAE, 0xE1,
0x7C, 0xDB, 0xFD, 0x59, 0x22, 0x20, 0x44, 0xAC, 0x9F, 0x87, 0x59,
0xA3, 0x26, 0x9A, 0xE4, 0xF3, 0x44, 0xD8, 0x6D,
},
};
wuffs_webp__decoder dec = {0};
dec.private_impl.f_width = width;
dec.private_impl.f_height = height;
for (int filter = 0; filter < 3; filter++) {
uint8_t buf[246];
memcpy(&buf[0], &src[0][0], 246);
wuffs_base__slice_u8 s = wuffs_base__make_slice_u8(&buf[0], 246);
switch (filter) {
case 0:
wuffs_webp__decoder__filter_alph_horizontal(&dec, s);
break;
case 1:
wuffs_webp__decoder__filter_alph_vertical(&dec, s);
break;
case 2:
wuffs_webp__decoder__filter_alph_gradient(&dec, s);
break;
}
if (0 == memcmp(&buf[0], &wants[filter][0], 246)) {
continue;
}
for (int y = 0; y < height; y++) {
for (int x = 0; x < width; x++) {
int i = (y * width) + x;
int have = buf[i];
int want = wants[filter][i];
if (have != want) {
RETURN_FAIL("filter=%d, y=%d, x=%d: have 0x%02X, want 0x%02X", filter,
y, x, have, want);
}
}
}
return "unreachable";
}
return NULL;
}
// ---------------- Mimic Tests
#ifdef WUFFS_MIMIC
const char* //
do_test_mimic_webp_decode(const char* filename) {
wuffs_base__io_buffer src = ((wuffs_base__io_buffer){
.data = g_src_slice_u8,
});
CHECK_STRING(read_file(&src, filename));
src.meta.ri = 0;
wuffs_base__io_buffer have = ((wuffs_base__io_buffer){
.data = g_have_slice_u8,
});
CHECK_STRING(wuffs_webp_decode(
NULL, &have, WUFFS_INITIALIZE__DEFAULT_OPTIONS,
wuffs_base__make_pixel_format(WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL),
NULL, 0, &src));
src.meta.ri = 0;
wuffs_base__io_buffer want = ((wuffs_base__io_buffer){
.data = g_want_slice_u8,
});
CHECK_STRING(mimic_webp_decode(
NULL, &want, WUFFS_INITIALIZE__DEFAULT_OPTIONS,
wuffs_base__make_pixel_format(WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL),
NULL, 0, &src));
return check_io_buffers_equal("", &have, &want);
}
const char* //
test_mimic_webp_lossless_decode_image_19k_8bpp() {
CHECK_FOCUS(__func__);
return do_test_mimic_webp_decode("test/data/bricks-gray.lossless.webp");
}
const char* //
test_mimic_webp_lossless_decode_image_40k_24bpp() {
CHECK_FOCUS(__func__);
return do_test_mimic_webp_decode("test/data/hat.lossless.webp");
}
const char* //
test_mimic_webp_lossless_decode_image_77k_8bpp() {
CHECK_FOCUS(__func__);
return do_test_mimic_webp_decode("test/data/bricks-dither.lossless.webp");
}
const char* //
test_mimic_webp_lossless_decode_image_552k_32bpp() {
CHECK_FOCUS(__func__);
return do_test_mimic_webp_decode(
"test/data/hibiscus.primitive.lossless.webp");
}
const char* //
test_mimic_webp_lossless_decode_image_4002k_24bpp() {
CHECK_FOCUS(__func__);
return do_test_mimic_webp_decode("test/data/harvesters.lossless.webp");
}
const char* //
test_mimic_webp_lossy_decode_image_19k_8bpp() {
CHECK_FOCUS(__func__);
return do_test_mimic_webp_decode("test/data/bricks-gray.lossy.webp");
}
const char* //
test_mimic_webp_lossy_decode_image_40k_24bpp() {
CHECK_FOCUS(__func__);
return do_test_mimic_webp_decode("test/data/hat.lossy.webp");
}
const char* //
test_mimic_webp_lossy_decode_image_77k_24bpp() {
CHECK_FOCUS(__func__);
return do_test_mimic_webp_decode("test/data/bricks-color.lossy.webp");
}
const char* //
test_mimic_webp_lossy_decode_image_552k_32bpp() {
CHECK_FOCUS(__func__);
return do_test_mimic_webp_decode("test/data/hibiscus.primitive.lossy.webp");
}
const char* //
test_mimic_webp_lossy_decode_image_4002k_24bpp() {
CHECK_FOCUS(__func__);
return do_test_mimic_webp_decode("test/data/harvesters.lossy.webp");
}
#endif // WUFFS_MIMIC
// ---------------- WebP Benches
const char* //
bench_wuffs_webp_lossless_decode_image_19k_8bpp() {
CHECK_FOCUS(__func__);
return do_bench_image_decode(
&wuffs_webp_decode,
WUFFS_INITIALIZE__LEAVE_INTERNAL_BUFFERS_UNINITIALIZED,
wuffs_base__make_pixel_format(WUFFS_BASE__PIXEL_FORMAT__Y), NULL, 0,
"test/data/bricks-gray.lossless.webp", 0, SIZE_MAX, 50);
}
const char* //
bench_wuffs_webp_lossless_decode_image_40k_24bpp() {
CHECK_FOCUS(__func__);
return do_bench_image_decode(
&wuffs_webp_decode,
WUFFS_INITIALIZE__LEAVE_INTERNAL_BUFFERS_UNINITIALIZED,
wuffs_base__make_pixel_format(WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL),
NULL, 0, "test/data/hat.lossless.webp", 0, SIZE_MAX, 30);
}
const char* //
bench_wuffs_webp_lossless_decode_image_77k_8bpp() {
CHECK_FOCUS(__func__);
return do_bench_image_decode(
&wuffs_webp_decode,
WUFFS_INITIALIZE__LEAVE_INTERNAL_BUFFERS_UNINITIALIZED,
wuffs_base__make_pixel_format(WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL),
NULL, 0, "test/data/bricks-dither.lossless.webp", 0, SIZE_MAX, 50);
}
const char* //
bench_wuffs_webp_lossless_decode_image_552k_32bpp() {
uint32_t q = WUFFS_BASE__QUIRK_IGNORE_CHECKSUM;
CHECK_FOCUS(__func__);
return do_bench_image_decode(
&wuffs_webp_decode,
WUFFS_INITIALIZE__LEAVE_INTERNAL_BUFFERS_UNINITIALIZED,
wuffs_base__make_pixel_format(WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL),
&q, 1, "test/data/hibiscus.primitive.lossless.webp", 0, SIZE_MAX, 4);
}
const char* //
bench_wuffs_webp_lossless_decode_image_4002k_24bpp() {
CHECK_FOCUS(__func__);
return do_bench_image_decode(
&wuffs_webp_decode,
WUFFS_INITIALIZE__LEAVE_INTERNAL_BUFFERS_UNINITIALIZED,
wuffs_base__make_pixel_format(WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL),
NULL, 0, "test/data/harvesters.lossless.webp", 0, SIZE_MAX, 1);
}
const char* //
bench_wuffs_webp_lossy_decode_image_19k_8bpp() {
CHECK_FOCUS(__func__);
return do_bench_image_decode(
&wuffs_webp_decode,
WUFFS_INITIALIZE__LEAVE_INTERNAL_BUFFERS_UNINITIALIZED,
wuffs_base__make_pixel_format(WUFFS_BASE__PIXEL_FORMAT__Y), NULL, 0,
"test/data/bricks-gray.lossy.webp", 0, SIZE_MAX, 50);
}
const char* //
bench_wuffs_webp_lossy_decode_image_40k_24bpp() {
CHECK_FOCUS(__func__);
return do_bench_image_decode(
&wuffs_webp_decode,
WUFFS_INITIALIZE__LEAVE_INTERNAL_BUFFERS_UNINITIALIZED,
wuffs_base__make_pixel_format(WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL),
NULL, 0, "test/data/hat.lossy.webp", 0, SIZE_MAX, 30);
}
const char* //
bench_wuffs_webp_lossy_decode_image_77k_24bpp() {
CHECK_FOCUS(__func__);
return do_bench_image_decode(
&wuffs_webp_decode,
WUFFS_INITIALIZE__LEAVE_INTERNAL_BUFFERS_UNINITIALIZED,
wuffs_base__make_pixel_format(WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL),
NULL, 0, "test/data/bricks-color.lossy.webp", 0, SIZE_MAX, 50);
}
const char* //
bench_wuffs_webp_lossy_decode_image_552k_32bpp() {
uint32_t q = WUFFS_BASE__QUIRK_IGNORE_CHECKSUM;
CHECK_FOCUS(__func__);
return do_bench_image_decode(
&wuffs_webp_decode,
WUFFS_INITIALIZE__LEAVE_INTERNAL_BUFFERS_UNINITIALIZED,
wuffs_base__make_pixel_format(WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL),
&q, 1, "test/data/hibiscus.primitive.lossy.webp", 0, SIZE_MAX, 4);
}
const char* //
bench_wuffs_webp_lossy_decode_image_4002k_24bpp() {
CHECK_FOCUS(__func__);
return do_bench_image_decode(
&wuffs_webp_decode,
WUFFS_INITIALIZE__LEAVE_INTERNAL_BUFFERS_UNINITIALIZED,
wuffs_base__make_pixel_format(WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL),
NULL, 0, "test/data/harvesters.lossy.webp", 0, SIZE_MAX, 1);
}
// ---------------- Mimic Benches
#ifdef WUFFS_MIMIC
const char* //
bench_mimic_webp_lossless_decode_image_19k_8bpp() {
CHECK_FOCUS(__func__);
return do_bench_image_decode(
&mimic_webp_decode,
WUFFS_INITIALIZE__LEAVE_INTERNAL_BUFFERS_UNINITIALIZED,
wuffs_base__make_pixel_format(WUFFS_BASE__PIXEL_FORMAT__Y), NULL, 0,
"test/data/bricks-gray.lossless.webp", 0, SIZE_MAX, 50);
}
const char* //
bench_mimic_webp_lossless_decode_image_40k_24bpp() {
CHECK_FOCUS(__func__);
return do_bench_image_decode(
&mimic_webp_decode,
WUFFS_INITIALIZE__LEAVE_INTERNAL_BUFFERS_UNINITIALIZED,
wuffs_base__make_pixel_format(WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL),
NULL, 0, "test/data/hat.lossless.webp", 0, SIZE_MAX, 30);
}
const char* //
bench_mimic_webp_lossless_decode_image_77k_8bpp() {
CHECK_FOCUS(__func__);
return do_bench_image_decode(
&mimic_webp_decode,
WUFFS_INITIALIZE__LEAVE_INTERNAL_BUFFERS_UNINITIALIZED,
wuffs_base__make_pixel_format(WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL),
NULL, 0, "test/data/bricks-dither.lossless.webp", 0, SIZE_MAX, 50);
}
const char* //
bench_mimic_webp_lossless_decode_image_552k_32bpp() {
uint32_t q = WUFFS_BASE__QUIRK_IGNORE_CHECKSUM;
CHECK_FOCUS(__func__);
return do_bench_image_decode(
&mimic_webp_decode,
WUFFS_INITIALIZE__LEAVE_INTERNAL_BUFFERS_UNINITIALIZED,
wuffs_base__make_pixel_format(WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL),
&q, 1, "test/data/hibiscus.primitive.lossless.webp", 0, SIZE_MAX, 4);
}
const char* //
bench_mimic_webp_lossless_decode_image_4002k_24bpp() {
CHECK_FOCUS(__func__);
return do_bench_image_decode(
&mimic_webp_decode,
WUFFS_INITIALIZE__LEAVE_INTERNAL_BUFFERS_UNINITIALIZED,
wuffs_base__make_pixel_format(WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL),
NULL, 0, "test/data/harvesters.lossless.webp", 0, SIZE_MAX, 1);
}
const char* //
bench_mimic_webp_lossy_decode_image_19k_8bpp() {
CHECK_FOCUS(__func__);
return do_bench_image_decode(
&mimic_webp_decode,
WUFFS_INITIALIZE__LEAVE_INTERNAL_BUFFERS_UNINITIALIZED,
wuffs_base__make_pixel_format(WUFFS_BASE__PIXEL_FORMAT__Y), NULL, 0,
"test/data/bricks-gray.lossy.webp", 0, SIZE_MAX, 50);
}
const char* //
bench_mimic_webp_lossy_decode_image_40k_24bpp() {
CHECK_FOCUS(__func__);
return do_bench_image_decode(
&mimic_webp_decode,
WUFFS_INITIALIZE__LEAVE_INTERNAL_BUFFERS_UNINITIALIZED,
wuffs_base__make_pixel_format(WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL),
NULL, 0, "test/data/hat.lossy.webp", 0, SIZE_MAX, 30);
}
const char* //
bench_mimic_webp_lossy_decode_image_77k_24bpp() {
CHECK_FOCUS(__func__);
return do_bench_image_decode(
&mimic_webp_decode,
WUFFS_INITIALIZE__LEAVE_INTERNAL_BUFFERS_UNINITIALIZED,
wuffs_base__make_pixel_format(WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL),
NULL, 0, "test/data/bricks-color.lossy.webp", 0, SIZE_MAX, 50);
}
const char* //
bench_mimic_webp_lossy_decode_image_552k_32bpp() {
uint32_t q = WUFFS_BASE__QUIRK_IGNORE_CHECKSUM;
CHECK_FOCUS(__func__);
return do_bench_image_decode(
&mimic_webp_decode,
WUFFS_INITIALIZE__LEAVE_INTERNAL_BUFFERS_UNINITIALIZED,
wuffs_base__make_pixel_format(WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL),
&q, 1, "test/data/hibiscus.primitive.lossy.webp", 0, SIZE_MAX, 4);
}
const char* //
bench_mimic_webp_lossy_decode_image_4002k_24bpp() {
CHECK_FOCUS(__func__);
return do_bench_image_decode(
&mimic_webp_decode,
WUFFS_INITIALIZE__LEAVE_INTERNAL_BUFFERS_UNINITIALIZED,
wuffs_base__make_pixel_format(WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL),
NULL, 0, "test/data/harvesters.lossy.webp", 0, SIZE_MAX, 1);
}
#endif // WUFFS_MIMIC
// ---------------- Manifest
proc g_tests[] = {
test_wuffs_webp_decode_filter_alph,
test_wuffs_webp_decode_interface_lossless,
test_wuffs_webp_decode_interface_lossy,
test_wuffs_webp_decode_interface_vp8x_alpha_lossy,
test_wuffs_webp_decode_many_small_reads,
#ifdef WUFFS_MIMIC
test_mimic_webp_lossless_decode_image_19k_8bpp,
test_mimic_webp_lossless_decode_image_40k_24bpp,
test_mimic_webp_lossless_decode_image_77k_8bpp,
test_mimic_webp_lossless_decode_image_552k_32bpp,
test_mimic_webp_lossless_decode_image_4002k_24bpp,
test_mimic_webp_lossy_decode_image_19k_8bpp,
test_mimic_webp_lossy_decode_image_40k_24bpp,
test_mimic_webp_lossy_decode_image_77k_24bpp,
test_mimic_webp_lossy_decode_image_552k_32bpp,
test_mimic_webp_lossy_decode_image_4002k_24bpp,
#endif // WUFFS_MIMIC
NULL,
};
proc g_benches[] = {
bench_wuffs_webp_lossless_decode_image_19k_8bpp,
bench_wuffs_webp_lossless_decode_image_40k_24bpp,
bench_wuffs_webp_lossless_decode_image_77k_8bpp,
bench_wuffs_webp_lossless_decode_image_552k_32bpp,
bench_wuffs_webp_lossless_decode_image_4002k_24bpp,
bench_wuffs_webp_lossy_decode_image_19k_8bpp,
bench_wuffs_webp_lossy_decode_image_40k_24bpp,
bench_wuffs_webp_lossy_decode_image_77k_24bpp,
bench_wuffs_webp_lossy_decode_image_552k_32bpp,
bench_wuffs_webp_lossy_decode_image_4002k_24bpp,
#ifdef WUFFS_MIMIC
bench_mimic_webp_lossless_decode_image_19k_8bpp,
bench_mimic_webp_lossless_decode_image_40k_24bpp,
bench_mimic_webp_lossless_decode_image_77k_8bpp,
bench_mimic_webp_lossless_decode_image_552k_32bpp,
bench_mimic_webp_lossless_decode_image_4002k_24bpp,
bench_mimic_webp_lossy_decode_image_19k_8bpp,
bench_mimic_webp_lossy_decode_image_40k_24bpp,
bench_mimic_webp_lossy_decode_image_77k_24bpp,
bench_mimic_webp_lossy_decode_image_552k_32bpp,
bench_mimic_webp_lossy_decode_image_4002k_24bpp,
#endif // WUFFS_MIMIC
NULL,
};
int //
main(int argc, char** argv) {
g_proc_package_name = "std/webp";
return test_main(argc, argv, g_tests, g_benches);
}