// 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 decoder? implements base.image_decoder(
        // These upper bounds should be 0xFFFF, on a strict reading of the GIF
        // spec, but our looser implementation uses 0x1_FFFE. See
        // test/data/artificial-gif/frame-out-of-bounds.gif.make-artificial.txt
        width  : base.u32[..= 0x1_FFFE],
        height : base.u32[..= 0x1_FFFE],

        // The call sequence state machine is discussed in
        // (/doc/std/image-decoders-call-sequence.md).
        //
        // A GIF's first frame's bounds affects the overall image bounds (per
        // test/data/artificial/gif-frame-out-of-bounds.gif.make-artificial.txt).
        // Decoding the first frame's bounds is part of decode_image_config even
        // though it's conceptually part of the first decode_frame_config.
        call_sequence : base.u8,

        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,
        previous_lzw_decode_ended_abruptly : base.bool,
        seen_header                        : 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_animation_loops_value : base.bool,
        num_animation_loops_value      : 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[..= 0x0_FFFF],
        frame_rect_y0 : base.u32[..= 0x0_FFFF],
        frame_rect_x1 : base.u32[..= 0x1_FFFE],
        frame_rect_y1 : base.u32[..= 0x1_FFFE],

        // The dst_etc fields are the output cursor during copy_to_image_buffer.
        dst_x            : base.u32,
        dst_y            : base.u32,
        dirty_max_excl_y : base.u32,

        // Indexes into the compressed array, defined below.
        compressed_ri : base.u64,
        compressed_wi : base.u64,

        swizzler : base.pixel_swizzler,

        util : base.utility,
) + (
        compressed : array[4096] base.u8,

        // palettes[0] and palettes[1] are the Global and Local Color Table.
        palettes : array[2] array[4 * 256] base.u8,
        // dst_palette is the swizzled color table.
        dst_palette : array[4 * 256] base.u8,

        lzw : lzw.decoder,
)

pub func decoder.set_quirk!(key: base.u32, value: base.u64) base.status {
    if (this.call_sequence == 0x00) and (args.key >= QUIRKS_BASE) {
        args.key -= QUIRKS_BASE
        if args.key < QUIRKS_COUNT {
            this.quirks[args.key] = args.value > 0
            return ok
        }
    }
    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
    } endwhile
}

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

    if this.call_sequence <> 0x00 {
        return base."#bad call sequence"
    } else if not this.seen_header {
        this.decode_header?(src: args.src)
        this.decode_lsd?(src: args.src)
        this.seen_header = true
    }

    this.decode_up_to_id_part1?(src: args.src)

    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 {
        args.dst.set!(
                pixfmt: base.PIXEL_FORMAT__INDEXED__BGRA_BINARY,
                pixsub: 0,
                width: this.width,
                height: this.height,
                first_frame_io_position: this.frame_config_io_position,
                first_frame_is_opaque: ffio)
    }

    if this.call_sequence == 0x00 {
        this.call_sequence = 0x20
    }
}

pub func 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 decoder.tell_me_more?(dst: base.io_writer, minfo: nptr base.more_information, src: base.io_reader) {
    var status : base.status

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

pri func decoder.do_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 & 0x10) == 0 {
        return base."#bad call sequence"
    }
    if this.metadata_fourcc == 0 {
        return base."#no more information"
    }

    while true {
        while true,
                post args.src.length() > 0,
        {
            if args.src.position() <> this.metadata_io_position {
                if args.minfo <> nullptr {
                    args.minfo.set!(
                            flavor: 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.length() <= 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.skip_u32_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.skip_u32_fast!(actual: 1, worst_case: 1)
        }
        this.metadata_io_position = args.src.position() ~sat+ chunk_length

        if args.minfo <> nullptr {
            args.minfo.set!(
                    flavor: base.MORE_INFORMATION__FLAVOR__METADATA_RAW_PASSTHROUGH,
                    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: base.MORE_INFORMATION__FLAVOR__METADATA_RAW_PASSTHROUGH,
                w: this.metadata_fourcc,
                x: 0,
                y: this.metadata_io_position,
                z: this.metadata_io_position)
    }
    this.call_sequence &= 0xEF
    this.metadata_fourcc = 0
    this.metadata_io_position = 0
    return ok
}

pub func decoder.num_animation_loops() base.u32 {
    if this.seen_num_animation_loops_value {
        return this.num_animation_loops_value
    }
    // Absent an explicit animation loop count, default to 1 meaning "play each
    // frame exactly once" for animated GIFs and 0 meaning "loop forever" for
    // still (non-animated) GIFs.
    //
    // In practice, returning 1 or 0 has no difference for still GIFs, in that
    // either way, the pixels on screen do not change over time. However,
    // returning 0 here matches other Wuffs image decoders (e.g. BMP, PNG)
    // returning 0 for their still images.
    //
    // As a consequence, if a still GIF is losslessly converted to a still BMP
    // and both of those are then converted to NIA, the two NIA outputs match.
    if this.num_decoded_frame_configs_value > 1 {
        return 1
    }
    return 0
}

pub func decoder.num_decoded_frame_configs() base.u64 {
    return this.num_decoded_frame_configs_value
}

pub func decoder.num_decoded_frames() base.u64 {
    return this.num_decoded_frames_value
}

pub func decoder.frame_dirty_rect() base.rect_ie_u32 {
    // The "foo.min(no_more_than: this.width_or_height)" calls clip the nominal
    // frame_rect to the image_rect.
    return this.util.make_rect_ie_u32(
            min_incl_x: this.frame_rect_x0.min(no_more_than: this.width),
            min_incl_y: this.frame_rect_y0.min(no_more_than: this.height),
            max_excl_x: this.frame_rect_x1.min(no_more_than: this.width),
            max_excl_y: this.dirty_max_excl_y.min(no_more_than: this.height))
}

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

pub func decoder.restart_frame!(index: base.u64, io_position: base.u64) base.status {
    if this.call_sequence < 0x20 {
        return base."#bad call sequence"
    } else if args.io_position == 0 {
        return base."#bad argument"
    }
    this.delayed_num_decoded_frames = false
    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!()
    this.call_sequence = 0x28
    return ok
}

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

pri func decoder.do_decode_frame_config?(dst: nptr base.frame_config, src: base.io_reader) {
    var background_color : base.u32
    var flags            : base.u8

    this.dirty_max_excl_y = 0

    if (this.call_sequence & 0x10) <> 0 {
        return base."#bad call sequence"
    } else 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 this.frame_config_io_position <> args.src.position() {
            return base."#bad restart"
        }
    } else if this.call_sequence == 0x40 {
        this.skip_frame?(src: args.src)
        if this.call_sequence >= 0x60 {
            return base."@end of data"
        }
    } else {
        return base."@end of data"
    }

    if (this.num_decoded_frame_configs_value > 0) or (this.call_sequence == 0x28) {
        this.decode_up_to_id_part1?(src: args.src)
        if this.call_sequence >= 0x60 {
            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.length() <= 0,
                    post args.src.length() > 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(no_more_than: this.width_or_height)" calls clip the
        // nominal frame_rect to the image_rect.
        args.dst.set!(bounds: this.util.make_rect_ie_u32(
                min_incl_x: this.frame_rect_x0.min(no_more_than: this.width),
                min_incl_y: this.frame_rect_y0.min(no_more_than: this.height),
                max_excl_x: this.frame_rect_x1.min(no_more_than: this.width),
                max_excl_y: this.frame_rect_y1.min(no_more_than: 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 = 0x40
}

pri func 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.skip_u32?(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!()
    this.call_sequence = 0x20
}

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

// TODO: honor args.opts.
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) {
    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"
    }
    if this.quirks[QUIRK_REJECT_EMPTY_FRAME - QUIRKS_BASE] and
            ((this.frame_rect_x0 == this.frame_rect_x1) or (this.frame_rect_y0 == this.frame_rect_y1)) {
        return "#bad frame size"
    }
    this.decode_id_part1?(dst: args.dst, src: args.src, blend: args.blend)
    this.decode_id_part2?(dst: args.dst, src: args.src, workbuf: args.workbuf)

    this.num_decoded_frames_value ~sat+= 1
    this.reset_gc!()
    this.call_sequence = 0x20
}

pri func decoder.reset_gc!() {
    // 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 decoder.decode_up_to_id_part1?(src: base.io_reader) {
    var block_type : base.u8

    if (this.frame_config_io_position == 0) or (this.num_decoded_frame_configs_value > 0) {
        this.frame_config_io_position = args.src.position()
    }

    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 we don't have 0x21 or 0x2C then, according to the spec, the
            // only valid byte is 0x3B, called the "Trailer". In practice, some
            // other popular decoders allow anything (other than 0x21 or 0x2C)
            // to be equivalent to 0x3B, which ends the animated GIF image, and
            // we do likewise here. Some real world GIF files that exhibit this
            // are at https://github.com/golang/go/issues/38853
            //
            // Chromium's decoder
            // https://skia.googlesource.com/libgifcodec/+/c002ec500aba1e1b0189547629787cb02db78193/SkGifImageReader.cpp#563
            //
            // Firefox's decoder
            // https://dxr.mozilla.org/mozilla-central/rev/93a33cb7f2369ac4f1d1f2ac97ec14ba60e1e7d7/image/decoders/nsGIFDecoder2.cpp#569
            if this.delayed_num_decoded_frames {
                this.delayed_num_decoded_frames = false
                this.num_decoded_frames_value ~sat+= 1
            }
            this.call_sequence = 0x60
            break
        }
    } endwhile
}

// decode_header reads either "GIF87a" or "GIF89a".
//
// See the spec section 17 "Header" on page 7.
pri func 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 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.skip_u32?(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 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 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.skip_u32?(n: block_size as base.u32)
    } endwhile
}

// decode_ae reads an Application Extension.
pri func 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.skip_u32?(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.skip_u32?(n: block_size as base.u32)
            break.goto_done
        }
        c = args.src.read_u8?()
        if c <> 0x01 {
            args.src.skip_u32?(n: 2)
            break.goto_done
        }
        this.num_animation_loops_value = args.src.read_u16le_as_u32?()
        this.seen_num_animation_loops_value = 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_animation_loops_value) and (this.num_animation_loops_value <= 0xFFFF) {
            this.num_animation_loops_value += 1
        }

    } else if this.call_sequence >= 0x20 {
        // 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 = 0x10
        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 = 0x10
        return base."@metadata reported"
    }

    break.goto_done
    }} endwhile.goto_done

    this.skip_blocks?(src: args.src)
}

