Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Decode grayscale images to RGBA #45

Merged
merged 1 commit into from Sep 4, 2014
Merged
Changes from all commits
Commits
File filter...
Filter file types
Jump to…
Jump to file
Failed to load files.

Always

Just for now

Decode grayscale images to RGBA

Part of the fix for servo/servo#3154.
  • Loading branch information
mbrubeck committed Sep 3, 2014
commit 8afb054170dcf05af90a30a9c07e9b18b049a2b5
@@ -70,6 +70,7 @@ extern {
pub fn png_get_image_height(png_ptr: *mut png_struct, info_ptr: *mut png_info) -> u32;
pub fn png_get_bit_depth(png_ptr: *mut png_struct, info_ptr: *mut png_info) -> u8;
pub fn png_get_color_type(png_ptr: *mut png_struct, info_ptr: *mut png_info) -> u8;
pub fn png_get_valid(png_ptr: *mut png_struct, info_ptr: *mut png_info, flag: u32) -> u32;
pub fn png_get_rows(png_ptr: *mut png_struct, info_ptr: *mut png_info) -> *mut *mut u8;

pub fn png_set_IHDR(png_ptr: *mut png_struct, info_ptr: *mut png_info, width: u32, height: u32, bit_depth: c_int, color_type: c_int, interlace_method: c_int, compression_method: c_int, filter_method: c_int);
@@ -79,7 +80,9 @@ extern {
pub fn png_set_packing(png_ptr: *mut png_struct);
pub fn png_set_palette_to_rgb(png_ptr: *mut png_struct);
pub fn png_set_expand_gray_1_2_4_to_8(png_ptr: *mut png_struct);
pub fn png_set_gray_to_rgb(png_ptr: *mut png_struct);
pub fn png_set_tRNS_to_alpha(png_ptr: *mut png_struct);
pub fn png_set_add_alpha(png_ptr: *mut png_struct, val: u32, flag: c_int);
pub fn png_set_filler(png_ptr: *mut png_struct, val: u32, flag: c_int);
pub fn png_set_interlace_handling(png_ptr: *mut png_struct);
}
@@ -105,22 +105,23 @@ pub fn load_png_from_memory(image: &[u8]) -> Result<Image,String> {

let width = ffi::png_get_image_width(png_ptr, info_ptr);
let height = ffi::png_get_image_height(png_ptr, info_ptr);
let bit_depth = ffi::png_get_bit_depth(png_ptr, info_ptr);
let color_type = ffi::png_get_color_type(png_ptr, info_ptr);

// we convert palette to rgb
if color_type as c_int == ffi::COLOR_TYPE_PALETTE {
ffi::png_set_palette_to_rgb(png_ptr);
}
// make each channel use 1 byte
if (color_type as c_int == ffi::COLOR_TYPE_GRAY) && (bit_depth < 8) {
ffi::png_set_expand_gray_1_2_4_to_8(png_ptr);
// convert palette and grayscale to rgb
match color_type as c_int {
ffi::COLOR_TYPE_PALETTE => {
ffi::png_set_palette_to_rgb(png_ptr);
}
ffi::COLOR_TYPE_GRAY | ffi::COLOR_TYPE_GRAY_ALPHA => {
ffi::png_set_gray_to_rgb(png_ptr);
}
_ => {}
}
// add alpha channels to palette and rgb
if (color_type as c_int == ffi::COLOR_TYPE_PALETTE) ||
(color_type as c_int == ffi::COLOR_TYPE_RGB) {

// add alpha channels
ffi::png_set_add_alpha(png_ptr, 0xff, ffi::FILLER_AFTER);
if ffi::png_get_valid(png_ptr, info_ptr, ffi::INFO_tRNS as u32) != 0 {
ffi::png_set_tRNS_to_alpha(png_ptr);
ffi::png_set_filler(png_ptr, 0xff, ffi::FILLER_AFTER);
}

ffi::png_set_packing(png_ptr);
@@ -285,6 +286,12 @@ mod test {
load_rgba8("test/store.png", 10, 10);
}

#[test]
fn test_load_grayscale() {
// grayscale images should be decoded to rgba
load_rgba8("test/gray.png", 100, 100);
}

fn bench_file_from_memory(file: &'static str, w: u32, h: u32, c: &'static str) {
let mut reader = match File::open_mode(&Path::new(file), io::Open, io::Read) {
Ok(r) => r,
@@ -317,7 +324,7 @@ mod test {
fn test_load_perf() {
bench_file_from_memory("test/servo-screenshot.png", 831, 624, "RGBA8");
bench_file_from_memory("test/mozilla-dinosaur-head-logo.png", 1300, 929, "RGBA8");
bench_file_from_memory("test/rust-huge-logo.png", 4000, 4000, "KA8");
bench_file_from_memory("test/rust-huge-logo.png", 4000, 4000, "RGBA8");
}

#[test]
BIN +2.26 KB test/gray.png
Binary file not shown.
ProTip! Use n and p to navigate between commits in a pull request.
You can’t perform that action at this time.