Spin out std/png/decode_filter_fallback.wuffs
diff --git a/release/c/wuffs-unsupported-snapshot.c b/release/c/wuffs-unsupported-snapshot.c
index a81ed39..ab9770c 100644
--- a/release/c/wuffs-unsupported-snapshot.c
+++ b/release/c/wuffs-unsupported-snapshot.c
@@ -29825,17 +29825,6 @@
// ---------------- Private Function Prototypes
-static wuffs_base__status
-wuffs_png__decoder__decode_plte(
- wuffs_png__decoder* self,
- wuffs_base__io_buffer* a_src);
-
-static wuffs_base__status
-wuffs_png__decoder__filter_and_swizzle(
- wuffs_png__decoder* self,
- wuffs_base__pixel_buffer* a_dst,
- wuffs_base__slice_u8 a_workbuf);
-
static wuffs_base__empty_struct
wuffs_png__decoder__filter_1(
wuffs_png__decoder* self,
@@ -29859,6 +29848,17 @@
wuffs_base__slice_u8 a_curr,
wuffs_base__slice_u8 a_prev);
+static wuffs_base__status
+wuffs_png__decoder__decode_plte(
+ wuffs_png__decoder* self,
+ wuffs_base__io_buffer* a_src);
+
+static wuffs_base__status
+wuffs_png__decoder__filter_and_swizzle(
+ wuffs_png__decoder* self,
+ wuffs_base__pixel_buffer* a_dst,
+ wuffs_base__slice_u8 a_workbuf);
+
// ---------------- VTables
const wuffs_base__image_decoder__func_ptrs
@@ -29980,6 +29980,140 @@
// ---------------- Function Implementations
+// -------- func png.decoder.filter_1
+
+static wuffs_base__empty_struct
+wuffs_png__decoder__filter_1(
+ wuffs_png__decoder* self,
+ wuffs_base__slice_u8 a_curr) {
+ uint64_t v_filter_distance = 0;
+ uint8_t v_fa = 0;
+ uint64_t v_i_start = 0;
+ uint64_t v_i = 0;
+
+ v_filter_distance = ((uint64_t)(self->private_impl.f_filter_distance));
+ v_i_start = 0;
+ while (v_i_start < v_filter_distance) {
+ v_fa = 0;
+ v_i = v_i_start;
+ while (v_i < ((uint64_t)(a_curr.len))) {
+ a_curr.ptr[v_i] += v_fa;
+ v_fa = a_curr.ptr[v_i];
+ v_i += v_filter_distance;
+ }
+ v_i_start += 1;
+ }
+ return wuffs_base__make_empty_struct();
+}
+
+// -------- func png.decoder.filter_2
+
+static wuffs_base__empty_struct
+wuffs_png__decoder__filter_2(
+ wuffs_png__decoder* self,
+ wuffs_base__slice_u8 a_curr,
+ wuffs_base__slice_u8 a_prev) {
+ uint64_t v_i = 0;
+
+ v_i = 0;
+ while ((v_i < ((uint64_t)(a_curr.len))) && (v_i < ((uint64_t)(a_prev.len)))) {
+ a_curr.ptr[v_i] += a_prev.ptr[v_i];
+ v_i += 1;
+ }
+ return wuffs_base__make_empty_struct();
+}
+
+// -------- func png.decoder.filter_3
+
+static wuffs_base__empty_struct
+wuffs_png__decoder__filter_3(
+ wuffs_png__decoder* self,
+ wuffs_base__slice_u8 a_curr,
+ wuffs_base__slice_u8 a_prev) {
+ uint64_t v_filter_distance = 0;
+ uint64_t v_i = 0;
+
+ v_filter_distance = ((uint64_t)(self->private_impl.f_filter_distance));
+ if (((uint64_t)(a_prev.len)) == 0) {
+ v_i = v_filter_distance;
+ while (v_i < ((uint64_t)(a_curr.len))) {
+ if (v_i >= v_filter_distance) {
+ if ((v_i - v_filter_distance) < ((uint64_t)(a_curr.len))) {
+ a_curr.ptr[v_i] += (a_curr.ptr[(v_i - v_filter_distance)] / 2);
+ }
+ }
+ v_i += 1;
+ }
+ } else {
+ v_i = 0;
+ while ((v_i < ((uint64_t)(a_curr.len))) && (v_i < ((uint64_t)(a_prev.len)))) {
+ if (v_i >= v_filter_distance) {
+ if ((v_i - v_filter_distance) < ((uint64_t)(a_curr.len))) {
+ a_curr.ptr[v_i] += ((uint8_t)(((((uint32_t)(a_curr.ptr[(v_i - v_filter_distance)])) + ((uint32_t)(a_prev.ptr[v_i]))) / 2)));
+ }
+ } else {
+ a_curr.ptr[v_i] += (a_prev.ptr[v_i] / 2);
+ }
+ v_i += 1;
+ }
+ }
+ return wuffs_base__make_empty_struct();
+}
+
+// -------- func png.decoder.filter_4
+
+static wuffs_base__empty_struct
+wuffs_png__decoder__filter_4(
+ wuffs_png__decoder* self,
+ wuffs_base__slice_u8 a_curr,
+ wuffs_base__slice_u8 a_prev) {
+ uint64_t v_filter_distance = 0;
+ uint64_t v_i = 0;
+ uint32_t v_fa = 0;
+ uint32_t v_fb = 0;
+ uint32_t v_fc = 0;
+ uint32_t v_pp = 0;
+ uint32_t v_pa = 0;
+ uint32_t v_pb = 0;
+ uint32_t v_pc = 0;
+
+ v_filter_distance = ((uint64_t)(self->private_impl.f_filter_distance));
+ v_i = 0;
+ while ((v_i < ((uint64_t)(a_curr.len))) && (v_i < ((uint64_t)(a_prev.len)))) {
+ if (v_i < v_filter_distance) {
+ a_curr.ptr[v_i] += a_prev.ptr[v_i];
+ } else {
+ if (((v_i - v_filter_distance) < ((uint64_t)(a_curr.len))) && ((v_i - v_filter_distance) < ((uint64_t)(a_prev.len)))) {
+ v_fa = ((uint32_t)(a_curr.ptr[(v_i - v_filter_distance)]));
+ v_fb = ((uint32_t)(a_prev.ptr[v_i]));
+ v_fc = ((uint32_t)(a_prev.ptr[(v_i - v_filter_distance)]));
+ v_pp = ((v_fa + v_fb) - v_fc);
+ v_pa = (v_pp - v_fa);
+ if (v_pa >= 2147483648) {
+ v_pa = (0 - v_pa);
+ }
+ v_pb = (v_pp - v_fb);
+ if (v_pb >= 2147483648) {
+ v_pb = (0 - v_pb);
+ }
+ v_pc = (v_pp - v_fc);
+ if (v_pc >= 2147483648) {
+ v_pc = (0 - v_pc);
+ }
+ if ((v_pa <= v_pb) && (v_pa <= v_pc)) {
+ a_curr.ptr[v_i] += ((uint8_t)((v_fa & 255)));
+ } else if (v_pb <= v_pc) {
+ a_curr.ptr[v_i] += ((uint8_t)((v_fb & 255)));
+ } else {
+ a_curr.ptr[v_i] += ((uint8_t)((v_fc & 255)));
+ }
+ }
+ }
+ v_i += 1;
+ }
+ return wuffs_base__make_empty_struct();
+}
+
// -------- func png.decoder.set_quirk_enabled
WUFFS_BASE__MAYBE_STATIC wuffs_base__empty_struct
@@ -31014,140 +31148,6 @@
return wuffs_base__make_status(NULL);
}
-// -------- func png.decoder.filter_1
-
-static wuffs_base__empty_struct
-wuffs_png__decoder__filter_1(
- wuffs_png__decoder* self,
- wuffs_base__slice_u8 a_curr) {
- uint64_t v_filter_distance = 0;
- uint8_t v_fa = 0;
- uint64_t v_i_start = 0;
- uint64_t v_i = 0;
-
- v_filter_distance = ((uint64_t)(self->private_impl.f_filter_distance));
- v_i_start = 0;
- while (v_i_start < v_filter_distance) {
- v_fa = 0;
- v_i = v_i_start;
- while (v_i < ((uint64_t)(a_curr.len))) {
- a_curr.ptr[v_i] += v_fa;
- v_fa = a_curr.ptr[v_i];
- v_i += v_filter_distance;
- }
- v_i_start += 1;
- }
- return wuffs_base__make_empty_struct();
-}
-
-// -------- func png.decoder.filter_2
-
-static wuffs_base__empty_struct
-wuffs_png__decoder__filter_2(
- wuffs_png__decoder* self,
- wuffs_base__slice_u8 a_curr,
- wuffs_base__slice_u8 a_prev) {
- uint64_t v_i = 0;
-
- v_i = 0;
- while ((v_i < ((uint64_t)(a_curr.len))) && (v_i < ((uint64_t)(a_prev.len)))) {
- a_curr.ptr[v_i] += a_prev.ptr[v_i];
- v_i += 1;
- }
- return wuffs_base__make_empty_struct();
-}
-
-// -------- func png.decoder.filter_3
-
-static wuffs_base__empty_struct
-wuffs_png__decoder__filter_3(
- wuffs_png__decoder* self,
- wuffs_base__slice_u8 a_curr,
- wuffs_base__slice_u8 a_prev) {
- uint64_t v_filter_distance = 0;
- uint64_t v_i = 0;
-
- v_filter_distance = ((uint64_t)(self->private_impl.f_filter_distance));
- if (((uint64_t)(a_prev.len)) == 0) {
- v_i = v_filter_distance;
- while (v_i < ((uint64_t)(a_curr.len))) {
- if (v_i >= v_filter_distance) {
- if ((v_i - v_filter_distance) < ((uint64_t)(a_curr.len))) {
- a_curr.ptr[v_i] += (a_curr.ptr[(v_i - v_filter_distance)] / 2);
- }
- }
- v_i += 1;
- }
- } else {
- v_i = 0;
- while ((v_i < ((uint64_t)(a_curr.len))) && (v_i < ((uint64_t)(a_prev.len)))) {
- if (v_i >= v_filter_distance) {
- if ((v_i - v_filter_distance) < ((uint64_t)(a_curr.len))) {
- a_curr.ptr[v_i] += ((uint8_t)(((((uint32_t)(a_curr.ptr[(v_i - v_filter_distance)])) + ((uint32_t)(a_prev.ptr[v_i]))) / 2)));
- }
- } else {
- a_curr.ptr[v_i] += (a_prev.ptr[v_i] / 2);
- }
- v_i += 1;
- }
- }
- return wuffs_base__make_empty_struct();
-}
-
-// -------- func png.decoder.filter_4
-
-static wuffs_base__empty_struct
-wuffs_png__decoder__filter_4(
- wuffs_png__decoder* self,
- wuffs_base__slice_u8 a_curr,
- wuffs_base__slice_u8 a_prev) {
- uint64_t v_filter_distance = 0;
- uint64_t v_i = 0;
- uint32_t v_fa = 0;
- uint32_t v_fb = 0;
- uint32_t v_fc = 0;
- uint32_t v_pp = 0;
- uint32_t v_pa = 0;
- uint32_t v_pb = 0;
- uint32_t v_pc = 0;
-
- v_filter_distance = ((uint64_t)(self->private_impl.f_filter_distance));
- v_i = 0;
- while ((v_i < ((uint64_t)(a_curr.len))) && (v_i < ((uint64_t)(a_prev.len)))) {
- if (v_i < v_filter_distance) {
- a_curr.ptr[v_i] += a_prev.ptr[v_i];
- } else {
- if (((v_i - v_filter_distance) < ((uint64_t)(a_curr.len))) && ((v_i - v_filter_distance) < ((uint64_t)(a_prev.len)))) {
- v_fa = ((uint32_t)(a_curr.ptr[(v_i - v_filter_distance)]));
- v_fb = ((uint32_t)(a_prev.ptr[v_i]));
- v_fc = ((uint32_t)(a_prev.ptr[(v_i - v_filter_distance)]));
- v_pp = ((v_fa + v_fb) - v_fc);
- v_pa = (v_pp - v_fa);
- if (v_pa >= 2147483648) {
- v_pa = (0 - v_pa);
- }
- v_pb = (v_pp - v_fb);
- if (v_pb >= 2147483648) {
- v_pb = (0 - v_pb);
- }
- v_pc = (v_pp - v_fc);
- if (v_pc >= 2147483648) {
- v_pc = (0 - v_pc);
- }
- if ((v_pa <= v_pb) && (v_pa <= v_pc)) {
- a_curr.ptr[v_i] += ((uint8_t)((v_fa & 255)));
- } else if (v_pb <= v_pc) {
- a_curr.ptr[v_i] += ((uint8_t)((v_fb & 255)));
- } else {
- a_curr.ptr[v_i] += ((uint8_t)((v_fc & 255)));
- }
- }
- }
- v_i += 1;
- }
- 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_filter_fallback.wuffs b/std/png/decode_filter_fallback.wuffs
new file mode 100644
index 0000000..4236475
--- /dev/null
+++ b/std/png/decode_filter_fallback.wuffs
@@ -0,0 +1,131 @@
+// Copyright 2020 The Wuffs Authors.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+pri func decoder.filter_1!(curr: slice base.u8) {
+ var filter_distance : base.u64[..= 8]
+ var fa : base.u8
+ var i_start : base.u64
+ var i : base.u64
+
+ filter_distance = this.filter_distance as base.u64
+ i_start = 0
+ while i_start < filter_distance {
+ assert i_start < 8 via "a < b: a < c; c <= b"(c: filter_distance)
+ fa = 0
+ i = i_start
+ while i < args.curr.length(),
+ inv i_start < 8,
+ {
+ args.curr[i] ~mod+= fa
+ fa = args.curr[i]
+ i ~mod+= filter_distance
+ } endwhile
+ i_start += 1
+ } endwhile
+}
+
+pri func decoder.filter_2!(curr: slice base.u8, prev: slice base.u8) {
+ var i : base.u64
+
+ i = 0
+ while (i < args.curr.length()) and (i < args.prev.length()) {
+ assert i < 0xFFFF_FFFF_FFFF_FFFF via "a < b: a < c; c <= b"(c: args.curr.length())
+ args.curr[i] ~mod+= args.prev[i]
+ i += 1
+ } endwhile
+}
+
+pri func decoder.filter_3!(curr: slice base.u8, prev: slice base.u8) {
+ var filter_distance : base.u64[..= 8]
+ var i : base.u64
+
+ filter_distance = this.filter_distance as base.u64
+ if args.prev.length() == 0 {
+ i = filter_distance
+ while i < args.curr.length() {
+ assert i < 0xFFFF_FFFF_FFFF_FFFF via "a < b: a < c; c <= b"(c: args.curr.length())
+ if i >= filter_distance {
+ if (i - filter_distance) < args.curr.length() {
+ args.curr[i] ~mod+= args.curr[i - filter_distance] / 2
+ }
+ }
+ i += 1
+ } endwhile
+ } else {
+ i = 0
+ while (i < args.curr.length()) and (i < args.prev.length()) {
+ assert i < 0xFFFF_FFFF_FFFF_FFFF via "a < b: a < c; c <= b"(c: args.curr.length())
+ if i >= filter_distance {
+ if (i - filter_distance) < args.curr.length() {
+ args.curr[i] ~mod+= ((
+ (args.curr[i - filter_distance] as base.u32) +
+ (args.prev[i] as base.u32)) / 2) as base.u8
+ }
+ } else {
+ args.curr[i] ~mod+= args.prev[i] / 2
+ }
+ i += 1
+ } endwhile
+ }
+}
+
+pri func decoder.filter_4!(curr: slice base.u8, prev: slice base.u8) {
+ var filter_distance : base.u64[..= 8]
+ var i : base.u64
+
+ var fa : base.u32
+ var fb : base.u32
+ var fc : base.u32
+ var pp : base.u32
+ var pa : base.u32
+ var pb : base.u32
+ var pc : base.u32
+
+ filter_distance = this.filter_distance as base.u64
+ i = 0
+ while (i < args.curr.length()) and (i < args.prev.length()) {
+ assert i < 0xFFFF_FFFF_FFFF_FFFF via "a < b: a < c; c <= b"(c: args.curr.length())
+ if i < filter_distance {
+ args.curr[i] ~mod+= args.prev[i]
+ } else {
+ if ((i - filter_distance) < args.curr.length()) and
+ ((i - filter_distance) < args.prev.length()) {
+ fa = args.curr[i - filter_distance] as base.u32
+ fb = args.prev[i] as base.u32
+ fc = args.prev[i - filter_distance] as base.u32
+ pp = (fa ~mod+ fb) ~mod- fc
+ pa = pp ~mod- fa
+ if pa >= 0x8000_0000 {
+ pa = 0 ~mod- pa
+ }
+ pb = pp ~mod- fb
+ if pb >= 0x8000_0000 {
+ pb = 0 ~mod- pb
+ }
+ pc = pp ~mod- fc
+ if pc >= 0x8000_0000 {
+ pc = 0 ~mod- pc
+ }
+ if (pa <= pb) and (pa <= pc) {
+ args.curr[i] ~mod+= (fa & 0xFF) as base.u8
+ } else if pb <= pc {
+ args.curr[i] ~mod+= (fb & 0xFF) as base.u8
+ } else {
+ args.curr[i] ~mod+= (fc & 0xFF) as base.u8
+ }
+ }
+ }
+ i += 1
+ } endwhile
+}
diff --git a/std/png/decode_png.wuffs b/std/png/decode_png.wuffs
index 5c1e6a4..882baf5 100644
--- a/std/png/decode_png.wuffs
+++ b/std/png/decode_png.wuffs
@@ -461,124 +461,6 @@
return ok
}
-pri func decoder.filter_1!(curr: slice base.u8) {
- var filter_distance : base.u64[..= 8]
- var fa : base.u8
- var i_start : base.u64
- var i : base.u64
-
- filter_distance = this.filter_distance as base.u64
- i_start = 0
- while i_start < filter_distance {
- assert i_start < 8 via "a < b: a < c; c <= b"(c: filter_distance)
- fa = 0
- i = i_start
- while i < args.curr.length(),
- inv i_start < 8,
- {
- args.curr[i] ~mod+= fa
- fa = args.curr[i]
- i ~mod+= filter_distance
- } endwhile
- i_start += 1
- } endwhile
-}
-
-pri func decoder.filter_2!(curr: slice base.u8, prev: slice base.u8) {
- var i : base.u64
-
- i = 0
- while (i < args.curr.length()) and (i < args.prev.length()) {
- assert i < 0xFFFF_FFFF_FFFF_FFFF via "a < b: a < c; c <= b"(c: args.curr.length())
- args.curr[i] ~mod+= args.prev[i]
- i += 1
- } endwhile
-}
-
-pri func decoder.filter_3!(curr: slice base.u8, prev: slice base.u8) {
- var filter_distance : base.u64[..= 8]
- var i : base.u64
-
- filter_distance = this.filter_distance as base.u64
- if args.prev.length() == 0 {
- i = filter_distance
- while i < args.curr.length() {
- assert i < 0xFFFF_FFFF_FFFF_FFFF via "a < b: a < c; c <= b"(c: args.curr.length())
- if i >= filter_distance {
- if (i - filter_distance) < args.curr.length() {
- args.curr[i] ~mod+= args.curr[i - filter_distance] / 2
- }
- }
- i += 1
- } endwhile
- } else {
- i = 0
- while (i < args.curr.length()) and (i < args.prev.length()) {
- assert i < 0xFFFF_FFFF_FFFF_FFFF via "a < b: a < c; c <= b"(c: args.curr.length())
- if i >= filter_distance {
- if (i - filter_distance) < args.curr.length() {
- args.curr[i] ~mod+= ((
- (args.curr[i - filter_distance] as base.u32) +
- (args.prev[i] as base.u32)) / 2) as base.u8
- }
- } else {
- args.curr[i] ~mod+= args.prev[i] / 2
- }
- i += 1
- } endwhile
- }
-}
-
-pri func decoder.filter_4!(curr: slice base.u8, prev: slice base.u8) {
- var filter_distance : base.u64[..= 8]
- var i : base.u64
-
- var fa : base.u32
- var fb : base.u32
- var fc : base.u32
- var pp : base.u32
- var pa : base.u32
- var pb : base.u32
- var pc : base.u32
-
- filter_distance = this.filter_distance as base.u64
- i = 0
- while (i < args.curr.length()) and (i < args.prev.length()) {
- assert i < 0xFFFF_FFFF_FFFF_FFFF via "a < b: a < c; c <= b"(c: args.curr.length())
- if i < filter_distance {
- args.curr[i] ~mod+= args.prev[i]
- } else {
- if ((i - filter_distance) < args.curr.length()) and
- ((i - filter_distance) < args.prev.length()) {
- fa = args.curr[i - filter_distance] as base.u32
- fb = args.prev[i] as base.u32
- fc = args.prev[i - filter_distance] as base.u32
- pp = (fa ~mod+ fb) ~mod- fc
- pa = pp ~mod- fa
- if pa >= 0x8000_0000 {
- pa = 0 ~mod- pa
- }
- pb = pp ~mod- fb
- if pb >= 0x8000_0000 {
- pb = 0 ~mod- pb
- }
- pc = pp ~mod- fc
- if pc >= 0x8000_0000 {
- pc = 0 ~mod- pc
- }
- if (pa <= pb) and (pa <= pc) {
- args.curr[i] ~mod+= (fa & 0xFF) as base.u8
- } else if pb <= pc {
- args.curr[i] ~mod+= (fb & 0xFF) as base.u8
- } else {
- args.curr[i] ~mod+= (fc & 0xFF) as base.u8
- }
- }
- }
- i += 1
- } endwhile
-}
-
pub func decoder.frame_dirty_rect() base.rect_ie_u32 {
return this.util.make_rect_ie_u32(
min_incl_x: 0,