// decode_gc reads a Graphic Control.
pri func 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
    flags = (flags >> 2) & 0x07
    if flags == 2 {
        this.gc_disposal = base.ANIMATION_DISPOSAL__RESTORE_BACKGROUND
    } else if (flags == 3) or (flags == 4) {
        this.gc_disposal = base.ANIMATION_DISPOSAL__RESTORE_PREVIOUS
    } else {
        this.gc_disposal = base.ANIMATION_DISPOSAL__NONE
    }

    // 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 part2 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 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 += this.frame_rect_x0
    this.frame_rect_y1 = args.src.read_u16le_as_u32?()
    this.frame_rect_y1 += this.frame_rect_y0

    this.dst_x = this.frame_rect_x0
    this.dst_y = 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.num_decoded_frame_configs_value == 0) and (not this.quirks[QUIRK_IMAGE_BOUNDS_ARE_STRICT - QUIRKS_BASE]) {
        this.width = this.width.max(no_less_than: this.frame_rect_x1)
        this.height = this.height.max(no_less_than: this.frame_rect_y1)
    }
}

pri func decoder.decode_id_part1?(dst: ptr base.pixel_buffer, src: base.io_reader, blend: base.pixel_blend) {
    var flags               : base.u8
    var which_palette       : base.u8[..= 1]
    var num_palette_entries : base.u32[..= 256]
    var i                   : base.u32
    var argb                : base.u32
    var status              : base.status
    var lw                  : base.u8

    flags = args.src.read_u8?()
    if (flags & 0x40) <> 0 {
        this.interlace = 4
    } else {
        this.interlace = 0
    }

    // Read the optional Local Color Table.
    which_palette = 1
    if (flags & 0x80) <> 0 {
        num_palette_entries = (1 as base.u32) << (1 + (flags & 0x07))
        i = 0
        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[1][(4 * i) + 0] = ((argb >> 0) & 0xFF) as base.u8
            this.palettes[1][(4 * i) + 1] = ((argb >> 8) & 0xFF) as base.u8
            this.palettes[1][(4 * i) + 2] = ((argb >> 16) & 0xFF) as base.u8
            this.palettes[1][(4 * i) + 3] = ((argb >> 24) & 0xFF) as base.u8
            i += 1
        } endwhile
        // Set the remaining palette entries to opaque black.
        while i < 256 {
            this.palettes[1][(4 * i) + 0] = 0x00
            this.palettes[1][(4 * i) + 1] = 0x00
            this.palettes[1][(4 * i) + 2] = 0x00
            this.palettes[1][(4 * i) + 3] = 0xFF
            i += 1
        } endwhile
    } else if this.quirks[QUIRK_REJECT_EMPTY_PALETTE - QUIRKS_BASE] and (not this.has_global_palette) {
        return "#bad palette"
    } else if this.gc_has_transparent_index {
        this.palettes[1][..].copy_from_slice!(s: this.palettes[0][..])
    } else {
        which_palette = 0
    }

    // Set the gc_transparent_index palette entry to transparent black.
    if this.gc_has_transparent_index {
        this.palettes[1][(4 * (this.gc_transparent_index as base.u32)) + 0] = 0x00
        this.palettes[1][(4 * (this.gc_transparent_index as base.u32)) + 1] = 0x00
        this.palettes[1][(4 * (this.gc_transparent_index as base.u32)) + 2] = 0x00
        this.palettes[1][(4 * (this.gc_transparent_index as base.u32)) + 3] = 0x00
    }

    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: base.PIXEL_FORMAT__INDEXED__BGRA_BINARY),
            src_palette: this.palettes[which_palette][..],
            blend: args.blend)
    if not status.is_ok() {
        return status
    }

    // Other GIF implementations accept GIF files that aren't completely spec
    // compliant. For example, the test/data/gifplayer-muybridge.gif file
    // (created by the gifsicle program) is accepted by other GIF decoders.
    // However, in that file, frame #61's embedded LZW data is truncated,
    // finishing with only 8 of the 9 bits required of the LZW end code. The
    // end code itself, 0x81, is representable in only 8 bits, but the number
    // of bits for the decoder to read has ticked over from 8 to 9 just before
    // that end code is encountered.
    //
    // To accommodate such malformed GIFs, we detect when the previous frame's
    // LZW decoding ended abruptly. The previous LZW decode 'works', in that it
    // decodes as much pixel data as is available, but without seeing that end
    // code (i.e. returning the "ok" status code), the LZW decoder is stuck in
    // a coroutine-in-progress lzw_decoder.decode call, still waiting for that
    // end code. To cancel that coroutine, we reset the LZW decoder.
    if this.previous_lzw_decode_ended_abruptly {
        this.lzw.reset!()
    }

    // Process the LZW literal width. The spec says that "images which have one
    // color bit must be indicated as having a code size [i.e. literal width]
    // of 2", but in practice, some encoders use a literal width of 1 or 0.
    lw = args.src.read_u8?()
    if lw > 8 {
        return "#bad literal width"
    }
    this.lzw.set_quirk!(key: lzw.QUIRK_LITERAL_WIDTH_PLUS_ONE, value: (1 + lw) as base.u64)

    this.previous_lzw_decode_ended_abruptly = true
}

