// 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 "go run preprocess-wuffs.go" TO MAKE decode_config.wuffs
//#WHEN PREPROC000
//
// This file defines "struct decoder". It is also preprocessed (copied with
// automatic edits) to generate the decode_config.wuffs file that defines
// "struct config_decoder". See preprocess-wuffs.go for more detail about the
// preprocessor language (the //#FOOBAR comments).
//
// config_decoder does not implement decode_frame, only decode_frame_config and
// decode_image_config (and other miscellaneous methods). The sizeof the
// config_decoder can be substantially smaller than the sizeof the full
// decoder, as it does not need any internal buffers for understanding the
// underlying compression format.
//
//#WHEN PREPROC000 decode_config.wuffs
//#REPLACE   "func decoder" WITH   "func config_decoder"
//#REPLACE "struct decoder" WITH "struct config_decoder"
//#DONE PREPROC000

// --------

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,

	//#WHEN PREPROC100
	// 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,
	//#DONE PREPROC100

	util : base.utility,
)(
	//#WHEN PREPROC101
	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,
	//#WHEN PREPROC101 decode_config.wuffs
	//## palettes : array[1] array[4 * 256] base.u8,
	//#DONE PREPROC101
)

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 {
		// TODO: a Wuffs (not just C) name for the
		// WUFFS_BASE__PIXEL_FORMAT__INDEXED__BGRA_BINARY magic pixfmt constant.
		args.dst.set!(
			pixfmt: 0x8304_0008,
			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.available() > 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.available() <= 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.skip32_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.skip32_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 {
	//#WHEN PREPROC200
	// 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))
	//#WHEN PREPROC200 decode_config.wuffs
	//## return this.util.empty_rect_ie_u32()
	//#DONE PREPROC200
}

pub func decoder.workbuf_len() base.range_ii_u64 {
	//#WHEN PREPROC201
	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)
	//#WHEN PREPROC201 decode_config.wuffs
	//## return this.util.empty_range_ii_u64()
	//#DONE PREPROC201
}

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

	//#WHEN PREPROC202
	this.dirty_max_excl_y = 0
	//#DONE PREPROC202

	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.available() <= 0,
				post args.src.available() > 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.update!(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.skip32?(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) {
	//#WHEN PREPROC300
	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!()
	//#WHEN PREPROC300 decode_config.wuffs
	//## return base."#unsupported method"
	//#DONE PREPROC300
}

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.skip32?(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.skip32?(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.skip32?(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.skip32?(n: block_size as base.u32)
			break.goto_done
		}
		c = args.src.read_u8?()
		if c <> 0x01 {
			args.src.skip32?(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

	//#WHEN PREPROC400
	this.dst_x = this.frame_rect_x0
	this.dst_y = this.frame_rect_y0
	//#DONE PREPROC400

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

//#WHEN PREPROC900
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 dst_palette         : slice base.u8
	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
	}

	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.
	status = this.swizzler.prepare!(
		dst_pixfmt: args.dst.pixel_format(),
		dst_palette: dst_palette,
		src_pixfmt: this.util.make_pixel_format(repr: 0x8304_0008),
		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_compressed    : base.u64
	var compressed      : slice base.u8
	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.available() == 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.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.skip32_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.skip32?(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!(
				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
}
//#DONE PREPROC900
