// Copyright 2024 The Wuffs Authors.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// https://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
//
// SPDX-License-Identifier: Apache-2.0 OR MIT

pub status "#bad footer"
pub status "#bad header"
pub status "#truncated input"

pub const DECODER_WORKBUF_LEN_MAX_INCL_WORST_CASE : base.u64 = 0

pub struct decoder? implements base.image_decoder(
        pixfmt : base.u32,
        width  : base.u32[..= 0xFF_FFFF],
        height : base.u32[..= 0xFF_FFFF],

        remaining_pixels_times_4 : base.u64,

        // The call sequence state machine is discussed in
        // (/doc/std/image-decoders-call-sequence.md).
        call_sequence : base.u8,

        buffer_index : base.u32[..= 8192],

        dst_x : base.u32,
        dst_y : base.u32,

        swizzler : base.pixel_swizzler,
        util     : base.utility,
) + (
        pixel  : array[4] base.u8,
        cache  : array[256] base.u8,
        buffer : array[8192 + 4] base.u8,
)

pub func decoder.get_quirk(key: base.u32) base.u64 {
    return 0
}

pub func decoder.set_quirk!(key: base.u32, value: base.u64) base.status {
    return base."#unsupported option"
}

pub func decoder.decode_image_config?(dst: nptr base.image_config, src: base.io_reader) {
    var status : base.status

    while true {
        status =? this.do_decode_image_config?(dst: args.dst, src: args.src)
        if (status == base."$short read") and args.src.is_closed() {
            return "#truncated input"
        }
        yield? status
    }
}

pri func decoder.do_decode_image_config?(dst: nptr base.image_config, src: base.io_reader) {
    var a : base.u32

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

    a = args.src.read_u32le?()
    if a <> 'qoif'le {
        return "#bad header"
    }

    a = args.src.read_u32be?()
    if a > 0xFF_FFFF {
        return base."#unsupported image dimension"
    }
    this.width = a

    a = args.src.read_u32be?()
    if a > 0xFF_FFFF {
        return base."#unsupported image dimension"
    }
    this.height = a

    a = args.src.read_u8_as_u32?()
    if a == 3 {
        this.pixfmt = base.PIXEL_FORMAT__BGRX
    } else if a == 4 {
        this.pixfmt = base.PIXEL_FORMAT__BGRA_NONPREMUL
    } else {
        return "#bad header"
    }

    args.src.skip?(n: 1)

    if args.dst <> nullptr {
        args.dst.set!(
                pixfmt: this.pixfmt,
                pixsub: 0,
                width: this.width,
                height: this.height,
                first_frame_io_position: 14,
                first_frame_is_opaque: this.pixfmt == base.PIXEL_FORMAT__BGRX)
    }

    this.call_sequence = 0x20
}

pub func decoder.decode_frame_config?(dst: nptr base.frame_config, src: base.io_reader) {
    var status : base.status

    while true {
        status =? this.do_decode_frame_config?(dst: args.dst, src: args.src)
        if (status == base."$short read") and args.src.is_closed() {
            return "#truncated input"
        }
        yield? status
    }
}

pri func decoder.do_decode_frame_config?(dst: nptr base.frame_config, src: base.io_reader) {
    var pixfmt : base.pixel_format

    if this.call_sequence == 0x20 {
        // No-op.
    } else if this.call_sequence < 0x20 {
        this.do_decode_image_config?(dst: nullptr, src: args.src)
    } else if this.call_sequence == 0x28 {
        if 14 <> args.src.position() {
            return base."#bad restart"
        }
    } else if this.call_sequence == 0x40 {
        this.call_sequence = 0x60
        return base."@end of data"
    } else {
        return base."@end of data"
    }

    if args.dst <> nullptr {
        pixfmt = this.util.make_pixel_format(repr: this.pixfmt)
        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: 14,
                disposal: 0,
                opaque_within_bounds: this.pixfmt == base.PIXEL_FORMAT__BGRX,
                overwrite_instead_of_blend: false,
                background_color: pixfmt.default_background_color())
    }

    this.call_sequence = 0x40
}

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

    while true {
        status =? this.do_decode_frame?(dst: args.dst, src: args.src, blend: args.blend, workbuf: args.workbuf, opts: args.opts)
        if (status == base."$short read") and args.src.is_closed() {
            return "#truncated input"
        }
        yield? status
    }
}

