Skip to content

Commit

Permalink
Use cargo features to conditionally compile codecs.
Browse files Browse the repository at this point in the history
The default continues to have all codecs activated, but a user can
opt-in to only supporting specific ones, via features, e.g. depending on
`image`, while only supporting JPEG and GIF:

    [dependencies.image]
    version = "0.2"
    default-features = false
    features = ["jpeg", "gif"]

On my computer `cargo build` takes ~95s, while `cargo build --features
jpeg --no-default-features` (only JPEG) takes ~28s.

This patch also updates the travis file to also compile the library with
each feature, to ensure they continue to compile. These codec features
are all independent, so testing each one individually is sufficient.

Closes image-rs#311.
  • Loading branch information
huonw committed Mar 16, 2015
1 parent f11e2f1 commit 32dc84e
Show file tree
Hide file tree
Showing 6 changed files with 57 additions and 4 deletions.
20 changes: 17 additions & 3 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,24 @@ os:
env:
global:
- secure: M2MCRtyP5P/Xf2TSqrbz8cs41TQY04mK/5Fi6qgr77OKLNZlDclKiFY8BmQ6f1JhVccoE5gMIFpfPoVUu8wZ0Pe7/X4IyO4vxWawVQfE6f0NYErD9yqiE1KEi/RGKPOQfL5HFUK7ifnXvLwsAMh1ix9XMgaBZfZLQ8KhkxNRXwI=
matrix:
- FEATURES=''
- FEATURES='gif'
- FEATURES='jpeg'
- FEATURES='png'
- FEATURES='ppm'
- FEATURES='tga'
- FEATURES='tiff'
- FEATURES='webp'
script:
- cargo build -v
- cargo test -v
- cargo doc -v
- if [ -z "$FEATURES" ]; then
cargo build -v
cargo test -v
cargo doc -v
else
cargo build --no-default-features --features "$FEATURES"
cargo test --no-default-features --features "$FEATURES"
fi
after_success: |
[ $TRAVIS_BRANCH = master ] &&
[ $TRAVIS_PULL_REQUEST = false ] &&
Expand Down
11 changes: 11 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -26,3 +26,14 @@ version = "0.1.15"

[dev-dependencies.glob]
version = "0.2.3"

[features]
default = ["gif", "jpeg", "png", "ppm", "tga", "tiff", "webp"]

gif = []
jpeg = []
png = []
ppm = []
tga = []
tiff = []
webp = []
21 changes: 20 additions & 1 deletion src/dynimage.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,19 @@ use std::old_io;
use std::iter;
use std::ascii::OwnedAsciiExt;

#[cfg(feature = "ppm")]
use ppm;
#[cfg(feature = "gif")]
use gif;
#[cfg(feature = "webp")]
use webp;
#[cfg(feature = "jpeg")]
use jpeg;
#[cfg(feature = "png")]
use png;
#[cfg(feature = "tiff")]
use tiff;
#[cfg(feature = "tga")]
use tga;

use color;
Expand Down Expand Up @@ -336,27 +343,30 @@ impl DynamicImage {
let color = self.color();

let r = match format {
#[cfg(feature = "png")]
image::ImageFormat::PNG => {
let mut p = png::PNGEncoder::new(w);

try!(p.encode(&bytes, width, height, color));
Ok(())
}

#[cfg(feature = "ppm")]
image::ImageFormat::PPM => {
let mut p = ppm::PPMEncoder::new(w);

try!(p.encode(&bytes, width, height, color));
Ok(())
}

#[cfg(feature = "jpeg")]
image::ImageFormat::JPEG => {
let mut j = jpeg::JPEGEncoder::new(w);

try!(j.encode(&bytes, width, height, color));
Ok(())
}

#[cfg(feature = "gif")]
image::ImageFormat::GIF => {
let mut g = gif::GIFEncoder::new(
self.to_rgba(), None, gif::ColorMode::Indexed(0xFF)
Expand Down Expand Up @@ -536,9 +546,12 @@ pub fn save_buffer(path: &Path, buf: &[u8], width: u32, height: u32, color: colo
.map_or("".to_string(), | s | s.to_string().into_ascii_lowercase());

match &*ext {
#[cfg(feature = "jpeg")]
"jpg" |
"jpeg" => jpeg::JPEGEncoder::new(fout).encode(buf, width, height, color),
#[cfg(feature = "png")]
"png" => png::PNGEncoder::new(fout).encode(buf, width, height, color),
#[cfg(feature = "ppm")]
"ppm" => ppm::PPMEncoder::new(fout).encode(buf, width, height, color),
format => Err(old_io::IoError {
kind: old_io::InvalidInput,
Expand All @@ -554,11 +567,17 @@ pub fn save_buffer(path: &Path, buf: &[u8], width: u32, height: u32, color: colo
/// Create a new image from a Reader
pub fn load<R: Reader+Seek>(r: R, format: ImageFormat) -> ImageResult<DynamicImage> {
match format {
#[cfg(feature = "png")]
image::ImageFormat::PNG => decoder_to_image(png::PNGDecoder::new(old_io::BufferedReader::new(r))),
#[cfg(feature = "gif")]
image::ImageFormat::GIF => decoder_to_image(gif::GIFDecoder::new(old_io::BufferedReader::new(r))),
#[cfg(feature = "jpeg")]
image::ImageFormat::JPEG => decoder_to_image(jpeg::JPEGDecoder::new(old_io::BufferedReader::new(r))),
#[cfg(feature = "webp")]
image::ImageFormat::WEBP => decoder_to_image(webp::WebpDecoder::new(old_io::BufferedReader::new(r))),
#[cfg(feature = "tiff")]
image::ImageFormat::TIFF => decoder_to_image(try!(tiff::TIFFDecoder::new(r))),
#[cfg(feature = "tga")]
image::ImageFormat::TGA => decoder_to_image(tga::TGADecoder::new(r)),
_ => Err(image::ImageError::UnsupportedError(format!("A decoder for {:?} is not available.", format))),
}
Expand Down
1 change: 1 addition & 0 deletions src/imageops/sample.rs
Original file line number Diff line number Diff line change
Expand Up @@ -475,6 +475,7 @@ mod tests {
use super::{resize, FilterType};

#[bench]
#[cfg(feature = "png")]
fn bench_resize(b: &mut test::Bencher) {
let img = ::open(&Path::new("./examples/fractal.png")).unwrap();
b.iter(|| {
Expand Down
7 changes: 7 additions & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -109,12 +109,19 @@ pub mod math;
pub mod imageops;

// Image Codecs
#[cfg(feature = "webp")]
pub mod webp;
#[cfg(feature = "ppm")]
pub mod ppm;
#[cfg(feature = "png")]
pub mod png;
#[cfg(feature = "jpeg")]
pub mod jpeg;
#[cfg(feature = "gif")]
pub mod gif;
#[cfg(feature = "tiff")]
pub mod tiff;
#[cfg(feature = "tga")]
pub mod tga;


Expand Down
1 change: 1 addition & 0 deletions tests/tga.rs
100644 → 100755
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
#![feature(old_io, old_path)]
#![cfg(feature = "tga")]

extern crate image;

Expand Down

0 comments on commit 32dc84e

Please sign in to comment.