// 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/image-rs/image-gif
// which is the top result for https://crates.io/search?q=gif&sort=downloads
//
// Wuffs' C code doesn't depend on Rust per se, but this program gives some
// performance data for specific Rust GIF implementations. The equivalent Wuffs
// benchmarks (on the same test images) are run via:
//
// wuffs bench std/gif
//
// To run this program, do "cargo run --release" from the parent directory (the
// directory containing the Cargo.toml file).

// 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;
extern crate rustc_version_runtime;

use gif::SetParameter;
use std::time::Instant;

const ITERSCALE: u64 = 10;
const REPS: u64 = 5;

fn main() {
    let version = rustc_version_runtime::version();
    print!(
        "# Rust {}.{}.{}\n",
        version.major,
        version.minor,
        version.patch
    );
    print!("#\n");
    print!("# The output format, including the \"Benchmark\" prefixes, is compatible with the\n");
    print!("# https://godoc.org/golang.org/x/perf/cmd/benchstat tool. To install it, first\n");
    print!("# install Go, then run \"go get golang.org/x/perf/cmd/benchstat\".\n");

    let mut dst = vec![0u8; 64 * 1024 * 1024];

    // The various magic constants below are copied from test/c/std/gif.c
    for i in 0..(1 + REPS) {
        bench(
            "1k_bw",
            &mut dst[..],
            include_bytes!("../../../test/data/pjw-thumbnail.gif"),
            i == 0, // warm_up
            32 * 32 * 1, // want_num_bytes
            2000, // iters_unscaled
        );

        bench(
            "1k_color_full_init",
            &mut dst[..],
            include_bytes!("../../../test/data/hippopotamus.regular.gif"),
            i == 0, // warm_up
            36 * 28 * 1, // want_num_bytes
            1000, // iters_unscaled
        );

        bench(
            "10k_bgra",
            &mut dst[..],
            include_bytes!("../../../test/data/hat.gif"),
            i == 0, // warm_up
            90 * 112 * 4, // want_num_bytes
            100, // iters_unscaled
        );

        bench(
            "10k_indexed",
            &mut dst[..],
            include_bytes!("../../../test/data/hat.gif"),
            i == 0, // warm_up
            90 * 112 * 1, // want_num_bytes
            100, // iters_unscaled
        );

        bench(
            "20k",
            &mut dst[..],
            include_bytes!("../../../test/data/bricks-gray.gif"),
            i == 0, // warm_up
            160 * 120 * 1, // want_num_bytes
            50, // iters_unscaled
        );

        bench(
            "100k_artificial",
            &mut dst[..],
            include_bytes!("../../../test/data/hibiscus.primitive.gif"),
            i == 0, // warm_up
            312 * 442 * 1, // want_num_bytes
            15, // iters_unscaled
        );

        bench(
            "100k_realistic",
            &mut dst[..],
            include_bytes!("../../../test/data/hibiscus.regular.gif"),
            i == 0, // warm_up
            312 * 442 * 1, // want_num_bytes
            10, // iters_unscaled
        );

        bench(
            "1000k_full_init",
            &mut dst[..],
            include_bytes!("../../../test/data/harvesters.gif"),
            i == 0, // warm_up
            1165 * 859, // want_num_bytes
            1, // iters_unscaled
        );

        bench(
            "anim_screencap",
            &mut dst[..],
            include_bytes!("../../../test/data/gifplayer-muybridge.gif"),
            i == 0, // warm_up
            4652198, // want_num_bytes
            1, // iters_unscaled
        );
    }
}

fn bench(
    name: &str, // Benchmark name.
    dst: &mut [u8], // Destination buffer.
    src: &[u8], // Source data.
    warm_up: bool, // Whether this is a warm up rep.
    want_num_bytes: u64, // Expected num_bytes per iteration.
    iters_unscaled: u64, // Base number of iterations.
) {
    let iters = iters_unscaled * ITERSCALE;
    let output_32_bit_color = name.ends_with("_bgra");
    let mut total_num_bytes = 0u64;

    let start = Instant::now();
    for _ in 0..iters {
        let n = decode(&mut dst[..], src, output_32_bit_color);
        if n != want_num_bytes {
            panic!("num_bytes: got {}, want {}", n, want_num_bytes);
        }
        total_num_bytes += n;
    }
    let elapsed = start.elapsed();

    let elapsed_nanos = (elapsed.as_secs() * 1_000_000_000) + (elapsed.subsec_nanos() as u64);
    let kb_per_s: u64 = total_num_bytes * 1_000_000 / elapsed_nanos;

    if warm_up {
        return;
    }

    print!(
        "Benchmarkrust_gif_decode_{:16}   {:8}   {:12} ns/op   {:3}.{:03} MB/s\n",
        name,
        iters,
        elapsed_nanos / iters,
        kb_per_s / 1_000,
        kb_per_s % 1_000
    );
}

// decode returns the number of bytes processed.
fn decode(dst: &mut [u8], src: &[u8], output_32_bit_color: bool) -> u64 {
    let mut num_bytes = 0u64;
    let mut decoder = gif::Decoder::new(src);
    if output_32_bit_color {
        decoder.set(gif::ColorOutput::RGBA);
    }

    let mut reader = decoder.read_info().unwrap();
    while let Some(_) = reader.next_frame_info().unwrap() {
        num_bytes += reader.buffer_size() as u64;
        reader.read_into_buffer(dst).unwrap();
    }
    num_bytes
}