pri func decoder.do_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 c64    : base.u64

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

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

    this.dst_x = 0
    this.dst_y = 0
    this.pixel[0] = 0x00
    this.pixel[1] = 0x00
    this.pixel[2] = 0x00
    this.pixel[3] = 0xFF
    this.cache[.. 256].bulk_memset!(byte_value: 0)

    this.remaining_pixels_times_4 = (this.width as base.u64) * (this.height as base.u64) * 4
    while this.remaining_pixels_times_4 > 0 {
        this.from_src_to_buffer?(src: args.src)
        if this.remaining_pixels_times_4 < (this.buffer_index as base.u64) {
            return base."#too much data"
        }
        this.remaining_pixels_times_4 -= this.buffer_index as base.u64
        status = this.from_buffer_to_dst!(dst: args.dst)
        if not status.is_ok() {
            return status
        }
    }

    c64 = args.src.read_u64be?()
    if c64 <> 1 {
        return "#bad footer"
    }

    this.call_sequence = 0x60
}

pri func decoder.from_src_to_buffer?(src: base.io_reader) {
    var c8    : base.u8
    var dg    : base.u8
    var bi    : base.u32[..= 8192]
    var bj    : base.u32[..= 8188]
    var bk    : base.u32[..= 7936]
    var ci    : base.u32[..= 252]
    var hash4 : base.u32[..= 252]

    bk = 7936  // 4 * (2048 - 64), so we always have room for a QOI_OP_RUN.
    if this.remaining_pixels_times_4 < 7936 {
        bk = this.remaining_pixels_times_4 as base.u32
    }

    while bi < bk {
        assert bi < 7936 via "a < b: a < c; c <= b"(c: bk)
        c8 = args.src.read_u8?()
        if c8 == 0xFE {  // QOI_OP_RGB.
            this.pixel[2] = args.src.read_u8?()
            this.pixel[1] = args.src.read_u8?()
            this.pixel[0] = args.src.read_u8?()

        } else if c8 == 0xFF {  // QOI_OP_RGBA.
            this.pixel[2] = args.src.read_u8?()
            this.pixel[1] = args.src.read_u8?()
            this.pixel[0] = args.src.read_u8?()
            this.pixel[3] = args.src.read_u8?()

        } else if (c8 >> 6) == 0 {  // QOI_OP_INDEX.
            ci = 4 * ((c8 & 0x3F) as base.u32)
            this.pixel[0] = this.cache[ci + 0]
            this.pixel[1] = this.cache[ci + 1]
            this.pixel[2] = this.cache[ci + 2]
            this.pixel[3] = this.cache[ci + 3]
            this.buffer[bi + 0] = this.pixel[0]
            this.buffer[bi + 1] = this.pixel[1]
            this.buffer[bi + 2] = this.pixel[2]
            this.buffer[bi + 3] = this.pixel[3]
            bi += 4
            continue

        } else if (c8 >> 6) == 1 {  // QOI_OP_DIFF.
            this.pixel[2] ~mod+= ((c8 >> 4) & 0x03) ~mod+ 0xFE
            this.pixel[1] ~mod+= ((c8 >> 2) & 0x03) ~mod+ 0xFE
            this.pixel[0] ~mod+= ((c8 >> 0) & 0x03) ~mod+ 0xFE

        } else if (c8 >> 6) == 2 {  // QOI_OP_LUMA.
            dg = (c8 & 0x3F) ~mod+ 0xE0
            c8 = args.src.read_u8?()
            this.pixel[2] ~mod+= (dg ~mod+ 0xF8) ~mod+ (0x0F & (c8 >> 4))
            this.pixel[1] ~mod+= dg
            this.pixel[0] ~mod+= (dg ~mod+ 0xF8) ~mod+ (0x0F & (c8 >> 0))

        } else {  // QOI_OP_RUN.
            bj = bi + (4 * (0x3F & (1 + (c8 as base.u32))))
            while bi < bj {
                assert bi < 8188 via "a < b: a < c; c <= b"(c: bj)
                this.buffer[bi + 0] = this.pixel[0]
                this.buffer[bi + 1] = this.pixel[1]
                this.buffer[bi + 2] = this.pixel[2]
                this.buffer[bi + 3] = this.pixel[3]
                bi += 4
            }
            continue
        }

        hash4 = 4 * (63 & (
                ((this.pixel[2] as base.u32) * 3) +
                ((this.pixel[1] as base.u32) * 5) +
                ((this.pixel[0] as base.u32) * 7) +
                ((this.pixel[3] as base.u32) * 11)))
        this.cache[hash4 + 0] = this.pixel[0]
        this.cache[hash4 + 1] = this.pixel[1]
        this.cache[hash4 + 2] = this.pixel[2]
        this.cache[hash4 + 3] = this.pixel[3]

        this.buffer[bi + 0] = this.pixel[0]
        this.buffer[bi + 1] = this.pixel[1]
        this.buffer[bi + 2] = this.pixel[2]
        this.buffer[bi + 3] = this.pixel[3]
        bi += 4
    }

    this.buffer_index = bi
}

