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

// --------

pub struct decoder? implements base.image_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      : base.u32,
	metadata_io_position : base.u64,

	quirks : array[QUIRKS_COUNT] base.bool,

	delayed_num_decoded_frames         : base.bool,
	end_of_data                        : base.bool,
	restarted                          : base.bool,
	previous_lzw_decode_ended_abruptly : base.bool,

	has_global_palette : base.bool,

	// 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,

	background_color_u32_argb_premul : base.u32,
	black_color_u32_argb_premul      : base.u32,

	gc_has_transparent_index : base.bool,
	gc_transparent_index     : base.u8,
	gc_disposal              : base.u8,
	// There are 7_056000 flicks per centisecond.
	gc_duration : base.u64[..= 0xFFFF * 7_056000],

	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_max_excl_y : base.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 (this.call_sequence == 0) and (args.quirk >= QUIRKS_BASE) {
		args.quirk -= QUIRKS_BASE
		if args.quirk < QUIRKS_COUNT {
			this.quirks[args.quirk] = 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
	if not this.quirks[QUIRK_HONOR_BACKGROUND_COLOR - QUIRKS_BASE] {
		ffio = ffio 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)
	} else if ffio {
		// Use opaque black, not transparent black.
		this.black_color_u32_argb_premul = 0xFF00_0000
	}

	if this.background_color_u32_argb_premul == 77 {
		this.background_color_u32_argb_premul = this.black_color_u32_argb_premul
	}

	if args.dst <> nullptr {
		args.dst.set!(
			pixfmt: base.PIXEL_FORMAT__INDEXED__BGRA_BINARY,
			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 == 'ICCP'be {
		this.report_metadata_iccp = args.report
	} else if args.fourcc == 'XMP 'be {
		this.report_metadata_xmp = args.report
	}
}

pub func decoder.tell_me_more?(dst: base.io_writer, minfo: nptr base.more_information, src: base.io_reader) {
	var chunk_length : base.u64

	if this.call_sequence <> 1 {
		return base."#bad call sequence"
	}
	if this.metadata_fourcc == 0 {
		return base."#no more information"
	}

	while true {
		while true,
			post args.src.length() > 0,
		{
			if args.src.position() <> this.metadata_io_position {
				if args.minfo <> nullptr {
					args.minfo.set!(
						flavor: 2,  // WUFFS_BASE__MORE_INFORMATION__FLAVOR__IO_SEEK
						w: 0,
						x: this.metadata_io_position,
						y: 0,
						z: 0)
				}
				yield? base."$mispositioned read"
				continue
			}

			if args.src.length() <= 0 {
				if args.minfo <> nullptr {
					args.minfo.set!(
						flavor: 0,
						w: 0,
						x: 0,
						y: 0,
						z: 0)
				}
				yield? base."$short read"
				continue
			}

			break
		} endwhile

		chunk_length = args.src.peek_u8_as_u64()
		if chunk_length <= 0 {
			// Consume the '\x00' that means a zero-length block.
			args.src.skip_u32_fast!(actual: 1, worst_case: 1)
			break
		}

		if this.metadata_fourcc == 'XMP 'be {
			// 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.
			chunk_length += 1
		} else {
			args.src.skip_u32_fast!(actual: 1, worst_case: 1)
		}
		this.metadata_io_position = args.src.position() ~sat+ chunk_length

		if args.minfo <> nullptr {
			args.minfo.set!(
				flavor: 3,  // WUFFS_BASE__MORE_INFORMATION__FLAVOR__METADATA
				w: this.metadata_fourcc,
				x: 0,
				y: args.src.position(),
				z: this.metadata_io_position)
		}

		yield? base."$even more information"
	} endwhile

	if args.minfo <> nullptr {
		args.minfo.set!(
			flavor: 3,  // WUFFS_BASE__MORE_INFORMATION__FLAVOR__METADATA
			w: this.metadata_fourcc,
			x: 0,
			y: this.metadata_io_position,
			z: this.metadata_io_position)
	}
	this.call_sequence = 2
	this.metadata_fourcc = 0
	this.metadata_io_position = 0
	return ok
}

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 {
	// The "foo.min(a:this.width_or_height)" calls clip the nominal frame_rect
	// to the image_rect.
	return this.util.make_rect_ie_u32(
		min_incl_x: this.frame_rect_x0.min(a: this.width),
		min_incl_y: this.frame_rect_y0.min(a: this.height),
		max_excl_x: this.frame_rect_x1.min(a: this.width),
		max_excl_y: this.dirty_max_excl_y.min(a: this.height))
}

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.delayed_num_decoded_frames = false
	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 background_color : base.u32
	var flags            : base.u8

	this.ignore_metadata = true

	this.dirty_max_excl_y = 0

	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"
	}

	background_color = this.black_color_u32_argb_premul
	if not this.gc_has_transparent_index {
		background_color = this.background_color_u32_argb_premul

		// If the quirk is enabled and the first frame has a local color
		// palette, its background color is black.
		if this.quirks[QUIRK_FIRST_FRAME_LOCAL_PALETTE_MEANS_BLACK_BACKGROUND - QUIRKS_BASE] and
			(this.num_decoded_frame_configs_value == 0) {

			while args.src.length() <= 0,
				post args.src.length() > 0,
			{
				yield? base."$short read"
			} endwhile
			flags = args.src.peek_u8()
			if (flags & 0x80) <> 0 {
				background_color = this.black_color_u32_argb_premul
			}
		}
	}

	if args.dst <> nullptr {
		// The "foo.min(a:this.width_or_height)" calls clip the nominal
		// frame_rect to the image_rect.
		args.dst.set!(bounds: this.util.make_rect_ie_u32(
			min_incl_x: this.frame_rect_x0.min(a: this.width),
			min_incl_y: this.frame_rect_y0.min(a: this.height),
			max_excl_x: this.frame_rect_x1.min(a: this.width),
			max_excl_y: this.frame_rect_y1.min(a: this.height)),
			duration: this.gc_duration,
			index: this.num_decoded_frame_configs_value,
			io_position: this.frame_config_io_position,
			disposal: this.gc_disposal,
			opaque_within_bounds: not this.gc_has_transparent_index,
			overwrite_instead_of_blend: false,
			background_color: background_color)
	}

	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
	var lw    : 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_u32?(n: (3 as base.u32) << (1 + (flags & 0x07)))
	}

	// Process the LZW literal width.
	lw = args.src.read_u8?()
	if lw > 8 {
		return "#bad literal width"
	}

	// Skip the blocks of LZW-compressed data.
	this.skip_blocks?(src: args.src)

	if this.quirks[QUIRK_DELAY_NUM_DECODED_FRAMES - QUIRKS_BASE] {
		this.delayed_num_decoded_frames = true
	} else {
		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, blend: base.pixel_blend, 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)
	}
	if this.quirks[QUIRK_REJECT_EMPTY_FRAME - QUIRKS_BASE] and
		((this.frame_rect_x0 == this.frame_rect_x1) or (this.frame_rect_y0 == this.frame_rect_y1)) {
		return "#bad frame size"
	}
	this.decode_id_part1?(dst: args.dst, src: args.src, blend: args.blend)
	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.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".
			if this.delayed_num_decoded_frames {
				this.delayed_num_decoded_frames = false
				this.num_decoded_frames_value ~sat+= 1
			}
			this.decode_id_part0?(src: args.src)
			break
		} else {
			// If we don't have 0x21 or 0x2C then, according to the spec, the
			// only valid byte is 0x3B, called the "Trailer". In practice, some
			// other popular decoders allow anything (other than 0x21 or 0x2C)
			// to be equivalent to 0x3B, which ends the animated GIF image, and
			// we do likewise here. Some real world GIF files that exhibit this
			// are at https://github.com/golang/go/issues/38853
			//
			// Chromium's decoder
			// https://skia.googlesource.com/libgifcodec/+/c002ec500aba1e1b0189547629787cb02db78193/SkGifImageReader.cpp#563
			//
			// Firefox's decoder
			// https://dxr.mozilla.org/mozilla-central/rev/93a33cb7f2369ac4f1d1f2ac97ec14ba60e1e7d7/image/decoders/nsGIFDecoder2.cpp#569
			if this.delayed_num_decoded_frames {
				this.delayed_num_decoded_frames = false
				this.num_decoded_frames_value ~sat+= 1
			}
			this.end_of_data = true
			break
		}
	} endwhile
}

