// Copyright 2017 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.

use "std/lzw"

pub status "#bad block"
pub status "#bad extension label"
pub status "#bad graphic control"
pub status "#bad header"
pub status "#bad literal width"

pri status "#internal error: inconsistent ri/wi"

// TODO: replace the placeholder 1 value with either 0 or 0xFFFF (plus
// lzw.decoder_workbuf_len_max_incl_worst_case), depending on whether we'll
// need a per-pixel-row workbuf.
pub const decoder_workbuf_len_max_incl_worst_case base.u64 = 1

// --------

// Quirks.
//
// A base38 (github.com/google/wuffs/lib/base38) value can fit in 21 bits.
// Leaving the high bit of a uint32 reserved, the low 10 bits can be used for
// package-specific quirk constants: the base38 value acts as a namespace.

// The base38 encoding of "gif " is 0xF8586.

// When this quirk is enabled, silently ignore e.g. a frame that reports a
// width and height of 6 pixels each, followed by 50 pixel values. In that
// case, we process the first 36 pixel values and discard the excess 14.
pub const quirk_ignore_too_much_pixel_data base.u32 = (0xF8586 << 10) | 1

// When this quirk is enabled, if the initial frame bounds extends beyond the
// image bounds, then the image bounds stay unchanged. By default (with this
// quirk disabled), the image bounds are adjusted to always contain the first
// frame's bounds (but not necessarily subsequent frame's bounds).
//
// For more discussion, see
// https://github.com/google/wuffs/blob/master/test/data/artificial/gif-frame-out-of-bounds.gif.make-artificial.txt
pub const quirk_image_bounds_are_strict base.u32 = (0xF8586 << 10) | 2

// When this quirk is enabled, if the initial frame bounds is smaller than the
// image bounds, those pixels outside the initial frame bounds are assumed to
// start as opaque black instead of transparent black.
pub const quirk_initial_background_is_opaque base.u32 = (0xF8586 << 10) | 3

// When this quirk is enabled, a frame with no explicit palette is rejected,
// instead of implicitly having a palette with every entry being opaque black.
pub const quirk_reject_empty_palette base.u32 = (0xF8586 << 10) | 4

// --------

// See the spec appendix E "Interlaced Images" on page 29. The first element
// represents either that the frame was non-interlaced, or that all interlace
// stages are complete. Otherwise, the four interlace stages are elements 4, 3,
// 2 and 1 in descending order. For example, the start and delta for the first
// interlace stage is 0 and 8, for the second interlace stage is 4 and 8, etc.
// For interlaced frames, the decoder.interlace field starts at 4 and is
// decremented towards 0.
//
// interlace_start[0] is a special case. For non-interlaced frames, that
// element is never accessed. For interlaced frames, that element is only
// accessed after all interlace stages are complete. Being the maximum base.u32
// value means that, after all interlace stages are complete, dst_y will be set
// to that maximum value (and therefore outside the frame rect).
pri const interlace_start array[5] base.u32 = [0xFFFFFFFF, 1, 2, 4, 0]
pri const interlace_delta array[5] base.u8 = [1, 2, 4, 8, 8]

pub struct decoder?(
	width  base.u32,
	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.
	//
	// 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
	//
	//  - 1 -> 2: via AMC
	//
	//  - 2 -> 1: via IC (metadata reported)
	//  - 2 -> 3: via IC (metadata not reported)
	//
	//  - 3 -> 4: via FC
	//  - 3 -> 5: via F  with implicit FC
	//
	//  - 4 -> 4: via FC with implicit F
	//  - 4 -> 5: via F
	//
	//  - 5 -> 4: via FC
	//  - 5 -> 5: via F  with implicit FC
	//
	// 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
	call_sequence base.u8,

	ignore_metadata             base.bool,
	report_metadata_iccp        base.bool,
	report_metadata_xmp         base.bool,
	metadata_fourcc_value       base.u32,
	metadata_chunk_length_value base.u64,
	metadata_io_position        base.u64,

	quirk_enabled_ignore_too_much_pixel_data   base.bool,
	quirk_enabled_image_bounds_are_strict      base.bool,
	quirk_enabled_initial_background_is_opaque base.bool,
	quirk_enabled_reject_empty_palette         base.bool,

	end_of_data                        base.bool,
	restarted                          base.bool,
	previous_lzw_decode_ended_abruptly base.bool,

	which_palette base.u8[..1],

	// interlace indexes the interlace_start and interlace_delta arrays.
	interlace base.u8[..4],

	// Absent an ANIMEXTS1.0 or NETSCAPE2.0 extension, the implicit number of
	// animation loops is 1.
	seen_num_loops base.bool,
	num_loops      base.u32,

	seen_graphic_control     base.bool,
	gc_has_transparent_index base.bool,
	gc_transparent_index     base.u8,
	gc_disposal              base.u8,
	// There are 7056000 flicks per centisecond.
	gc_duration base.u64[..0xFFFF * 7056000],

	frame_config_io_position        base.u64,
	num_decoded_frame_configs_value base.u64,
	num_decoded_frames_value        base.u64,

	frame_rect_x0 base.u32,
	frame_rect_y0 base.u32,
	frame_rect_x1 base.u32,
	frame_rect_y1 base.u32,

	// The dst_etc fields are the output cursor during copy_to_image_buffer.
	dst_x   base.u32,
	dst_y   base.u32,
	dirty_y base.range_ie_u32,

	// Indexes into the compressed array, defined below.
	compressed_ri base.u64,
	compressed_wi base.u64,

	swizzler base.pixel_swizzler,
	util     base.utility,
)(
	compressed array[4096] base.u8,

	// palettes[0] and palettes[1] are the Global and Local Color Table.
	palettes array[2] array[4 * 256] base.u8,
	// dst_palette is the swizzled color table.
	dst_palette array[4 * 256] base.u8,

	lzw lzw.decoder,
)

