Split RowFilter and FilterStrategy
This commit is contained in:
parent
ff9beb00fe
commit
682b5d9ad0
16 changed files with 297 additions and 203 deletions
|
|
@ -13,7 +13,10 @@ fn filters_16_bits_filter_0(b: &mut Bencher) {
|
||||||
let input = test::black_box(PathBuf::from("tests/files/rgb_16_should_be_rgb_16.png"));
|
let input = test::black_box(PathBuf::from("tests/files/rgb_16_should_be_rgb_16.png"));
|
||||||
let png = PngData::new(&input, &Options::default()).unwrap();
|
let png = PngData::new(&input, &Options::default()).unwrap();
|
||||||
|
|
||||||
b.iter(|| png.raw.filter_image(RowFilter::None, false));
|
b.iter(|| {
|
||||||
|
png.raw
|
||||||
|
.filter_image(FilterStrategy::Basic(RowFilter::None), false)
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
#[bench]
|
#[bench]
|
||||||
|
|
@ -21,7 +24,10 @@ fn filters_8_bits_filter_0(b: &mut Bencher) {
|
||||||
let input = test::black_box(PathBuf::from("tests/files/rgb_8_should_be_rgb_8.png"));
|
let input = test::black_box(PathBuf::from("tests/files/rgb_8_should_be_rgb_8.png"));
|
||||||
let png = PngData::new(&input, &Options::default()).unwrap();
|
let png = PngData::new(&input, &Options::default()).unwrap();
|
||||||
|
|
||||||
b.iter(|| png.raw.filter_image(RowFilter::None, false));
|
b.iter(|| {
|
||||||
|
png.raw
|
||||||
|
.filter_image(FilterStrategy::Basic(RowFilter::None), false)
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
#[bench]
|
#[bench]
|
||||||
|
|
@ -31,7 +37,10 @@ fn filters_4_bits_filter_0(b: &mut Bencher) {
|
||||||
));
|
));
|
||||||
let png = PngData::new(&input, &Options::default()).unwrap();
|
let png = PngData::new(&input, &Options::default()).unwrap();
|
||||||
|
|
||||||
b.iter(|| png.raw.filter_image(RowFilter::None, false));
|
b.iter(|| {
|
||||||
|
png.raw
|
||||||
|
.filter_image(FilterStrategy::Basic(RowFilter::None), false)
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
#[bench]
|
#[bench]
|
||||||
|
|
@ -41,7 +50,10 @@ fn filters_2_bits_filter_0(b: &mut Bencher) {
|
||||||
));
|
));
|
||||||
let png = PngData::new(&input, &Options::default()).unwrap();
|
let png = PngData::new(&input, &Options::default()).unwrap();
|
||||||
|
|
||||||
b.iter(|| png.raw.filter_image(RowFilter::None, false));
|
b.iter(|| {
|
||||||
|
png.raw
|
||||||
|
.filter_image(FilterStrategy::Basic(RowFilter::None), false)
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
#[bench]
|
#[bench]
|
||||||
|
|
@ -51,7 +63,10 @@ fn filters_1_bits_filter_0(b: &mut Bencher) {
|
||||||
));
|
));
|
||||||
let png = PngData::new(&input, &Options::default()).unwrap();
|
let png = PngData::new(&input, &Options::default()).unwrap();
|
||||||
|
|
||||||
b.iter(|| png.raw.filter_image(RowFilter::None, false));
|
b.iter(|| {
|
||||||
|
png.raw
|
||||||
|
.filter_image(FilterStrategy::Basic(RowFilter::None), false)
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
#[bench]
|
#[bench]
|
||||||
|
|
@ -59,7 +74,10 @@ fn filters_16_bits_filter_1(b: &mut Bencher) {
|
||||||
let input = test::black_box(PathBuf::from("tests/files/rgb_16_should_be_rgb_16.png"));
|
let input = test::black_box(PathBuf::from("tests/files/rgb_16_should_be_rgb_16.png"));
|
||||||
let png = PngData::new(&input, &Options::default()).unwrap();
|
let png = PngData::new(&input, &Options::default()).unwrap();
|
||||||
|
|
||||||
b.iter(|| png.raw.filter_image(RowFilter::Sub, false));
|
b.iter(|| {
|
||||||
|
png.raw
|
||||||
|
.filter_image(FilterStrategy::Basic(RowFilter::Sub), false)
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
#[bench]
|
#[bench]
|
||||||
|
|
@ -67,7 +85,10 @@ fn filters_8_bits_filter_1(b: &mut Bencher) {
|
||||||
let input = test::black_box(PathBuf::from("tests/files/rgb_8_should_be_rgb_8.png"));
|
let input = test::black_box(PathBuf::from("tests/files/rgb_8_should_be_rgb_8.png"));
|
||||||
let png = PngData::new(&input, &Options::default()).unwrap();
|
let png = PngData::new(&input, &Options::default()).unwrap();
|
||||||
|
|
||||||
b.iter(|| png.raw.filter_image(RowFilter::Sub, false));
|
b.iter(|| {
|
||||||
|
png.raw
|
||||||
|
.filter_image(FilterStrategy::Basic(RowFilter::Sub), false)
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
#[bench]
|
#[bench]
|
||||||
|
|
@ -77,7 +98,10 @@ fn filters_4_bits_filter_1(b: &mut Bencher) {
|
||||||
));
|
));
|
||||||
let png = PngData::new(&input, &Options::default()).unwrap();
|
let png = PngData::new(&input, &Options::default()).unwrap();
|
||||||
|
|
||||||
b.iter(|| png.raw.filter_image(RowFilter::Sub, false));
|
b.iter(|| {
|
||||||
|
png.raw
|
||||||
|
.filter_image(FilterStrategy::Basic(RowFilter::Sub), false)
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
#[bench]
|
#[bench]
|
||||||
|
|
@ -87,7 +111,10 @@ fn filters_2_bits_filter_1(b: &mut Bencher) {
|
||||||
));
|
));
|
||||||
let png = PngData::new(&input, &Options::default()).unwrap();
|
let png = PngData::new(&input, &Options::default()).unwrap();
|
||||||
|
|
||||||
b.iter(|| png.raw.filter_image(RowFilter::Sub, false));
|
b.iter(|| {
|
||||||
|
png.raw
|
||||||
|
.filter_image(FilterStrategy::Basic(RowFilter::Sub), false)
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
#[bench]
|
#[bench]
|
||||||
|
|
@ -97,7 +124,10 @@ fn filters_1_bits_filter_1(b: &mut Bencher) {
|
||||||
));
|
));
|
||||||
let png = PngData::new(&input, &Options::default()).unwrap();
|
let png = PngData::new(&input, &Options::default()).unwrap();
|
||||||
|
|
||||||
b.iter(|| png.raw.filter_image(RowFilter::Sub, false));
|
b.iter(|| {
|
||||||
|
png.raw
|
||||||
|
.filter_image(FilterStrategy::Basic(RowFilter::Sub), false)
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
#[bench]
|
#[bench]
|
||||||
|
|
@ -105,7 +135,10 @@ fn filters_16_bits_filter_2(b: &mut Bencher) {
|
||||||
let input = test::black_box(PathBuf::from("tests/files/rgb_16_should_be_rgb_16.png"));
|
let input = test::black_box(PathBuf::from("tests/files/rgb_16_should_be_rgb_16.png"));
|
||||||
let png = PngData::new(&input, &Options::default()).unwrap();
|
let png = PngData::new(&input, &Options::default()).unwrap();
|
||||||
|
|
||||||
b.iter(|| png.raw.filter_image(RowFilter::Up, false));
|
b.iter(|| {
|
||||||
|
png.raw
|
||||||
|
.filter_image(FilterStrategy::Basic(RowFilter::Up), false)
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
#[bench]
|
#[bench]
|
||||||
|
|
@ -113,7 +146,10 @@ fn filters_8_bits_filter_2(b: &mut Bencher) {
|
||||||
let input = test::black_box(PathBuf::from("tests/files/rgb_8_should_be_rgb_8.png"));
|
let input = test::black_box(PathBuf::from("tests/files/rgb_8_should_be_rgb_8.png"));
|
||||||
let png = PngData::new(&input, &Options::default()).unwrap();
|
let png = PngData::new(&input, &Options::default()).unwrap();
|
||||||
|
|
||||||
b.iter(|| png.raw.filter_image(RowFilter::Up, false));
|
b.iter(|| {
|
||||||
|
png.raw
|
||||||
|
.filter_image(FilterStrategy::Basic(RowFilter::Up), false)
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
#[bench]
|
#[bench]
|
||||||
|
|
@ -123,7 +159,10 @@ fn filters_4_bits_filter_2(b: &mut Bencher) {
|
||||||
));
|
));
|
||||||
let png = PngData::new(&input, &Options::default()).unwrap();
|
let png = PngData::new(&input, &Options::default()).unwrap();
|
||||||
|
|
||||||
b.iter(|| png.raw.filter_image(RowFilter::Up, false));
|
b.iter(|| {
|
||||||
|
png.raw
|
||||||
|
.filter_image(FilterStrategy::Basic(RowFilter::Up), false)
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
#[bench]
|
#[bench]
|
||||||
|
|
@ -133,7 +172,10 @@ fn filters_2_bits_filter_2(b: &mut Bencher) {
|
||||||
));
|
));
|
||||||
let png = PngData::new(&input, &Options::default()).unwrap();
|
let png = PngData::new(&input, &Options::default()).unwrap();
|
||||||
|
|
||||||
b.iter(|| png.raw.filter_image(RowFilter::Up, false));
|
b.iter(|| {
|
||||||
|
png.raw
|
||||||
|
.filter_image(FilterStrategy::Basic(RowFilter::Up), false)
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
#[bench]
|
#[bench]
|
||||||
|
|
@ -143,7 +185,10 @@ fn filters_1_bits_filter_2(b: &mut Bencher) {
|
||||||
));
|
));
|
||||||
let png = PngData::new(&input, &Options::default()).unwrap();
|
let png = PngData::new(&input, &Options::default()).unwrap();
|
||||||
|
|
||||||
b.iter(|| png.raw.filter_image(RowFilter::Up, false));
|
b.iter(|| {
|
||||||
|
png.raw
|
||||||
|
.filter_image(FilterStrategy::Basic(RowFilter::Up), false)
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
#[bench]
|
#[bench]
|
||||||
|
|
@ -151,7 +196,10 @@ fn filters_16_bits_filter_3(b: &mut Bencher) {
|
||||||
let input = test::black_box(PathBuf::from("tests/files/rgb_16_should_be_rgb_16.png"));
|
let input = test::black_box(PathBuf::from("tests/files/rgb_16_should_be_rgb_16.png"));
|
||||||
let png = PngData::new(&input, &Options::default()).unwrap();
|
let png = PngData::new(&input, &Options::default()).unwrap();
|
||||||
|
|
||||||
b.iter(|| png.raw.filter_image(RowFilter::Average, false));
|
b.iter(|| {
|
||||||
|
png.raw
|
||||||
|
.filter_image(FilterStrategy::Basic(RowFilter::Average), false)
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
#[bench]
|
#[bench]
|
||||||
|
|
@ -159,7 +207,10 @@ fn filters_8_bits_filter_3(b: &mut Bencher) {
|
||||||
let input = test::black_box(PathBuf::from("tests/files/rgb_8_should_be_rgb_8.png"));
|
let input = test::black_box(PathBuf::from("tests/files/rgb_8_should_be_rgb_8.png"));
|
||||||
let png = PngData::new(&input, &Options::default()).unwrap();
|
let png = PngData::new(&input, &Options::default()).unwrap();
|
||||||
|
|
||||||
b.iter(|| png.raw.filter_image(RowFilter::Average, false));
|
b.iter(|| {
|
||||||
|
png.raw
|
||||||
|
.filter_image(FilterStrategy::Basic(RowFilter::Average), false)
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
#[bench]
|
#[bench]
|
||||||
|
|
@ -169,7 +220,10 @@ fn filters_4_bits_filter_3(b: &mut Bencher) {
|
||||||
));
|
));
|
||||||
let png = PngData::new(&input, &Options::default()).unwrap();
|
let png = PngData::new(&input, &Options::default()).unwrap();
|
||||||
|
|
||||||
b.iter(|| png.raw.filter_image(RowFilter::Average, false));
|
b.iter(|| {
|
||||||
|
png.raw
|
||||||
|
.filter_image(FilterStrategy::Basic(RowFilter::Average), false)
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
#[bench]
|
#[bench]
|
||||||
|
|
@ -179,7 +233,10 @@ fn filters_2_bits_filter_3(b: &mut Bencher) {
|
||||||
));
|
));
|
||||||
let png = PngData::new(&input, &Options::default()).unwrap();
|
let png = PngData::new(&input, &Options::default()).unwrap();
|
||||||
|
|
||||||
b.iter(|| png.raw.filter_image(RowFilter::Average, false));
|
b.iter(|| {
|
||||||
|
png.raw
|
||||||
|
.filter_image(FilterStrategy::Basic(RowFilter::Average), false)
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
#[bench]
|
#[bench]
|
||||||
|
|
@ -189,7 +246,10 @@ fn filters_1_bits_filter_3(b: &mut Bencher) {
|
||||||
));
|
));
|
||||||
let png = PngData::new(&input, &Options::default()).unwrap();
|
let png = PngData::new(&input, &Options::default()).unwrap();
|
||||||
|
|
||||||
b.iter(|| png.raw.filter_image(RowFilter::Average, false));
|
b.iter(|| {
|
||||||
|
png.raw
|
||||||
|
.filter_image(FilterStrategy::Basic(RowFilter::Average), false)
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
#[bench]
|
#[bench]
|
||||||
|
|
@ -197,7 +257,10 @@ fn filters_16_bits_filter_4(b: &mut Bencher) {
|
||||||
let input = test::black_box(PathBuf::from("tests/files/rgb_16_should_be_rgb_16.png"));
|
let input = test::black_box(PathBuf::from("tests/files/rgb_16_should_be_rgb_16.png"));
|
||||||
let png = PngData::new(&input, &Options::default()).unwrap();
|
let png = PngData::new(&input, &Options::default()).unwrap();
|
||||||
|
|
||||||
b.iter(|| png.raw.filter_image(RowFilter::Paeth, false));
|
b.iter(|| {
|
||||||
|
png.raw
|
||||||
|
.filter_image(FilterStrategy::Basic(RowFilter::Paeth), false)
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
#[bench]
|
#[bench]
|
||||||
|
|
@ -205,7 +268,10 @@ fn filters_8_bits_filter_4(b: &mut Bencher) {
|
||||||
let input = test::black_box(PathBuf::from("tests/files/rgb_8_should_be_rgb_8.png"));
|
let input = test::black_box(PathBuf::from("tests/files/rgb_8_should_be_rgb_8.png"));
|
||||||
let png = PngData::new(&input, &Options::default()).unwrap();
|
let png = PngData::new(&input, &Options::default()).unwrap();
|
||||||
|
|
||||||
b.iter(|| png.raw.filter_image(RowFilter::Paeth, false));
|
b.iter(|| {
|
||||||
|
png.raw
|
||||||
|
.filter_image(FilterStrategy::Basic(RowFilter::Paeth), false)
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
#[bench]
|
#[bench]
|
||||||
|
|
@ -215,7 +281,10 @@ fn filters_4_bits_filter_4(b: &mut Bencher) {
|
||||||
));
|
));
|
||||||
let png = PngData::new(&input, &Options::default()).unwrap();
|
let png = PngData::new(&input, &Options::default()).unwrap();
|
||||||
|
|
||||||
b.iter(|| png.raw.filter_image(RowFilter::Paeth, false));
|
b.iter(|| {
|
||||||
|
png.raw
|
||||||
|
.filter_image(FilterStrategy::Basic(RowFilter::Paeth), false)
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
#[bench]
|
#[bench]
|
||||||
|
|
@ -225,7 +294,10 @@ fn filters_2_bits_filter_4(b: &mut Bencher) {
|
||||||
));
|
));
|
||||||
let png = PngData::new(&input, &Options::default()).unwrap();
|
let png = PngData::new(&input, &Options::default()).unwrap();
|
||||||
|
|
||||||
b.iter(|| png.raw.filter_image(RowFilter::Paeth, false));
|
b.iter(|| {
|
||||||
|
png.raw
|
||||||
|
.filter_image(FilterStrategy::Basic(RowFilter::Paeth), false)
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
#[bench]
|
#[bench]
|
||||||
|
|
@ -235,7 +307,10 @@ fn filters_1_bits_filter_4(b: &mut Bencher) {
|
||||||
));
|
));
|
||||||
let png = PngData::new(&input, &Options::default()).unwrap();
|
let png = PngData::new(&input, &Options::default()).unwrap();
|
||||||
|
|
||||||
b.iter(|| png.raw.filter_image(RowFilter::Paeth, false));
|
b.iter(|| {
|
||||||
|
png.raw
|
||||||
|
.filter_image(FilterStrategy::Basic(RowFilter::Paeth), false)
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
#[bench]
|
#[bench]
|
||||||
|
|
@ -243,7 +318,7 @@ fn filters_16_bits_filter_5(b: &mut Bencher) {
|
||||||
let input = test::black_box(PathBuf::from("tests/files/rgb_16_should_be_rgb_16.png"));
|
let input = test::black_box(PathBuf::from("tests/files/rgb_16_should_be_rgb_16.png"));
|
||||||
let png = PngData::new(&input, &Options::default()).unwrap();
|
let png = PngData::new(&input, &Options::default()).unwrap();
|
||||||
|
|
||||||
b.iter(|| png.raw.filter_image(RowFilter::MinSum, false));
|
b.iter(|| png.raw.filter_image(FilterStrategy::MinSum, false));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[bench]
|
#[bench]
|
||||||
|
|
@ -251,7 +326,7 @@ fn filters_8_bits_filter_5(b: &mut Bencher) {
|
||||||
let input = test::black_box(PathBuf::from("tests/files/rgb_8_should_be_rgb_8.png"));
|
let input = test::black_box(PathBuf::from("tests/files/rgb_8_should_be_rgb_8.png"));
|
||||||
let png = PngData::new(&input, &Options::default()).unwrap();
|
let png = PngData::new(&input, &Options::default()).unwrap();
|
||||||
|
|
||||||
b.iter(|| png.raw.filter_image(RowFilter::MinSum, false));
|
b.iter(|| png.raw.filter_image(FilterStrategy::MinSum, false));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[bench]
|
#[bench]
|
||||||
|
|
@ -261,7 +336,7 @@ fn filters_4_bits_filter_5(b: &mut Bencher) {
|
||||||
));
|
));
|
||||||
let png = PngData::new(&input, &Options::default()).unwrap();
|
let png = PngData::new(&input, &Options::default()).unwrap();
|
||||||
|
|
||||||
b.iter(|| png.raw.filter_image(RowFilter::MinSum, false));
|
b.iter(|| png.raw.filter_image(FilterStrategy::MinSum, false));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[bench]
|
#[bench]
|
||||||
|
|
@ -271,7 +346,7 @@ fn filters_2_bits_filter_5(b: &mut Bencher) {
|
||||||
));
|
));
|
||||||
let png = PngData::new(&input, &Options::default()).unwrap();
|
let png = PngData::new(&input, &Options::default()).unwrap();
|
||||||
|
|
||||||
b.iter(|| png.raw.filter_image(RowFilter::MinSum, false));
|
b.iter(|| png.raw.filter_image(FilterStrategy::MinSum, false));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[bench]
|
#[bench]
|
||||||
|
|
@ -281,5 +356,5 @@ fn filters_1_bits_filter_5(b: &mut Bencher) {
|
||||||
));
|
));
|
||||||
let png = PngData::new(&input, &Options::default()).unwrap();
|
let png = PngData::new(&input, &Options::default()).unwrap();
|
||||||
|
|
||||||
b.iter(|| png.raw.filter_image(RowFilter::MinSum, false));
|
b.iter(|| png.raw.filter_image(FilterStrategy::MinSum, false));
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -13,7 +13,7 @@ fn filters_minsum(b: &mut Bencher) {
|
||||||
let input = test::black_box(PathBuf::from("tests/files/rgb_8_should_be_rgb_8.png"));
|
let input = test::black_box(PathBuf::from("tests/files/rgb_8_should_be_rgb_8.png"));
|
||||||
let png = PngData::new(&input, &Options::default()).unwrap();
|
let png = PngData::new(&input, &Options::default()).unwrap();
|
||||||
|
|
||||||
b.iter(|| png.raw.filter_image(RowFilter::MinSum, false));
|
b.iter(|| png.raw.filter_image(FilterStrategy::MinSum, false));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[bench]
|
#[bench]
|
||||||
|
|
@ -21,7 +21,7 @@ fn filters_entropy(b: &mut Bencher) {
|
||||||
let input = test::black_box(PathBuf::from("tests/files/rgb_8_should_be_rgb_8.png"));
|
let input = test::black_box(PathBuf::from("tests/files/rgb_8_should_be_rgb_8.png"));
|
||||||
let png = PngData::new(&input, &Options::default()).unwrap();
|
let png = PngData::new(&input, &Options::default()).unwrap();
|
||||||
|
|
||||||
b.iter(|| png.raw.filter_image(RowFilter::Entropy, false));
|
b.iter(|| png.raw.filter_image(FilterStrategy::Entropy, false));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[bench]
|
#[bench]
|
||||||
|
|
@ -29,7 +29,7 @@ fn filters_bigrams(b: &mut Bencher) {
|
||||||
let input = test::black_box(PathBuf::from("tests/files/rgb_8_should_be_rgb_8.png"));
|
let input = test::black_box(PathBuf::from("tests/files/rgb_8_should_be_rgb_8.png"));
|
||||||
let png = PngData::new(&input, &Options::default()).unwrap();
|
let png = PngData::new(&input, &Options::default()).unwrap();
|
||||||
|
|
||||||
b.iter(|| png.raw.filter_image(RowFilter::Bigrams, false));
|
b.iter(|| png.raw.filter_image(FilterStrategy::Bigrams, false));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[bench]
|
#[bench]
|
||||||
|
|
@ -37,7 +37,7 @@ fn filters_bigent(b: &mut Bencher) {
|
||||||
let input = test::black_box(PathBuf::from("tests/files/rgb_8_should_be_rgb_8.png"));
|
let input = test::black_box(PathBuf::from("tests/files/rgb_8_should_be_rgb_8.png"));
|
||||||
let png = PngData::new(&input, &Options::default()).unwrap();
|
let png = PngData::new(&input, &Options::default()).unwrap();
|
||||||
|
|
||||||
b.iter(|| png.raw.filter_image(RowFilter::BigEnt, false));
|
b.iter(|| png.raw.filter_image(FilterStrategy::BigEnt, false));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[bench]
|
#[bench]
|
||||||
|
|
@ -45,5 +45,5 @@ fn filters_brute(b: &mut Bencher) {
|
||||||
let input = test::black_box(PathBuf::from("tests/files/rgb_8_should_be_rgb_8.png"));
|
let input = test::black_box(PathBuf::from("tests/files/rgb_8_should_be_rgb_8.png"));
|
||||||
let png = PngData::new(&input, &Options::default()).unwrap();
|
let png = PngData::new(&input, &Options::default()).unwrap();
|
||||||
|
|
||||||
b.iter(|| png.raw.filter_image(RowFilter::Brute, false));
|
b.iter(|| png.raw.filter_image(FilterStrategy::Brute, false));
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -17,14 +17,16 @@ use rayon::prelude::*;
|
||||||
|
|
||||||
#[cfg(not(feature = "parallel"))]
|
#[cfg(not(feature = "parallel"))]
|
||||||
use crate::rayon;
|
use crate::rayon;
|
||||||
use crate::{Deadline, PngError, atomicmin::AtomicMin, deflate, filters::RowFilter, png::PngImage};
|
use crate::{
|
||||||
|
Deadline, PngError, atomicmin::AtomicMin, deflate, filters::FilterStrategy, png::PngImage,
|
||||||
|
};
|
||||||
|
|
||||||
pub(crate) struct Candidate {
|
pub(crate) struct Candidate {
|
||||||
pub image: Arc<PngImage>,
|
pub image: Arc<PngImage>,
|
||||||
pub data: Vec<u8>,
|
pub data: Vec<u8>,
|
||||||
pub data_is_compressed: bool,
|
pub data_is_compressed: bool,
|
||||||
pub estimated_output_size: usize,
|
pub estimated_output_size: usize,
|
||||||
pub filter: RowFilter,
|
pub filter: FilterStrategy,
|
||||||
// For determining tie-breaker
|
// For determining tie-breaker
|
||||||
nth: usize,
|
nth: usize,
|
||||||
}
|
}
|
||||||
|
|
@ -44,7 +46,7 @@ impl Candidate {
|
||||||
/// Collect image versions and pick one that compresses best
|
/// Collect image versions and pick one that compresses best
|
||||||
pub(crate) struct Evaluator {
|
pub(crate) struct Evaluator {
|
||||||
deadline: Arc<Deadline>,
|
deadline: Arc<Deadline>,
|
||||||
filters: IndexSet<RowFilter>,
|
filters: IndexSet<FilterStrategy>,
|
||||||
deflater: Deflaters,
|
deflater: Deflaters,
|
||||||
optimize_alpha: bool,
|
optimize_alpha: bool,
|
||||||
final_round: bool,
|
final_round: bool,
|
||||||
|
|
@ -62,7 +64,7 @@ pub(crate) struct Evaluator {
|
||||||
impl Evaluator {
|
impl Evaluator {
|
||||||
pub fn new(
|
pub fn new(
|
||||||
deadline: Arc<Deadline>,
|
deadline: Arc<Deadline>,
|
||||||
filters: IndexSet<RowFilter>,
|
filters: IndexSet<FilterStrategy>,
|
||||||
deflater: Deflaters,
|
deflater: Deflaters,
|
||||||
optimize_alpha: bool,
|
optimize_alpha: bool,
|
||||||
final_round: bool,
|
final_round: bool,
|
||||||
|
|
|
||||||
|
|
@ -1,30 +1,67 @@
|
||||||
use std::{fmt, fmt::Display, mem::transmute};
|
use std::{fmt, fmt::Display, mem::transmute};
|
||||||
|
|
||||||
use crate::error::PngError;
|
|
||||||
|
|
||||||
/// Filtering strategy for use in [`Options`][crate::Options]
|
/// Filtering strategy for use in [`Options`][crate::Options]
|
||||||
|
#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Clone, Copy, Hash)]
|
||||||
|
pub enum FilterStrategy {
|
||||||
|
/// Same filter for all rows
|
||||||
|
Basic(RowFilter),
|
||||||
|
/// Minimum sum of absolute differences
|
||||||
|
MinSum,
|
||||||
|
/// Shannon entropy
|
||||||
|
Entropy,
|
||||||
|
/// Count of distinct bigrams
|
||||||
|
Bigrams,
|
||||||
|
/// Shannon entropy of bigrams
|
||||||
|
BigEnt,
|
||||||
|
/// Deflate compression
|
||||||
|
Brute,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Display for FilterStrategy {
|
||||||
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
|
match self {
|
||||||
|
Self::Basic(filter) => filter.fmt(f),
|
||||||
|
Self::MinSum => "MinSum".fmt(f),
|
||||||
|
Self::Entropy => "Entropy".fmt(f),
|
||||||
|
Self::Bigrams => "Bigrams".fmt(f),
|
||||||
|
Self::BigEnt => "BigEnt".fmt(f),
|
||||||
|
Self::Brute => "Brute".fmt(f),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl TryFrom<u8> for FilterStrategy {
|
||||||
|
type Error = ();
|
||||||
|
|
||||||
|
fn try_from(value: u8) -> Result<Self, Self::Error> {
|
||||||
|
match value {
|
||||||
|
0..=4 => Ok(Self::Basic(value.try_into()?)),
|
||||||
|
5 => Ok(Self::MinSum),
|
||||||
|
6 => Ok(Self::Entropy),
|
||||||
|
7 => Ok(Self::Bigrams),
|
||||||
|
8 => Ok(Self::BigEnt),
|
||||||
|
9 => Ok(Self::Brute),
|
||||||
|
_ => Err(()),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// PNG delta filters
|
||||||
#[repr(u8)]
|
#[repr(u8)]
|
||||||
#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Clone, Copy, Hash)]
|
#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Clone, Copy, Hash)]
|
||||||
pub enum RowFilter {
|
pub enum RowFilter {
|
||||||
// Standard filter types
|
|
||||||
None,
|
None,
|
||||||
Sub,
|
Sub,
|
||||||
Up,
|
Up,
|
||||||
Average,
|
Average,
|
||||||
Paeth,
|
Paeth,
|
||||||
// Heuristic strategies
|
|
||||||
MinSum,
|
|
||||||
Entropy,
|
|
||||||
Bigrams,
|
|
||||||
BigEnt,
|
|
||||||
Brute,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl TryFrom<u8> for RowFilter {
|
impl TryFrom<u8> for RowFilter {
|
||||||
type Error = ();
|
type Error = ();
|
||||||
|
|
||||||
fn try_from(value: u8) -> Result<Self, Self::Error> {
|
fn try_from(value: u8) -> Result<Self, Self::Error> {
|
||||||
if value > Self::LAST {
|
if value > 4 {
|
||||||
return Err(());
|
return Err(());
|
||||||
}
|
}
|
||||||
unsafe { transmute(value as i8) }
|
unsafe { transmute(value as i8) }
|
||||||
|
|
@ -40,11 +77,6 @@ impl Display for RowFilter {
|
||||||
Self::Up => "Up",
|
Self::Up => "Up",
|
||||||
Self::Average => "Average",
|
Self::Average => "Average",
|
||||||
Self::Paeth => "Paeth",
|
Self::Paeth => "Paeth",
|
||||||
Self::MinSum => "MinSum",
|
|
||||||
Self::Entropy => "Entropy",
|
|
||||||
Self::Bigrams => "Bigrams",
|
|
||||||
Self::BigEnt => "BigEnt",
|
|
||||||
Self::Brute => "Brute",
|
|
||||||
},
|
},
|
||||||
f,
|
f,
|
||||||
)
|
)
|
||||||
|
|
@ -52,9 +84,7 @@ impl Display for RowFilter {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl RowFilter {
|
impl RowFilter {
|
||||||
pub const LAST: u8 = Self::Brute as u8;
|
pub(crate) const ALL: [Self; 5] = [Self::None, Self::Sub, Self::Up, Self::Average, Self::Paeth];
|
||||||
pub(crate) const STANDARD: [Self; 5] =
|
|
||||||
[Self::None, Self::Sub, Self::Up, Self::Average, Self::Paeth];
|
|
||||||
pub(crate) const SINGLE_LINE: [Self; 2] = [Self::None, Self::Sub];
|
pub(crate) const SINGLE_LINE: [Self; 2] = [Self::None, Self::Sub];
|
||||||
|
|
||||||
pub(crate) fn filter_line(
|
pub(crate) fn filter_line(
|
||||||
|
|
@ -115,7 +145,6 @@ impl RowFilter {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_ => unreachable!(),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -140,6 +169,7 @@ impl RowFilter {
|
||||||
_ => i - 1,
|
_ => i - 1,
|
||||||
};
|
};
|
||||||
match self {
|
match self {
|
||||||
|
Self::None => unreachable!(),
|
||||||
Self::Sub => {
|
Self::Sub => {
|
||||||
for j in 0..color_bytes {
|
for j in 0..color_bytes {
|
||||||
pixels[i][j] = pixels[prev][j];
|
pixels[i][j] = pixels[prev][j];
|
||||||
|
|
@ -171,7 +201,6 @@ impl RowFilter {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_ => unreachable!(),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -183,7 +212,7 @@ impl RowFilter {
|
||||||
data: &[u8],
|
data: &[u8],
|
||||||
prev_line: &[u8],
|
prev_line: &[u8],
|
||||||
buf: &mut Vec<u8>,
|
buf: &mut Vec<u8>,
|
||||||
) -> Result<(), PngError> {
|
) {
|
||||||
buf.clear();
|
buf.clear();
|
||||||
buf.reserve(data.len());
|
buf.reserve(data.len());
|
||||||
assert!(data.len() >= bpp);
|
assert!(data.len() >= bpp);
|
||||||
|
|
@ -232,9 +261,7 @@ impl RowFilter {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_ => return Err(PngError::InvalidData),
|
|
||||||
}
|
}
|
||||||
Ok(())
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
12
src/lib.rs
12
src/lib.rs
|
|
@ -45,7 +45,7 @@ pub use crate::{
|
||||||
colors::{BitDepth, ColorType},
|
colors::{BitDepth, ColorType},
|
||||||
deflate::Deflaters,
|
deflate::Deflaters,
|
||||||
error::PngError,
|
error::PngError,
|
||||||
filters::RowFilter,
|
filters::{FilterStrategy, RowFilter},
|
||||||
headers::StripChunks,
|
headers::StripChunks,
|
||||||
interlace::Interlacing,
|
interlace::Interlacing,
|
||||||
options::{InFile, Options, OutFile},
|
options::{InFile, Options, OutFile},
|
||||||
|
|
@ -432,7 +432,7 @@ fn optimize_raw(
|
||||||
opts.filter.clone()
|
opts.filter.clone()
|
||||||
} else {
|
} else {
|
||||||
// None and Bigrams work well together, especially for alpha reductions
|
// None and Bigrams work well together, especially for alpha reductions
|
||||||
indexset! {RowFilter::None, RowFilter::Bigrams}
|
indexset! {FilterStrategy::Basic(RowFilter::None), FilterStrategy::Bigrams}
|
||||||
};
|
};
|
||||||
// This will collect all versions of images and pick one that compresses best
|
// This will collect all versions of images and pick one that compresses best
|
||||||
let eval = Evaluator::new(
|
let eval = Evaluator::new(
|
||||||
|
|
@ -489,7 +489,7 @@ fn perform_trials(
|
||||||
deadline: Arc<Deadline>,
|
deadline: Arc<Deadline>,
|
||||||
max_size: Option<usize>,
|
max_size: Option<usize>,
|
||||||
mut eval_result: Option<Candidate>,
|
mut eval_result: Option<Candidate>,
|
||||||
eval_filters: IndexSet<RowFilter>,
|
eval_filters: IndexSet<FilterStrategy>,
|
||||||
eval_deflater: Deflaters,
|
eval_deflater: Deflaters,
|
||||||
) -> Option<Candidate> {
|
) -> Option<Candidate> {
|
||||||
let mut filters = opts.filter.clone();
|
let mut filters = opts.filter.clone();
|
||||||
|
|
@ -548,10 +548,10 @@ fn perform_trials(
|
||||||
// Pick a filter automatically
|
// Pick a filter automatically
|
||||||
if image.ihdr.bit_depth as u8 >= 8 {
|
if image.ihdr.bit_depth as u8 >= 8 {
|
||||||
// Bigrams is the best all-rounder when there's at least one byte per pixel
|
// Bigrams is the best all-rounder when there's at least one byte per pixel
|
||||||
filters.insert(RowFilter::Bigrams);
|
filters.insert(FilterStrategy::Bigrams);
|
||||||
} else {
|
} else {
|
||||||
// Otherwise delta filters generally don't work well, so just stick with None
|
// Otherwise delta filters generally don't work well, so just stick with None
|
||||||
filters.insert(RowFilter::None);
|
filters.insert(FilterStrategy::Basic(RowFilter::None));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -627,7 +627,7 @@ fn recompress_frames(
|
||||||
png: &mut PngData,
|
png: &mut PngData,
|
||||||
opts: &Options,
|
opts: &Options,
|
||||||
deadline: Arc<Deadline>,
|
deadline: Arc<Deadline>,
|
||||||
filter: RowFilter,
|
filter: FilterStrategy,
|
||||||
) -> PngResult<()> {
|
) -> PngResult<()> {
|
||||||
if !opts.idat_recoding || png.frames.is_empty() {
|
if !opts.idat_recoding || png.frames.is_empty() {
|
||||||
return Ok(());
|
return Ok(());
|
||||||
|
|
|
||||||
|
|
@ -26,7 +26,7 @@ use clap::ArgMatches;
|
||||||
mod cli;
|
mod cli;
|
||||||
use indexmap::IndexSet;
|
use indexmap::IndexSet;
|
||||||
use log::{Level, LevelFilter, error, warn};
|
use log::{Level, LevelFilter, error, warn};
|
||||||
use oxipng::{Deflaters, InFile, Options, OutFile, PngError, RowFilter, StripChunks};
|
use oxipng::{Deflaters, InFile, Options, OutFile, PngError, StripChunks};
|
||||||
use rayon::prelude::*;
|
use rayon::prelude::*;
|
||||||
|
|
||||||
use crate::cli::DISPLAY_CHUNKS;
|
use crate::cli::DISPLAY_CHUNKS;
|
||||||
|
|
@ -36,8 +36,7 @@ fn main() -> ExitCode {
|
||||||
// Set the value parser for filters which isn't appropriate to do in the build_command function
|
// Set the value parser for filters which isn't appropriate to do in the build_command function
|
||||||
.mut_arg("filters", |arg| {
|
.mut_arg("filters", |arg| {
|
||||||
arg.value_parser(|x: &str| {
|
arg.value_parser(|x: &str| {
|
||||||
parse_numeric_range_opts(x, 0, RowFilter::LAST)
|
parse_numeric_range_opts(x, 0, 9).map_err(|_| "Invalid option for filters")
|
||||||
.map_err(|_| "Invalid option for filters")
|
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
.after_help("Run `oxipng --help` to see full details of all options")
|
.after_help("Run `oxipng --help` to see full details of all options")
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,12 @@ use std::{
|
||||||
use indexmap::{IndexSet, indexset};
|
use indexmap::{IndexSet, indexset};
|
||||||
use log::warn;
|
use log::warn;
|
||||||
|
|
||||||
use crate::{deflate::Deflaters, filters::RowFilter, headers::StripChunks, interlace::Interlacing};
|
use crate::{
|
||||||
|
deflate::Deflaters,
|
||||||
|
filters::{FilterStrategy, RowFilter},
|
||||||
|
headers::StripChunks,
|
||||||
|
interlace::Interlacing,
|
||||||
|
};
|
||||||
|
|
||||||
/// Write destination for [`optimize`][crate::optimize].
|
/// Write destination for [`optimize`][crate::optimize].
|
||||||
/// You can use [`optimize_from_memory`](crate::optimize_from_memory) to avoid external I/O.
|
/// You can use [`optimize_from_memory`](crate::optimize_from_memory) to avoid external I/O.
|
||||||
|
|
@ -94,10 +99,10 @@ pub struct Options {
|
||||||
///
|
///
|
||||||
/// Default: `false`
|
/// Default: `false`
|
||||||
pub force: bool,
|
pub force: bool,
|
||||||
/// Which `RowFilters` to try on the file
|
/// Which `FilterStrategy` to try on the file
|
||||||
///
|
///
|
||||||
/// Default: `None,Sub,Entropy,Bigrams`
|
/// Default: `None,Sub,Entropy,Bigrams`
|
||||||
pub filter: IndexSet<RowFilter>,
|
pub filter: IndexSet<FilterStrategy>,
|
||||||
/// Whether to change the interlacing type of the file.
|
/// Whether to change the interlacing type of the file.
|
||||||
///
|
///
|
||||||
/// These are the interlacing types avaliable:
|
/// These are the interlacing types avaliable:
|
||||||
|
|
@ -207,10 +212,10 @@ impl Options {
|
||||||
fn apply_preset_3(mut self) -> Self {
|
fn apply_preset_3(mut self) -> Self {
|
||||||
self.fast_evaluation = false;
|
self.fast_evaluation = false;
|
||||||
self.filter = indexset! {
|
self.filter = indexset! {
|
||||||
RowFilter::None,
|
FilterStrategy::Basic(RowFilter::None),
|
||||||
RowFilter::Bigrams,
|
FilterStrategy::Bigrams,
|
||||||
RowFilter::BigEnt,
|
FilterStrategy::BigEnt,
|
||||||
RowFilter::Brute
|
FilterStrategy::Brute
|
||||||
};
|
};
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
@ -224,10 +229,10 @@ impl Options {
|
||||||
|
|
||||||
fn apply_preset_5(mut self) -> Self {
|
fn apply_preset_5(mut self) -> Self {
|
||||||
self.fast_evaluation = false;
|
self.fast_evaluation = false;
|
||||||
self.filter.insert(RowFilter::Up);
|
self.filter.insert(FilterStrategy::Basic(RowFilter::Up));
|
||||||
self.filter.insert(RowFilter::MinSum);
|
self.filter.insert(FilterStrategy::MinSum);
|
||||||
self.filter.insert(RowFilter::BigEnt);
|
self.filter.insert(FilterStrategy::BigEnt);
|
||||||
self.filter.insert(RowFilter::Brute);
|
self.filter.insert(FilterStrategy::Brute);
|
||||||
if let Deflaters::Libdeflater { compression } = &mut self.deflate {
|
if let Deflaters::Libdeflater { compression } = &mut self.deflate {
|
||||||
*compression = 12;
|
*compression = 12;
|
||||||
}
|
}
|
||||||
|
|
@ -235,8 +240,9 @@ impl Options {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn apply_preset_6(mut self) -> Self {
|
fn apply_preset_6(mut self) -> Self {
|
||||||
self.filter.insert(RowFilter::Average);
|
self.filter
|
||||||
self.filter.insert(RowFilter::Paeth);
|
.insert(FilterStrategy::Basic(RowFilter::Average));
|
||||||
|
self.filter.insert(FilterStrategy::Basic(RowFilter::Paeth));
|
||||||
self.apply_preset_5()
|
self.apply_preset_5()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -247,7 +253,12 @@ impl Default for Options {
|
||||||
Self {
|
Self {
|
||||||
fix_errors: false,
|
fix_errors: false,
|
||||||
force: false,
|
force: false,
|
||||||
filter: indexset! {RowFilter::None, RowFilter::Sub, RowFilter::Entropy, RowFilter::Bigrams},
|
filter: indexset! {
|
||||||
|
FilterStrategy::Basic(RowFilter::None),
|
||||||
|
FilterStrategy::Basic(RowFilter::Sub),
|
||||||
|
FilterStrategy::Entropy,
|
||||||
|
FilterStrategy::Bigrams
|
||||||
|
},
|
||||||
interlace: Some(Interlacing::None),
|
interlace: Some(Interlacing::None),
|
||||||
optimize_alpha: false,
|
optimize_alpha: false,
|
||||||
bit_depth_reduction: true,
|
bit_depth_reduction: true,
|
||||||
|
|
|
||||||
|
|
@ -376,7 +376,7 @@ impl PngImage {
|
||||||
}
|
}
|
||||||
last_line.resize(line.data.len(), 0);
|
last_line.resize(line.data.len(), 0);
|
||||||
let filter = RowFilter::try_from(line.filter).map_err(|_| PngError::InvalidData)?;
|
let filter = RowFilter::try_from(line.filter).map_err(|_| PngError::InvalidData)?;
|
||||||
filter.unfilter_line(bpp, line.data, &last_line, &mut unfiltered_buf)?;
|
filter.unfilter_line(bpp, line.data, &last_line, &mut unfiltered_buf);
|
||||||
unfiltered.extend_from_slice(&unfiltered_buf);
|
unfiltered.extend_from_slice(&unfiltered_buf);
|
||||||
std::mem::swap(&mut last_line, &mut unfiltered_buf);
|
std::mem::swap(&mut last_line, &mut unfiltered_buf);
|
||||||
unfiltered_buf.clear();
|
unfiltered_buf.clear();
|
||||||
|
|
@ -386,7 +386,7 @@ impl PngImage {
|
||||||
|
|
||||||
/// Apply the specified filter type to all rows in the image
|
/// Apply the specified filter type to all rows in the image
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub fn filter_image(&self, filter: RowFilter, optimize_alpha: bool) -> Vec<u8> {
|
pub fn filter_image(&self, strategy: FilterStrategy, optimize_alpha: bool) -> Vec<u8> {
|
||||||
let mut filtered = Vec::with_capacity(self.data.len());
|
let mut filtered = Vec::with_capacity(self.data.len());
|
||||||
let bpp = self.bytes_per_channel() * self.channels_per_pixel();
|
let bpp = self.bytes_per_channel() * self.channels_per_pixel();
|
||||||
// If alpha optimization is enabled, determine how many bytes of alpha there are per pixel
|
// If alpha optimization is enabled, determine how many bytes of alpha there are per pixel
|
||||||
|
|
@ -406,7 +406,7 @@ impl PngImage {
|
||||||
// Alpha optimisation may alter the line data, so we need a mutable copy of it
|
// Alpha optimisation may alter the line data, so we need a mutable copy of it
|
||||||
let mut line_data = line.data.to_vec();
|
let mut line_data = line.data.to_vec();
|
||||||
|
|
||||||
if filter <= RowFilter::Paeth {
|
if let FilterStrategy::Basic(filter) = strategy {
|
||||||
// Standard filters
|
// Standard filters
|
||||||
let filter = if prev_pass == line.pass || filter <= RowFilter::Sub {
|
let filter = if prev_pass == line.pass || filter <= RowFilter::Sub {
|
||||||
filter
|
filter
|
||||||
|
|
@ -431,12 +431,12 @@ impl PngImage {
|
||||||
let mut best_line_raw = Vec::new();
|
let mut best_line_raw = Vec::new();
|
||||||
// Avoid vertical filtering on first line of each interlacing pass
|
// Avoid vertical filtering on first line of each interlacing pass
|
||||||
let try_filters = if prev_pass == line.pass {
|
let try_filters = if prev_pass == line.pass {
|
||||||
RowFilter::STANDARD.iter()
|
RowFilter::ALL.iter()
|
||||||
} else {
|
} else {
|
||||||
RowFilter::SINGLE_LINE.iter()
|
RowFilter::SINGLE_LINE.iter()
|
||||||
};
|
};
|
||||||
match filter {
|
match strategy {
|
||||||
RowFilter::MinSum => {
|
FilterStrategy::MinSum => {
|
||||||
// MSAD algorithm mentioned in libpng reference docs
|
// MSAD algorithm mentioned in libpng reference docs
|
||||||
// http://www.libpng.org/pub/png/book/chapter09.html
|
// http://www.libpng.org/pub/png/book/chapter09.html
|
||||||
let mut best_size = usize::MAX;
|
let mut best_size = usize::MAX;
|
||||||
|
|
@ -453,7 +453,7 @@ impl PngImage {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
RowFilter::Entropy => {
|
FilterStrategy::Entropy => {
|
||||||
// Shannon entropy algorithm, from LodePNG
|
// Shannon entropy algorithm, from LodePNG
|
||||||
// https://github.com/lvandeve/lodepng
|
// https://github.com/lvandeve/lodepng
|
||||||
let mut best_size = i32::MIN;
|
let mut best_size = i32::MIN;
|
||||||
|
|
@ -476,7 +476,7 @@ impl PngImage {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
RowFilter::Bigrams => {
|
FilterStrategy::Bigrams => {
|
||||||
// Count distinct bigrams, from pngwolf
|
// Count distinct bigrams, from pngwolf
|
||||||
// https://bjoern.hoehrmann.de/pngwolf/
|
// https://bjoern.hoehrmann.de/pngwolf/
|
||||||
let mut best_size = usize::MAX;
|
let mut best_size = usize::MAX;
|
||||||
|
|
@ -495,7 +495,7 @@ impl PngImage {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
RowFilter::BigEnt => {
|
FilterStrategy::BigEnt => {
|
||||||
// Bigram entropy, combined from Entropy and Bigrams filters
|
// Bigram entropy, combined from Entropy and Bigrams filters
|
||||||
let mut best_size = i32::MIN;
|
let mut best_size = i32::MIN;
|
||||||
// FxHasher is the fastest rust hasher currently available for this purpose
|
// FxHasher is the fastest rust hasher currently available for this purpose
|
||||||
|
|
@ -515,7 +515,7 @@ impl PngImage {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
RowFilter::Brute => {
|
FilterStrategy::Brute => {
|
||||||
// Brute force by compressing each filter attempt
|
// Brute force by compressing each filter attempt
|
||||||
// Similar to that of LodePNG but includes some previous lines for context
|
// Similar to that of LodePNG but includes some previous lines for context
|
||||||
let mut best_size = usize::MAX;
|
let mut best_size = usize::MAX;
|
||||||
|
|
|
||||||
141
tests/filters.rs
141
tests/filters.rs
|
|
@ -12,20 +12,17 @@ const GRAYSCALE_ALPHA: u8 = 4;
|
||||||
const RGBA: u8 = 6;
|
const RGBA: u8 = 6;
|
||||||
|
|
||||||
fn get_opts(input: &Path) -> (OutFile, oxipng::Options) {
|
fn get_opts(input: &Path) -> (OutFile, oxipng::Options) {
|
||||||
let mut options = oxipng::Options {
|
let options = oxipng::Options {
|
||||||
force: true,
|
force: true,
|
||||||
|
filter: indexset! {FilterStrategy::Basic(RowFilter::None)},
|
||||||
..Default::default()
|
..Default::default()
|
||||||
};
|
};
|
||||||
let mut filter = IndexSet::new();
|
|
||||||
filter.insert(RowFilter::None);
|
|
||||||
options.filter = filter;
|
|
||||||
|
|
||||||
(OutFile::from_path(input.with_extension("out.png")), options)
|
(OutFile::from_path(input.with_extension("out.png")), options)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn test_it_converts(
|
fn test_it_converts(
|
||||||
input: &str,
|
input: &str,
|
||||||
filter: RowFilter,
|
filter: FilterStrategy,
|
||||||
color_type_in: u8,
|
color_type_in: u8,
|
||||||
bit_depth_in: BitDepth,
|
bit_depth_in: BitDepth,
|
||||||
color_type_out: u8,
|
color_type_out: u8,
|
||||||
|
|
@ -68,7 +65,7 @@ fn test_it_converts(
|
||||||
fn filter_0_for_rgba_16() {
|
fn filter_0_for_rgba_16() {
|
||||||
test_it_converts(
|
test_it_converts(
|
||||||
"tests/files/filter_0_for_rgba_16.png",
|
"tests/files/filter_0_for_rgba_16.png",
|
||||||
RowFilter::None,
|
FilterStrategy::Basic(RowFilter::None),
|
||||||
RGBA,
|
RGBA,
|
||||||
BitDepth::Sixteen,
|
BitDepth::Sixteen,
|
||||||
RGBA,
|
RGBA,
|
||||||
|
|
@ -80,7 +77,7 @@ fn filter_0_for_rgba_16() {
|
||||||
fn filter_1_for_rgba_16() {
|
fn filter_1_for_rgba_16() {
|
||||||
test_it_converts(
|
test_it_converts(
|
||||||
"tests/files/filter_1_for_rgba_16.png",
|
"tests/files/filter_1_for_rgba_16.png",
|
||||||
RowFilter::Sub,
|
FilterStrategy::Basic(RowFilter::Sub),
|
||||||
RGBA,
|
RGBA,
|
||||||
BitDepth::Sixteen,
|
BitDepth::Sixteen,
|
||||||
RGBA,
|
RGBA,
|
||||||
|
|
@ -92,7 +89,7 @@ fn filter_1_for_rgba_16() {
|
||||||
fn filter_2_for_rgba_16() {
|
fn filter_2_for_rgba_16() {
|
||||||
test_it_converts(
|
test_it_converts(
|
||||||
"tests/files/filter_2_for_rgba_16.png",
|
"tests/files/filter_2_for_rgba_16.png",
|
||||||
RowFilter::Up,
|
FilterStrategy::Basic(RowFilter::Up),
|
||||||
RGBA,
|
RGBA,
|
||||||
BitDepth::Sixteen,
|
BitDepth::Sixteen,
|
||||||
RGBA,
|
RGBA,
|
||||||
|
|
@ -104,7 +101,7 @@ fn filter_2_for_rgba_16() {
|
||||||
fn filter_3_for_rgba_16() {
|
fn filter_3_for_rgba_16() {
|
||||||
test_it_converts(
|
test_it_converts(
|
||||||
"tests/files/filter_3_for_rgba_16.png",
|
"tests/files/filter_3_for_rgba_16.png",
|
||||||
RowFilter::Average,
|
FilterStrategy::Basic(RowFilter::Average),
|
||||||
RGBA,
|
RGBA,
|
||||||
BitDepth::Sixteen,
|
BitDepth::Sixteen,
|
||||||
RGBA,
|
RGBA,
|
||||||
|
|
@ -116,7 +113,7 @@ fn filter_3_for_rgba_16() {
|
||||||
fn filter_4_for_rgba_16() {
|
fn filter_4_for_rgba_16() {
|
||||||
test_it_converts(
|
test_it_converts(
|
||||||
"tests/files/filter_4_for_rgba_16.png",
|
"tests/files/filter_4_for_rgba_16.png",
|
||||||
RowFilter::Paeth,
|
FilterStrategy::Basic(RowFilter::Paeth),
|
||||||
RGBA,
|
RGBA,
|
||||||
BitDepth::Sixteen,
|
BitDepth::Sixteen,
|
||||||
RGBA,
|
RGBA,
|
||||||
|
|
@ -128,7 +125,7 @@ fn filter_4_for_rgba_16() {
|
||||||
fn filter_5_for_rgba_16() {
|
fn filter_5_for_rgba_16() {
|
||||||
test_it_converts(
|
test_it_converts(
|
||||||
"tests/files/filter_5_for_rgba_16.png",
|
"tests/files/filter_5_for_rgba_16.png",
|
||||||
RowFilter::MinSum,
|
FilterStrategy::MinSum,
|
||||||
RGBA,
|
RGBA,
|
||||||
BitDepth::Sixteen,
|
BitDepth::Sixteen,
|
||||||
RGBA,
|
RGBA,
|
||||||
|
|
@ -140,7 +137,7 @@ fn filter_5_for_rgba_16() {
|
||||||
fn filter_0_for_rgba_8() {
|
fn filter_0_for_rgba_8() {
|
||||||
test_it_converts(
|
test_it_converts(
|
||||||
"tests/files/filter_0_for_rgba_8.png",
|
"tests/files/filter_0_for_rgba_8.png",
|
||||||
RowFilter::None,
|
FilterStrategy::Basic(RowFilter::None),
|
||||||
RGBA,
|
RGBA,
|
||||||
BitDepth::Eight,
|
BitDepth::Eight,
|
||||||
RGBA,
|
RGBA,
|
||||||
|
|
@ -152,7 +149,7 @@ fn filter_0_for_rgba_8() {
|
||||||
fn filter_1_for_rgba_8() {
|
fn filter_1_for_rgba_8() {
|
||||||
test_it_converts(
|
test_it_converts(
|
||||||
"tests/files/filter_1_for_rgba_8.png",
|
"tests/files/filter_1_for_rgba_8.png",
|
||||||
RowFilter::Sub,
|
FilterStrategy::Basic(RowFilter::Sub),
|
||||||
RGBA,
|
RGBA,
|
||||||
BitDepth::Eight,
|
BitDepth::Eight,
|
||||||
RGBA,
|
RGBA,
|
||||||
|
|
@ -164,7 +161,7 @@ fn filter_1_for_rgba_8() {
|
||||||
fn filter_2_for_rgba_8() {
|
fn filter_2_for_rgba_8() {
|
||||||
test_it_converts(
|
test_it_converts(
|
||||||
"tests/files/filter_2_for_rgba_8.png",
|
"tests/files/filter_2_for_rgba_8.png",
|
||||||
RowFilter::Up,
|
FilterStrategy::Basic(RowFilter::Up),
|
||||||
RGBA,
|
RGBA,
|
||||||
BitDepth::Eight,
|
BitDepth::Eight,
|
||||||
RGBA,
|
RGBA,
|
||||||
|
|
@ -176,7 +173,7 @@ fn filter_2_for_rgba_8() {
|
||||||
fn filter_3_for_rgba_8() {
|
fn filter_3_for_rgba_8() {
|
||||||
test_it_converts(
|
test_it_converts(
|
||||||
"tests/files/filter_3_for_rgba_8.png",
|
"tests/files/filter_3_for_rgba_8.png",
|
||||||
RowFilter::Average,
|
FilterStrategy::Basic(RowFilter::Average),
|
||||||
RGBA,
|
RGBA,
|
||||||
BitDepth::Eight,
|
BitDepth::Eight,
|
||||||
RGBA,
|
RGBA,
|
||||||
|
|
@ -188,7 +185,7 @@ fn filter_3_for_rgba_8() {
|
||||||
fn filter_4_for_rgba_8() {
|
fn filter_4_for_rgba_8() {
|
||||||
test_it_converts(
|
test_it_converts(
|
||||||
"tests/files/filter_4_for_rgba_8.png",
|
"tests/files/filter_4_for_rgba_8.png",
|
||||||
RowFilter::Paeth,
|
FilterStrategy::Basic(RowFilter::Paeth),
|
||||||
RGBA,
|
RGBA,
|
||||||
BitDepth::Eight,
|
BitDepth::Eight,
|
||||||
RGBA,
|
RGBA,
|
||||||
|
|
@ -200,7 +197,7 @@ fn filter_4_for_rgba_8() {
|
||||||
fn filter_5_for_rgba_8() {
|
fn filter_5_for_rgba_8() {
|
||||||
test_it_converts(
|
test_it_converts(
|
||||||
"tests/files/filter_5_for_rgba_8.png",
|
"tests/files/filter_5_for_rgba_8.png",
|
||||||
RowFilter::MinSum,
|
FilterStrategy::MinSum,
|
||||||
RGBA,
|
RGBA,
|
||||||
BitDepth::Eight,
|
BitDepth::Eight,
|
||||||
RGBA,
|
RGBA,
|
||||||
|
|
@ -212,7 +209,7 @@ fn filter_5_for_rgba_8() {
|
||||||
fn filter_0_for_rgb_16() {
|
fn filter_0_for_rgb_16() {
|
||||||
test_it_converts(
|
test_it_converts(
|
||||||
"tests/files/filter_0_for_rgb_16.png",
|
"tests/files/filter_0_for_rgb_16.png",
|
||||||
RowFilter::None,
|
FilterStrategy::Basic(RowFilter::None),
|
||||||
RGB,
|
RGB,
|
||||||
BitDepth::Sixteen,
|
BitDepth::Sixteen,
|
||||||
RGB,
|
RGB,
|
||||||
|
|
@ -224,7 +221,7 @@ fn filter_0_for_rgb_16() {
|
||||||
fn filter_1_for_rgb_16() {
|
fn filter_1_for_rgb_16() {
|
||||||
test_it_converts(
|
test_it_converts(
|
||||||
"tests/files/filter_1_for_rgb_16.png",
|
"tests/files/filter_1_for_rgb_16.png",
|
||||||
RowFilter::Sub,
|
FilterStrategy::Basic(RowFilter::Sub),
|
||||||
RGB,
|
RGB,
|
||||||
BitDepth::Sixteen,
|
BitDepth::Sixteen,
|
||||||
RGB,
|
RGB,
|
||||||
|
|
@ -236,7 +233,7 @@ fn filter_1_for_rgb_16() {
|
||||||
fn filter_2_for_rgb_16() {
|
fn filter_2_for_rgb_16() {
|
||||||
test_it_converts(
|
test_it_converts(
|
||||||
"tests/files/filter_2_for_rgb_16.png",
|
"tests/files/filter_2_for_rgb_16.png",
|
||||||
RowFilter::Up,
|
FilterStrategy::Basic(RowFilter::Up),
|
||||||
RGB,
|
RGB,
|
||||||
BitDepth::Sixteen,
|
BitDepth::Sixteen,
|
||||||
RGB,
|
RGB,
|
||||||
|
|
@ -248,7 +245,7 @@ fn filter_2_for_rgb_16() {
|
||||||
fn filter_3_for_rgb_16() {
|
fn filter_3_for_rgb_16() {
|
||||||
test_it_converts(
|
test_it_converts(
|
||||||
"tests/files/filter_3_for_rgb_16.png",
|
"tests/files/filter_3_for_rgb_16.png",
|
||||||
RowFilter::Average,
|
FilterStrategy::Basic(RowFilter::Average),
|
||||||
RGB,
|
RGB,
|
||||||
BitDepth::Sixteen,
|
BitDepth::Sixteen,
|
||||||
RGB,
|
RGB,
|
||||||
|
|
@ -260,7 +257,7 @@ fn filter_3_for_rgb_16() {
|
||||||
fn filter_4_for_rgb_16() {
|
fn filter_4_for_rgb_16() {
|
||||||
test_it_converts(
|
test_it_converts(
|
||||||
"tests/files/filter_4_for_rgb_16.png",
|
"tests/files/filter_4_for_rgb_16.png",
|
||||||
RowFilter::Paeth,
|
FilterStrategy::Basic(RowFilter::Paeth),
|
||||||
RGB,
|
RGB,
|
||||||
BitDepth::Sixteen,
|
BitDepth::Sixteen,
|
||||||
RGB,
|
RGB,
|
||||||
|
|
@ -272,7 +269,7 @@ fn filter_4_for_rgb_16() {
|
||||||
fn filter_5_for_rgb_16() {
|
fn filter_5_for_rgb_16() {
|
||||||
test_it_converts(
|
test_it_converts(
|
||||||
"tests/files/filter_5_for_rgb_16.png",
|
"tests/files/filter_5_for_rgb_16.png",
|
||||||
RowFilter::MinSum,
|
FilterStrategy::MinSum,
|
||||||
RGB,
|
RGB,
|
||||||
BitDepth::Sixteen,
|
BitDepth::Sixteen,
|
||||||
RGB,
|
RGB,
|
||||||
|
|
@ -284,7 +281,7 @@ fn filter_5_for_rgb_16() {
|
||||||
fn filter_0_for_rgb_8() {
|
fn filter_0_for_rgb_8() {
|
||||||
test_it_converts(
|
test_it_converts(
|
||||||
"tests/files/filter_0_for_rgb_8.png",
|
"tests/files/filter_0_for_rgb_8.png",
|
||||||
RowFilter::None,
|
FilterStrategy::Basic(RowFilter::None),
|
||||||
RGB,
|
RGB,
|
||||||
BitDepth::Eight,
|
BitDepth::Eight,
|
||||||
RGB,
|
RGB,
|
||||||
|
|
@ -296,7 +293,7 @@ fn filter_0_for_rgb_8() {
|
||||||
fn filter_1_for_rgb_8() {
|
fn filter_1_for_rgb_8() {
|
||||||
test_it_converts(
|
test_it_converts(
|
||||||
"tests/files/filter_1_for_rgb_8.png",
|
"tests/files/filter_1_for_rgb_8.png",
|
||||||
RowFilter::Sub,
|
FilterStrategy::Basic(RowFilter::Sub),
|
||||||
RGB,
|
RGB,
|
||||||
BitDepth::Eight,
|
BitDepth::Eight,
|
||||||
RGB,
|
RGB,
|
||||||
|
|
@ -308,7 +305,7 @@ fn filter_1_for_rgb_8() {
|
||||||
fn filter_2_for_rgb_8() {
|
fn filter_2_for_rgb_8() {
|
||||||
test_it_converts(
|
test_it_converts(
|
||||||
"tests/files/filter_2_for_rgb_8.png",
|
"tests/files/filter_2_for_rgb_8.png",
|
||||||
RowFilter::Up,
|
FilterStrategy::Basic(RowFilter::Up),
|
||||||
RGB,
|
RGB,
|
||||||
BitDepth::Eight,
|
BitDepth::Eight,
|
||||||
RGB,
|
RGB,
|
||||||
|
|
@ -320,7 +317,7 @@ fn filter_2_for_rgb_8() {
|
||||||
fn filter_3_for_rgb_8() {
|
fn filter_3_for_rgb_8() {
|
||||||
test_it_converts(
|
test_it_converts(
|
||||||
"tests/files/filter_3_for_rgb_8.png",
|
"tests/files/filter_3_for_rgb_8.png",
|
||||||
RowFilter::Average,
|
FilterStrategy::Basic(RowFilter::Average),
|
||||||
RGB,
|
RGB,
|
||||||
BitDepth::Eight,
|
BitDepth::Eight,
|
||||||
RGB,
|
RGB,
|
||||||
|
|
@ -332,7 +329,7 @@ fn filter_3_for_rgb_8() {
|
||||||
fn filter_4_for_rgb_8() {
|
fn filter_4_for_rgb_8() {
|
||||||
test_it_converts(
|
test_it_converts(
|
||||||
"tests/files/filter_4_for_rgb_8.png",
|
"tests/files/filter_4_for_rgb_8.png",
|
||||||
RowFilter::Paeth,
|
FilterStrategy::Basic(RowFilter::Paeth),
|
||||||
RGB,
|
RGB,
|
||||||
BitDepth::Eight,
|
BitDepth::Eight,
|
||||||
RGB,
|
RGB,
|
||||||
|
|
@ -344,7 +341,7 @@ fn filter_4_for_rgb_8() {
|
||||||
fn filter_5_for_rgb_8() {
|
fn filter_5_for_rgb_8() {
|
||||||
test_it_converts(
|
test_it_converts(
|
||||||
"tests/files/filter_5_for_rgb_8.png",
|
"tests/files/filter_5_for_rgb_8.png",
|
||||||
RowFilter::MinSum,
|
FilterStrategy::MinSum,
|
||||||
RGB,
|
RGB,
|
||||||
BitDepth::Eight,
|
BitDepth::Eight,
|
||||||
RGB,
|
RGB,
|
||||||
|
|
@ -356,7 +353,7 @@ fn filter_5_for_rgb_8() {
|
||||||
fn filter_0_for_grayscale_alpha_16() {
|
fn filter_0_for_grayscale_alpha_16() {
|
||||||
test_it_converts(
|
test_it_converts(
|
||||||
"tests/files/filter_0_for_grayscale_alpha_16.png",
|
"tests/files/filter_0_for_grayscale_alpha_16.png",
|
||||||
RowFilter::None,
|
FilterStrategy::Basic(RowFilter::None),
|
||||||
GRAYSCALE_ALPHA,
|
GRAYSCALE_ALPHA,
|
||||||
BitDepth::Sixteen,
|
BitDepth::Sixteen,
|
||||||
GRAYSCALE_ALPHA,
|
GRAYSCALE_ALPHA,
|
||||||
|
|
@ -368,7 +365,7 @@ fn filter_0_for_grayscale_alpha_16() {
|
||||||
fn filter_1_for_grayscale_alpha_16() {
|
fn filter_1_for_grayscale_alpha_16() {
|
||||||
test_it_converts(
|
test_it_converts(
|
||||||
"tests/files/filter_1_for_grayscale_alpha_16.png",
|
"tests/files/filter_1_for_grayscale_alpha_16.png",
|
||||||
RowFilter::Sub,
|
FilterStrategy::Basic(RowFilter::Sub),
|
||||||
GRAYSCALE_ALPHA,
|
GRAYSCALE_ALPHA,
|
||||||
BitDepth::Sixteen,
|
BitDepth::Sixteen,
|
||||||
GRAYSCALE_ALPHA,
|
GRAYSCALE_ALPHA,
|
||||||
|
|
@ -380,7 +377,7 @@ fn filter_1_for_grayscale_alpha_16() {
|
||||||
fn filter_2_for_grayscale_alpha_16() {
|
fn filter_2_for_grayscale_alpha_16() {
|
||||||
test_it_converts(
|
test_it_converts(
|
||||||
"tests/files/filter_2_for_grayscale_alpha_16.png",
|
"tests/files/filter_2_for_grayscale_alpha_16.png",
|
||||||
RowFilter::Up,
|
FilterStrategy::Basic(RowFilter::Up),
|
||||||
GRAYSCALE_ALPHA,
|
GRAYSCALE_ALPHA,
|
||||||
BitDepth::Sixteen,
|
BitDepth::Sixteen,
|
||||||
GRAYSCALE_ALPHA,
|
GRAYSCALE_ALPHA,
|
||||||
|
|
@ -392,7 +389,7 @@ fn filter_2_for_grayscale_alpha_16() {
|
||||||
fn filter_3_for_grayscale_alpha_16() {
|
fn filter_3_for_grayscale_alpha_16() {
|
||||||
test_it_converts(
|
test_it_converts(
|
||||||
"tests/files/filter_3_for_grayscale_alpha_16.png",
|
"tests/files/filter_3_for_grayscale_alpha_16.png",
|
||||||
RowFilter::Average,
|
FilterStrategy::Basic(RowFilter::Average),
|
||||||
GRAYSCALE_ALPHA,
|
GRAYSCALE_ALPHA,
|
||||||
BitDepth::Sixteen,
|
BitDepth::Sixteen,
|
||||||
GRAYSCALE_ALPHA,
|
GRAYSCALE_ALPHA,
|
||||||
|
|
@ -404,7 +401,7 @@ fn filter_3_for_grayscale_alpha_16() {
|
||||||
fn filter_4_for_grayscale_alpha_16() {
|
fn filter_4_for_grayscale_alpha_16() {
|
||||||
test_it_converts(
|
test_it_converts(
|
||||||
"tests/files/filter_4_for_grayscale_alpha_16.png",
|
"tests/files/filter_4_for_grayscale_alpha_16.png",
|
||||||
RowFilter::Paeth,
|
FilterStrategy::Basic(RowFilter::Paeth),
|
||||||
GRAYSCALE_ALPHA,
|
GRAYSCALE_ALPHA,
|
||||||
BitDepth::Sixteen,
|
BitDepth::Sixteen,
|
||||||
GRAYSCALE_ALPHA,
|
GRAYSCALE_ALPHA,
|
||||||
|
|
@ -416,7 +413,7 @@ fn filter_4_for_grayscale_alpha_16() {
|
||||||
fn filter_5_for_grayscale_alpha_16() {
|
fn filter_5_for_grayscale_alpha_16() {
|
||||||
test_it_converts(
|
test_it_converts(
|
||||||
"tests/files/filter_5_for_grayscale_alpha_16.png",
|
"tests/files/filter_5_for_grayscale_alpha_16.png",
|
||||||
RowFilter::MinSum,
|
FilterStrategy::MinSum,
|
||||||
GRAYSCALE_ALPHA,
|
GRAYSCALE_ALPHA,
|
||||||
BitDepth::Sixteen,
|
BitDepth::Sixteen,
|
||||||
GRAYSCALE_ALPHA,
|
GRAYSCALE_ALPHA,
|
||||||
|
|
@ -428,7 +425,7 @@ fn filter_5_for_grayscale_alpha_16() {
|
||||||
fn filter_0_for_grayscale_alpha_8() {
|
fn filter_0_for_grayscale_alpha_8() {
|
||||||
test_it_converts(
|
test_it_converts(
|
||||||
"tests/files/filter_0_for_grayscale_alpha_8.png",
|
"tests/files/filter_0_for_grayscale_alpha_8.png",
|
||||||
RowFilter::None,
|
FilterStrategy::Basic(RowFilter::None),
|
||||||
GRAYSCALE_ALPHA,
|
GRAYSCALE_ALPHA,
|
||||||
BitDepth::Eight,
|
BitDepth::Eight,
|
||||||
GRAYSCALE_ALPHA,
|
GRAYSCALE_ALPHA,
|
||||||
|
|
@ -440,7 +437,7 @@ fn filter_0_for_grayscale_alpha_8() {
|
||||||
fn filter_1_for_grayscale_alpha_8() {
|
fn filter_1_for_grayscale_alpha_8() {
|
||||||
test_it_converts(
|
test_it_converts(
|
||||||
"tests/files/filter_1_for_grayscale_alpha_8.png",
|
"tests/files/filter_1_for_grayscale_alpha_8.png",
|
||||||
RowFilter::Sub,
|
FilterStrategy::Basic(RowFilter::Sub),
|
||||||
GRAYSCALE_ALPHA,
|
GRAYSCALE_ALPHA,
|
||||||
BitDepth::Eight,
|
BitDepth::Eight,
|
||||||
GRAYSCALE_ALPHA,
|
GRAYSCALE_ALPHA,
|
||||||
|
|
@ -452,7 +449,7 @@ fn filter_1_for_grayscale_alpha_8() {
|
||||||
fn filter_2_for_grayscale_alpha_8() {
|
fn filter_2_for_grayscale_alpha_8() {
|
||||||
test_it_converts(
|
test_it_converts(
|
||||||
"tests/files/filter_2_for_grayscale_alpha_8.png",
|
"tests/files/filter_2_for_grayscale_alpha_8.png",
|
||||||
RowFilter::Up,
|
FilterStrategy::Basic(RowFilter::Up),
|
||||||
GRAYSCALE_ALPHA,
|
GRAYSCALE_ALPHA,
|
||||||
BitDepth::Eight,
|
BitDepth::Eight,
|
||||||
GRAYSCALE_ALPHA,
|
GRAYSCALE_ALPHA,
|
||||||
|
|
@ -464,7 +461,7 @@ fn filter_2_for_grayscale_alpha_8() {
|
||||||
fn filter_3_for_grayscale_alpha_8() {
|
fn filter_3_for_grayscale_alpha_8() {
|
||||||
test_it_converts(
|
test_it_converts(
|
||||||
"tests/files/filter_3_for_grayscale_alpha_8.png",
|
"tests/files/filter_3_for_grayscale_alpha_8.png",
|
||||||
RowFilter::Average,
|
FilterStrategy::Basic(RowFilter::Average),
|
||||||
GRAYSCALE_ALPHA,
|
GRAYSCALE_ALPHA,
|
||||||
BitDepth::Eight,
|
BitDepth::Eight,
|
||||||
GRAYSCALE_ALPHA,
|
GRAYSCALE_ALPHA,
|
||||||
|
|
@ -476,7 +473,7 @@ fn filter_3_for_grayscale_alpha_8() {
|
||||||
fn filter_4_for_grayscale_alpha_8() {
|
fn filter_4_for_grayscale_alpha_8() {
|
||||||
test_it_converts(
|
test_it_converts(
|
||||||
"tests/files/filter_4_for_grayscale_alpha_8.png",
|
"tests/files/filter_4_for_grayscale_alpha_8.png",
|
||||||
RowFilter::Paeth,
|
FilterStrategy::Basic(RowFilter::Paeth),
|
||||||
GRAYSCALE_ALPHA,
|
GRAYSCALE_ALPHA,
|
||||||
BitDepth::Eight,
|
BitDepth::Eight,
|
||||||
GRAYSCALE_ALPHA,
|
GRAYSCALE_ALPHA,
|
||||||
|
|
@ -488,7 +485,7 @@ fn filter_4_for_grayscale_alpha_8() {
|
||||||
fn filter_5_for_grayscale_alpha_8() {
|
fn filter_5_for_grayscale_alpha_8() {
|
||||||
test_it_converts(
|
test_it_converts(
|
||||||
"tests/files/filter_5_for_grayscale_alpha_8.png",
|
"tests/files/filter_5_for_grayscale_alpha_8.png",
|
||||||
RowFilter::MinSum,
|
FilterStrategy::MinSum,
|
||||||
GRAYSCALE_ALPHA,
|
GRAYSCALE_ALPHA,
|
||||||
BitDepth::Eight,
|
BitDepth::Eight,
|
||||||
GRAYSCALE_ALPHA,
|
GRAYSCALE_ALPHA,
|
||||||
|
|
@ -500,7 +497,7 @@ fn filter_5_for_grayscale_alpha_8() {
|
||||||
fn filter_0_for_grayscale_16() {
|
fn filter_0_for_grayscale_16() {
|
||||||
test_it_converts(
|
test_it_converts(
|
||||||
"tests/files/filter_0_for_grayscale_16.png",
|
"tests/files/filter_0_for_grayscale_16.png",
|
||||||
RowFilter::None,
|
FilterStrategy::Basic(RowFilter::None),
|
||||||
GRAYSCALE,
|
GRAYSCALE,
|
||||||
BitDepth::Sixteen,
|
BitDepth::Sixteen,
|
||||||
GRAYSCALE,
|
GRAYSCALE,
|
||||||
|
|
@ -512,7 +509,7 @@ fn filter_0_for_grayscale_16() {
|
||||||
fn filter_1_for_grayscale_16() {
|
fn filter_1_for_grayscale_16() {
|
||||||
test_it_converts(
|
test_it_converts(
|
||||||
"tests/files/filter_1_for_grayscale_16.png",
|
"tests/files/filter_1_for_grayscale_16.png",
|
||||||
RowFilter::Sub,
|
FilterStrategy::Basic(RowFilter::Sub),
|
||||||
GRAYSCALE,
|
GRAYSCALE,
|
||||||
BitDepth::Sixteen,
|
BitDepth::Sixteen,
|
||||||
GRAYSCALE,
|
GRAYSCALE,
|
||||||
|
|
@ -524,7 +521,7 @@ fn filter_1_for_grayscale_16() {
|
||||||
fn filter_2_for_grayscale_16() {
|
fn filter_2_for_grayscale_16() {
|
||||||
test_it_converts(
|
test_it_converts(
|
||||||
"tests/files/filter_2_for_grayscale_16.png",
|
"tests/files/filter_2_for_grayscale_16.png",
|
||||||
RowFilter::Up,
|
FilterStrategy::Basic(RowFilter::Up),
|
||||||
GRAYSCALE,
|
GRAYSCALE,
|
||||||
BitDepth::Sixteen,
|
BitDepth::Sixteen,
|
||||||
GRAYSCALE,
|
GRAYSCALE,
|
||||||
|
|
@ -536,7 +533,7 @@ fn filter_2_for_grayscale_16() {
|
||||||
fn filter_3_for_grayscale_16() {
|
fn filter_3_for_grayscale_16() {
|
||||||
test_it_converts(
|
test_it_converts(
|
||||||
"tests/files/filter_3_for_grayscale_16.png",
|
"tests/files/filter_3_for_grayscale_16.png",
|
||||||
RowFilter::Average,
|
FilterStrategy::Basic(RowFilter::Average),
|
||||||
GRAYSCALE,
|
GRAYSCALE,
|
||||||
BitDepth::Sixteen,
|
BitDepth::Sixteen,
|
||||||
GRAYSCALE,
|
GRAYSCALE,
|
||||||
|
|
@ -548,7 +545,7 @@ fn filter_3_for_grayscale_16() {
|
||||||
fn filter_4_for_grayscale_16() {
|
fn filter_4_for_grayscale_16() {
|
||||||
test_it_converts(
|
test_it_converts(
|
||||||
"tests/files/filter_4_for_grayscale_16.png",
|
"tests/files/filter_4_for_grayscale_16.png",
|
||||||
RowFilter::Paeth,
|
FilterStrategy::Basic(RowFilter::Paeth),
|
||||||
GRAYSCALE,
|
GRAYSCALE,
|
||||||
BitDepth::Sixteen,
|
BitDepth::Sixteen,
|
||||||
GRAYSCALE,
|
GRAYSCALE,
|
||||||
|
|
@ -560,7 +557,7 @@ fn filter_4_for_grayscale_16() {
|
||||||
fn filter_5_for_grayscale_16() {
|
fn filter_5_for_grayscale_16() {
|
||||||
test_it_converts(
|
test_it_converts(
|
||||||
"tests/files/filter_5_for_grayscale_16.png",
|
"tests/files/filter_5_for_grayscale_16.png",
|
||||||
RowFilter::MinSum,
|
FilterStrategy::MinSum,
|
||||||
GRAYSCALE,
|
GRAYSCALE,
|
||||||
BitDepth::Sixteen,
|
BitDepth::Sixteen,
|
||||||
GRAYSCALE,
|
GRAYSCALE,
|
||||||
|
|
@ -572,7 +569,7 @@ fn filter_5_for_grayscale_16() {
|
||||||
fn filter_0_for_grayscale_8() {
|
fn filter_0_for_grayscale_8() {
|
||||||
test_it_converts(
|
test_it_converts(
|
||||||
"tests/files/filter_0_for_grayscale_8.png",
|
"tests/files/filter_0_for_grayscale_8.png",
|
||||||
RowFilter::None,
|
FilterStrategy::Basic(RowFilter::None),
|
||||||
GRAYSCALE,
|
GRAYSCALE,
|
||||||
BitDepth::Eight,
|
BitDepth::Eight,
|
||||||
GRAYSCALE,
|
GRAYSCALE,
|
||||||
|
|
@ -584,7 +581,7 @@ fn filter_0_for_grayscale_8() {
|
||||||
fn filter_1_for_grayscale_8() {
|
fn filter_1_for_grayscale_8() {
|
||||||
test_it_converts(
|
test_it_converts(
|
||||||
"tests/files/filter_1_for_grayscale_8.png",
|
"tests/files/filter_1_for_grayscale_8.png",
|
||||||
RowFilter::Sub,
|
FilterStrategy::Basic(RowFilter::Sub),
|
||||||
GRAYSCALE,
|
GRAYSCALE,
|
||||||
BitDepth::Eight,
|
BitDepth::Eight,
|
||||||
GRAYSCALE,
|
GRAYSCALE,
|
||||||
|
|
@ -596,7 +593,7 @@ fn filter_1_for_grayscale_8() {
|
||||||
fn filter_2_for_grayscale_8() {
|
fn filter_2_for_grayscale_8() {
|
||||||
test_it_converts(
|
test_it_converts(
|
||||||
"tests/files/filter_2_for_grayscale_8.png",
|
"tests/files/filter_2_for_grayscale_8.png",
|
||||||
RowFilter::Up,
|
FilterStrategy::Basic(RowFilter::Up),
|
||||||
GRAYSCALE,
|
GRAYSCALE,
|
||||||
BitDepth::Eight,
|
BitDepth::Eight,
|
||||||
GRAYSCALE,
|
GRAYSCALE,
|
||||||
|
|
@ -608,7 +605,7 @@ fn filter_2_for_grayscale_8() {
|
||||||
fn filter_3_for_grayscale_8() {
|
fn filter_3_for_grayscale_8() {
|
||||||
test_it_converts(
|
test_it_converts(
|
||||||
"tests/files/filter_3_for_grayscale_8.png",
|
"tests/files/filter_3_for_grayscale_8.png",
|
||||||
RowFilter::Average,
|
FilterStrategy::Basic(RowFilter::Average),
|
||||||
GRAYSCALE,
|
GRAYSCALE,
|
||||||
BitDepth::Eight,
|
BitDepth::Eight,
|
||||||
GRAYSCALE,
|
GRAYSCALE,
|
||||||
|
|
@ -620,7 +617,7 @@ fn filter_3_for_grayscale_8() {
|
||||||
fn filter_4_for_grayscale_8() {
|
fn filter_4_for_grayscale_8() {
|
||||||
test_it_converts(
|
test_it_converts(
|
||||||
"tests/files/filter_4_for_grayscale_8.png",
|
"tests/files/filter_4_for_grayscale_8.png",
|
||||||
RowFilter::Paeth,
|
FilterStrategy::Basic(RowFilter::Paeth),
|
||||||
GRAYSCALE,
|
GRAYSCALE,
|
||||||
BitDepth::Eight,
|
BitDepth::Eight,
|
||||||
GRAYSCALE,
|
GRAYSCALE,
|
||||||
|
|
@ -632,7 +629,7 @@ fn filter_4_for_grayscale_8() {
|
||||||
fn filter_5_for_grayscale_8() {
|
fn filter_5_for_grayscale_8() {
|
||||||
test_it_converts(
|
test_it_converts(
|
||||||
"tests/files/filter_5_for_grayscale_8.png",
|
"tests/files/filter_5_for_grayscale_8.png",
|
||||||
RowFilter::MinSum,
|
FilterStrategy::MinSum,
|
||||||
GRAYSCALE,
|
GRAYSCALE,
|
||||||
BitDepth::Eight,
|
BitDepth::Eight,
|
||||||
GRAYSCALE,
|
GRAYSCALE,
|
||||||
|
|
@ -644,7 +641,7 @@ fn filter_5_for_grayscale_8() {
|
||||||
fn filter_0_for_palette_4() {
|
fn filter_0_for_palette_4() {
|
||||||
test_it_converts(
|
test_it_converts(
|
||||||
"tests/files/filter_0_for_palette_4.png",
|
"tests/files/filter_0_for_palette_4.png",
|
||||||
RowFilter::None,
|
FilterStrategy::Basic(RowFilter::None),
|
||||||
INDEXED,
|
INDEXED,
|
||||||
BitDepth::Four,
|
BitDepth::Four,
|
||||||
INDEXED,
|
INDEXED,
|
||||||
|
|
@ -656,7 +653,7 @@ fn filter_0_for_palette_4() {
|
||||||
fn filter_1_for_palette_4() {
|
fn filter_1_for_palette_4() {
|
||||||
test_it_converts(
|
test_it_converts(
|
||||||
"tests/files/filter_1_for_palette_4.png",
|
"tests/files/filter_1_for_palette_4.png",
|
||||||
RowFilter::Sub,
|
FilterStrategy::Basic(RowFilter::Sub),
|
||||||
INDEXED,
|
INDEXED,
|
||||||
BitDepth::Four,
|
BitDepth::Four,
|
||||||
INDEXED,
|
INDEXED,
|
||||||
|
|
@ -668,7 +665,7 @@ fn filter_1_for_palette_4() {
|
||||||
fn filter_2_for_palette_4() {
|
fn filter_2_for_palette_4() {
|
||||||
test_it_converts(
|
test_it_converts(
|
||||||
"tests/files/filter_2_for_palette_4.png",
|
"tests/files/filter_2_for_palette_4.png",
|
||||||
RowFilter::Up,
|
FilterStrategy::Basic(RowFilter::Up),
|
||||||
INDEXED,
|
INDEXED,
|
||||||
BitDepth::Four,
|
BitDepth::Four,
|
||||||
INDEXED,
|
INDEXED,
|
||||||
|
|
@ -680,7 +677,7 @@ fn filter_2_for_palette_4() {
|
||||||
fn filter_3_for_palette_4() {
|
fn filter_3_for_palette_4() {
|
||||||
test_it_converts(
|
test_it_converts(
|
||||||
"tests/files/filter_3_for_palette_4.png",
|
"tests/files/filter_3_for_palette_4.png",
|
||||||
RowFilter::Average,
|
FilterStrategy::Basic(RowFilter::Average),
|
||||||
INDEXED,
|
INDEXED,
|
||||||
BitDepth::Four,
|
BitDepth::Four,
|
||||||
INDEXED,
|
INDEXED,
|
||||||
|
|
@ -692,7 +689,7 @@ fn filter_3_for_palette_4() {
|
||||||
fn filter_4_for_palette_4() {
|
fn filter_4_for_palette_4() {
|
||||||
test_it_converts(
|
test_it_converts(
|
||||||
"tests/files/filter_4_for_palette_4.png",
|
"tests/files/filter_4_for_palette_4.png",
|
||||||
RowFilter::Paeth,
|
FilterStrategy::Basic(RowFilter::Paeth),
|
||||||
INDEXED,
|
INDEXED,
|
||||||
BitDepth::Four,
|
BitDepth::Four,
|
||||||
INDEXED,
|
INDEXED,
|
||||||
|
|
@ -704,7 +701,7 @@ fn filter_4_for_palette_4() {
|
||||||
fn filter_5_for_palette_4() {
|
fn filter_5_for_palette_4() {
|
||||||
test_it_converts(
|
test_it_converts(
|
||||||
"tests/files/filter_5_for_palette_4.png",
|
"tests/files/filter_5_for_palette_4.png",
|
||||||
RowFilter::MinSum,
|
FilterStrategy::MinSum,
|
||||||
INDEXED,
|
INDEXED,
|
||||||
BitDepth::Four,
|
BitDepth::Four,
|
||||||
INDEXED,
|
INDEXED,
|
||||||
|
|
@ -716,7 +713,7 @@ fn filter_5_for_palette_4() {
|
||||||
fn filter_0_for_palette_2() {
|
fn filter_0_for_palette_2() {
|
||||||
test_it_converts(
|
test_it_converts(
|
||||||
"tests/files/filter_0_for_palette_2.png",
|
"tests/files/filter_0_for_palette_2.png",
|
||||||
RowFilter::None,
|
FilterStrategy::Basic(RowFilter::None),
|
||||||
INDEXED,
|
INDEXED,
|
||||||
BitDepth::Two,
|
BitDepth::Two,
|
||||||
INDEXED,
|
INDEXED,
|
||||||
|
|
@ -728,7 +725,7 @@ fn filter_0_for_palette_2() {
|
||||||
fn filter_1_for_palette_2() {
|
fn filter_1_for_palette_2() {
|
||||||
test_it_converts(
|
test_it_converts(
|
||||||
"tests/files/filter_1_for_palette_2.png",
|
"tests/files/filter_1_for_palette_2.png",
|
||||||
RowFilter::Sub,
|
FilterStrategy::Basic(RowFilter::Sub),
|
||||||
INDEXED,
|
INDEXED,
|
||||||
BitDepth::Two,
|
BitDepth::Two,
|
||||||
INDEXED,
|
INDEXED,
|
||||||
|
|
@ -740,7 +737,7 @@ fn filter_1_for_palette_2() {
|
||||||
fn filter_2_for_palette_2() {
|
fn filter_2_for_palette_2() {
|
||||||
test_it_converts(
|
test_it_converts(
|
||||||
"tests/files/filter_2_for_palette_2.png",
|
"tests/files/filter_2_for_palette_2.png",
|
||||||
RowFilter::Up,
|
FilterStrategy::Basic(RowFilter::Up),
|
||||||
INDEXED,
|
INDEXED,
|
||||||
BitDepth::Two,
|
BitDepth::Two,
|
||||||
INDEXED,
|
INDEXED,
|
||||||
|
|
@ -752,7 +749,7 @@ fn filter_2_for_palette_2() {
|
||||||
fn filter_3_for_palette_2() {
|
fn filter_3_for_palette_2() {
|
||||||
test_it_converts(
|
test_it_converts(
|
||||||
"tests/files/filter_3_for_palette_2.png",
|
"tests/files/filter_3_for_palette_2.png",
|
||||||
RowFilter::Average,
|
FilterStrategy::Basic(RowFilter::Average),
|
||||||
INDEXED,
|
INDEXED,
|
||||||
BitDepth::Two,
|
BitDepth::Two,
|
||||||
INDEXED,
|
INDEXED,
|
||||||
|
|
@ -764,7 +761,7 @@ fn filter_3_for_palette_2() {
|
||||||
fn filter_4_for_palette_2() {
|
fn filter_4_for_palette_2() {
|
||||||
test_it_converts(
|
test_it_converts(
|
||||||
"tests/files/filter_4_for_palette_2.png",
|
"tests/files/filter_4_for_palette_2.png",
|
||||||
RowFilter::Paeth,
|
FilterStrategy::Basic(RowFilter::Paeth),
|
||||||
INDEXED,
|
INDEXED,
|
||||||
BitDepth::Two,
|
BitDepth::Two,
|
||||||
INDEXED,
|
INDEXED,
|
||||||
|
|
@ -776,7 +773,7 @@ fn filter_4_for_palette_2() {
|
||||||
fn filter_5_for_palette_2() {
|
fn filter_5_for_palette_2() {
|
||||||
test_it_converts(
|
test_it_converts(
|
||||||
"tests/files/filter_5_for_palette_2.png",
|
"tests/files/filter_5_for_palette_2.png",
|
||||||
RowFilter::MinSum,
|
FilterStrategy::MinSum,
|
||||||
INDEXED,
|
INDEXED,
|
||||||
BitDepth::Two,
|
BitDepth::Two,
|
||||||
INDEXED,
|
INDEXED,
|
||||||
|
|
@ -788,7 +785,7 @@ fn filter_5_for_palette_2() {
|
||||||
fn filter_0_for_palette_1() {
|
fn filter_0_for_palette_1() {
|
||||||
test_it_converts(
|
test_it_converts(
|
||||||
"tests/files/filter_0_for_palette_1.png",
|
"tests/files/filter_0_for_palette_1.png",
|
||||||
RowFilter::None,
|
FilterStrategy::Basic(RowFilter::None),
|
||||||
INDEXED,
|
INDEXED,
|
||||||
BitDepth::One,
|
BitDepth::One,
|
||||||
INDEXED,
|
INDEXED,
|
||||||
|
|
@ -800,7 +797,7 @@ fn filter_0_for_palette_1() {
|
||||||
fn filter_1_for_palette_1() {
|
fn filter_1_for_palette_1() {
|
||||||
test_it_converts(
|
test_it_converts(
|
||||||
"tests/files/filter_1_for_palette_1.png",
|
"tests/files/filter_1_for_palette_1.png",
|
||||||
RowFilter::Sub,
|
FilterStrategy::Basic(RowFilter::Sub),
|
||||||
INDEXED,
|
INDEXED,
|
||||||
BitDepth::One,
|
BitDepth::One,
|
||||||
INDEXED,
|
INDEXED,
|
||||||
|
|
@ -812,7 +809,7 @@ fn filter_1_for_palette_1() {
|
||||||
fn filter_2_for_palette_1() {
|
fn filter_2_for_palette_1() {
|
||||||
test_it_converts(
|
test_it_converts(
|
||||||
"tests/files/filter_2_for_palette_1.png",
|
"tests/files/filter_2_for_palette_1.png",
|
||||||
RowFilter::Up,
|
FilterStrategy::Basic(RowFilter::Up),
|
||||||
INDEXED,
|
INDEXED,
|
||||||
BitDepth::One,
|
BitDepth::One,
|
||||||
INDEXED,
|
INDEXED,
|
||||||
|
|
@ -824,7 +821,7 @@ fn filter_2_for_palette_1() {
|
||||||
fn filter_3_for_palette_1() {
|
fn filter_3_for_palette_1() {
|
||||||
test_it_converts(
|
test_it_converts(
|
||||||
"tests/files/filter_3_for_palette_1.png",
|
"tests/files/filter_3_for_palette_1.png",
|
||||||
RowFilter::Average,
|
FilterStrategy::Basic(RowFilter::Average),
|
||||||
INDEXED,
|
INDEXED,
|
||||||
BitDepth::One,
|
BitDepth::One,
|
||||||
INDEXED,
|
INDEXED,
|
||||||
|
|
@ -836,7 +833,7 @@ fn filter_3_for_palette_1() {
|
||||||
fn filter_4_for_palette_1() {
|
fn filter_4_for_palette_1() {
|
||||||
test_it_converts(
|
test_it_converts(
|
||||||
"tests/files/filter_4_for_palette_1.png",
|
"tests/files/filter_4_for_palette_1.png",
|
||||||
RowFilter::Paeth,
|
FilterStrategy::Basic(RowFilter::Paeth),
|
||||||
INDEXED,
|
INDEXED,
|
||||||
BitDepth::One,
|
BitDepth::One,
|
||||||
INDEXED,
|
INDEXED,
|
||||||
|
|
@ -848,7 +845,7 @@ fn filter_4_for_palette_1() {
|
||||||
fn filter_5_for_palette_1() {
|
fn filter_5_for_palette_1() {
|
||||||
test_it_converts(
|
test_it_converts(
|
||||||
"tests/files/filter_5_for_palette_1.png",
|
"tests/files/filter_5_for_palette_1.png",
|
||||||
RowFilter::MinSum,
|
FilterStrategy::MinSum,
|
||||||
INDEXED,
|
INDEXED,
|
||||||
BitDepth::One,
|
BitDepth::One,
|
||||||
INDEXED,
|
INDEXED,
|
||||||
|
|
|
||||||
|
|
@ -16,7 +16,7 @@ fn get_opts(input: &Path) -> (OutFile, Options) {
|
||||||
let options = Options {
|
let options = Options {
|
||||||
force: true,
|
force: true,
|
||||||
fast_evaluation: false,
|
fast_evaluation: false,
|
||||||
filter: indexset! {RowFilter::None},
|
filter: indexset! {FilterStrategy::Basic(RowFilter::None)},
|
||||||
..Default::default()
|
..Default::default()
|
||||||
};
|
};
|
||||||
(OutFile::from_path(input.with_extension("out.png")), options)
|
(OutFile::from_path(input.with_extension("out.png")), options)
|
||||||
|
|
@ -409,7 +409,7 @@ fn interlaced_0_to_1_other_filter_mode() {
|
||||||
let input = PathBuf::from("tests/files/interlaced_0_to_1_other_filter_mode.png");
|
let input = PathBuf::from("tests/files/interlaced_0_to_1_other_filter_mode.png");
|
||||||
let (output, mut opts) = get_opts(&input);
|
let (output, mut opts) = get_opts(&input);
|
||||||
opts.interlace = Some(Interlacing::Adam7);
|
opts.interlace = Some(Interlacing::Adam7);
|
||||||
opts.filter = indexset! {RowFilter::Paeth};
|
opts.filter = indexset! {FilterStrategy::Basic(RowFilter::Paeth)};
|
||||||
|
|
||||||
test_it_converts_callbacks(
|
test_it_converts_callbacks(
|
||||||
input,
|
input,
|
||||||
|
|
|
||||||
|
|
@ -12,16 +12,13 @@ const GRAYSCALE_ALPHA: u8 = 4;
|
||||||
const RGBA: u8 = 6;
|
const RGBA: u8 = 6;
|
||||||
|
|
||||||
fn get_opts(input: &Path) -> (OutFile, oxipng::Options) {
|
fn get_opts(input: &Path) -> (OutFile, oxipng::Options) {
|
||||||
let mut options = oxipng::Options {
|
let options = oxipng::Options {
|
||||||
force: true,
|
force: true,
|
||||||
fast_evaluation: false,
|
fast_evaluation: false,
|
||||||
|
filter: indexset! {FilterStrategy::Basic(RowFilter::None)},
|
||||||
interlace: None,
|
interlace: None,
|
||||||
..Default::default()
|
..Default::default()
|
||||||
};
|
};
|
||||||
let mut filter = IndexSet::new();
|
|
||||||
filter.insert(RowFilter::None);
|
|
||||||
options.filter = filter;
|
|
||||||
|
|
||||||
(OutFile::from_path(input.with_extension("out.png")), options)
|
(OutFile::from_path(input.with_extension("out.png")), options)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -9,14 +9,11 @@ const RGB: u8 = 2;
|
||||||
const INDEXED: u8 = 3;
|
const INDEXED: u8 = 3;
|
||||||
|
|
||||||
fn get_opts(input: &Path) -> (OutFile, oxipng::Options) {
|
fn get_opts(input: &Path) -> (OutFile, oxipng::Options) {
|
||||||
let mut options = oxipng::Options {
|
let options = oxipng::Options {
|
||||||
force: true,
|
force: true,
|
||||||
|
filter: indexset! {FilterStrategy::Basic(RowFilter::None)},
|
||||||
..Default::default()
|
..Default::default()
|
||||||
};
|
};
|
||||||
let mut filter = IndexSet::new();
|
|
||||||
filter.insert(RowFilter::None);
|
|
||||||
options.filter = filter;
|
|
||||||
|
|
||||||
(OutFile::from_path(input.with_extension("out.png")), options)
|
(OutFile::from_path(input.with_extension("out.png")), options)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,7 @@ use oxipng::{internal_tests::*, *};
|
||||||
fn get_opts() -> Options {
|
fn get_opts() -> Options {
|
||||||
Options {
|
Options {
|
||||||
force: true,
|
force: true,
|
||||||
filter: indexset! { RowFilter::None },
|
filter: indexset! {FilterStrategy::Basic(RowFilter::None)},
|
||||||
..Default::default()
|
..Default::default()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -12,15 +12,12 @@ const GRAYSCALE_ALPHA: u8 = 4;
|
||||||
const RGBA: u8 = 6;
|
const RGBA: u8 = 6;
|
||||||
|
|
||||||
fn get_opts(input: &Path) -> (OutFile, oxipng::Options) {
|
fn get_opts(input: &Path) -> (OutFile, oxipng::Options) {
|
||||||
let mut options = oxipng::Options {
|
let options = oxipng::Options {
|
||||||
force: true,
|
force: true,
|
||||||
fast_evaluation: false,
|
fast_evaluation: false,
|
||||||
|
filter: indexset! {FilterStrategy::Basic(RowFilter::None)},
|
||||||
..Default::default()
|
..Default::default()
|
||||||
};
|
};
|
||||||
let mut filter = IndexSet::new();
|
|
||||||
filter.insert(RowFilter::None);
|
|
||||||
options.filter = filter;
|
|
||||||
|
|
||||||
(OutFile::from_path(input.with_extension("out.png")), options)
|
(OutFile::from_path(input.with_extension("out.png")), options)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -12,14 +12,11 @@ const GRAYSCALE_ALPHA: u8 = 4;
|
||||||
const RGBA: u8 = 6;
|
const RGBA: u8 = 6;
|
||||||
|
|
||||||
fn get_opts(input: &Path) -> (OutFile, oxipng::Options) {
|
fn get_opts(input: &Path) -> (OutFile, oxipng::Options) {
|
||||||
let mut options = oxipng::Options {
|
let options = oxipng::Options {
|
||||||
force: true,
|
force: true,
|
||||||
|
filter: indexset! {FilterStrategy::Basic(RowFilter::None)},
|
||||||
..Default::default()
|
..Default::default()
|
||||||
};
|
};
|
||||||
let mut filter = IndexSet::new();
|
|
||||||
filter.insert(RowFilter::None);
|
|
||||||
options.filter = filter;
|
|
||||||
|
|
||||||
(OutFile::from_path(input.with_extension("out.png")), options)
|
(OutFile::from_path(input.with_extension("out.png")), options)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -11,20 +11,16 @@ const INDEXED: u8 = 3;
|
||||||
const RGBA: u8 = 6;
|
const RGBA: u8 = 6;
|
||||||
|
|
||||||
fn get_opts(input: &Path) -> (OutFile, oxipng::Options) {
|
fn get_opts(input: &Path) -> (OutFile, oxipng::Options) {
|
||||||
let mut options = oxipng::Options {
|
let options = oxipng::Options {
|
||||||
force: true,
|
force: true,
|
||||||
..Default::default()
|
..Default::default()
|
||||||
};
|
};
|
||||||
let mut filter = IndexSet::new();
|
|
||||||
filter.insert(RowFilter::None);
|
|
||||||
options.filter = filter;
|
|
||||||
|
|
||||||
(OutFile::from_path(input.with_extension("out.png")), options)
|
(OutFile::from_path(input.with_extension("out.png")), options)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn test_it_converts(
|
fn test_it_converts(
|
||||||
input: &str,
|
input: &str,
|
||||||
filter: RowFilter,
|
filter: FilterStrategy,
|
||||||
color_type_in: u8,
|
color_type_in: u8,
|
||||||
bit_depth_in: BitDepth,
|
bit_depth_in: BitDepth,
|
||||||
color_type_out: u8,
|
color_type_out: u8,
|
||||||
|
|
@ -34,8 +30,7 @@ fn test_it_converts(
|
||||||
|
|
||||||
let (output, mut opts) = get_opts(&input);
|
let (output, mut opts) = get_opts(&input);
|
||||||
let png = PngData::new(&input, &opts).unwrap();
|
let png = PngData::new(&input, &opts).unwrap();
|
||||||
opts.filter = IndexSet::new();
|
opts.filter = indexset! {filter};
|
||||||
opts.filter.insert(filter);
|
|
||||||
assert_eq!(png.raw.ihdr.color_type.png_header_code(), color_type_in);
|
assert_eq!(png.raw.ihdr.color_type.png_header_code(), color_type_in);
|
||||||
assert_eq!(png.raw.ihdr.bit_depth, bit_depth_in);
|
assert_eq!(png.raw.ihdr.bit_depth, bit_depth_in);
|
||||||
|
|
||||||
|
|
@ -67,7 +62,7 @@ fn test_it_converts(
|
||||||
fn filter_minsum() {
|
fn filter_minsum() {
|
||||||
test_it_converts(
|
test_it_converts(
|
||||||
"tests/files/rgb_16_should_be_rgb_16.png",
|
"tests/files/rgb_16_should_be_rgb_16.png",
|
||||||
RowFilter::MinSum,
|
FilterStrategy::MinSum,
|
||||||
RGB,
|
RGB,
|
||||||
BitDepth::Sixteen,
|
BitDepth::Sixteen,
|
||||||
RGB,
|
RGB,
|
||||||
|
|
@ -79,7 +74,7 @@ fn filter_minsum() {
|
||||||
fn filter_entropy() {
|
fn filter_entropy() {
|
||||||
test_it_converts(
|
test_it_converts(
|
||||||
"tests/files/rgb_8_should_be_rgb_8.png",
|
"tests/files/rgb_8_should_be_rgb_8.png",
|
||||||
RowFilter::Entropy,
|
FilterStrategy::Entropy,
|
||||||
RGB,
|
RGB,
|
||||||
BitDepth::Eight,
|
BitDepth::Eight,
|
||||||
RGB,
|
RGB,
|
||||||
|
|
@ -91,7 +86,7 @@ fn filter_entropy() {
|
||||||
fn filter_bigrams() {
|
fn filter_bigrams() {
|
||||||
test_it_converts(
|
test_it_converts(
|
||||||
"tests/files/rgba_8_should_be_rgba_8.png",
|
"tests/files/rgba_8_should_be_rgba_8.png",
|
||||||
RowFilter::Bigrams,
|
FilterStrategy::Bigrams,
|
||||||
RGBA,
|
RGBA,
|
||||||
BitDepth::Eight,
|
BitDepth::Eight,
|
||||||
RGBA,
|
RGBA,
|
||||||
|
|
@ -103,7 +98,7 @@ fn filter_bigrams() {
|
||||||
fn filter_bigent() {
|
fn filter_bigent() {
|
||||||
test_it_converts(
|
test_it_converts(
|
||||||
"tests/files/grayscale_8_should_be_grayscale_8.png",
|
"tests/files/grayscale_8_should_be_grayscale_8.png",
|
||||||
RowFilter::BigEnt,
|
FilterStrategy::BigEnt,
|
||||||
GRAYSCALE,
|
GRAYSCALE,
|
||||||
BitDepth::Eight,
|
BitDepth::Eight,
|
||||||
GRAYSCALE,
|
GRAYSCALE,
|
||||||
|
|
@ -115,7 +110,7 @@ fn filter_bigent() {
|
||||||
fn filter_brute() {
|
fn filter_brute() {
|
||||||
test_it_converts(
|
test_it_converts(
|
||||||
"tests/files/palette_8_should_be_palette_8.png",
|
"tests/files/palette_8_should_be_palette_8.png",
|
||||||
RowFilter::Brute,
|
FilterStrategy::Brute,
|
||||||
INDEXED,
|
INDEXED,
|
||||||
BitDepth::Eight,
|
BitDepth::Eight,
|
||||||
INDEXED,
|
INDEXED,
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue