// Copyright 2020 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/crc32"
use "std/zlib"

pub status "#bad checksum"
pub status "#bad chunk"
pub status "#bad filter"
pub status "#bad header"
pub status "#missing palette"
pub status "#unsupported PNG file"

pri status "#internal error: inconsistent workbuf length"
pri status "#internal error: zlib decoder did not exhaust its input"

pub const DECODER_WORKBUF_LEN_MAX_INCL_WORST_CASE : base.u64 = 0

pub struct decoder? implements base.image_decoder(
	// The 0x00FF_FFFF limit is arbitrary (the PNG spec says 0x7FFF_FFFF) but
	// it means that (width * height * bytes_per_pixel) doesn't overflow.
	width  : base.u32[..= 0x00FF_FFFF],
	height : base.u32[..= 0x00FF_FFFF],

	// pass_bytes_per_row doesn't include the 1 byte for the per-row filter.
	pass_bytes_per_row : base.u64[..= 0x07FF_FFF8],

	workbuf_wi             : base.u64,
	overall_workbuf_length : base.u64[..= 0x0007_FFFF_F100_0007],
	pass_workbuf_length    : base.u64[..= 0x0007_FFFF_F100_0007],

	// Call sequence states:
	//  - 0x00: initial state.
	//  - 0x03: image config decoded.
	//  - 0x04: frame config decoded.
	//  - 0xFF: end-of-data, usually after (the non-animated) frame decoded.
	//
	// State transitions:
	//
	//  - 0x00 -> 0x03: via DIC
	//  - 0x00 -> 0x04: via DFC with implicit DIC
	//  - 0x00 -> 0xFF: via DF  with implicit DIC and DFC
	//
	//  - 0x03 -> 0x04: via DFC
	//  - 0x03 -> 0xFF: via DF  with implicit DFC
	//
	//  - 0x04 -> 0xFF: via DFC
	//  - 0x04 -> 0xFF: via DF
	//
	//  - ???? -> 0x03: via RF  for ???? > 0x00
	//
	// Where:
	//  - DF  is decode_frame
	//  - DFC is decode_frame_config, implicit means nullptr args.dst
	//  - DIC is decode_image_config, implicit means nullptr args.dst
	//  - RF  is restart_frame
	call_sequence : base.u8,

	ignore_checksum : base.bool,

	depth           : base.u8[..= 16],
	color_type      : base.u8[..= 6],
	filter_distance : base.u8[..= 8],
	interlace_pass  : base.u8[..= 7],

	seen_plte : base.bool,
	seen_trns : base.bool,

	dst_pixfmt : base.u32,
	src_pixfmt : base.u32,

	chunk_type       : base.u32,
	chunk_type_array : array[4] base.u8,
	chunk_length     : base.u64,

	frame_config_io_position : base.u64,

	swizzler : base.pixel_swizzler,
	util     : base.utility,
)(
	crc32 : crc32.ieee_hasher,
	zlib  : zlib.decoder,

	dst_palette : array[4 * 256] base.u8,
	src_palette : array[4 * 256] base.u8,
)

pub func decoder.set_quirk_enabled!(quirk: base.u32, enabled: base.bool) {
	if args.quirk == base.QUIRK_IGNORE_CHECKSUM {
		this.ignore_checksum = args.enabled
		this.zlib.set_quirk_enabled!(quirk: args.quirk, enabled: args.enabled)
	}
}

pub func decoder.decode_image_config?(dst: nptr base.image_config, src: base.io_reader) {
	var magic         : base.u64
	var mark          : base.u64
	var checksum_have : base.u32
	var checksum_want : base.u32
	var status        : base.status

	if this.call_sequence <> 0 {
		return base."#bad call sequence"
	}

	magic = args.src.read_u64le?()
	if magic <> '\x89PNG\x0D\x0A\x1A\x0A'le {
		return "#bad header"
	}
	magic = args.src.read_u64le?()
	if magic <> '\x00\x00\x00\x0DIHDR'le {
		return "#bad header"
	}
	this.crc32.reset!()
	this.chunk_type_array[0] = 'I'
	this.chunk_type_array[1] = 'H'
	this.chunk_type_array[2] = 'D'
	this.chunk_type_array[3] = 'R'
	this.crc32.update_u32!(x: this.chunk_type_array[..])

	while true {
		mark = args.src.mark()
		status =? this.decode_ihdr?(src: args.src)
		if not this.ignore_checksum {
			checksum_have = this.crc32.update_u32!(x: args.src.since(mark: mark))
		}
		if status.is_ok() {
			break
		}
		yield? status
	} endwhile

	// Verify CRC-32 checksum.
	checksum_want = args.src.read_u32be?()
	if (not this.ignore_checksum) and (checksum_have <> checksum_want) {
		return "#bad checksum"
	}

	// Read up until an IDAT chunk.
	//
	// By default, libpng "warns and discards" when seeing ancillary chunk
	// checksum failures (as opposed to critical chunk checksum failures) but
	// it still continues to decode the image. Wuffs' decoder is similar,
	// simply always ignoring ancillary chunks' CRC-32 checksums.
	//
	// https://github.com/glennrp/libpng/blob/dbe3e0c43e549a1602286144d94b0666549b18e6/png.h#L1436
	//
	// We've already seen the IHDR chunk. We're not expecting an IEND chunk. An
	// IDAT chunk breaks the loop. The only other possible critical chunk is a
	// PLTE chunk. We verify PLTE checksums here but ignore other checksums.
	while true {
		this.chunk_length = args.src.read_u32be_as_u64?()
		this.chunk_type = args.src.read_u32le?()
		if (not this.ignore_checksum) and
			((this.chunk_type == 'IDAT'le) or (this.chunk_type == 'PLTE'le)) {
			this.crc32.reset!()
			this.chunk_type_array[0] = ((this.chunk_type >> 0) & 0xFF) as base.u8
			this.chunk_type_array[1] = ((this.chunk_type >> 8) & 0xFF) as base.u8
			this.chunk_type_array[2] = ((this.chunk_type >> 16) & 0xFF) as base.u8
			this.chunk_type_array[3] = ((this.chunk_type >> 24) & 0xFF) as base.u8
			this.crc32.update_u32!(x: this.chunk_type_array[..])
		}

		if this.chunk_type == 'IDAT'le {
			break
		}

		while true {
			mark = args.src.mark()
			status =? this.decode_other_chunk?(src: args.src)
			if (not this.ignore_checksum) and (this.chunk_type == 'PLTE'le) {
				checksum_have = this.crc32.update_u32!(x: args.src.since(mark: mark))
			}
			if status.is_ok() {
				break
			}
			yield? status
		} endwhile
		checksum_want = args.src.read_u32be?()
		if (not this.ignore_checksum) and (this.chunk_type == 'PLTE'le) and
			(checksum_have <> checksum_want) {
			return "#bad checksum"
		}

	} endwhile

	if (this.color_type == 3) and (not this.seen_plte) {
		return "#missing palette"
	}

	this.frame_config_io_position = args.src.position()

	if args.dst <> nullptr {
		args.dst.set!(
			pixfmt: this.dst_pixfmt,
			pixsub: 0,
			width: this.width,
			height: this.height,
			first_frame_io_position: this.frame_config_io_position,
			first_frame_is_opaque: (this.color_type <= 3) and (not this.seen_trns))
	}

	this.call_sequence = 3
}