pub func decoder.set_quirk_enabled!(quirk base.u32, enabled base.bool) {
	if args.quirk == quirk_ignore_too_much_pixel_data {
		this.quirk_enabled_ignore_too_much_pixel_data = args.enabled
	} else if args.quirk == quirk_image_bounds_are_strict {
		this.quirk_enabled_image_bounds_are_strict = args.enabled
	} else if args.quirk == quirk_initial_background_is_opaque {
		this.quirk_enabled_initial_background_is_opaque = args.enabled
	} else if args.quirk == quirk_reject_empty_palette {
		this.quirk_enabled_reject_empty_palette = args.enabled
	}
}

pub func decoder.decode_image_config?(dst nptr base.image_config, src base.io_reader) {
	var ffio base.bool

	if this.call_sequence == 0 {
		this.decode_header?(src:args.src)
		this.decode_lsd?(src:args.src)
	} else if this.call_sequence <> 2 {
		return base."#bad call sequence"
	}

	this.decode_up_to_id_part1?(src:args.src)

	// TODO: if this.end_of_data, return an error and/or set dst to zero?

	ffio = (not this.gc_has_transparent_index) and
		(this.frame_rect_x0 == 0) and
		(this.frame_rect_y0 == 0) and
		(this.frame_rect_x1 == this.width) and
		(this.frame_rect_y1 == this.height)

	if args.dst <> nullptr {
		// TODO: a Wuffs (not just C) name for the
		// WUFFS_BASE__PIXEL_FORMAT__INDEXED__BGRA_BINARY magic pixfmt constant.
		args.dst.set!(
			pixfmt:0x47040008,
			pixsub:0,
			width:this.width,
			height:this.height,
			first_frame_io_position:this.frame_config_io_position,
			first_frame_is_opaque:ffio)
	}

	this.call_sequence = 3
}

pub func decoder.set_report_metadata!(fourcc base.u32, report base.bool) {
	if args.fourcc == 0x49434350 {  // "ICCP"
		this.report_metadata_iccp = args.report
	} else if args.fourcc == 0x584D5020 {  // "XMP "
		this.report_metadata_xmp = args.report
	}
}

pub func decoder.ack_metadata_chunk?(src base.io_reader) {
	if this.call_sequence <> 1 {
		return base."#bad call sequence"
	}
	if args.src.position() <> this.metadata_io_position {
		return base."#bad I/O position"
	}
	while args.src.available() <= 0,
		post args.src.available() > 0,
	{
		yield? base."$short read"
	}

	if this.metadata_fourcc_value == 0x584D5020 {  // "XMP "
		// The +1 is because XMP metadata's encoding includes each block's leading
		// byte (the block size) as part of the metadata passed to the caller.
		this.metadata_chunk_length_value = args.src.peek_u8_as_u64() + 1
		if this.metadata_chunk_length_value > 1 {
			this.metadata_io_position = args.src.position() ~sat+ this.metadata_chunk_length_value
			return base."@metadata reported"
		}
	} else {
		this.metadata_chunk_length_value = args.src.peek_u8_as_u64()
		if this.metadata_chunk_length_value > 0 {
			args.src.skip_fast!(actual:1, worst_case:1)
			this.metadata_io_position = args.src.position() ~sat+ this.metadata_chunk_length_value
			return base."@metadata reported"
		}
	}

	args.src.skip_fast!(actual:1, worst_case:1)
	this.call_sequence = 2
	this.metadata_fourcc_value = 0
	this.metadata_io_position = 0
	return ok
}

pub func decoder.metadata_fourcc() base.u32 {
	return this.metadata_fourcc_value
}

pub func decoder.metadata_chunk_length() base.u64 {
	return this.metadata_chunk_length_value
}

