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

pri func decoder.filter_and_swizzle!(dst: ptr base.pixel_buffer, workbuf: slice base.u8) base.status,
	choosy,
{
	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_row0  : base.u64
	var dst_bytes_per_row1  : 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_row0 = (this.frame_rect_x0 as base.u64) * dst_bytes_per_pixel
	dst_bytes_per_row1 = (this.frame_rect_x1 as base.u64) * dst_bytes_per_pixel
	dst_palette = args.dst.palette_or_else(fallback: this.dst_palette[..])
	tab = args.dst.plane(p: 0)

	if dst_bytes_per_row1 < tab.width() {
		tab = tab.subtable(
			min_incl_x: 0,
			min_incl_y: 0,
			max_incl_x: dst_bytes_per_row1,
			max_incl_y: tab.height())
	}

	if dst_bytes_per_row0 < tab.width() {
		tab = tab.subtable(
			min_incl_x: dst_bytes_per_row0,
			min_incl_y: 0,
			max_incl_x: tab.width(),
			max_incl_y: tab.height())
	} else {
		tab = tab.subtable(
			min_incl_x: 0,
			min_incl_y: 0,
			max_incl_x: 0,
			max_incl_y: 0)
	}

	y = this.frame_rect_y0
	while y < this.frame_rect_y1 {
		assert y < 0x00FF_FFFF via "a < b: a < c; c <= b"(c: this.frame_rect_y1)
		dst = tab.row_u32(y: y)

		if 1 > args.workbuf.length() {
			return "#internal error: inconsistent workbuf length"
		}
		filter = args.workbuf[0]
		args.workbuf = args.workbuf[1 ..]
		if this.pass_bytes_per_row > args.workbuf.length() {
			return "#internal error: inconsistent workbuf length"
		}
		curr_row = args.workbuf[.. this.pass_bytes_per_row]
		args.workbuf = args.workbuf[this.pass_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
}
