Fix dirty rect for interlaced GIFs
diff --git a/release/c/wuffs-unsupported-snapshot.c b/release/c/wuffs-unsupported-snapshot.c
index fea15d5..24a46ec 100644
--- a/release/c/wuffs-unsupported-snapshot.c
+++ b/release/c/wuffs-unsupported-snapshot.c
@@ -11179,6 +11179,18 @@
v_replicate_src);
v_replicate_count -= 1;
}
+ v_replicate_count =
+ (((uint32_t)(
+ wuffs_gif__interlace_count[self->private_impl.f_interlace])) +
+ 1);
+ v_replicate_count = wuffs_base__u32__sat_add(
+ v_replicate_count, self->private_impl.f_dst_y);
+ v_replicate_count = wuffs_base__u32__min(
+ v_replicate_count, self->private_impl.f_frame_rect_y1);
+ self->private_impl.f_dirty_y = wuffs_base__range_ie_u32__unite(
+ &self->private_impl.f_dirty_y,
+ wuffs_base__utility__make_range_ie_u32(self->private_impl.f_dst_y,
+ v_replicate_count));
}
wuffs_base__u32__sat_add_indirect(
&self->private_impl.f_dst_y,
diff --git a/std/gif/decode_gif.wuffs b/std/gif/decode_gif.wuffs
index 377db62..b414c3f 100644
--- a/std/gif/decode_gif.wuffs
+++ b/std/gif/decode_gif.wuffs
@@ -1189,6 +1189,13 @@
replicate_dst.copy_from_slice!(s:replicate_src)
replicate_count -= 1
}
+
+ replicate_count = (interlace_count[this.interlace] as base.u32) + 1
+ replicate_count = replicate_count ~sat+ this.dst_y
+ replicate_count = replicate_count.min(x:this.frame_rect_y1)
+ this.dirty_y = this.dirty_y.unite(r:this.util.make_range_ie_u32(
+ min_incl:this.dst_y,
+ max_excl:replicate_count))
}
this.dst_y ~sat+= interlace_delta[this.interlace] as base.u32
diff --git a/test/c/std/gif.c b/test/c/std/gif.c
index a8f0bd9..e30c3c2 100644
--- a/test/c/std/gif.c
+++ b/test/c/std/gif.c
@@ -1324,6 +1324,12 @@
RETURN_FAIL("final pixel index, after: got 0x%02X, want not 0x%02X",
pixel_ptr[num_pixel_indexes - 1], 0xEE);
}
+
+ wuffs_base__rect_ie_u32 r = wuffs_gif__decoder__frame_dirty_rect(&dec);
+ if (r.max_excl_y != 28) {
+ RETURN_FAIL("frame_dirty_rect max_excl_y: got %" PRIu32 ", want 28",
+ r.max_excl_y);
+ }
return NULL;
}
@@ -1719,9 +1725,10 @@
// The hippopotamus.interlaced.gif image is 28 pixels high. As we decode rows
// of pixels, interlacing means that we decode rows 0, 8, 16, 24, 4, 12, 20,
// 2, 6, 10, ..., 22, 26, 1, 3, 5, ..., 25, 27. As we progress, the dirty
- // rect's max_excl_y should be one more than the highest decoded row so far.
- // If we haven't decoded any rows yet, max_excl_y should be zero.
- uint32_t wants[7] = {0, 1, 9, 17, 25, 27, 28};
+ // rect's max_excl_y should be one more than the highest decoded row so far,
+ // until the row is complete, when it is replicated (to a multiple of 8). If
+ // we haven't decoded any rows yet, max_excl_y should be zero.
+ uint32_t wants[9] = {0, 1, 8, 9, 16, 17, 24, 25, 28};
int i = 0;
while (true) {