pub func decoder.num_animation_loops() base.u32 {
	if this.seen_num_loops {
		return this.num_loops
	}
	return 1
}

pub func decoder.num_decoded_frame_configs() base.u64 {
	return this.num_decoded_frame_configs_value
}

pub func decoder.num_decoded_frames() base.u64 {
	return this.num_decoded_frames_value
}

pub func decoder.frame_dirty_rect() base.rect_ie_u32 {
	// TODO: intersect this with the frame_rect? In theory, that should be
	// unnecessary, and could hide bugs, but it'd be a cheap way to ensure that
	// the dirty_rect is inside the frame_rect.
	//
	// Note that this method is pure, so it cannot set a sticky error bit if
	// the dirty_rect is too big.
	return this.util.make_rect_ie_u32(
		min_incl_x:this.frame_rect_x0.min(x:this.width),
		min_incl_y:this.dirty_y.get_min_incl(),
		max_excl_x:this.frame_rect_x1.min(x:this.width),
		max_excl_y:this.dirty_y.get_max_excl())
}

pub func decoder.workbuf_len() base.range_ii_u64 {
	return this.util.make_range_ii_u64(
		min_incl:decoder_workbuf_len_max_incl_worst_case,
		max_incl:decoder_workbuf_len_max_incl_worst_case)
}

pub func decoder.restart_frame!(index base.u64, io_position base.u64) base.status {
	if this.call_sequence == 0 {
		return base."#bad call sequence"
	}
	this.end_of_data = false
	this.restarted = true
	this.frame_config_io_position = args.io_position
	this.num_decoded_frame_configs_value = args.index
	this.num_decoded_frames_value = args.index
	this.reset_gc!()
	return ok
}

pub func decoder.decode_frame_config?(dst nptr base.frame_config, src base.io_reader) {
	var blend base.u8

	this.ignore_metadata = true
	this.dirty_y.reset!()

	if not this.end_of_data {
		if this.call_sequence == 0 {
			this.decode_image_config?(dst:nullptr, src:args.src)
		} else if this.call_sequence <> 3 {
			if this.call_sequence == 4 {
				this.skip_frame?(src:args.src)
			}
			this.decode_up_to_id_part1?(src:args.src)
		}
	}

	// This is a new "if", not an "else", because the calls above can modify
	// this.end_of_data.
	if this.end_of_data {
		return base."@end of data"
	}

	blend = 0
	if not this.gc_has_transparent_index {
		blend = 2  // 2 is WUFFS_BASE__ANIMATION_BLEND__OPAQUE.
	}

	if args.dst <> nullptr {
		args.dst.update!(bounds:this.util.make_rect_ie_u32(
			min_incl_x:this.frame_rect_x0.min(x:this.width),
			min_incl_y:this.frame_rect_y0.min(x:this.height),
			max_excl_x:this.frame_rect_x1.min(x:this.width),
			max_excl_y:this.frame_rect_y1.min(x:this.height)),
			duration:this.gc_duration,
			index:this.num_decoded_frame_configs_value,
			io_position:this.frame_config_io_position,
			blend:blend,
			disposal:this.gc_disposal)
	}

	this.num_decoded_frame_configs_value ~sat+= 1
	this.call_sequence = 4
}

pri func decoder.skip_frame?(src base.io_reader) {
	var flags base.u8

	// Skip the optional Local Color Table, 3 bytes (RGB) per entry.
	flags = args.src.read_u8?()
	if (flags & 0x80) <> 0 {
		args.src.skip?(n:(3 as base.u32) << (1 + (flags & 0x07)))
	}
	// Skip the literal width.
	args.src.skip?(n:1)
	// Skip the blocks of LZW-compressed data.
	this.skip_blocks?(src:args.src)

	this.num_decoded_frames_value ~sat+= 1
	this.reset_gc!()
}

// TODO: honor args.opts.
pub func decoder.decode_frame?(dst ptr base.pixel_buffer, src base.io_reader, workbuf slice base.u8, opts nptr base.decode_frame_options) {
	this.ignore_metadata = true
	if this.call_sequence <> 4 {
		this.decode_frame_config?(dst:nullptr, src:args.src)
	}
	this.decode_id_part1?(dst:args.dst, src:args.src)
	this.decode_id_part2?(dst:args.dst, src:args.src, workbuf:args.workbuf)

	this.num_decoded_frames_value ~sat+= 1
	this.reset_gc!()
}

pri func decoder.reset_gc!() {
	this.call_sequence = 5
	// The Image Descriptor is mandatory, but the Graphic Control extension is
	// optional. Reset the GC related fields for the next decode_frame call.
	this.seen_graphic_control = false
	this.gc_has_transparent_index = false
	this.gc_transparent_index = 0
	this.gc_disposal = 0
	this.gc_duration = 0
}