pri func decoder.decode_ihdr?(src: base.io_reader) {
	var a32 : base.u32
	var a8  : base.u8

	a32 = args.src.read_u32be?()
	if (a32 == 0) or (a32 >= 0x8000_0000) {
		return "#bad header"
	} else if a32 >= 0x0100_0000 {
		return "#unsupported PNG file"
	}
	this.width = a32

	a32 = args.src.read_u32be?()
	if (a32 == 0) or (a32 >= 0x8000_0000) {
		return "#bad header"
	} else if a32 >= 0x0100_0000 {
		return "#unsupported PNG file"
	}
	this.height = a32

	// Depth.
	a8 = args.src.read_u8?()
	if a8 > 16 {
		return "#bad header"
	}
	this.depth = a8

	// Color.
	a8 = args.src.read_u8?()
	if (a8 == 1) or (a8 == 5) or (a8 > 6) {
		return "#bad header"
	}
	this.color_type = a8

	// Compression.
	a8 = args.src.read_u8?()
	if a8 <> 0 {
		return "#bad header"
	}

	// Filter.
	a8 = args.src.read_u8?()
	if a8 <> 0 {
		return "#bad header"
	}

	// Interlace.
	a8 = args.src.read_u8?()
	if a8 == 0 {
		this.interlace_pass = 0
	} else if a8 == 1 {
		this.interlace_pass = 1
		choose filter_and_swizzle = [filter_and_swizzle_tricky]
	} else {
		return "#bad header"
	}

	// Derived fields.
	this.filter_distance = 0
	this.assign_filter_distance!()
	if this.filter_distance == 0 {
		return "#unsupported PNG file"
	}
	this.overall_workbuf_length = (this.height as base.u64) *
		(1 + this.calculate_bytes_per_row(width: this.width))
	this.choose_filter_implementations!()
}

pri func decoder.assign_filter_distance!() {
	if this.depth < 8 {
		if this.color_type == 0 {
			this.dst_pixfmt = base.PIXEL_FORMAT__Y
			this.src_pixfmt = base.PIXEL_FORMAT__Y
		} else if this.color_type == 3 {
			this.dst_pixfmt = base.PIXEL_FORMAT__INDEXED__BGRA_BINARY
			this.src_pixfmt = base.PIXEL_FORMAT__INDEXED__BGRA_BINARY
		} else {
			return nothing
		}

		this.filter_distance = 1
		choose filter_and_swizzle = [filter_and_swizzle_tricky]

	} else if this.color_type == 0 {
		if this.depth == 8 {
			this.dst_pixfmt = base.PIXEL_FORMAT__Y
			this.src_pixfmt = base.PIXEL_FORMAT__Y
			this.filter_distance = 1
		} else if this.depth == 16 {
			this.dst_pixfmt = base.PIXEL_FORMAT__Y_16LE
			this.src_pixfmt = base.PIXEL_FORMAT__Y_16BE
			this.filter_distance = 2
		}

	} else if this.color_type == 2 {
		if this.depth == 8 {
			this.dst_pixfmt = base.PIXEL_FORMAT__BGR
			this.src_pixfmt = base.PIXEL_FORMAT__RGB
			this.filter_distance = 3
		} else if this.depth == 16 {
			this.dst_pixfmt = base.PIXEL_FORMAT__BGRA_NONPREMUL_4X16LE
			this.src_pixfmt = base.PIXEL_FORMAT__BGRA_NONPREMUL_4X16LE
			this.filter_distance = 6
			choose filter_and_swizzle = [filter_and_swizzle_tricky]
		}

	} else if this.color_type == 3 {
		if this.depth == 8 {
			this.dst_pixfmt = base.PIXEL_FORMAT__INDEXED__BGRA_BINARY
			this.src_pixfmt = base.PIXEL_FORMAT__INDEXED__BGRA_BINARY
			this.filter_distance = 1
		}

	} else if this.color_type == 4 {
		if this.depth == 8 {
			this.dst_pixfmt = base.PIXEL_FORMAT__BGRA_NONPREMUL
			this.src_pixfmt = base.PIXEL_FORMAT__BGRA_NONPREMUL
			this.filter_distance = 2
			choose filter_and_swizzle = [filter_and_swizzle_tricky]
		} else if this.depth == 16 {
			this.dst_pixfmt = base.PIXEL_FORMAT__BGRA_NONPREMUL_4X16LE
			this.src_pixfmt = base.PIXEL_FORMAT__BGRA_NONPREMUL_4X16LE
			this.filter_distance = 4
			choose filter_and_swizzle = [filter_and_swizzle_tricky]
		}

	} else if this.color_type == 6 {
		if this.depth == 8 {
			this.dst_pixfmt = base.PIXEL_FORMAT__BGRA_NONPREMUL
			this.src_pixfmt = base.PIXEL_FORMAT__RGBA_NONPREMUL
			this.filter_distance = 4
		} else if this.depth == 16 {
			this.dst_pixfmt = base.PIXEL_FORMAT__BGRA_NONPREMUL_4X16LE
			this.src_pixfmt = base.PIXEL_FORMAT__BGRA_NONPREMUL_4X16LE
			this.filter_distance = 8
			choose filter_and_swizzle = [filter_and_swizzle_tricky]
		}
	}
}

