summaryrefslogtreecommitdiff
path: root/README.md
blob: 15c33602c936976b7a6886257723317557811d44 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
## tiny-png

Tiny Rust PNG decoder.

This decoder can be used without `std` or `alloc` by disabling the `std` feature (enabled by default).

Also it has tiny code size (e.g. 5x smaller `.wasm.gz` size compared to the `png` crate — see `check-size.sh`).

## Goals

- Correctly decode all valid non-interlaced PNG files which can fit in memory.
- Small code size
- No dependencies other than `core`.
- No panics.
- Minimal if any unsafe code

## Non-goals

- Adam7 interlacing (interlaced PNGs are rare, and this would require additional code complexity
  — but if you want to add it behind a feature gate, feel free to)
- Significantly sacrificing code size for speed (except maybe with a feature enabled)
- Checking block CRCs (increases code complexity
  and there’s already Adler32 checksums for IDAT chunks)

## Example usage

Basic usage:

```rust
let mut buffer = vec![0; 1 << 20]; // hope this is big enough!
let mut png = &include_bytes!("../examples/image.png")[..];
let image = tiny_png::read_png(&mut png, None, &mut buffer).expect("bad PNG");
assert!(png.is_empty(), "extra data after PNG image end");
println!("{}×{} image", image.width(), image.height());
let pixels = image.pixels();
println!("top-left pixel is #{:02x}{:02x}{:02x}", pixels[0], pixels[1], pixels[2]);
// (^ this only makes sense for RGB 8bpc images)
```

Allocate the right number of bytes:

```rust
let mut png = &include_bytes!("../examples/image.png")[..];
let header = tiny_png::read_png_header(&mut png).expect("bad PNG");
let mut buffer = vec![0; header.required_bytes()];
let image = tiny_png::read_png(&mut png, Some(&header), &mut buffer).expect("bad PNG");
assert!(png.is_empty(), "extra data after PNG image end");
println!("{}×{} image", image.width(), image.height());
let pixels = image.pixels();
println!("top-left pixel is #{:02x}{:02x}{:02x}", pixels[0], pixels[1], pixels[2]);
// (^ this only makes sense for RGB 8bpc images)
```

## Features

- `std` (default: enabled) — use standard library. enabling it allows you to read from `BufReader<File>` but
   adds `std` as a dependency.
- `adler` (default: disabled) — check Adler-32 checksums. slightly increases code size and
  slightly decreases performance but verifies integrity of PNG files.

## Development

A `pre-commit` git hook is provided to run `cargo fmt` and `cargo clippy`. You can install it with:

```sh
ln -s ../../pre-commit .git/hooks/
```

## License

```text
Zero-Clause BSD
=============

Permission to use, copy, modify, and/or distribute this software for
any purpose with or without fee is hereby granted.

THE SOFTWARE IS PROVIDED “AS IS” AND THE AUTHOR DISCLAIMS ALL
WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE
FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY
DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
```

Note: all the test PNG images are either in the U.S. public domain or are CC0-licensed.