pri func decoder.decode_up_to_id_part1?(src base.io_reader) {
	var block_type base.u8

	if not this.restarted {
		if this.call_sequence <> 2 {
			this.frame_config_io_position = args.src.position()
		}
	} else if this.frame_config_io_position <> args.src.position() {
		return base."#bad restart"
	} else {
		this.restarted = false
	}

	while true {
		block_type = args.src.read_u8?()
		if block_type == 0x21 {  // The spec calls 0x21 the "Extension Introducer".
			this.decode_extension?(src:args.src)
		} else if block_type == 0x2C {  // The spec calls 0x2C the "Image Separator".
			this.decode_id_part0?(src:args.src)
			break
		} else if block_type == 0x3B {  // The spec calls 0x3B the "Trailer".
			this.end_of_data = true
			break
		} else {
			return "#bad block"
		}
	}
}

// decode_header reads either "GIF87a" or "GIF89a".
//
// See the spec section 17 "Header" on page 7.
pri func decoder.decode_header?(src base.io_reader) {
	var c array[6] base.u8
	var i base.u32

	while i < 6 {
		c[i] = args.src.read_u8?()
		i += 1
	}
	if (c[0] <> 0x47) or (c[1] <> 0x49) or (c[2] <> 0x46) or (c[3] <> 0x38) or
		((c[4] <> 0x37) and (c[4] <> 0x39)) or (c[5] <> 0x61) {
		return "#bad header"
	}
}

// decode_lsd reads the Logical Screen Descriptor.
//
// See the spec section 18 "Logical Screen Descriptor" on page 8.
pri func decoder.decode_lsd?(src base.io_reader) {
	var flags               base.u8
	var num_palette_entries base.u32[..256]
	var i                   base.u32
	var argb                base.u32

	this.width = args.src.read_u16le_as_u32?()
	this.height = args.src.read_u16le_as_u32?()
	flags = args.src.read_u8?()
	// Ignore the Background Color Index and Pixel Aspect Ratio bytes.
	args.src.skip?(n:2)

	// Read the optional Global Color Table.
	if (flags & 0x80) <> 0 {
		num_palette_entries = (1 as base.u32) << (1 + (flags & 0x07))
		i = 0
		while i < num_palette_entries {
			assert i < 256 via "a < b: a < c; c <= b"(c:num_palette_entries)
			// Convert from RGB (in memory order) to ARGB (in native u32 order)
			// to BGRA (in memory order).
			argb = args.src.read_u24be_as_u32?()
			argb |= 0xFF000000
			this.palettes[0][(4 * i) + 0] = ((argb >> 0) & 0xFF) as base.u8
			this.palettes[0][(4 * i) + 1] = ((argb >> 8) & 0xFF) as base.u8
			this.palettes[0][(4 * i) + 2] = ((argb >> 16) & 0xFF) as base.u8
			this.palettes[0][(4 * i) + 3] = ((argb >> 24) & 0xFF) as base.u8
			i += 1
		}
		// Set the remaining palette entries to opaque black.
		while i < 256 {
			this.palettes[0][(4 * i) + 0] = 0x00
			this.palettes[0][(4 * i) + 1] = 0x00
			this.palettes[0][(4 * i) + 2] = 0x00
			this.palettes[0][(4 * i) + 3] = 0xFF
			i += 1
		}
	}
}

// decode_extension reads an extension. The Extension Introducer byte has
// already been read.
//
// See the spec:
//  - section 23 "Graphic Control Extension" on page 15.
//  - section 24 "Comment Extension" on page 17.
//  - section 25 "Plain Text Extension" on page 18.
//  - section 26 "Application Extension" on page 21.
pri func decoder.decode_extension?(src base.io_reader) {
	var label base.u8

	label = args.src.read_u8?()
	if label == 0xF9 {  // The spec calls 0xF9 the "Graphic Control Label".
		this.decode_gc?(src:args.src)
		return ok
	} else if label == 0xFF {  // The spec calls 0xFF the "Application Extension Label".
		this.decode_ae?(src:args.src)
		return ok
	}
	// We skip over all other extensions, including 0x01 "Plain Text Label" and
	// 0xFE "Comment Label".
	this.skip_blocks?(src:args.src)
}

pri func decoder.skip_blocks?(src base.io_reader) {
	var block_size base.u8

	while true {
		block_size = args.src.read_u8?()
		if block_size == 0 {
			return ok
		}
		args.src.skip?(n:block_size as base.u32)
	}
}

// animexts1dot0 is "ANIMEXTS1.0" as bytes.
pri const animexts1dot0 array[11] base.u8 = [
	0x41, 0x4E, 0x49, 0x4D, 0x45, 0x58, 0x54, 0x53, 0x31, 0x2E, 0x30,
]

