Harmonize image decoders' call_sequence states
diff --git a/release/c/wuffs-unsupported-snapshot.c b/release/c/wuffs-unsupported-snapshot.c
index a870bb9..a3a8802 100644
--- a/release/c/wuffs-unsupported-snapshot.c
+++ b/release/c/wuffs-unsupported-snapshot.c
@@ -16885,7 +16885,7 @@
self->private_impl.f_frame_config_io_position,
(self->private_impl.f_channel_masks[3] == 0));
}
- self->private_impl.f_call_sequence = 1;
+ self->private_impl.f_call_sequence = 3;
goto ok;
ok:
@@ -16953,7 +16953,7 @@
switch (coro_susp_point) {
WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
- if (self->private_impl.f_call_sequence < 1) {
+ if (self->private_impl.f_call_sequence < 3) {
if (a_src) {
a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
}
@@ -16965,13 +16965,13 @@
if (status.repr) {
goto suspend;
}
- } else if (self->private_impl.f_call_sequence == 1) {
+ } else if (self->private_impl.f_call_sequence == 3) {
if (self->private_impl.f_frame_config_io_position != wuffs_base__u64__sat_add(a_src->meta.pos, ((uint64_t)(iop_a_src - io0_a_src)))) {
status = wuffs_base__make_status(wuffs_base__error__bad_restart);
goto exit;
}
- } else if (self->private_impl.f_call_sequence == 2) {
- self->private_impl.f_call_sequence = 3;
+ } else if (self->private_impl.f_call_sequence == 4) {
+ self->private_impl.f_call_sequence = 255;
status = wuffs_base__make_status(wuffs_base__note__end_of_data);
goto ok;
} else {
@@ -16994,7 +16994,7 @@
false,
4278190080);
}
- self->private_impl.f_call_sequence = 2;
+ self->private_impl.f_call_sequence = 4;
goto ok;
ok:
@@ -17070,7 +17070,7 @@
switch (coro_susp_point) {
WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
- if (self->private_impl.f_call_sequence < 2) {
+ if (self->private_impl.f_call_sequence < 4) {
if (a_src) {
a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
}
@@ -17082,7 +17082,7 @@
if (status.repr) {
goto suspend;
}
- } else if (self->private_impl.f_call_sequence == 2) {
+ } else if (self->private_impl.f_call_sequence == 4) {
} else {
status = wuffs_base__make_status(wuffs_base__note__end_of_data);
goto ok;
@@ -17182,7 +17182,7 @@
iop_a_src += self->private_data.s_decode_frame[0].scratch;
self->private_impl.f_pending_pad = 0;
}
- self->private_impl.f_call_sequence = 3;
+ self->private_impl.f_call_sequence = 255;
goto ok;
ok:
@@ -17931,7 +17931,7 @@
return 0;
}
- if (self->private_impl.f_call_sequence > 1) {
+ if (self->private_impl.f_call_sequence > 3) {
return 1;
}
return 0;
@@ -17950,7 +17950,7 @@
return 0;
}
- if (self->private_impl.f_call_sequence > 2) {
+ if (self->private_impl.f_call_sequence > 4) {
return 1;
}
return 0;
@@ -17979,7 +17979,7 @@
if (a_index != 0) {
return wuffs_base__make_status(wuffs_base__error__bad_argument);
}
- self->private_impl.f_call_sequence = 1;
+ self->private_impl.f_call_sequence = 3;
self->private_impl.f_frame_config_io_position = a_io_position;
return wuffs_base__make_status(NULL);
}
@@ -27625,7 +27625,7 @@
self->private_impl.f_frame_config_io_position,
true);
}
- self->private_impl.f_call_sequence = 1;
+ self->private_impl.f_call_sequence = 3;
goto ok;
ok:
@@ -27695,7 +27695,7 @@
switch (coro_susp_point) {
WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
- if (self->private_impl.f_call_sequence < 1) {
+ if (self->private_impl.f_call_sequence < 3) {
if (a_src) {
a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
}
@@ -27707,13 +27707,13 @@
if (status.repr) {
goto suspend;
}
- } else if (self->private_impl.f_call_sequence == 1) {
+ } else if (self->private_impl.f_call_sequence == 3) {
if (self->private_impl.f_frame_config_io_position != wuffs_base__u64__sat_add(a_src->meta.pos, ((uint64_t)(iop_a_src - io0_a_src)))) {
status = wuffs_base__make_status(wuffs_base__error__bad_restart);
goto exit;
}
- } else if (self->private_impl.f_call_sequence == 2) {
- self->private_impl.f_call_sequence = 3;
+ } else if (self->private_impl.f_call_sequence == 4) {
+ self->private_impl.f_call_sequence = 255;
status = wuffs_base__make_status(wuffs_base__note__end_of_data);
goto ok;
} else {
@@ -27736,7 +27736,7 @@
false,
4278190080);
}
- self->private_impl.f_call_sequence = 2;
+ self->private_impl.f_call_sequence = 4;
goto ok;
ok:
@@ -27826,7 +27826,7 @@
switch (coro_susp_point) {
WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
- if (self->private_impl.f_call_sequence < 2) {
+ if (self->private_impl.f_call_sequence < 4) {
if (a_src) {
a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
}
@@ -27838,7 +27838,7 @@
if (status.repr) {
goto suspend;
}
- } else if (self->private_impl.f_call_sequence == 2) {
+ } else if (self->private_impl.f_call_sequence == 4) {
} else {
status = wuffs_base__make_status(wuffs_base__note__end_of_data);
goto ok;
@@ -27901,7 +27901,7 @@
v_dst_y += 1;
}
}
- self->private_impl.f_call_sequence = 3;
+ self->private_impl.f_call_sequence = 255;
goto ok;
ok:
@@ -27980,7 +27980,7 @@
return 0;
}
- if (self->private_impl.f_call_sequence > 1) {
+ if (self->private_impl.f_call_sequence > 3) {
return 1;
}
return 0;
@@ -27999,7 +27999,7 @@
return 0;
}
- if (self->private_impl.f_call_sequence > 2) {
+ if (self->private_impl.f_call_sequence > 4) {
return 1;
}
return 0;
@@ -28028,7 +28028,7 @@
if (a_index != 0) {
return wuffs_base__make_status(wuffs_base__error__bad_argument);
}
- self->private_impl.f_call_sequence = 1;
+ self->private_impl.f_call_sequence = 3;
self->private_impl.f_frame_config_io_position = a_io_position;
return wuffs_base__make_status(NULL);
}
diff --git a/std/bmp/decode_bmp.wuffs b/std/bmp/decode_bmp.wuffs
index 96f91f0..2833402 100644
--- a/std/bmp/decode_bmp.wuffs
+++ b/std/bmp/decode_bmp.wuffs
@@ -33,6 +33,31 @@
width : base.u32[..= 0x7FFF_FFFF],
height : base.u32[..= 0x7FFF_FFFF],
+ // Call sequence states:
+ // - 0x00: initial state.
+ // - 0x03: image config decoded.
+ // - 0x04: frame config decoded.
+ // - 0xFF: end-of-data, usually after (the non-animated) frame decoded.
+ //
+ // State transitions:
+ //
+ // - 0x00 -> 0x03: via DIC
+ // - 0x00 -> 0x04: via DFC with implicit DIC
+ // - 0x00 -> 0xFF: via DF with implicit DIC and DFC
+ //
+ // - 0x03 -> 0x04: via DFC
+ // - 0x03 -> 0xFF: via DF with implicit DFC
+ //
+ // - 0x04 -> 0xFF: via DFC
+ // - 0x04 -> 0xFF: via DF
+ //
+ // - ???? -> 0x03: via RF for ???? > 0x00
+ //
+ // Where:
+ // - DF is decode_frame
+ // - DFC is decode_frame_config, implicit means nullptr args.dst
+ // - DIC is decode_image_config, implicit means nullptr args.dst
+ // - RF is restart_frame
call_sequence : base.u8,
top_down : base.bool,
@@ -364,18 +389,18 @@
first_frame_is_opaque: this.channel_masks[3] == 0)
}
- this.call_sequence = 1
+ this.call_sequence = 3
}
pub func decoder.decode_frame_config?(dst: nptr base.frame_config, src: base.io_reader) {
- if this.call_sequence < 1 {
+ if this.call_sequence < 3 {
this.decode_image_config?(dst: nullptr, src: args.src)
- } else if this.call_sequence == 1 {
+ } else if this.call_sequence == 3 {
if this.frame_config_io_position <> args.src.position() {
return base."#bad restart"
}
- } else if this.call_sequence == 2 {
- this.call_sequence = 3
+ } else if this.call_sequence == 4 {
+ this.call_sequence = 0xFF
return base."@end of data"
} else {
return base."@end of data"
@@ -396,15 +421,15 @@
background_color: 0xFF00_0000)
}
- this.call_sequence = 2
+ this.call_sequence = 4
}
pub func decoder.decode_frame?(dst: ptr base.pixel_buffer, src: base.io_reader, blend: base.pixel_blend, workbuf: slice base.u8, opts: nptr base.decode_frame_options) {
var status : base.status
- if this.call_sequence < 2 {
+ if this.call_sequence < 4 {
this.decode_frame_config?(dst: nullptr, src: args.src)
- } else if this.call_sequence == 2 {
+ } else if this.call_sequence == 4 {
// No-op.
} else {
return base."@end of data"
@@ -455,7 +480,7 @@
this.pending_pad = 0
}
- this.call_sequence = 3
+ this.call_sequence = 0xFF
}
pri func decoder.swizzle_none!(dst: ptr base.pixel_buffer, src: base.io_reader) base.status {
@@ -1091,14 +1116,14 @@
}
pub func decoder.num_decoded_frame_configs() base.u64 {
- if this.call_sequence > 1 {
+ if this.call_sequence > 3 {
return 1
}
return 0
}
pub func decoder.num_decoded_frames() base.u64 {
- if this.call_sequence > 2 {
+ if this.call_sequence > 4 {
return 1
}
return 0
@@ -1111,7 +1136,7 @@
if args.index <> 0 {
return base."#bad argument"
}
- this.call_sequence = 1
+ this.call_sequence = 3
this.frame_config_io_position = args.io_position
return ok
}
diff --git a/std/gif/decode_gif.wuffs b/std/gif/decode_gif.wuffs
index 17d83c5..21e6fb7 100644
--- a/std/gif/decode_gif.wuffs
+++ b/std/gif/decode_gif.wuffs
@@ -19,40 +19,49 @@
height : base.u32,
// Call sequence states:
- // - 0: initial state.
- // - 1: metadata reported; image config decode is in progress.
- // - 2: metadata finished; image config decode is in progress.
- // - 3: image config decoded, including the first frame's bounds, but not
- // the first frame's pixels.
- // - 4: frame config decoded.
- // - 5: frame decoded.
+ // - 0x00: initial state.
+ // - 0x01: metadata reported; image config decode is in progress.
+ // - 0x02: metadata finished; image config decode is in progress.
+ // - 0x03: image config decoded, including the first frame's bounds, but
+ // not the first frame's pixels.
+ // - 0x04: frame config decoded.
+ // - 0x05: frame decoded.
+ //
+ // GIF is unusual (distinguishing state 0x03 / state 0x05) in that the
+ // first frame's bounds can affect the overall image bounds (as per
+ // test/data/artificial/gif-frame-out-of-bounds.gif.make-artificial.txt).
+ // Decoding the first frame's bounds is part of DIC even though,
+ // conceptually, it should be part of the first DFC.
//
// State transitions:
//
- // - 0 -> 1: via IC (metadata reported)
- // - 0 -> 3: via IC (metadata not reported)
- // - 0 -> 4: via FC with implicit IC
- // - 0 -> 5: via F with implicit IC and FC
+ // - 0x00 -> 0x01: via DIC (metadata reported)
+ // - 0x00 -> 0x03: via DIC (metadata not reported)
+ // - 0x00 -> 0x04: via DFC with implicit DIC
+ // - 0x00 -> 0x05: via DF with implicit DIC and DFC
//
- // - 1 -> 2: via AMC
+ // - 0x01 -> 0x02: via AMC
//
- // - 2 -> 1: via IC (metadata reported)
- // - 2 -> 3: via IC (metadata not reported)
+ // - 0x02 -> 0x01: via DIC (metadata reported)
+ // - 0x02 -> 0x03: via DIC (metadata not reported)
//
- // - 3 -> 4: via FC
- // - 3 -> 5: via F with implicit FC
+ // - 0x03 -> 0x04: via DFC
+ // - 0x03 -> 0x05: via DF with implicit DFC
//
- // - 4 -> 4: via FC with implicit F
- // - 4 -> 5: via F
+ // - 0x04 -> 0x04: via DFC with implicit DF
+ // - 0x04 -> 0x05: via DF
//
- // - 5 -> 4: via FC
- // - 5 -> 5: via F with implicit FC
+ // - 0x05 -> 0x04: via DFC
+ // - 0x05 -> 0x05: via DF with implicit DFC
+ //
+ // - ???? -> 0x05: via RF for ???? > 0x00
//
// Where:
// - AMC is ack_metadata_chunk
- // - F is decode_frame, implicit means skip_frame
- // - FC is decode_frame_config, implicit means nullptr args.dst
- // - IC is decode_image_config, implicit means nullptr args.dst
+ // - DF is decode_frame, implicit means skip_frame
+ // - DFC is decode_frame_config, implicit means nullptr args.dst
+ // - DIC is decode_image_config, implicit means nullptr args.dst
+ // - RF is restart_frame
call_sequence : base.u8,
ignore_metadata : base.bool,
diff --git a/std/wbmp/decode_wbmp.wuffs b/std/wbmp/decode_wbmp.wuffs
index caff601..2bec4c3 100644
--- a/std/wbmp/decode_wbmp.wuffs
+++ b/std/wbmp/decode_wbmp.wuffs
@@ -20,6 +20,31 @@
width : base.u32,
height : base.u32,
+ // Call sequence states:
+ // - 0x00: initial state.
+ // - 0x03: image config decoded.
+ // - 0x04: frame config decoded.
+ // - 0xFF: end-of-data, usually after (the non-animated) frame decoded.
+ //
+ // State transitions:
+ //
+ // - 0x00 -> 0x03: via DIC
+ // - 0x00 -> 0x04: via DFC with implicit DIC
+ // - 0x00 -> 0xFF: via DF with implicit DIC and DFC
+ //
+ // - 0x03 -> 0x04: via DFC
+ // - 0x03 -> 0xFF: via DF with implicit DFC
+ //
+ // - 0x04 -> 0xFF: via DFC
+ // - 0x04 -> 0xFF: via DF
+ //
+ // - ???? -> 0x03: via RF for ???? > 0x00
+ //
+ // Where:
+ // - DF is decode_frame
+ // - DFC is decode_frame_config, implicit means nullptr args.dst
+ // - DIC is decode_image_config, implicit means nullptr args.dst
+ // - RF is restart_frame
call_sequence : base.u8,
frame_config_io_position : base.u64,
@@ -91,18 +116,18 @@
first_frame_is_opaque: true)
}
- this.call_sequence = 1
+ this.call_sequence = 3
}
pub func decoder.decode_frame_config?(dst: nptr base.frame_config, src: base.io_reader) {
- if this.call_sequence < 1 {
+ if this.call_sequence < 3 {
this.decode_image_config?(dst: nullptr, src: args.src)
- } else if this.call_sequence == 1 {
+ } else if this.call_sequence == 3 {
if this.frame_config_io_position <> args.src.position() {
return base."#bad restart"
}
- } else if this.call_sequence == 2 {
- this.call_sequence = 3
+ } else if this.call_sequence == 4 {
+ this.call_sequence = 0xFF
return base."@end of data"
} else {
return base."@end of data"
@@ -123,7 +148,7 @@
background_color: 0xFF00_0000)
}
- this.call_sequence = 2
+ this.call_sequence = 4
}
pub func decoder.decode_frame?(dst: ptr base.pixel_buffer, src: base.io_reader, blend: base.pixel_blend, workbuf: slice base.u8, opts: nptr base.decode_frame_options) {
@@ -139,9 +164,9 @@
var src : array[1] base.u8
var c : base.u8
- if this.call_sequence < 2 {
+ if this.call_sequence < 4 {
this.decode_frame_config?(dst: nullptr, src: args.src)
- } else if this.call_sequence == 2 {
+ } else if this.call_sequence == 4 {
// No-op.
} else {
return base."@end of data"
@@ -221,7 +246,7 @@
} endwhile
}
- this.call_sequence = 3
+ this.call_sequence = 0xFF
}
pub func decoder.frame_dirty_rect() base.rect_ie_u32 {
@@ -237,14 +262,14 @@
}
pub func decoder.num_decoded_frame_configs() base.u64 {
- if this.call_sequence > 1 {
+ if this.call_sequence > 3 {
return 1
}
return 0
}
pub func decoder.num_decoded_frames() base.u64 {
- if this.call_sequence > 2 {
+ if this.call_sequence > 4 {
return 1
}
return 0
@@ -257,7 +282,7 @@
if args.index <> 0 {
return base."#bad argument"
}
- this.call_sequence = 1
+ this.call_sequence = 3
this.frame_config_io_position = args.io_position
return ok
}