// 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
	} endwhile
	if (c[0] <> 'G') or (c[1] <> 'I') or (c[2] <> 'F') or (c[3] <> '8') or
		((c[4] <> '7') and (c[4] <> '9')) or (c[5] <> 'a') {
		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 background_color_index : base.u8
	var num_palette_entries    : base.u32[..= 256]
	var i                      : base.u32
	var j                      : base.u32[..= 1020]
	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?()
	background_color_index = args.src.read_u8?()
	// Ignore the Pixel Aspect Ratio byte.
	args.src.skip_u32?(n: 1)

	// Read the optional Global Color Table.
	i = 0
	this.has_global_palette = (flags & 0x80) <> 0
	if this.has_global_palette {
		num_palette_entries = (1 as base.u32) << (1 + (flags & 0x07))
		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 |= 0xFF00_0000
			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
		} endwhile

		if this.quirks[QUIRK_HONOR_BACKGROUND_COLOR - QUIRKS_BASE] {
			if (background_color_index <> 0) and
				((background_color_index as base.u32) < num_palette_entries) {

				j = 4 * (background_color_index as base.u32)
				this.background_color_u32_argb_premul =
					((this.palettes[0][j + 0] as base.u32) << 0) |
					((this.palettes[0][j + 1] as base.u32) << 8) |
					((this.palettes[0][j + 2] as base.u32) << 16) |
					((this.palettes[0][j + 3] as base.u32) << 24)
			} else {
				// The background color is either opaque black or transparent
				// black. We set it to an arbitrary nonsense value (77) for
				// now, and set it to its real value later, once we know
				// whether the first frame is opaque (the ffio value).
				this.background_color_u32_argb_premul = 77
			}
		}
	}

	// 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
	} endwhile
}