// netscape2dot0 is "NETSCAPE2.0" as bytes.
pri const netscape2dot0 array[11] base.u8 = [
	0x4E, 0x45, 0x54, 0x53, 0x43, 0x41, 0x50, 0x45, 0x32, 0x2E, 0x30,
]

// iccrgbg1012 is "ICCRGBG1012" as bytes.
pri const iccrgbg1012 array[11] base.u8 = [
	0x49, 0x43, 0x43, 0x52, 0x47, 0x42, 0x47, 0x31, 0x30, 0x31, 0x32,
]

// xmpdataxmp is "XMP DataXMP" as bytes.
pri const xmpdataxmp array[11] base.u8 = [
	0x58, 0x4D, 0x50, 0x20, 0x44, 0x61, 0x74, 0x61, 0x58, 0x4D, 0x50,
]

// decode_ae reads an Application Extension.
pri func decoder.decode_ae?(src base.io_reader) {
	var c           base.u8
	var block_size  base.u8
	var is_animexts base.bool
	var is_netscape base.bool
	var is_iccp     base.bool
	var is_xmp      base.bool

	// This "while true" always executes exactly once, as it ends with a
	// "break", but using "break"s throughout simplifies the control flow.
	while true {
		block_size = args.src.read_u8?()
		if block_size == 0 {
			return ok
		}

		// Look only for an 11 byte "ANIMEXTS1.0", "NETSCAPE2.0" or other
		// extension, as per:
		//  - http://www.vurdalakov.net/misc/gif/animexts-looping-application-extension
		//  - http://www.vurdalakov.net/misc/gif/netscape-looping-application-extension
		//
		// Other extensions include XMP metadata.
		if block_size <> 11 {
			args.src.skip?(n:block_size as base.u32)
			break
		}
		is_animexts = true
		is_netscape = true
		is_iccp = true
		is_xmp = true
		block_size = 0  // Re-purpose the block_size variable as a counter.
		while block_size < 11 {
			c = args.src.read_u8?()
			is_animexts = is_animexts and (c == animexts1dot0[block_size])
			is_netscape = is_netscape and (c == netscape2dot0[block_size])
			is_iccp = is_iccp and (c == iccrgbg1012[block_size])
			is_xmp = is_xmp and (c == xmpdataxmp[block_size])
			block_size += 1
		}

		if is_animexts or is_netscape {
			// Those 11 bytes should be followed by 0x03, 0x01 and then the loop
			// count.
			block_size = args.src.read_u8?()
			if block_size <> 3 {
				args.src.skip?(n:block_size as base.u32)
				break
			}
			c = args.src.read_u8?()
			if c <> 0x01 {
				args.src.skip?(n:2)
				break
			}
			this.num_loops = args.src.read_u16le_as_u32?()
			this.seen_num_loops = true

			// A loop count of N, in the wire format, actually means "repeat N
			// times after the first play", if N is positive. A zero N means to
			// loop forever. Playing the frames exactly once is denoted by the
			// *absence* of this NETSCAPE2.0 application extension.
			//
			// For example, if there are four frames: A, B, C, D, and N is 2, then
			// each frame is actually played N+1 or 3 times: ABCDABCDABCD.
			//
			// Thus, we increment N if it is positive. The comparison against
			// 0xFFFF will never fail, but is necessary for the overflow checker.
			if (0 < this.num_loops) and (this.num_loops <= 0xFFFF) {
				this.num_loops += 1
			}

		} else if this.ignore_metadata {
			// No-op.

		} else if is_iccp and this.report_metadata_iccp {
			while args.src.available() <= 0,
				post args.src.available() > 0,
			{
				yield? base."$short read"
			}
			this.metadata_chunk_length_value = args.src.peek_u8_as_u64()
			args.src.skip_fast!(actual:1, worst_case:1)
			this.metadata_fourcc_value = 0x49434350  // "ICCP"
			this.metadata_io_position = args.src.position() ~sat+ this.metadata_chunk_length_value
			this.call_sequence = 1
			return base."@metadata reported"

		} else if is_xmp and this.report_metadata_xmp {
			while args.src.available() <= 0,
				post args.src.available() > 0,
			{
				yield? base."$short read"
			}
			// The +1 is because XMP metadata's encoding includes each block's
			// leading byte (the block size) as part of the metadata passed to
			// the caller.
			this.metadata_chunk_length_value = args.src.peek_u8_as_u64() + 1
			this.metadata_fourcc_value = 0x584D5020  // "XMP "
			this.metadata_io_position = args.src.position() ~sat+ this.metadata_chunk_length_value
			this.call_sequence = 1
			return base."@metadata reported"
		}

		break
	}
	this.skip_blocks?(src:args.src)
}

