• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2018 The Wuffs Authors.
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 //    https://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 // ----------------
16 
17 // This program exercises the Rust GIF decoder at
18 // https://github.com/PistonDevelopers/image-gif
19 //
20 // Wuffs' C code doesn't depend on Rust per se, but this program gives some
21 // performance data for specific Rust GIF implementations. The equivalent Wuffs
22 // benchmarks (on the same test image) are run via:
23 //
24 // wuffs bench -mimic -focus=wuffs_gif_decode_1000k,mimic_gif_decode_1000k std/gif
25 //
26 // The "1000k" is because the test image (harvesters.gif) has approximately 1
27 // million pixels.
28 //
29 // The Wuffs benchmark reports megabytes per second. This program reports
30 // megapixels per second. The two concepts should be equivalent, since GIF
31 // images' pixel data are always 1 byte per pixel indices into a color palette.
32 //
33 // To run this program, do "cargo run --release" from the parent directory (the
34 // directory containing the Cargo.toml file).
35 
36 // TODO: unify this program, bench-rust-gif-dot-rs, with bench-rust-gif, the
37 // other Rust GIF benchmark program. They are two separate programs because
38 // both libraries want to be named "gif", and the cargo package manager cannot
39 // handle duplicate names (https://github.com/rust-lang/cargo/issues/1311).
40 
41 extern crate gif;
42 
43 use std::time::Instant;
44 
45 // These constants are hard-coded to the harvesters.gif test image.
46 const WIDTH: usize = 1165;
47 const HEIGHT: usize = 859;
48 const BYTES_PER_PIXEL: usize = 1; // Palette index.
49 const NUM_BYTES: usize = WIDTH * HEIGHT * BYTES_PER_PIXEL;
50 const FIRST_PIXEL: u8 = 0; // Top left pixel's palette index is 0x00.
51 const LAST_PIXEL: u8 = 1; // Bottom right pixel's palette index is 0x01.
52 
main()53 fn main() {
54     let mut dst = [0; NUM_BYTES];
55     let src = include_bytes!("../../../test/data/harvesters.gif");
56 
57     let start = Instant::now();
58 
59     const REPS: u32 = 50;
60     for _ in 0..REPS {
61         decode(&mut dst[..], src);
62     }
63 
64     let elapsed = start.elapsed();
65     let elapsed_nanos = elapsed.as_secs() * 1_000_000_000 + (elapsed.subsec_nanos() as u64);
66 
67     let total_pixels: u64 = ((WIDTH * HEIGHT) as u64) * (REPS as u64);
68     let kp_per_s: u64 = total_pixels * 1_000_000 / elapsed_nanos;
69 
70     print!(
71         "gif     {:3}.{:03} megapixels/second  github.com/PistonDevelopers/image-gif\n",
72         kp_per_s / 1_000,
73         kp_per_s % 1_000
74     );
75 }
76 
decode(dst: &mut [u8], src: &[u8])77 fn decode(dst: &mut [u8], src: &[u8]) {
78     // Set up the hard-coded sanity check, executed below.
79     dst[0] = 0xFE;
80     dst[NUM_BYTES - 1] = 0xFE;
81 
82     let mut reader = gif::Decoder::new(src).read_info().unwrap();
83     reader.next_frame_info().unwrap().unwrap();
84 
85     if reader.buffer_size() != NUM_BYTES {
86         panic!("wrong num_bytes")
87     }
88 
89     reader.read_into_buffer(dst).unwrap();
90 
91     // A hard-coded sanity check that we decoded the pixel data correctly.
92     if (dst[0] != FIRST_PIXEL) || (dst[NUM_BYTES - 1] != LAST_PIXEL) {
93         panic!("wrong dst pixels")
94     }
95 }
96