// 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 {
		// 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 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.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 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.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 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.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 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 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"
		}
	} 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.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 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.skip32?(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.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 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)
	}
}