// 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_u32?(n: block_size as base.u32)
	} endwhile
}

// 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

	while.goto_done true {{
	if this.metadata_fourcc <> 0 {
		return base."@metadata reported"
	}

	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_u32?(n: block_size as base.u32)
		break.goto_done
	}
	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
	} endwhile

	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_u32?(n: block_size as base.u32)
			break.goto_done
		}
		c = args.src.read_u8?()
		if c <> 0x01 {
			args.src.skip_u32?(n: 2)
			break.goto_done
		}
		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 {
		this.metadata_fourcc = 'ICCP'be
		this.metadata_io_position = args.src.position()
		this.call_sequence = 1
		return base."@metadata reported"

	} else if is_xmp and this.report_metadata_xmp {
		this.metadata_fourcc = 'XMP 'be
		this.metadata_io_position = args.src.position()
		this.call_sequence = 1
		return base."@metadata reported"
	}

	break.goto_done
	}} endwhile.goto_done

	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

	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 7_056000 flicks per centisecond.
	gc_duration_centiseconds = args.src.read_u16le?()
	this.gc_duration = (gc_duration_centiseconds as base.u64) * 7_056000
	this.gc_transparent_index = args.src.read_u8?()

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

// 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.quirks[QUIRK_IMAGE_BOUNDS_ARE_STRICT - QUIRKS_BASE]) {
		this.width = this.width.max(a: this.frame_rect_x1)
		this.height = this.height.max(a: this.frame_rect_y1)
	}
}

