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

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

	workbuf_wi     : base.u64,
	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,

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

	seen_palette : base.bool,

	src_pixfmt : base.u32,

	chunk_type   : base.u32,
	chunk_length : base.u64,

	frame_config_io_position : base.u64,

	swizzler : base.pixel_swizzler,
	util     : base.utility,
)(
	crc  : 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) {
}

pub func decoder.decode_image_config?(dst: nptr base.image_config, src: base.io_reader) {
	var magic      : base.u64
	var a32        : base.u32
	var a8         : base.u8
	var dst_pixfmt : base.u32

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

	a32 = args.src.read_u32be?()
	if 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 >= 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.
	this.color_type = args.src.read_u8?()
	if this.color_type == 0 {
		dst_pixfmt = base.PIXEL_FORMAT__Y
		this.src_pixfmt = base.PIXEL_FORMAT__Y
		if this.depth == 8 {
			this.filter_distance = 1
			this.bytes_per_row = (this.width as base.u64) * 1
		} else {
			return "#unsupported PNG file"
		}
	} else if this.color_type == 2 {
		dst_pixfmt = base.PIXEL_FORMAT__BGR
		this.src_pixfmt = base.PIXEL_FORMAT__RGB
		if this.depth == 8 {
			this.filter_distance = 3
			this.bytes_per_row = (this.width as base.u64) * 3
		} else {
			return "#unsupported PNG file"
		}
	} else if this.color_type == 3 {
		// TODO: s/BINARY/NONPREMUL/ and decode the tRNS chunk.
		dst_pixfmt = base.PIXEL_FORMAT__INDEXED__BGRA_BINARY
		this.src_pixfmt = base.PIXEL_FORMAT__INDEXED__BGRA_BINARY
		if this.depth == 8 {
			this.filter_distance = 1
			this.bytes_per_row = (this.width as base.u64) * 1
		} else {
			return "#unsupported PNG file"
		}
	} else if this.color_type == 6 {
		dst_pixfmt = base.PIXEL_FORMAT__BGRA_NONPREMUL
		this.src_pixfmt = base.PIXEL_FORMAT__RGBA_NONPREMUL
		if this.depth == 8 {
			this.filter_distance = 4
			this.bytes_per_row = (this.width as base.u64) * 4
		} else {
			return "#unsupported PNG file"
		}
	} else {
		return "#unsupported PNG file"
	}
	this.workbuf_length = (this.height as base.u64) * (1 + this.bytes_per_row)

	// 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 {
		// No-op.
	} else if a8 == 1 {
		return "#unsupported PNG file"
	} else {
		return "#bad header"
	}

	// TODO: verify CRC-32 checksum.
	args.src.skip_u32?(n: 4)

	// Read up until an IDAT chunk.
	while true {
		this.chunk_length = args.src.read_u32be_as_u64?()
		this.chunk_type = args.src.read_u32le?()
		if this.chunk_type == 'IDAT'le {
			break
		} else if this.chunk_type == 'PLTE'le {
			if this.seen_palette {
				return "#bad chunk"
			}
			this.decode_plte?(src: args.src)
			this.seen_palette = true
		} else if this.chunk_type == 'tRNS'le {
			// TODO.
			args.src.skip?(n: this.chunk_length)
		} else {
			args.src.skip?(n: this.chunk_length)
		}
		// TODO: verify CRC-32 checksum.
		args.src.skip_u32?(n: 4)
	} endwhile

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

	this.frame_config_io_position = args.src.position()

	if args.dst <> nullptr {
		args.dst.set!(
			pixfmt: dst_pixfmt,
			pixsub: 0,
			width: this.width,
			height: this.height,
			first_frame_io_position: this.frame_config_io_position,
			first_frame_is_opaque: false)
	}

	this.call_sequence = 3
}

pri func decoder.decode_plte?(src: base.io_reader) {
	var num_palette_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 header"
	}
	num_palette_entries = (this.chunk_length as base.u32) / 3

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

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 w               : base.io_writer
	var w_mark          : base.u64
	var r_mark          : base.u64
	var swizzler_status : base.status
	var zlib_status     : base.status

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

	this.workbuf_wi = 0
	while true {
		if (this.workbuf_wi > this.workbuf_length) or (
			this.workbuf_length > args.workbuf.length()) {
			return base."#bad workbuf length"
		}
		io_bind (io: w, data: args.workbuf[this.workbuf_wi .. this.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())
				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() {
			break
		} else if zlib_status == base."$short write" {
			return base."#too much data"
		} else if zlib_status <> base."$short read" {
			return zlib_status
		} else if this.chunk_length == 0 {
			// TODO: verify CRC-32 checksum.
			args.src.skip_u32?(n: 4)
			// 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"
			}
			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.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
		}
	}

	swizzler_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 swizzler_status.is_ok() {
		return swizzler_status
	}
	swizzler_status = this.filter_and_swizzle!(dst: args.dst, workbuf: args.workbuf)
	if not swizzler_status.is_ok() {
		return swizzler_status
	}

	this.call_sequence = 0xFF
}

pri func decoder.filter_and_swizzle!(dst: ptr base.pixel_buffer, workbuf: slice base.u8) base.status {
	var dst_pixfmt          : base.pixel_format
	var dst_bits_per_pixel  : base.u32[..= 256]
	var dst_bytes_per_pixel : base.u64[..= 32]
	var dst_bytes_per_row   : base.u64
	var dst_palette         : slice base.u8
	var tab                 : table base.u8

	var y        : base.u32
	var dst      : slice base.u8
	var filter   : base.u8
	var curr_row : slice base.u8
	var prev_row : slice base.u8

	// TODO: the dst_pixfmt variable shouldn't be necessary. We should be able
	// to chain the two calls: "args.dst.pixel_format().bits_per_pixel()".
	dst_pixfmt = args.dst.pixel_format()
	dst_bits_per_pixel = dst_pixfmt.bits_per_pixel()
	if (dst_bits_per_pixel & 7) <> 0 {
		return base."#unsupported option"
	}
	dst_bytes_per_pixel = (dst_bits_per_pixel / 8) as base.u64
	dst_bytes_per_row = (this.width as base.u64) * dst_bytes_per_pixel
	dst_palette = args.dst.palette_or_else(fallback: this.dst_palette[..])
	tab = args.dst.plane(p: 0)

	while y < this.height {
		assert y < 0xFFFF_FFFF via "a < b: a < c; c <= b"(c: this.height)
		dst = tab.row(y: y)
		if dst_bytes_per_row < dst.length() {
			dst = dst[.. dst_bytes_per_row]
		}

		if 1 > args.workbuf.length() {
			return "#internal error: inconsistent workbuf length"
		}
		filter = args.workbuf[0]
		args.workbuf = args.workbuf[1 ..]
		if this.bytes_per_row > args.workbuf.length() {
			return "#internal error: inconsistent workbuf length"
		}
		curr_row = args.workbuf[.. this.bytes_per_row]
		args.workbuf = args.workbuf[this.bytes_per_row ..]

		if filter == 0 {
			// No-op.
		} else if filter == 1 {
			this.filter_1!(curr: curr_row)
		} else if filter == 2 {
			this.filter_2!(curr: curr_row, prev: prev_row)
		} else if filter == 3 {
			this.filter_3!(curr: curr_row, prev: prev_row)
		} else if filter == 4 {
			this.filter_4!(curr: curr_row, prev: prev_row)
		} else {
			return "#bad filter"
		}

		this.swizzler.swizzle_interleaved_from_slice!(
			dst: dst,
			dst_palette: dst_palette,
			src: curr_row)

		prev_row = curr_row
		y += 1
	} endwhile

	return ok
}

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
	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.workbuf_length,
		max_incl: this.workbuf_length)
}