// decode_gc reads a Graphic Control.
pri func decoder.decode_gc?(src base.io_reader) {
	var c                        base.u8
	var flags                    base.u8
	var gc_duration_centiseconds base.u16

	if this.seen_graphic_control {
		return "#bad graphic control"
	}
	c = args.src.read_u8?()
	if c <> 4 {
		return "#bad graphic control"
	}

	flags = args.src.read_u8?()
	this.gc_has_transparent_index = (flags & 0x01) <> 0

	// Convert the disposal method from GIF's wire format to Wuffs constants.
	//
	// The GIF spec discusses the 3-bit flag value being 0, 1, 2 or 3. Values
	// in the range [4..7] are "to be defined". In practice, some encoders also
	// use 4 for "restore previous". See
	// https://cs.chromium.org/chromium/src/third_party/blink/renderer/platform/image-decoders/gif/gif_image_reader.cc?rcl=5161173c43324da2b13e1aa45bbe69901daa1279&l=625
	//
	// TODO: named constants instead of assigning 1 for
	// WUFFS_BASE__ANIMATION_DISPOSAL__RESTORE_BACKGROUND, etc.
	flags = (flags >> 2) & 0x07
	if flags == 2 {
		this.gc_disposal = 1  // 1 is WUFFS_BASE__ANIMATION_DISPOSAL__RESTORE_BACKGROUND
	} else if (flags == 3) or (flags == 4) {
		this.gc_disposal = 2  // 2 is WUFFS_BASE__ANIMATION_DISPOSAL__RESTORE_PREVIOUS
	} else {
		this.gc_disposal = 0
	}

	// There are 7056000 flicks per centisecond.
	gc_duration_centiseconds = args.src.read_u16le?()
	this.gc_duration = (gc_duration_centiseconds as base.u64) * 7056000
	this.gc_transparent_index = args.src.read_u8?()

	c = args.src.read_u8?()
	if c <> 0 {
		return "#bad graphic control"
	}
	this.seen_graphic_control = true
}

// decode_id_partX reads an Image Descriptor. The Image Separator byte has
// already been read.
//
// See the spec section 20 "Image Descriptor" on page 11.
//
// The code is split into three parts (part0, part 1 and part12 because
// determining the overall image's width and height also requires decoding the
// first frame's bounds (part0), but doesn't require decoding the first frame's
// pixels (the other two parts). Decoding the actual pixels is split into two
// (part1 and part2) not out of necessity, just for the general programming
// principle that smaller functions are easier to understand.

pri func decoder.decode_id_part0?(src base.io_reader) {
	this.frame_rect_x0 = args.src.read_u16le_as_u32?()
	this.frame_rect_y0 = args.src.read_u16le_as_u32?()
	this.frame_rect_x1 = args.src.read_u16le_as_u32?()
	this.frame_rect_x1 ~mod+= this.frame_rect_x0
	this.frame_rect_y1 = args.src.read_u16le_as_u32?()
	this.frame_rect_y1 ~mod+= this.frame_rect_y0
	this.dst_x = this.frame_rect_x0
	this.dst_y = this.frame_rect_y0

	// Set the image's overall width and height to be the maximum of the
	// nominal image width and height (given in the Logical Screen Descriptor)
	// and the bottom right extent of the first frame. See
	// test/data/artificial/gif-frame-out-of-bounds.gif.make-artificial.txt for
	// more discussion.
	if this.call_sequence == 0 {
		this.width = this.width.max(x:this.frame_rect_x1)
		this.height = this.height.max(x:this.frame_rect_y1)
	}
}