pri func decoder.decode_id_part1?(dst: ptr base.pixel_buffer, src: base.io_reader, blend: base.pixel_blend) {
	var flags               : base.u8
	var which_palette       : base.u8[..= 1]
	var num_palette_entries : base.u32[..= 256]
	var i                   : base.u32
	var argb                : base.u32
	var status              : base.status
	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.
	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 |= 0xFF00_0000
			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
		} endwhile
		// 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
		} endwhile
	} else if this.quirks[QUIRK_REJECT_EMPTY_PALETTE - QUIRKS_BASE] and (not this.has_global_palette) {
		return "#bad palette"
	} else if this.gc_has_transparent_index {
		this.palettes[1][..].copy_from_slice!(s: this.palettes[0][..])
	} else {
		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
	}

	status = this.swizzler.prepare!(
		dst_pixfmt: args.dst.pixel_format(),
		dst_palette: args.dst.palette_or_else(fallback: this.dst_palette[..]),
		src_pixfmt: this.util.make_pixel_format(repr: base.PIXEL_FORMAT__INDEXED__BGRA_BINARY),
		src_palette: this.palettes[which_palette][..],
		blend: args.blend)
	if not status.is_ok() {
		return status
	}

	// 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!()
	}

	// Process the LZW literal width. The spec says that "images which have one
	// color bit must be indicated as having a code size [i.e. literal width]
	// of 2", but in practice, some encoders use a literal width of 1 or 0.
	lw = args.src.read_u8?()
	if lw > 8 {
		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_copied        : base.u32
	var n_compressed    : base.u64
	var r               : base.io_reader
	var mark            : base.u64
	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.outer
		}
		while args.src.length() == 0 {
			yield? base."$short read"
		} endwhile

		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(a: args.src.length())
			if n_compressed <= 0 {
				break
			}
			n_copied = args.src.limited_copy_u32_to_slice!(
				up_to: (n_compressed & 0xFFFF_FFFF) as base.u32,
				s: this.compressed[this.compressed_wi ..])
			this.compressed_wi ~sat+= n_copied as base.u64
			block_size ~sat-= n_copied as base.u64
			if block_size > 0 {
				break
			}
			if args.src.length() <= 0 {
				need_block_size = true
				break
			}
			block_size = args.src.peek_u8_as_u64()
			args.src.skip_u32_fast!(actual: 1, worst_case: 1)
		} endwhile

		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]) {
				mark = r.mark()
				lzw_status =? this.lzw.transform_io?(
					dst: this.util.empty_io_writer(), src: r, workbuf: this.util.empty_slice_u8())
				this.compressed_ri ~sat+= r.count_since(mark: mark)
			}

			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_u32?(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
		} endwhile.inner
	} endwhile.outer

	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 an interleaved pixel format.
	var dst             : slice base.u8
	var src             : slice base.u8
	var width_in_bytes  : base.u64
	var n               : base.u64
	var src_ri          : base.u64
	var pixfmt          : base.pixel_format
	var bytes_per_pixel : base.u32[..= 32]
	var bits_per_pixel  : base.u32[..= 256]
	var tab             : table base.u8
	var i               : base.u64
	var j               : base.u64
	var replicate_y0    : base.u32
	var replicate_y1    : base.u32
	var replicate_dst   : slice base.u8
	var replicate_src   : slice base.u8

	// TODO: the pixfmt variable shouldn't be necessary. We should be able to
	// chain the two calls: "args.pb.pixel_format().bits_per_pixel()".
	pixfmt = args.pb.pixel_format()
	bits_per_pixel = pixfmt.bits_per_pixel()
	if (bits_per_pixel & 7) <> 0 {
		return base."#unsupported option"
	}
	bytes_per_pixel = bits_per_pixel >> 3

	width_in_bytes = (this.width as base.u64) * (bytes_per_pixel as base.u64)
	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 {
			if this.quirks[QUIRK_IGNORE_TOO_MUCH_PIXEL_DATA - QUIRKS_BASE] {
				return ok
			}
			return base."#too much data"
		}

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

		dst = tab.row(y: this.dst_y)
		if this.dst_y >= this.height {
			dst = dst[.. 0]
		} else if width_in_bytes < dst.length() {
			dst = dst[.. width_in_bytes]
		}

		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_interleaved_from_slice!(
				dst: dst, dst_palette: this.dst_palette[..], src: src)

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

			this.dirty_max_excl_y = this.dirty_max_excl_y.max(a: this.dst_y ~sat+ 1)
		}

		if this.frame_rect_x1 <= this.dst_x {
			this.dst_x = this.frame_rect_x0
			if this.interlace == 0 {
				this.dst_y ~sat+= 1
				continue
			}

			// For the first frame of an interlaced, non-transparent GIF,
			// replicate the early passes' rows. For example, when such an
			// image is downloaded over a slow network, this produces a richer
			// intermediate image while waiting for the complete image.
			//
			// Some other GIF implementations call this progressive display or
			// a "Haeberli inspired" technique.
			if (this.num_decoded_frames_value == 0) and
				(not this.gc_has_transparent_index) and
				(this.interlace > 1) {

				replicate_src = tab.row(y: this.dst_y)
				replicate_y0 = this.dst_y ~sat+ 1
				replicate_y1 = this.dst_y ~sat+ (INTERLACE_COUNT[this.interlace] as base.u32)
				replicate_y1 = replicate_y1.min(a: this.frame_rect_y1)
				while replicate_y0 < replicate_y1 {
					assert replicate_y0 < 0xFFFF_FFFF via "a < b: a < c; c <= b"(c: replicate_y1)
					replicate_dst = tab.row(y: replicate_y0)
					replicate_dst.copy_from_slice!(s: replicate_src)
					replicate_y0 += 1
				} endwhile
				this.dirty_max_excl_y = this.dirty_max_excl_y.max(a: replicate_y1)
			}

			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]
			} endwhile
			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(a: args.src.length() - src_ri)

		src_ri ~sat+= n
		this.dst_x ~sat+= (n & 0xFFFF_FFFF) 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]
			} endwhile
			continue
		}

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