pri func decoder.decode_id_part2?(dst: ptr base.pixel_buffer, src: base.io_reader, workbuf: slice base.u8) {
    var block_size      : base.u64[..= 255]
    var need_block_size : base.bool
    var n_copied        : base.u32
    var n_compressed    : base.u64
    var r               : base.io_reader
    var mark            : base.u64
    var lzw_status      : base.status
    var copy_status     : base.status
    var uncompressed    : roslice base.u8

    need_block_size = true
    while.outer true {
        if need_block_size {
            need_block_size = false
            block_size = args.src.read_u8_as_u64?()
        }
        if block_size == 0 {
            break.outer
        }
        while args.src.length() == 0 {
            yield? base."$short read"
        } endwhile

        if this.compressed_ri == this.compressed_wi {
            this.compressed_ri = 0
            this.compressed_wi = 0
        }
        while this.compressed_wi <= (4096 - 255) {
            n_compressed = block_size.min(no_more_than: args.src.length())
            if n_compressed <= 0 {
                break
            }
            n_copied = args.src.limited_copy_u32_to_slice!(
                    up_to: (n_compressed & 0xFFFF_FFFF) as base.u32,
                    s: this.compressed[this.compressed_wi ..])
            this.compressed_wi ~sat+= n_copied as base.u64
            block_size ~sat-= n_copied as base.u64
            if block_size > 0 {
                break
            }
            if args.src.length() <= 0 {
                need_block_size = true
                break
            }
            block_size = args.src.peek_u8_as_u64()
            args.src.skip_u32_fast!(actual: 1, worst_case: 1)
        } endwhile

        while.inner true {
            if (this.compressed_ri > this.compressed_wi) or (this.compressed_wi > 4096) {
                return "#internal error: inconsistent ri/wi"
            }
            io_bind (io: r, data: this.compressed[this.compressed_ri .. this.compressed_wi], history_position: 0) {
                mark = r.mark()
                lzw_status =? this.lzw.transform_io?(
                        dst: this.util.empty_io_writer(), src: r, workbuf: this.util.empty_slice_u8())
                this.compressed_ri ~sat+= r.count_since(mark: mark)
            }

            uncompressed = this.lzw.flush!()
            if uncompressed.length() > 0 {
                copy_status = this.copy_to_image_buffer!(pb: args.dst, src: uncompressed)
                if copy_status.is_error() {
                    return copy_status
                }
            }

            if lzw_status.is_ok() {
                this.previous_lzw_decode_ended_abruptly = false

                // Skip any trailing blocks.
                if need_block_size or (block_size > 0) {
                    args.src.skip_u32?(n: block_size as base.u32)
                    this.skip_blocks?(src: args.src)
                }

                break.outer
            } else if lzw_status == base."$short read" {
                continue.outer
            } else if lzw_status == base."$short write" {
                continue.inner
            } else if this.quirks[QUIRK_IGNORE_TOO_MUCH_PIXEL_DATA - QUIRKS_BASE] and
                    (this.dst_y >= this.frame_rect_y1) and (this.interlace == 0) {
                // It's invalid LZW-compressed data, but we still have a full
                // frame and have opted in to QUIRK_IGNORE_TOO_MUCH_PIXEL_DATA,
                // so treat it like the lzw_status.is_ok() case, other than not
                // clearing this.previous_lzw_decode_ended_abruptly.
                if need_block_size or (block_size > 0) {
                    args.src.skip_u32?(n: block_size as base.u32)
                    this.skip_blocks?(src: args.src)
                }
                break.outer
            }
            return lzw_status
        } endwhile.inner
    } endwhile.outer

    this.compressed_ri = 0
    this.compressed_wi = 0

    if (this.dst_y < this.frame_rect_y1) and
            (this.frame_rect_x0 <> this.frame_rect_x1) and
            (this.frame_rect_y0 <> this.frame_rect_y1) {
        return base."#not enough data"
    }
}