pri func decoder.decode_id_part1?(dst ptr base.pixel_buffer, src base.io_reader) {
	var flags               base.u8
	var num_palette_entries base.u32[..256]
	var i                   base.u32
	var argb                base.u32
	var dst_palette         slice base.u8
	var lw                  base.u8

	flags = args.src.read_u8?()
	if (flags & 0x40) <> 0 {
		this.interlace = 4
	} else {
		this.interlace = 0
	}

	// Read the optional Local Color Table.
	this.which_palette = 1
	if (flags & 0x80) <> 0 {
		num_palette_entries = (1 as base.u32) << (1 + (flags & 0x07))
		i = 0
		while i < num_palette_entries {
			assert i < 256 via "a < b: a < c; c <= b"(c:num_palette_entries)
			// Convert from RGB (in memory order) to ARGB (in native u32 order)
			// to BGRA (in memory order).
			argb = args.src.read_u24be_as_u32?()
			argb |= 0xFF000000
			this.palettes[1][(4 * i) + 0] = ((argb >> 0) & 0xFF) as base.u8
			this.palettes[1][(4 * i) + 1] = ((argb >> 8) & 0xFF) as base.u8
			this.palettes[1][(4 * i) + 2] = ((argb >> 16) & 0xFF) as base.u8
			this.palettes[1][(4 * i) + 3] = ((argb >> 24) & 0xFF) as base.u8
			i += 1
		}
		// Set the remaining palette entries to opaque black.
		while i < 256 {
			this.palettes[1][(4 * i) + 0] = 0x00
			this.palettes[1][(4 * i) + 1] = 0x00
			this.palettes[1][(4 * i) + 2] = 0x00
			this.palettes[1][(4 * i) + 3] = 0xFF
			i += 1
		}
	} else if this.gc_has_transparent_index {
		this.palettes[1][:].copy_from_slice!(s:this.palettes[0][:])
	} else {
		this.which_palette = 0
	}

	// Set the gc_transparent_index palette entry to transparent black.
	if this.gc_has_transparent_index {
		this.palettes[1][(4 * (this.gc_transparent_index as base.u32)) + 0] = 0x00
		this.palettes[1][(4 * (this.gc_transparent_index as base.u32)) + 1] = 0x00
		this.palettes[1][(4 * (this.gc_transparent_index as base.u32)) + 2] = 0x00
		this.palettes[1][(4 * (this.gc_transparent_index as base.u32)) + 3] = 0x00
	}

	dst_palette = args.dst.palette()
	if dst_palette.length() == 0 {
		dst_palette = this.dst_palette[:]
	}

	// TODO: a Wuffs (not just C) name for the
	// WUFFS_BASE__PIXEL_FORMAT__INDEXED__BGRA_BINARY magic pixfmt constant.
	this.swizzler.prepare!(
		dst_pixfmt:args.dst.pixel_format(),
		dst_palette:dst_palette,
		src_pixfmt:0x47040008,
		src_palette:this.palettes[this.which_palette][:])

	// Other GIF implementations accept GIF files that aren't completely spec
	// compliant. For example, the test/data/gifplayer-muybridge.gif file
	// (created by the gifsicle program) is accepted by other GIF decoders.
	// However, in that file, frame #61's embedded LZW data is truncated,
	// finishing with only 8 of the 9 bits required of the LZW end code. The
	// end code itself, 0x81, is representable in only 8 bits, but the number
	// of bits for the decoder to read has ticked over from 8 to 9 just before
	// that end code is encountered.
	//
	// To accommodate such malformed GIFs, we detect when the previous frame's
	// LZW decoding ended abruptly. The previous LZW decode 'works', in that it
	// decodes as much pixel data as is available, but without seeing that end
	// code (i.e. returning the "ok" status code), the LZW decoder is stuck in
	// a coroutine-in-progress lzw_decoder.decode call, still waiting for that
	// end code. To cancel that coroutine, we reset the LZW decoder.
	if this.previous_lzw_decode_ended_abruptly {
		this.lzw.reset!()
	}

	lw = args.src.read_u8?()
	if (lw < 2) or (8 < lw) {
		return "#bad literal width"
	}
	this.lzw.set_literal_width!(lw:lw as base.u32)

	this.previous_lzw_decode_ended_abruptly = true
}

pri func decoder.decode_id_part2?(dst ptr base.pixel_buffer, src base.io_reader, workbuf slice base.u8) {
	var block_size      base.u64[..255]
	var need_block_size base.bool
	var n_compressed    base.u64
	var compressed      slice base.u8
	var r               base.io_reader
	var lzw_status      base.status
	var copy_status     base.status
	var uncompressed    slice base.u8

	need_block_size = true
	while:outer true {
		if need_block_size {
			need_block_size = false
			block_size = args.src.read_u8_as_u64?()
		}
		if block_size == 0 {
			break
		}
		while args.src.available() == 0 {
			yield? base."$short read"
		}

		if this.compressed_ri == this.compressed_wi {
			this.compressed_ri = 0
			this.compressed_wi = 0
		}
		while this.compressed_wi <= (4096 - 255) {
			n_compressed = block_size.min(x:args.src.available())
			if n_compressed <= 0 {
				break
			}
			compressed = args.src.take!(n:n_compressed)
			this.compressed[this.compressed_wi:].copy_from_slice!(s:compressed)
			this.compressed_wi ~sat+= n_compressed
			block_size ~sat-= n_compressed
			if block_size > 0 {
				break
			}
			if args.src.available() <= 0 {
				need_block_size = true
				break
			}
			block_size = args.src.peek_u8_as_u64()
			args.src.skip_fast!(actual:1, worst_case:1)
		}

		if decoder_workbuf_len_max_incl_worst_case > args.workbuf.length() {
			return base."#bad workbuf length"
		}

		while:inner true {
			if (this.compressed_ri > this.compressed_wi) or (this.compressed_wi > 4096) {
				return "#internal error: inconsistent ri/wi"
			}
			io_bind (io:r, data:this.compressed[this.compressed_ri:this.compressed_wi]) {
				lzw_status =? this.lzw.decode_io_writer?(
					dst:this.util.null_io_writer(), src:r, workbuf:this.util.null_slice_u8())
				this.compressed_ri ~sat+= r.since_mark().length()
			}

			uncompressed = this.lzw.flush!()
			if uncompressed.length() > 0 {
				copy_status = this.copy_to_image_buffer!(pb:args.dst, src:uncompressed)
				if copy_status.is_error() {
					return copy_status
				}
			}

			if lzw_status.is_ok() {
				this.previous_lzw_decode_ended_abruptly = false

				// Skip any trailing blocks.
				if need_block_size or (block_size > 0) {
					args.src.skip?(n:block_size as base.u32)
					this.skip_blocks?(src:args.src)
				}

				break:outer
			} else if lzw_status == base."$short read" {
				continue:outer
			} else if lzw_status == base."$short write" {
				continue:inner
			}
			return lzw_status
		}
	}

	this.compressed_ri = 0
	this.compressed_wi = 0

	if (this.dst_y < this.frame_rect_y1) and
		(this.frame_rect_x0 <> this.frame_rect_x1) and
		(this.frame_rect_y0 <> this.frame_rect_y1) {
		return base."#not enough data"
	}
}