pri func decoder.calculate_bytes_per_row(width: base.u32[..= 0x00FF_FFFF]) base.u64[..= 0x07FF_FFF8] {
	var bytes_per_channel : base.u64[..= 2]

	if this.depth == 1 {
		return ((args.width + 7) / 8) as base.u64
	} else if this.depth == 2 {
		return ((args.width + 3) / 4) as base.u64
	} else if this.depth == 4 {
		return ((args.width + 1) / 2) as base.u64
	}
	bytes_per_channel = (this.depth >> 3) as base.u64
	return (args.width as base.u64) * bytes_per_channel *
		(NUM_CHANNELS[this.color_type] as base.u64)
}

pri func decoder.choose_filter_implementations!() {
	// Filter 0 is a no-op. Filter 2, the up filter, should already vectorize
	// easily by a good optimizing C compiler.
	if this.filter_distance == 3 {
		choose filter_1 = [filter_1_distance_3_fallback]
		choose filter_3 = [filter_3_distance_3_fallback]
		choose filter_4 = [
			filter_4_distance_3_arm_neon,
			filter_4_distance_3_x86_sse42,
			filter_4_distance_3_fallback]
	} else if this.filter_distance == 4 {
		choose filter_1 = [
			filter_1_distance_4_arm_neon,
			filter_1_distance_4_x86_sse42,
			filter_1_distance_4_fallback]
		choose filter_3 = [
			filter_3_distance_4_arm_neon,
			filter_3_distance_4_x86_sse42,
			filter_3_distance_4_fallback]
		choose filter_4 = [
			filter_4_distance_4_arm_neon,
			filter_4_distance_4_x86_sse42,
			filter_4_distance_4_fallback]
	}
}

pri func decoder.decode_other_chunk?(src: base.io_reader) {
	if this.chunk_type == 'PLTE'le {
		if this.seen_plte or (this.color_type <> 3) {
			return "#bad chunk"
		}
		this.decode_plte?(src: args.src)
		this.seen_plte = true
	} else if this.chunk_type == 'tRNS'le {
		if this.seen_trns or (this.color_type > 3) or
			((this.color_type == 3) and (not this.seen_plte)) {
			return "#bad chunk"
		}
		this.decode_trns?(src: args.src)
		this.seen_trns = true
	} else {
		args.src.skip?(n: this.chunk_length)
	}
}