pri func decoder.from_buffer_to_dst!(dst: ptr base.pixel_buffer) base.status {
    var dst_pixfmt          : base.pixel_format
    var dst_bits_per_pixel  : base.u32[..= 256]
    var dst_bytes_per_pixel : base.u32[..= 32]
    var dst_bytes_per_row   : base.u64
    var tab                 : table base.u8
    var bi                  : base.u32
    var rem_x               : base.u32[..= 0xFF_FFFF]
    var dst                 : slice base.u8
    var src                 : slice base.u8
    var src_length          : base.u32
    var i                   : base.u64

    // 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
    dst_bytes_per_row = (this.width * dst_bytes_per_pixel) as base.u64
    tab = args.dst.plane(p: 0)

    while bi < this.buffer_index {
        assert bi < 8192 via "a < b: a < c; c <= b"(c: this.buffer_index)

        if this.width <= this.dst_x {
            this.dst_x = 0
            this.dst_y ~mod+= 1
            if this.dst_y >= this.height {
                break
            }
            rem_x = this.width
        } else {
            rem_x = this.width - this.dst_x
        }

        src = this.buffer[bi .. this.buffer_index]
        if ((4 * rem_x) as base.u64) < src.length() {
            src = src[.. (4 * rem_x) as base.u64]
        }
        src_length = (src.length() & 0xFFFF_FFFF) as base.u32
        bi ~mod+= src_length

        dst = tab.row_u32(y: this.dst_y)
        if dst_bytes_per_row < dst.length() {
            dst = dst[.. dst_bytes_per_row]
        }

        i = (this.dst_x as base.u64) * (dst_bytes_per_pixel as base.u64)
        this.dst_x ~mod+= src_length / 4
        if i < dst.length() {
            this.swizzler.swizzle_interleaved_from_slice!(
                    dst: dst[i ..],
                    dst_palette: args.dst.palette(),
                    src: src)
        }
    }

    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 > 0x20 {
        return 1
    }
    return 0
}

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

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

pub func decoder.set_report_metadata!(fourcc: base.u32, report: base.bool) {
    // No-op. QOI doesn't support metadata.
}

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: 0, max_incl: 0)
}
