// 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) and (not this.quirk_enabled_image_bounds_are_strict) {
		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
}