pri func decoder.copy_to_image_buffer!(pb ptr base.pixel_buffer, src slice base.u8) base.status {
	// TODO: don't assume a packed pixel format.
	var dst             slice base.u8
	var src             slice base.u8
	var n               base.u64
	var src_ri          base.u64
	var bytes_per_pixel base.u32[..64]
	var pixfmt          base.u32
	var tab             table base.u8
	var i               base.u64
	var j               base.u64

	// TODO: a Wuffs (not just C) name for the WUFFS_BASE__PIXEL_FORMAT__ETC
	// magic pixfmt constants. Also, support more formats.
	bytes_per_pixel = 1
	pixfmt = args.pb.pixel_format()
	if (pixfmt == 0x45008888) or (pixfmt == 0x55008888) or
		(pixfmt == 0x46008888) or (pixfmt == 0x56008888) or
		(pixfmt == 0x47008888) or (pixfmt == 0x57008888) {
		bytes_per_pixel = 4
	}

	tab = args.pb.plane(p:0)
	while src_ri < args.src.length() {
		src = args.src[src_ri:]

		if this.dst_y >= this.frame_rect_y1 {
			return base."#too much data"
		}

		// First, copy from src to that part of the frame rect that is inside
		// args.pb's bounds.

		dst = tab.row(y:this.dst_y)
		i = (this.dst_x as base.u64) * (bytes_per_pixel as base.u64)
		if i < dst.length() {
			j = (this.frame_rect_x1 as base.u64) * (bytes_per_pixel as base.u64)
			if (i <= j) and (j <= dst.length()) {
				dst = dst[i:j]
			} else {
				dst = dst[i:]
			}
			n = this.swizzler.swizzle_packed!(dst:dst, dst_palette:this.dst_palette[:], src:src)

			src_ri ~sat+= n
			this.dst_x ~sat+= (n & 0xFFFFFFFF) as base.u32

			this.dirty_y = this.dirty_y.unite(r:this.util.make_range_ie_u32(
				min_incl:this.dst_y,
				max_excl:this.dst_y ~sat+ 1))
		}

		if this.frame_rect_x1 <= this.dst_x {
			this.dst_x = this.frame_rect_x0
			this.dst_y ~sat+= interlace_delta[this.interlace] as base.u32
			while (this.interlace > 0) and (this.dst_y >= this.frame_rect_y1) {
				this.interlace -= 1
				this.dst_y = this.frame_rect_y0 ~sat+ interlace_start[this.interlace]
			}
			continue
		}

		if args.src.length() == src_ri {
			break
		} else if args.src.length() < src_ri {
			return "#internal error: inconsistent ri/wi"
		}

		// Second, skip over src for that part of the frame rect that is
		// outside args.pb's bounds. This second step should be infrequent.

		// Set n to the number of pixels (i.e. the number of bytes) to skip.
		n = (this.frame_rect_x1 - this.dst_x) as base.u64
		n = n.min(x:args.src.length() - src_ri)

		src_ri ~sat+= n
		this.dst_x ~sat+= (n & 0xFFFFFFFF) as base.u32

		if this.frame_rect_x1 <= this.dst_x {
			this.dst_x = this.frame_rect_x0
			this.dst_y ~sat+= interlace_delta[this.interlace] as base.u32
			while (this.interlace > 0) and (this.dst_y >= this.frame_rect_y1) {
				this.interlace -= 1
				this.dst_y = this.frame_rect_y0 ~sat+ interlace_start[this.interlace]
			}
			continue
		}

		if src_ri <> args.src.length() {
			return "#internal error: inconsistent ri/wi"
		}
		break
	}
	return ok
}
