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

// ----------------

// This program exercises the Rust GIF decoder at
// https://github.com/Geal/gif.rs
//
// Wuffs' C code doesn't depend on Rust or Nom (a parser combinator library
// written in Rust) per se, but this program gives some performance data for
// specific Rust GIF implementations. The equivalent Wuffs benchmarks (on the
// same test image) are run via:
//
// wuffs bench -mimic -focus=wuffs_gif_decode_1000k,mimic_gif_decode_1000k std/gif
//
// The "1000k" is because the test image (harvesters.gif) has approximately 1
// million pixels.
//
// The Wuffs benchmark reports megabytes per second. This program reports
// megapixels per second. The two concepts should be equivalent, since GIF
// images' pixel data are always 1 byte per pixel indices into a color palette.
// However, the gif.rs library only lets you decode 3 bytes per pixel (RGB),
// not 1 byte per pixel. This automatic palette look-up is arguably a defect in
// its API: decoding a 1,000 × 1,000 pixel image requires (2,000,000 - 768)
// more bytes this way, per frame, and animated GIFs have multiple frames.
//
// To run this program, do "cargo run --release > /dev/null" from the parent
// directory (the directory containing the Cargo.toml file). See the eprint
// comment below for why we redirect to /dev/null.

// TODO: unify this program, bench-rust-gif-dot-rs, with bench-rust-gif, the
// other Rust GIF benchmark program. They are two separate programs because
// both libraries want to be named "gif", and the cargo package manager cannot
// handle duplicate names (https://github.com/rust-lang/cargo/issues/1311).

extern crate gif;

use std::time::Instant;

// These constants are hard-coded to the harvesters.gif test image. As of
// 2018-01-27, the https://github.com/Geal/gif.rs library's src/lib.rs' Decoder
// implementation is incomplete, and doesn't expose enough API to calculate
// these from the source GIF image.
const WIDTH: usize = 1165;
const HEIGHT: usize = 859;
const BYTES_PER_PIXEL: usize = 3; // Red, green, blue.
const NUM_BYTES: usize = WIDTH * HEIGHT * BYTES_PER_PIXEL;
const COLOR_TABLE_ELEMENT_COUNT: u16 = 256;
const COLOR_TABLE_OFFSET: usize = 13;
const GRAPHIC_BLOCK_OFFSET: usize = 782;
const FIRST_PIXEL: u8 = 1; // Top left pixel's red component is 0x01.
const LAST_PIXEL: u8 = 3; // Bottom right pixel's blue component is 0x03.

fn main() {
    let mut dst = [0; NUM_BYTES];
    let src = include_bytes!("../../../test/data/harvesters.gif");

    let start = Instant::now();

    const REPS: u32 = 50;
    for _ in 0..REPS {
        decode(&mut dst[..], src);
    }

    let elapsed = start.elapsed();
    let elapsed_nanos = elapsed.as_secs() * 1_000_000_000 + (elapsed.subsec_nanos() as u64);

    let total_pixels: u64 = ((WIDTH * HEIGHT) as u64) * (REPS as u64);
    let kp_per_s: u64 = total_pixels * 1_000_000 / elapsed_nanos;

    // Use eprint instead of print because the https://github.com/Geal/gif.rs
    // library can print its own debugging messages (this is filed as
    // https://github.com/Geal/gif.rs/issues/4). When running this program, it
    // can be useful to redirect stdout (but not stderr) to /dev/null.
    eprint!(
        "gif.rs  {:3}.{:03} megapixels/second  github.com/Geal/gif.rs\n",
        kp_per_s / 1_000,
        kp_per_s % 1_000
    );
}

fn decode(dst: &mut [u8], src: &[u8]) {
    // Set up the hard-coded sanity check, executed below.
    dst[0] = 0xFE;
    dst[NUM_BYTES - 1] = 0xFE;

    let (_, colors) =
        gif::parser::color_table(&src[COLOR_TABLE_OFFSET..], COLOR_TABLE_ELEMENT_COUNT).unwrap();

    let (_, block) = gif::parser::graphic_block(&src[GRAPHIC_BLOCK_OFFSET..]).unwrap();

    let rendering = match block {
        gif::parser::Block::GraphicBlock(_, x) => x,
        _ => panic!("not a graphic block"),
    };

    let (code_size, blocks) = match rendering {
        gif::parser::GraphicRenderingBlock::TableBasedImage(_, x, y) => (x, y),
        _ => panic!("not a table based image"),
    };

    let num_bytes = gif::lzw::decode_lzw(&colors, code_size as usize, blocks, dst).unwrap();

    if num_bytes != NUM_BYTES {
        panic!("wrong num_bytes")
    }

    // A hard-coded sanity check that we decoded the pixel data correctly.
    if (dst[0] != FIRST_PIXEL) || (dst[NUM_BYTES - 1] != LAST_PIXEL) {
        panic!("wrong dst pixels")
    }
}