pri func decoder.copy_to_image_buffer!(pb: ptr base.pixel_buffer, src: roslice base.u8) base.status {
    // TODO: don't assume an interleaved pixel format.
    var dst             : slice base.u8
    var src             : roslice base.u8
    var width_in_bytes  : base.u64
    var n               : base.u64
    var src_ri          : base.u64
    var pixfmt          : base.pixel_format
    var bytes_per_pixel : base.u32[..= 32]
    var bits_per_pixel  : base.u32[..= 256]
    var tab             : table base.u8
    var i               : base.u64
    var j               : base.u64
    var replicate_y0    : base.u32
    var replicate_y1    : base.u32
    var replicate_dst   : slice base.u8
    var replicate_src   : roslice base.u8

    // TODO: the pixfmt variable shouldn't be necessary. We should be able to
    // chain the two calls: "args.pb.pixel_format().bits_per_pixel()".
    pixfmt = args.pb.pixel_format()
    bits_per_pixel = pixfmt.bits_per_pixel()
    if (bits_per_pixel & 7) <> 0 {
        return base."#unsupported option"
    }
    bytes_per_pixel = bits_per_pixel >> 3

    width_in_bytes = (this.width * bytes_per_pixel) as base.u64
    tab = args.pb.plane(p: 0)
    while src_ri < args.src.length() {
        src = args.src[src_ri ..]

        if this.dst_y >= this.frame_rect_y1 {
            if this.quirks[QUIRK_IGNORE_TOO_MUCH_PIXEL_DATA - QUIRKS_BASE] {
                return ok
            }
            return base."#too much data"
        }

        // First, copy from src to that part of the frame rect that is inside
        // args.pb's bounds (clipped to the image bounds).

        dst = tab.row_u32(y: this.dst_y)
        if this.dst_y >= this.height {
            dst = dst[.. 0]
        } else if width_in_bytes < dst.length() {
            dst = dst[.. width_in_bytes]
        }

        i = (this.dst_x as base.u64) * (bytes_per_pixel as base.u64)
        if i < dst.length() {
            j = (this.frame_rect_x1 as base.u64) * (bytes_per_pixel as base.u64)
            if (i <= j) and (j <= dst.length()) {
                dst = dst[i .. j]
            } else {
                dst = dst[i ..]
            }
            n = this.swizzler.swizzle_interleaved_from_slice!(
                    dst: dst, dst_palette: this.dst_palette[..], src: src)

            src_ri ~sat+= n
            this.dst_x ~sat+= (n & 0xFFFF_FFFF) as base.u32

            this.dirty_max_excl_y = this.dirty_max_excl_y.max(no_less_than: this.dst_y ~sat+ 1)
        }

        if this.frame_rect_x1 <= this.dst_x {
            this.dst_x = this.frame_rect_x0
            if this.interlace == 0 {
                this.dst_y ~sat+= 1
                continue
            }

            // For the first frame of an interlaced, non-transparent GIF,
            // replicate the early passes' rows. For example, when such an
            // image is downloaded over a slow network, this produces a richer
            // intermediate image while waiting for the complete image.
            //
            // Some other GIF implementations call this progressive display or
            // a "Haeberli inspired" technique.
            if (this.num_decoded_frames_value == 0) and
                    (not this.gc_has_transparent_index) and
                    (this.interlace > 1) {

                replicate_src = tab.row_u32(y: this.dst_y)
                replicate_y0 = this.dst_y ~sat+ 1
                replicate_y1 = this.dst_y ~sat+ (INTERLACE_COUNT[this.interlace] as base.u32)
                replicate_y1 = replicate_y1.min(no_more_than: this.frame_rect_y1)
                while replicate_y0 < replicate_y1 {
                    assert replicate_y0 < 0xFFFF_FFFF via "a < b: a < c; c <= b"(c: replicate_y1)
                    replicate_dst = tab.row_u32(y: replicate_y0)
                    replicate_dst.copy_from_slice!(s: replicate_src)
                    replicate_y0 += 1
                } endwhile
                this.dirty_max_excl_y = this.dirty_max_excl_y.max(no_less_than: replicate_y1)
            }

            this.dst_y ~sat+= INTERLACE_DELTA[this.interlace] as base.u32
            while (this.interlace > 0) and (this.dst_y >= this.frame_rect_y1) {
                this.interlace -= 1
                this.dst_y = this.frame_rect_y0 ~sat+ INTERLACE_START[this.interlace]
            } endwhile
            continue
        }

        if args.src.length() == src_ri {
            break
        } else if args.src.length() < src_ri {
            return "#internal error: inconsistent ri/wi"
        }

        // Second, skip over src for that part of the frame rect that is
        // outside args.pb's bounds. This second step should be infrequent.

        // Set n to the number of pixels (i.e. the number of bytes) to skip.
        n = (this.frame_rect_x1 - this.dst_x) as base.u64
        n = n.min(no_more_than: args.src.length() - src_ri)

        src_ri ~sat+= n
        this.dst_x ~sat+= (n & 0xFFFF_FFFF) as base.u32

        if this.frame_rect_x1 <= this.dst_x {
            this.dst_x = this.frame_rect_x0
            this.dst_y ~sat+= INTERLACE_DELTA[this.interlace] as base.u32
            while (this.interlace > 0) and (this.dst_y >= this.frame_rect_y1) {
                this.interlace -= 1
                this.dst_y = this.frame_rect_y0 ~sat+ INTERLACE_START[this.interlace]
            } endwhile
            continue
        }

        if src_ri <> args.src.length() {
            return "#internal error: inconsistent ri/wi"
        }
        break
    } endwhile
    return ok
}