pri func decoder.decode_plte?(src: base.io_reader) {
	var num_entries : base.u32[..= 256]
	var i           : base.u32
	var argb        : base.u32

	if (this.chunk_length > 768) or ((this.chunk_length % 3) <> 0) {
		return "#bad chunk"
	}
	num_entries = (this.chunk_length as base.u32) / 3

	while i < num_entries {
		assert i < 256 via "a < b: a < c; c <= b"(c: num_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.src_palette[(4 * i) + 0] = ((argb >> 0) & 0xFF) as base.u8
		this.src_palette[(4 * i) + 1] = ((argb >> 8) & 0xFF) as base.u8
		this.src_palette[(4 * i) + 2] = ((argb >> 16) & 0xFF) as base.u8
		this.src_palette[(4 * i) + 3] = ((argb >> 24) & 0xFF) as base.u8
		i += 1
	} endwhile

	// Set the remaining palette entries to opaque black.
	while i < 256 {
		this.src_palette[(4 * i) + 0] = 0x00
		this.src_palette[(4 * i) + 1] = 0x00
		this.src_palette[(4 * i) + 2] = 0x00
		this.src_palette[(4 * i) + 3] = 0xFF
		i += 1
	} endwhile
}

pri func decoder.decode_trns?(src: base.io_reader) {
	var num_entries : base.u32[..= 256]
	var i           : base.u32

	if this.chunk_length > 256 {
		return "#bad chunk"
	}
	num_entries = this.chunk_length as base.u32

	while i < num_entries {
		assert i < 256 via "a < b: a < c; c <= b"(c: num_entries)
		this.src_palette[(4 * i) + 3] = args.src.read_u8?()
		i += 1
	} endwhile

	if this.color_type == 3 {
		this.dst_pixfmt = base.PIXEL_FORMAT__INDEXED__BGRA_NONPREMUL
		this.src_pixfmt = base.PIXEL_FORMAT__INDEXED__BGRA_NONPREMUL
	} else {
		choose filter_and_swizzle = [filter_and_swizzle_tricky]
		if this.color_type == 0 {
			// TODO: PIXEL_FORMAT__YA_NONPREMUL
			this.dst_pixfmt = base.PIXEL_FORMAT__BGRA_NONPREMUL
			this.src_pixfmt = base.PIXEL_FORMAT__BGRA_NONPREMUL_4X16LE
		} else if this.color_type == 2 {
			this.dst_pixfmt = base.PIXEL_FORMAT__BGRA_NONPREMUL
			this.src_pixfmt = base.PIXEL_FORMAT__BGRA_NONPREMUL_4X16LE
		}
	}
}

pub func decoder.decode_frame_config?(dst: nptr base.frame_config, src: base.io_reader) {
	if this.call_sequence < 3 {
		this.decode_image_config?(dst: nullptr, src: args.src)
	} else if this.call_sequence == 3 {
		if this.frame_config_io_position <> args.src.position() {
			return base."#bad restart"
		}
	} else if this.call_sequence == 4 {
		this.call_sequence = 0xFF
		return base."@end of data"
	} else {
		return base."@end of data"
	}

	if args.dst <> nullptr {
		args.dst.set!(bounds: this.util.make_rect_ie_u32(
			min_incl_x: 0,
			min_incl_y: 0,
			max_excl_x: this.width,
			max_excl_y: this.height),
			duration: 0,
			index: 0,
			io_position: this.frame_config_io_position,
			disposal: 0,
			opaque_within_bounds: false,
			overwrite_instead_of_blend: false,
			background_color: 0x0000_0000)
	}

	this.call_sequence = 4
}

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) {
	var status      : base.status
	var pass_width  : base.u32[..= 0x00FF_FFFF]
	var pass_height : base.u32[..= 0x00FF_FFFF]

	if this.call_sequence < 4 {
		this.decode_frame_config?(dst: nullptr, src: args.src)
	} else if this.call_sequence == 4 {
		// No-op.
	} else {
		return base."@end of data"
	}

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

	while true {
		pass_width = 0x00FF_FFFF &
			(((INTERLACING[this.interlace_pass][1] as base.u32) + this.width) >>
			INTERLACING[this.interlace_pass][0])
		pass_height = 0x00FF_FFFF &
			(((INTERLACING[this.interlace_pass][4] as base.u32) + this.height) >>
			INTERLACING[this.interlace_pass][3])

		if (pass_width > 0) and (pass_height > 0) {
			this.pass_bytes_per_row = this.calculate_bytes_per_row(width: pass_width)
			this.pass_workbuf_length = (pass_height as base.u64) * (1 + this.pass_bytes_per_row)
			this.decode_pass?(src: args.src, workbuf: args.workbuf)
			status = this.filter_and_swizzle!(dst: args.dst, workbuf: args.workbuf)
			if not status.is_ok() {
				return status
			}
		}

		if (this.interlace_pass == 0) or (this.interlace_pass >= 7) {
			break
		}
		this.interlace_pass += 1
	} endwhile

	this.call_sequence = 0xFF
}

