// This file was automatically generated by "preprocess-wuffs.go".

// --------

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

	util : base.utility,
)(
	palettes : array[1] array[4 * 256] base.u8,
)

pub func config_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 config_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 config_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 config_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 config_decoder.num_animation_loops() base.u32 {
	if this.seen_num_loops {
		return this.num_loops
	}
	return 1
}

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

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

pub func config_decoder.frame_dirty_rect() base.rect_ie_u32 {
	return this.util.empty_rect_ie_u32()
}

pub func config_decoder.workbuf_len() base.range_ii_u64 {
	return this.util.empty_range_ii_u64()
}

pub func config_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 config_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

	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 config_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 config_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) {
	return base."#unsupported method"
}

pri func config_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 config_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 config_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 config_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 config_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 config_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 config_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 config_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 config_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

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