Drop std/png filter_and_swizzle_low_bit_depth
diff --git a/release/c/wuffs-unsupported-snapshot.c b/release/c/wuffs-unsupported-snapshot.c
index 55710eb..c0457f6 100644
--- a/release/c/wuffs-unsupported-snapshot.c
+++ b/release/c/wuffs-unsupported-snapshot.c
@@ -8568,7 +8568,6 @@
wuffs_zlib__decoder f_zlib;
uint8_t f_dst_palette[1024];
uint8_t f_src_palette[1024];
- uint8_t f_scratch[1024];
struct {
uint32_t v_checksum_have;
@@ -30943,20 +30942,6 @@
wuffs_base__slice_u8 a_workbuf);
static wuffs_base__status
-wuffs_png__decoder__filter_and_swizzle_low_bit_depth(
- wuffs_png__decoder* self,
- wuffs_base__pixel_buffer* a_dst,
- wuffs_base__slice_u8 a_workbuf);
-
-static wuffs_base__empty_struct
-wuffs_png__decoder__swizzle_low_bit_depth(
- wuffs_png__decoder* self,
- wuffs_base__slice_u8 a_dst,
- wuffs_base__slice_u8 a_dst_palette,
- uint64_t a_dst_bytes_per_pixel,
- wuffs_base__slice_u8 a_curr_row);
-
-static wuffs_base__status
wuffs_png__decoder__filter_and_swizzle_tricky(
wuffs_png__decoder* self,
wuffs_base__pixel_buffer* a_dst,
@@ -32732,8 +32717,7 @@
return wuffs_base__make_empty_struct();
}
self->private_impl.f_filter_distance = 1;
- self->private_impl.choosy_filter_and_swizzle = (
- &wuffs_png__decoder__filter_and_swizzle_low_bit_depth);
+ self->private_impl.f_tricky = true;
} else if (self->private_impl.f_color_type == 0) {
if (self->private_impl.f_depth == 8) {
self->private_impl.f_dst_pixfmt = 536870920;
@@ -33694,152 +33678,6 @@
return wuffs_base__make_status(NULL);
}
-// -------- func png.decoder.filter_and_swizzle_low_bit_depth
-
-static wuffs_base__status
-wuffs_png__decoder__filter_and_swizzle_low_bit_depth(
- wuffs_png__decoder* self,
- wuffs_base__pixel_buffer* a_dst,
- wuffs_base__slice_u8 a_workbuf) {
- wuffs_base__pixel_format v_dst_pixfmt = {0};
- uint32_t v_dst_bits_per_pixel = 0;
- uint64_t v_dst_bytes_per_pixel = 0;
- uint64_t v_dst_bytes_per_row = 0;
- wuffs_base__slice_u8 v_dst_palette = {0};
- wuffs_base__table_u8 v_tab = {0};
- uint32_t v_y = 0;
- wuffs_base__slice_u8 v_dst = {0};
- uint8_t v_filter = 0;
- wuffs_base__slice_u8 v_curr_row = {0};
- wuffs_base__slice_u8 v_prev_row = {0};
-
- v_dst_pixfmt = wuffs_base__pixel_buffer__pixel_format(a_dst);
- v_dst_bits_per_pixel = wuffs_base__pixel_format__bits_per_pixel(&v_dst_pixfmt);
- if ((v_dst_bits_per_pixel & 7) != 0) {
- return wuffs_base__make_status(wuffs_base__error__unsupported_option);
- }
- v_dst_bytes_per_pixel = ((uint64_t)((v_dst_bits_per_pixel / 8)));
- v_dst_bytes_per_row = (((uint64_t)(self->private_impl.f_width)) * v_dst_bytes_per_pixel);
- v_dst_palette = wuffs_base__pixel_buffer__palette_or_else(a_dst, wuffs_base__make_slice_u8(self->private_data.f_dst_palette, 1024));
- v_tab = wuffs_base__pixel_buffer__plane(a_dst, 0);
- while (v_y < self->private_impl.f_height) {
- v_dst = wuffs_base__table_u8__row(v_tab, v_y);
- if (v_dst_bytes_per_row < ((uint64_t)(v_dst.len))) {
- v_dst = wuffs_base__slice_u8__subslice_j(v_dst, v_dst_bytes_per_row);
- }
- if (1 > ((uint64_t)(a_workbuf.len))) {
- return wuffs_base__make_status(wuffs_png__error__internal_error_inconsistent_workbuf_length);
- }
- v_filter = a_workbuf.ptr[0];
- a_workbuf = wuffs_base__slice_u8__subslice_i(a_workbuf, 1);
- if (self->private_impl.f_pass_bytes_per_row > ((uint64_t)(a_workbuf.len))) {
- return wuffs_base__make_status(wuffs_png__error__internal_error_inconsistent_workbuf_length);
- }
- v_curr_row = wuffs_base__slice_u8__subslice_j(a_workbuf, self->private_impl.f_pass_bytes_per_row);
- a_workbuf = wuffs_base__slice_u8__subslice_i(a_workbuf, self->private_impl.f_pass_bytes_per_row);
- if (v_filter == 0) {
- } else if (v_filter == 1) {
- wuffs_png__decoder__filter_1(self, v_curr_row);
- } else if (v_filter == 2) {
- wuffs_png__decoder__filter_2(self, v_curr_row, v_prev_row);
- } else if (v_filter == 3) {
- wuffs_png__decoder__filter_3(self, v_curr_row, v_prev_row);
- } else if (v_filter == 4) {
- wuffs_png__decoder__filter_4(self, v_curr_row, v_prev_row);
- } else {
- return wuffs_base__make_status(wuffs_png__error__bad_filter);
- }
- wuffs_png__decoder__swizzle_low_bit_depth(self,
- v_dst,
- v_dst_palette,
- v_dst_bytes_per_pixel,
- v_curr_row);
- v_prev_row = v_curr_row;
- v_y += 1;
- }
- return wuffs_base__make_status(NULL);
-}
-
-// -------- func png.decoder.swizzle_low_bit_depth
-
-static wuffs_base__empty_struct
-wuffs_png__decoder__swizzle_low_bit_depth(
- wuffs_png__decoder* self,
- wuffs_base__slice_u8 a_dst,
- wuffs_base__slice_u8 a_dst_palette,
- uint64_t a_dst_bytes_per_pixel,
- wuffs_base__slice_u8 a_curr_row) {
- uint8_t v_multiplier = 0;
- uint8_t v_c = 0;
- uint64_t v_i = 0;
- uint64_t v_n = 0;
- wuffs_base__slice_u8 v_fragment = {0};
- wuffs_base__slice_u8 v_remaining = {0};
-
- v_multiplier = 1;
- if (self->private_impl.f_color_type == 0) {
- v_multiplier = WUFFS_PNG__LOW_BIT_DEPTH_MULTIPLIERS[(self->private_impl.f_depth & 7)];
- }
- v_remaining = a_curr_row;
- while (((uint64_t)(a_dst.len)) > 0) {
- v_fragment = v_remaining;
- v_remaining = wuffs_base__utility__empty_slice_u8();
- if (self->private_impl.f_depth == 1) {
- if (((uint64_t)(v_fragment.len)) > 128) {
- v_remaining = wuffs_base__slice_u8__subslice_i(v_fragment, 128);
- v_fragment = wuffs_base__slice_u8__subslice_j(v_fragment, 128);
- }
- v_i = 0;
- while (v_i < ((uint64_t)(v_fragment.len))) {
- v_c = v_fragment.ptr[v_i];
- self->private_data.f_scratch[((v_i * 8) + 0)] = ((uint8_t)((1 & (v_c >> 7)) * v_multiplier));
- self->private_data.f_scratch[((v_i * 8) + 1)] = ((uint8_t)((1 & (v_c >> 6)) * v_multiplier));
- self->private_data.f_scratch[((v_i * 8) + 2)] = ((uint8_t)((1 & (v_c >> 5)) * v_multiplier));
- self->private_data.f_scratch[((v_i * 8) + 3)] = ((uint8_t)((1 & (v_c >> 4)) * v_multiplier));
- self->private_data.f_scratch[((v_i * 8) + 4)] = ((uint8_t)((1 & (v_c >> 3)) * v_multiplier));
- self->private_data.f_scratch[((v_i * 8) + 5)] = ((uint8_t)((1 & (v_c >> 2)) * v_multiplier));
- self->private_data.f_scratch[((v_i * 8) + 6)] = ((uint8_t)((1 & (v_c >> 1)) * v_multiplier));
- self->private_data.f_scratch[((v_i * 8) + 7)] = ((uint8_t)((1 & (v_c >> 0)) * v_multiplier));
- v_i += 1;
- }
- } else if (self->private_impl.f_depth == 2) {
- if (((uint64_t)(v_fragment.len)) > 256) {
- v_remaining = wuffs_base__slice_u8__subslice_i(v_fragment, 256);
- v_fragment = wuffs_base__slice_u8__subslice_j(v_fragment, 256);
- }
- v_i = 0;
- while (v_i < ((uint64_t)(v_fragment.len))) {
- v_c = v_fragment.ptr[v_i];
- self->private_data.f_scratch[((v_i * 4) + 0)] = ((uint8_t)((3 & (v_c >> 6)) * v_multiplier));
- self->private_data.f_scratch[((v_i * 4) + 1)] = ((uint8_t)((3 & (v_c >> 4)) * v_multiplier));
- self->private_data.f_scratch[((v_i * 4) + 2)] = ((uint8_t)((3 & (v_c >> 2)) * v_multiplier));
- self->private_data.f_scratch[((v_i * 4) + 3)] = ((uint8_t)((3 & (v_c >> 0)) * v_multiplier));
- v_i += 1;
- }
- } else {
- if (((uint64_t)(v_fragment.len)) > 512) {
- v_remaining = wuffs_base__slice_u8__subslice_i(v_fragment, 512);
- v_fragment = wuffs_base__slice_u8__subslice_j(v_fragment, 512);
- }
- v_i = 0;
- while (v_i < ((uint64_t)(v_fragment.len))) {
- v_c = v_fragment.ptr[v_i];
- self->private_data.f_scratch[((v_i * 2) + 0)] = ((uint8_t)((15 & (v_c >> 4)) * v_multiplier));
- self->private_data.f_scratch[((v_i * 2) + 1)] = ((uint8_t)((15 & (v_c >> 0)) * v_multiplier));
- v_i += 1;
- }
- }
- wuffs_base__pixel_swizzler__swizzle_interleaved_from_slice(&self->private_impl.f_swizzler, a_dst, a_dst_palette, wuffs_base__make_slice_u8(self->private_data.f_scratch, 1024));
- v_n = (1024 * a_dst_bytes_per_pixel);
- if (v_n < ((uint64_t)(a_dst.len))) {
- a_dst = wuffs_base__slice_u8__subslice_i(a_dst, v_n);
- } else {
- a_dst = wuffs_base__utility__empty_slice_u8();
- }
- }
- return wuffs_base__make_empty_struct();
-}
-
// -------- func png.decoder.frame_dirty_rect
WUFFS_BASE__MAYBE_STATIC wuffs_base__rect_ie_u32
diff --git a/std/png/decode_png.wuffs b/std/png/decode_png.wuffs
index 6b7da75..b3603b8 100644
--- a/std/png/decode_png.wuffs
+++ b/std/png/decode_png.wuffs
@@ -96,10 +96,6 @@
dst_palette : array[4 * 256] base.u8,
src_palette : array[4 * 256] base.u8,
-
- // scratch is used for low bit depths, expanding less-than-1 byte per pixel
- // to 1 byte per pixel before passing to this.swizzler.
- scratch : array[1024] base.u8,
)
pub func decoder.set_quirk_enabled!(quirk: base.u32, enabled: base.bool) {
@@ -302,7 +298,7 @@
}
this.filter_distance = 1
- choose filter_and_swizzle = [filter_and_swizzle_low_bit_depth]
+ this.tricky = true
} else if this.color_type == 0 {
if this.depth == 8 {
@@ -696,9 +692,6 @@
return "#bad filter"
}
- // filter_and_swizzle_low_bit_depth copy-pastes this filter_and_swizzle
- // function and adds code here to expand to 8 bits per pixel.
-
this.swizzler.swizzle_interleaved_from_slice!(
dst: dst,
dst_palette: dst_palette,
@@ -711,172 +704,6 @@
return ok
}
-pri func decoder.filter_and_swizzle_low_bit_depth!(dst: ptr base.pixel_buffer, workbuf: slice base.u8) base.status {
- // This function is largely copy-pasted from filter_and_swizzle.
- // Differences are marked with a §.
-
- var dst_pixfmt : base.pixel_format
- var dst_bits_per_pixel : base.u32[..= 256]
- var dst_bytes_per_pixel : base.u64[..= 32]
- var dst_bytes_per_row : base.u64
- var dst_palette : slice base.u8
- var tab : table base.u8
-
- var y : base.u32
- var dst : slice base.u8
- var filter : base.u8
- var curr_row : slice base.u8
- var prev_row : slice base.u8
-
- // TODO: the dst_pixfmt variable shouldn't be necessary. We should be able
- // to chain the two calls: "args.dst.pixel_format().bits_per_pixel()".
- dst_pixfmt = args.dst.pixel_format()
- dst_bits_per_pixel = dst_pixfmt.bits_per_pixel()
- if (dst_bits_per_pixel & 7) <> 0 {
- return base."#unsupported option"
- }
- dst_bytes_per_pixel = (dst_bits_per_pixel / 8) as base.u64
- dst_bytes_per_row = (this.width as base.u64) * dst_bytes_per_pixel
- dst_palette = args.dst.palette_or_else(fallback: this.dst_palette[..])
- tab = args.dst.plane(p: 0)
-
- while y < this.height {
- assert y < 0x00FF_FFFF via "a < b: a < c; c <= b"(c: this.height)
- dst = tab.row(y: y)
- if dst_bytes_per_row < dst.length() {
- dst = dst[.. dst_bytes_per_row]
- }
-
- if 1 > args.workbuf.length() {
- return "#internal error: inconsistent workbuf length"
- }
- filter = args.workbuf[0]
- args.workbuf = args.workbuf[1 ..]
- if this.pass_bytes_per_row > args.workbuf.length() {
- return "#internal error: inconsistent workbuf length"
- }
- curr_row = args.workbuf[.. this.pass_bytes_per_row]
- args.workbuf = args.workbuf[this.pass_bytes_per_row ..]
-
- if filter == 0 {
- // No-op.
- } else if filter == 1 {
- this.filter_1!(curr: curr_row)
- } else if filter == 2 {
- this.filter_2!(curr: curr_row, prev: prev_row)
- } else if filter == 3 {
- this.filter_3!(curr: curr_row, prev: prev_row)
- } else if filter == 4 {
- this.filter_4!(curr: curr_row, prev: prev_row)
- } else {
- return "#bad filter"
- }
-
- this.swizzle_low_bit_depth!( // §
- dst: dst,
- dst_palette: dst_palette,
- dst_bytes_per_pixel: dst_bytes_per_pixel,
- curr_row: curr_row)
-
- prev_row = curr_row
- y += 1
- } endwhile
-
- return ok
-}
-
-pri func decoder.swizzle_low_bit_depth!(dst: slice base.u8, dst_palette: slice base.u8, dst_bytes_per_pixel: base.u64[..= 32], curr_row: slice base.u8) {
- var multiplier : base.u8
- var c : base.u8
- var i : base.u64
- var n : base.u64
- var fragment : slice base.u8
- var remaining : slice base.u8
-
- multiplier = 1
- if this.color_type == 0 { // Color type 0 means base.PIXEL_FORMAT__Y.
- multiplier = LOW_BIT_DEPTH_MULTIPLIERS[this.depth & 7]
- }
-
- remaining = args.curr_row
- while args.dst.length() > 0 {
- fragment = remaining
- remaining = this.util.empty_slice_u8()
-
- if this.depth == 1 {
- if fragment.length() > 128 {
- remaining = fragment[128 ..]
- fragment = fragment[.. 128]
- assert fragment.length() <= 128
- }
- i = 0
- while i < fragment.length(),
- inv fragment.length() <= 128,
- {
- assert i < 128 via "a < b: a < c; c <= b"(c: fragment.length())
- c = fragment[i]
- this.scratch[(i * 8) + 0] = (0b0001 & (c >> 7)) ~mod* multiplier
- this.scratch[(i * 8) + 1] = (0b0001 & (c >> 6)) ~mod* multiplier
- this.scratch[(i * 8) + 2] = (0b0001 & (c >> 5)) ~mod* multiplier
- this.scratch[(i * 8) + 3] = (0b0001 & (c >> 4)) ~mod* multiplier
- this.scratch[(i * 8) + 4] = (0b0001 & (c >> 3)) ~mod* multiplier
- this.scratch[(i * 8) + 5] = (0b0001 & (c >> 2)) ~mod* multiplier
- this.scratch[(i * 8) + 6] = (0b0001 & (c >> 1)) ~mod* multiplier
- this.scratch[(i * 8) + 7] = (0b0001 & (c >> 0)) ~mod* multiplier
- i += 1
- } endwhile
-
- } else if this.depth == 2 {
- if fragment.length() > 256 {
- remaining = fragment[256 ..]
- fragment = fragment[.. 256]
- assert fragment.length() <= 256
- }
- i = 0
- while i < fragment.length(),
- inv fragment.length() <= 256,
- {
- assert i < 256 via "a < b: a < c; c <= b"(c: fragment.length())
- c = fragment[i]
- this.scratch[(i * 4) + 0] = (0b0011 & (c >> 6)) ~mod* multiplier
- this.scratch[(i * 4) + 1] = (0b0011 & (c >> 4)) ~mod* multiplier
- this.scratch[(i * 4) + 2] = (0b0011 & (c >> 2)) ~mod* multiplier
- this.scratch[(i * 4) + 3] = (0b0011 & (c >> 0)) ~mod* multiplier
- i += 1
- } endwhile
-
- } else {
- if fragment.length() > 512 {
- remaining = fragment[512 ..]
- fragment = fragment[.. 512]
- assert fragment.length() <= 512
- }
- i = 0
- while i < fragment.length(),
- inv fragment.length() <= 512,
- {
- assert i < 512 via "a < b: a < c; c <= b"(c: fragment.length())
- c = fragment[i]
- this.scratch[(i * 2) + 0] = (0b1111 & (c >> 4)) ~mod* multiplier
- this.scratch[(i * 2) + 1] = (0b1111 & (c >> 0)) ~mod* multiplier
- i += 1
- } endwhile
- }
-
- this.swizzler.swizzle_interleaved_from_slice!(
- dst: args.dst,
- dst_palette: args.dst_palette,
- src: this.scratch[.. 1024])
-
- n = 1024 * args.dst_bytes_per_pixel
- if n < args.dst.length() {
- args.dst = args.dst[n ..]
- } else {
- args.dst = this.util.empty_slice_u8()
- }
- } endwhile
-}
-
pub func decoder.frame_dirty_rect() base.rect_ie_u32 {
return this.util.make_rect_ie_u32(
min_incl_x: 0,