pri func decoder.decode_pass?(src: base.io_reader, workbuf: slice base.u8) {
	var w             : base.io_writer
	var w_mark        : base.u64
	var r_mark        : base.u64
	var zlib_status   : base.status
	var checksum_have : base.u32
	var checksum_want : base.u32

	this.workbuf_wi = 0
	while true {
		if (this.workbuf_wi > this.pass_workbuf_length) or (
			this.pass_workbuf_length > args.workbuf.length()) {
			return base."#bad workbuf length"
		}
		io_bind (io: w, data: args.workbuf[this.workbuf_wi .. this.pass_workbuf_length]) {
			io_limit (io: args.src, limit: this.chunk_length) {
				w_mark = w.mark()
				r_mark = args.src.mark()
				zlib_status =? this.zlib.transform_io?(
					dst: w, src: args.src, workbuf: this.util.empty_slice_u8())
				if not this.ignore_checksum {
					this.crc32.update_u32!(x: args.src.since(mark: r_mark))
				}
				this.chunk_length ~sat-= args.src.count_since(mark: r_mark)
				this.workbuf_wi ~sat+= w.count_since(mark: w_mark)
			}
		}

		if zlib_status.is_ok() {
			// Verify the final IDAT chunk's CRC-32 checksum.
			if not this.ignore_checksum {
				if this.chunk_length > 0 {
					// TODO: should this really be a fatal error?
					return base."#too much data"
				}
				checksum_have = this.crc32.update_u32!(x: this.util.empty_slice_u8())
				checksum_want = args.src.read_u32be?()
				if checksum_have <> checksum_want {
					return "#bad checksum"
				}
			}
			break
		} else if zlib_status == base."$short write" {
			if (1 <= this.interlace_pass) and (this.interlace_pass <= 6) {
				break
			}
			return base."#too much data"
		} else if zlib_status <> base."$short read" {
			return zlib_status
		} else if this.chunk_length == 0 {
			// Verify the non-final IDAT chunk's CRC-32 checksum.
			checksum_want = args.src.read_u32be?()
			if not this.ignore_checksum {
				checksum_have = this.crc32.update_u32!(x: this.util.empty_slice_u8())
				if checksum_have <> checksum_want {
					return "#bad checksum"
				}
			}

			// The next chunk should be another IDAT.
			this.chunk_length = args.src.read_u32be_as_u64?()
			this.chunk_type = args.src.read_u32le?()
			if this.chunk_type <> 'IDAT'le {
				return "#bad chunk"
			}

			// The 'IDAT'be is part of the next CRC-32 checksum's input.
			if not this.ignore_checksum {
				this.crc32.reset!()
				this.chunk_type_array[0] = 'I'
				this.chunk_type_array[1] = 'D'
				this.chunk_type_array[2] = 'A'
				this.chunk_type_array[3] = 'T'
				this.crc32.update_u32!(x: this.chunk_type_array[..])
			}
			continue
		} else if args.src.length() > 0 {
			return "#internal error: zlib decoder did not exhaust its input"
		}
		yield? base."$short read"
	} endwhile

	if this.workbuf_wi <> this.pass_workbuf_length {
		return base."#not enough data"
	} else if 0 < args.workbuf.length() {
		// For the top row, the Paeth filter (4) is equivalent to the Sub
		// filter (1), but the Paeth implementation is simpler if it can assume
		// that there is a previous row.
		if args.workbuf[0] == 4 {
			args.workbuf[0] = 1
		}
	}
}

