wuffs gen -version=0.2.0-alpha.42
diff --git a/release/c/wuffs-v0.2.c b/release/c/wuffs-v0.2.c
index 427d1d6..270d0f1 100644
--- a/release/c/wuffs-v0.2.c
+++ b/release/c/wuffs-v0.2.c
@@ -60,15 +60,15 @@
// each major.minor branch, the commit count should increase monotonically.
//
// WUFFS_VERSION was overridden by "wuffs gen -version" based on revision
-// abaab57cfdb4ff6f98c01bfea0d45bc00bcf2e56 committed on 2019-05-31.
+// 6159143f0120ef08bd76aa9cd088d3c38ae6cab7 committed on 2019-06-09.
#define WUFFS_VERSION ((uint64_t)0x0000000000020000)
#define WUFFS_VERSION_MAJOR ((uint64_t)0x00000000)
#define WUFFS_VERSION_MINOR ((uint64_t)0x0002)
#define WUFFS_VERSION_PATCH ((uint64_t)0x0000)
-#define WUFFS_VERSION_PRE_RELEASE_LABEL "alpha.41"
-#define WUFFS_VERSION_BUILD_METADATA_COMMIT_COUNT 1729
-#define WUFFS_VERSION_BUILD_METADATA_COMMIT_DATE 20190531
-#define WUFFS_VERSION_STRING "0.2.0-alpha.41+1729.20190531"
+#define WUFFS_VERSION_PRE_RELEASE_LABEL "alpha.42"
+#define WUFFS_VERSION_BUILD_METADATA_COMMIT_COUNT 1736
+#define WUFFS_VERSION_BUILD_METADATA_COMMIT_DATE 20190609
+#define WUFFS_VERSION_STRING "0.2.0-alpha.42+1736.20190609"
// Define WUFFS_CONFIG__STATIC_FUNCTIONS to make all of Wuffs' functions have
// static storage. The motivation is discussed in the "ALLOW STATIC
@@ -210,6 +210,7 @@
extern const char* wuffs_base__error__initialize_not_called;
extern const char* wuffs_base__error__interleaved_coroutine_calls;
extern const char* wuffs_base__error__not_enough_data;
+extern const char* wuffs_base__error__unsupported_option;
extern const char* wuffs_base__error__too_much_data;
static inline bool //
@@ -2439,6 +2440,8 @@
#ifdef __cplusplus
inline wuffs_base__status set_from_slice(wuffs_base__pixel_config* pixcfg,
wuffs_base__slice_u8 pixbuf_memory);
+ inline wuffs_base__status set_from_table(wuffs_base__pixel_config* pixcfg,
+ wuffs_base__table_u8 pixbuf_memory);
inline wuffs_base__slice_u8 palette();
inline wuffs_base__pixel_format pixel_format() const;
inline wuffs_base__table_u8 plane(uint32_t p);
@@ -2470,12 +2473,13 @@
}
if (wuffs_base__pixel_format__is_planar(pixcfg->private_impl.pixfmt)) {
// TODO: support planar pixel formats, concious of pixel subsampling.
- return wuffs_base__error__bad_argument;
+ return wuffs_base__error__unsupported_option;
}
uint32_t bits_per_pixel =
wuffs_base__pixel_format__bits_per_pixel(pixcfg->private_impl.pixfmt);
if ((bits_per_pixel == 0) || ((bits_per_pixel % 8) != 0)) {
- return wuffs_base__error__bad_argument;
+ // TODO: support fraction-of-byte pixels, e.g. 1 bit per pixel?
+ return wuffs_base__error__unsupported_option;
}
uint64_t bytes_per_pixel = bits_per_pixel / 8;
@@ -2521,6 +2525,38 @@
return NULL;
}
+static inline wuffs_base__status //
+wuffs_base__pixel_buffer__set_from_table(wuffs_base__pixel_buffer* b,
+ wuffs_base__pixel_config* pixcfg,
+ wuffs_base__table_u8 pixbuf_memory) {
+ if (!b) {
+ return wuffs_base__error__bad_receiver;
+ }
+ memset(b, 0, sizeof(*b));
+ if (!pixcfg ||
+ wuffs_base__pixel_format__is_planar(pixcfg->private_impl.pixfmt)) {
+ return wuffs_base__error__bad_argument;
+ }
+ uint32_t bits_per_pixel =
+ wuffs_base__pixel_format__bits_per_pixel(pixcfg->private_impl.pixfmt);
+ if ((bits_per_pixel == 0) || ((bits_per_pixel % 8) != 0)) {
+ // TODO: support fraction-of-byte pixels, e.g. 1 bit per pixel?
+ return wuffs_base__error__unsupported_option;
+ }
+ uint64_t bytes_per_pixel = bits_per_pixel / 8;
+
+ uint64_t width_in_bytes =
+ ((uint64_t)pixcfg->private_impl.width) * bytes_per_pixel;
+ if ((width_in_bytes > pixbuf_memory.width) ||
+ (pixcfg->private_impl.height > pixbuf_memory.height)) {
+ return wuffs_base__error__bad_argument;
+ }
+
+ b->pixcfg = *pixcfg;
+ b->private_impl.planes[0] = pixbuf_memory;
+ return NULL;
+}
+
// wuffs_base__pixel_buffer__palette returns the palette color data. If
// non-empty, it will have length 1024.
static inline wuffs_base__slice_u8 //
@@ -2566,6 +2602,12 @@
return wuffs_base__pixel_buffer__set_from_slice(this, pixcfg, pixbuf_memory);
}
+inline wuffs_base__status //
+wuffs_base__pixel_buffer::set_from_table(wuffs_base__pixel_config* pixcfg,
+ wuffs_base__table_u8 pixbuf_memory) {
+ return wuffs_base__pixel_buffer__set_from_table(this, pixcfg, pixbuf_memory);
+}
+
inline wuffs_base__slice_u8 //
wuffs_base__pixel_buffer::palette() {
return wuffs_base__pixel_buffer__palette(this);
@@ -2614,10 +2656,10 @@
} private_impl;
#ifdef __cplusplus
- inline void prepare(wuffs_base__pixel_format dst_format,
- wuffs_base__slice_u8 dst_palette,
- wuffs_base__pixel_format src_format,
- wuffs_base__slice_u8 src_palette);
+ inline wuffs_base__status prepare(wuffs_base__pixel_format dst_format,
+ wuffs_base__slice_u8 dst_palette,
+ wuffs_base__pixel_format src_format,
+ wuffs_base__slice_u8 src_palette);
inline uint64_t swizzle_packed(wuffs_base__slice_u8 dst,
wuffs_base__slice_u8 dst_palette,
wuffs_base__slice_u8 src) const;
@@ -2625,9 +2667,7 @@
} wuffs_base__pixel_swizzler;
-// TODO: should prepare (both the C and C++ methods) return a status?
-
-void //
+wuffs_base__status //
wuffs_base__pixel_swizzler__prepare(wuffs_base__pixel_swizzler* p,
wuffs_base__pixel_format dst_format,
wuffs_base__slice_u8 dst_palette,
@@ -2642,13 +2682,13 @@
#ifdef __cplusplus
-inline void //
+inline wuffs_base__status //
wuffs_base__pixel_swizzler::prepare(wuffs_base__pixel_format dst_format,
wuffs_base__slice_u8 dst_palette,
wuffs_base__pixel_format src_format,
wuffs_base__slice_u8 src_palette) {
- wuffs_base__pixel_swizzler__prepare(this, dst_format, dst_palette, src_format,
- src_palette);
+ return wuffs_base__pixel_swizzler__prepare(this, dst_format, dst_palette,
+ src_format, src_palette);
}
uint64_t //
@@ -4816,6 +4856,7 @@
const char* wuffs_base__error__interleaved_coroutine_calls =
"#base: interleaved coroutine calls";
const char* wuffs_base__error__not_enough_data = "#base: not enough data";
+const char* wuffs_base__error__unsupported_option = "#base: unsupported option";
const char* wuffs_base__error__too_much_data = "#base: too much data";
// ---------------- Images
@@ -4833,6 +4874,61 @@
}
static uint64_t //
+wuffs_base__pixel_swizzler__copy_3_1(wuffs_base__slice_u8 dst,
+ wuffs_base__slice_u8 dst_palette,
+ wuffs_base__slice_u8 src) {
+ if (dst_palette.len != 1024) {
+ return 0;
+ }
+ size_t dst_len3 = dst.len / 3;
+ size_t len = dst_len3 < src.len ? dst_len3 : src.len;
+ uint8_t* d = dst.ptr;
+ uint8_t* s = src.ptr;
+ size_t n = len;
+
+ // N is the loop unroll count.
+ const int N = 4;
+
+ // The comparison in the while condition is ">", not ">=", because with ">=",
+ // the last 4-byte store could write past the end of the dst slice.
+ //
+ // Each 4-byte store writes one too many bytes, but a subsequent store will
+ // overwrite that with the correct byte. There is always another store,
+ // whether a 4-byte store in this loop or a 1-byte store in the next loop.
+ while (n > N) {
+ wuffs_base__store_u32le(
+ d + (0 * 3),
+ wuffs_base__load_u32le(dst_palette.ptr + ((uint32_t)(s[0]) * 4)));
+ wuffs_base__store_u32le(
+ d + (1 * 3),
+ wuffs_base__load_u32le(dst_palette.ptr + ((uint32_t)(s[1]) * 4)));
+ wuffs_base__store_u32le(
+ d + (2 * 3),
+ wuffs_base__load_u32le(dst_palette.ptr + ((uint32_t)(s[2]) * 4)));
+ wuffs_base__store_u32le(
+ d + (3 * 3),
+ wuffs_base__load_u32le(dst_palette.ptr + ((uint32_t)(s[3]) * 4)));
+
+ s += 1 * N;
+ d += 3 * N;
+ n -= (size_t)(1 * N);
+ }
+
+ while (n >= 1) {
+ uint32_t color =
+ wuffs_base__load_u32le(dst_palette.ptr + ((uint32_t)(s[0]) * 4));
+ d[0] = (uint8_t)(color >> 0);
+ d[1] = (uint8_t)(color >> 8);
+ d[2] = (uint8_t)(color >> 16);
+
+ s += 1 * 1;
+ d += 3 * 1;
+ n -= (size_t)(1 * 1);
+ }
+
+ return len;
+}
+static uint64_t //
wuffs_base__pixel_swizzler__copy_4_1(wuffs_base__slice_u8 dst,
wuffs_base__slice_u8 dst_palette,
wuffs_base__slice_u8 src) {
@@ -4843,8 +4939,9 @@
size_t len = dst_len4 < src.len ? dst_len4 : src.len;
uint8_t* d = dst.ptr;
uint8_t* s = src.ptr;
-
size_t n = len;
+
+ // N is the loop unroll count.
const int N = 4;
while (n >= N) {
@@ -4902,14 +4999,14 @@
return len4 * 4;
}
-void //
+wuffs_base__status //
wuffs_base__pixel_swizzler__prepare(wuffs_base__pixel_swizzler* p,
wuffs_base__pixel_format dst_format,
wuffs_base__slice_u8 dst_palette,
wuffs_base__pixel_format src_format,
wuffs_base__slice_u8 src_palette) {
if (!p) {
- return;
+ return wuffs_base__error__bad_receiver;
}
// TODO: support many more formats.
@@ -4929,6 +5026,13 @@
}
func = wuffs_base__pixel_swizzler__copy_1_1;
break;
+ case WUFFS_BASE__PIXEL_FORMAT__BGR:
+ if (wuffs_base__slice_u8__copy_from_slice(dst_palette, src_palette) !=
+ 1024) {
+ break;
+ }
+ func = wuffs_base__pixel_swizzler__copy_3_1;
+ break;
case WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL:
case WUFFS_BASE__PIXEL_FORMAT__BGRA_PREMUL:
case WUFFS_BASE__PIXEL_FORMAT__BGRA_BINARY:
@@ -4938,6 +5042,13 @@
}
func = wuffs_base__pixel_swizzler__copy_4_1;
break;
+ case WUFFS_BASE__PIXEL_FORMAT__RGB:
+ if (wuffs_base__pixel_swizzler__swap_rgbx_bgrx(dst_palette,
+ src_palette) != 1024) {
+ break;
+ }
+ func = wuffs_base__pixel_swizzler__copy_3_1;
+ break;
case WUFFS_BASE__PIXEL_FORMAT__RGBA_NONPREMUL:
case WUFFS_BASE__PIXEL_FORMAT__RGBA_PREMUL:
case WUFFS_BASE__PIXEL_FORMAT__RGBA_BINARY:
@@ -4957,6 +5068,7 @@
}
p->private_impl.func = func;
+ return func ? NULL : wuffs_base__error__unsupported_option;
}
uint64_t //
@@ -10743,6 +10855,7 @@
uint32_t v_i = 0;
uint32_t v_argb = 0;
wuffs_base__slice_u8 v_dst_palette = {0};
+ wuffs_base__status v_status = NULL;
uint8_t v_lw = 0;
uint8_t* iop_a_src = NULL;
@@ -10867,12 +10980,22 @@
v_dst_palette =
wuffs_base__make_slice_u8(self->private_data.f_dst_palette, 1024);
}
- wuffs_base__pixel_swizzler__prepare(
+ v_status = wuffs_base__pixel_swizzler__prepare(
&self->private_impl.f_swizzler,
wuffs_base__pixel_buffer__pixel_format(a_dst), v_dst_palette,
1191444488,
wuffs_base__make_slice_u8(
self->private_data.f_palettes[v_which_palette], 1024));
+ if (!wuffs_base__status__is_ok(v_status)) {
+ status = v_status;
+ if (wuffs_base__status__is_error(status)) {
+ goto exit;
+ } else if (wuffs_base__status__is_suspension(status)) {
+ status = wuffs_base__error__cannot_return_a_suspension;
+ goto exit;
+ }
+ goto ok;
+ }
if (self->private_impl.f_previous_lzw_decode_ended_abruptly) {
wuffs_base__ignore_status(wuffs_lzw__decoder__initialize(
&self->private_data.f_lzw, sizeof(wuffs_lzw__decoder), WUFFS_VERSION,
@@ -11162,17 +11285,20 @@
uint64_t v_n = 0;
uint64_t v_src_ri = 0;
uint32_t v_bytes_per_pixel = 0;
- uint32_t v_pixfmt = 0;
+ uint32_t v_pixfmt_channels = 0;
wuffs_base__table_u8 v_tab = {0};
uint64_t v_i = 0;
uint64_t v_j = 0;
- v_bytes_per_pixel = 1;
- v_pixfmt = wuffs_base__pixel_buffer__pixel_format(a_pb);
- if ((v_pixfmt == 1157662856) || (v_pixfmt == 1426098312) ||
- (v_pixfmt == 1174440072) || (v_pixfmt == 1442875528) ||
- (v_pixfmt == 1191217288) || (v_pixfmt == 1459652744)) {
+ v_pixfmt_channels = (wuffs_base__pixel_buffer__pixel_format(a_pb) & 65535);
+ if (v_pixfmt_channels == 34952) {
v_bytes_per_pixel = 4;
+ } else if (v_pixfmt_channels == 2184) {
+ v_bytes_per_pixel = 3;
+ } else if (v_pixfmt_channels == 8) {
+ v_bytes_per_pixel = 1;
+ } else {
+ return wuffs_base__error__unsupported_option;
}
v_tab = wuffs_base__pixel_buffer__plane(a_pb, 0);
label_0_continue:;