// 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 frame size"
pub status "#bad graphic control"
pub status "#bad header"
pub status "#bad literal width"
pub status "#bad palette"

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 are configuration options that let Wuffs more closely match other
// codec implementations.
//
// Some codecs and file formats are more tightly specified than others. When a
// spec doesn't fully dictate how to treat malformed files, different codec
// implementations have disagreed on whether to accept it (e.g. whether they
// follow Postel's Principle of "be liberal in what you accept") and if so, how
// to interpret it. Some implementations also raise those decisions to the
// application level, not the library level: "provide mechanism, not policy".
//
// For example, in an animated image, the first frame might not fill out the
// entire image, and different implementations choose a different default color
// for the outside pixels: opaque black, transparent black, or something else.
//
// Wuffs, out of the box, makes particular choices (typically mimicking the de
// facto canonical implementation), but enabling various quirks result in
// different choices. In particular, quirks are useful in regression testing
// that Wuffs and another implementation produce the same output for the same
// input, even for malformed input.
//
// In terms of the Wuffs API, each quirk is assigned a uint32 value. 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 hold a package-specific
// enumeration: the base38 value acts as a namespace.
//
// The base38 encoding of "gif " is 0xF8586.

// When this quirk is enabled, when skipping over frames, the number of frames
// visited isn't incremented when the last byte of the N'th frame is seen.
// Instead, it is incremented when the first byte of the N+1'th frame's header
// is seen. There may be zero or more GIF extensions between the N'th frame's
// payload and the N+1'th frame's header.
//
// For a well-formed GIF, this won't have much effect. For a malformed GIF,
// this can affect the number of valid frames, if there is an error detected in
// the extensions between one frame's payload and the next frame's header.
//
// Some other GIF decoders don't register the N'th frame as complete until they
// see the N+1'th frame's header (or the end-of-animation terminator), so that
// e.g. the API for visiting the N'th frame can also return whether it's the
// final frame. Enabling this quirk allows for matching that behavior.
pub const quirk_delay_num_decoded_frames base.u32 = (0xF8586 << 10) | 0

// 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, the background color is opaque instead of always
// being transparent black. If the background color index in the GIF header is
// non-zero but less than the global palette's size, the background color is
// that global palette's entry. Otherwise, it is opaque black.
//
// Specifically, if the initial frame bounds is smaller than the image bounds,
// those pixels outside the initial frame bounds are assumed to start as that
// opaque background color. The same color should be used when processing
// WUFFS_BASE__ANIMATION_DISPOSAL__RESTORE_BACKGROUND. In both cases, the
// caller of Wuffs, not Wuffs itself, is responsible for filling the pixel
// buffer with that color.
pub const quirk_background_is_opaque base.u32 = (0xF8586 << 10) | 3

// When this quirk is enabled, a frame with zero width or height is rejected
// during decode_frame (but accepted during decode_frame_config).
pub const quirk_reject_empty_frame base.u32 = (0xF8586 << 10) | 5

// 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_delay_num_decoded_frames   base.bool,
	quirk_enabled_ignore_too_much_pixel_data base.bool,
	quirk_enabled_image_bounds_are_strict    base.bool,
	quirk_enabled_background_is_opaque       base.bool,
	quirk_enabled_reject_empty_frame         base.bool,
	quirk_enabled_reject_empty_palette       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,

	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 this.call_sequence == 0 {
		if args.quirk == quirk_delay_num_decoded_frames {
			this.quirk_enabled_delay_num_decoded_frames = args.enabled
		} else 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_background_is_opaque {
			this.quirk_enabled_background_is_opaque = args.enabled
		} else if args.quirk == quirk_reject_empty_frame {
			this.quirk_enabled_reject_empty_frame = 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
	if not this.quirk_enabled_background_is_opaque {
		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)
	}

	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,
			background_color:this.background_color_u32_argb_premul)
	}

	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.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 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
	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?(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.quirk_enabled_delay_num_decoded_frames {
		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, 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.quirk_enabled_reject_empty_frame 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)
	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 block_type == 0x3B {  // The spec calls 0x3B the "Trailer".
			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
		} 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 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?(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 |= 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
		}

		if this.quirk_enabled_background_is_opaque {
			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 {
				this.background_color_u32_argb_premul = 0xFF000000
			}
		}
	}

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

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

// 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 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 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 |= 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.quirk_enabled_reject_empty_palette 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.
	this.swizzler.prepare!(
		dst_pixfmt:args.dst.pixel_format(),
		dst_palette:dst_palette,
		src_pixfmt:0x47040008,
		src_palette:this.palettes[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!()
	}

	// 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 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 {
			if this.quirk_enabled_ignore_too_much_pixel_data {
				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.

		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
}