pub func decoder.frame_dirty_rect() base.rect_ie_u32 {
	return this.util.make_rect_ie_u32(
		min_incl_x: 0,
		min_incl_y: 0,
		max_excl_x: this.width,
		max_excl_y: this.height)
}

pub func decoder.num_animation_loops() base.u32 {
	return 0
}

pub func decoder.num_decoded_frame_configs() base.u64 {
	if this.call_sequence > 3 {
		return 1
	}
	return 0
}

pub func decoder.num_decoded_frames() base.u64 {
	if this.call_sequence > 4 {
		return 1
	}
	return 0
}

pub func decoder.restart_frame!(index: base.u64, io_position: base.u64) base.status {
	if this.call_sequence < 3 {
		return base."#bad call sequence"
	}
	if args.index <> 0 {
		return base."#bad argument"
	}
	this.call_sequence = 3
	if this.interlace_pass >= 1 {
		this.interlace_pass = 1
	}
	this.frame_config_io_position = args.io_position
	return ok
}

pub func decoder.set_report_metadata!(fourcc: base.u32, report: base.bool) {
	// TODO.
}

pub func decoder.tell_me_more?(dst: base.io_writer, minfo: nptr base.more_information, src: base.io_reader) {
	return base."#no more information"
}

pub func decoder.workbuf_len() base.range_ii_u64 {
	return this.util.make_range_ii_u64(
		min_incl: this.overall_workbuf_length,
		max_incl: this.overall_workbuf_length)
}

// INTERLACING holds the Adam7 interlacing pattern, involving 7 passes:
//  1 6 4 6 2 6 4 6
//  7 7 7 7 7 7 7 7
//  5 6 5 6 5 6 5 6
//  7 7 7 7 7 7 7 7
//  3 6 4 6 3 6 4 6
//  7 7 7 7 7 7 7 7
//  5 6 5 6 5 6 5 6
//  7 7 7 7 7 7 7 7
//
// The six elements of each inner array are:
//  0: log2(x_stride)
//  1: x_stride - x_offset - 1
//  2: x_offset
//  3: log2(y_stride)
//  4: y_stride - y_offset - 1
//  5: y_offset
pri const INTERLACING : array[8] array[6] base.u8[..= 8] = [
	[0, 0, 0, 0, 0, 0],  // non-interlaced; xy_stride=1, xy_offset=0
	[3, 7, 0, 3, 7, 0],  // interlace_pass == 1
	[3, 3, 4, 3, 7, 0],  // interlace_pass == 2
	[2, 3, 0, 3, 3, 4],  // interlace_pass == 3
	[2, 1, 2, 2, 3, 0],  // interlace_pass == 4
	[1, 1, 0, 2, 1, 2],  // interlace_pass == 5
	[1, 0, 1, 1, 1, 0],  // interlace_pass == 6
	[0, 0, 0, 1, 0, 1],  // interlace_pass == 7
]

// LOW_BIT_DEPTH_MULTIPLIERS holds multipliers that convert D-bit values into
// 8-bit values, for depth D.
pri const LOW_BIT_DEPTH_MULTIPLIERS : array[8] base.u8 = [
	0,
	0b1111_1111,  // depth == 1
	0b0101_0101,  // depth == 2
	0,
	0b0001_0001,  // depth == 4
	0,
	0,
	0,
]

// LOW_BIT_DEPTH_NUM_PACKS holds the number of smaller-than-1-byte units that
// are packed into each byte.
pri const LOW_BIT_DEPTH_NUM_PACKS : array[8] base.u8 = [
	0,
	8,  // depth == 1
	4,  // depth == 2
	0,
	2,  // depth == 4
	0,
	0,
	0,
]

// NUM_CHANNELS holds the number of channels for each valid color type.
pri const NUM_CHANNELS : array[8] base.u8[..= 4] = [
	1,  // color_type == 0: Y
	0,
	3,  // color_type == 2: RGB
	1,  // color_type == 3: indexed
	2,  // color_type == 4: YA
	0,
	4,  // color_type == 6: RGBA
	0,
]
