From 85f1af42c3255b24f670f9a9fda3088a288b44d3 Mon Sep 17 00:00:00 2001 From: Patrick Walton Date: Tue, 10 Dec 2013 18:57:46 -0800 Subject: [PATCH] net: Color space convert 32-bit ARGB PNGs as well. --- src/components/net/image/base.rs | 42 +++++++++++++----------- src/test/ref/png_rgba_colorspace_a.html | 8 +++++ src/test/ref/png_rgba_colorspace_a.png | Bin 0 -> 510 bytes src/test/ref/png_rgba_colorspace_b.html | 8 +++++ 4 files changed, 39 insertions(+), 19 deletions(-) create mode 100644 src/test/ref/png_rgba_colorspace_a.html create mode 100644 src/test/ref/png_rgba_colorspace_a.png create mode 100644 src/test/ref/png_rgba_colorspace_b.html diff --git a/src/components/net/image/base.rs b/src/components/net/image/base.rs index f715f534640..4437f8bb95b 100644 --- a/src/components/net/image/base.rs +++ b/src/components/net/image/base.rs @@ -2,7 +2,7 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -use std::vec; +use std::iter::range_step; use stb_image = stb_image::image; use png; @@ -25,10 +25,28 @@ pub fn test_image_bin() -> ~[u8] { TEST_IMAGE.into_owned() } +// TODO(pcwalton): Speed up with SIMD, or better yet, find some way to not do this. +fn byte_swap(color_type: png::ColorType, data: &mut [u8]) { + match color_type { + png::RGBA8 => { + let length = data.len(); + for i in range_step(0, length, 4) { + let r = data[i + 2]; + data[i + 2] = data[i + 0]; + data[i + 0] = r; + } + } + _ => {} + } +} + pub fn load_from_memory(buffer: &[u8]) -> Option { if png::is_png(buffer) { match png::load_png_from_memory(buffer) { - Ok(png_image) => Some(png_image), + Ok(mut png_image) => { + byte_swap(png_image.color_type, png_image.pixels); + Some(png_image) + } Err(_err) => None, } } else { @@ -37,24 +55,10 @@ pub fn load_from_memory(buffer: &[u8]) -> Option { static FORCE_DEPTH: uint = 4; match stb_image::load_from_memory_with_depth(buffer, FORCE_DEPTH, true) { - stb_image::ImageU8(image) => { + stb_image::ImageU8(mut image) => { assert!(image.depth == 4); - // Do color space conversion :( - let data = do vec::from_fn(image.width * image.height * 4) |i| { - let color = i % 4; - let pixel = i / 4; - match color { - 0 => image.data[pixel * 4 + 2], - 1 => image.data[pixel * 4 + 1], - 2 => image.data[pixel * 4 + 0], - 3 => 0xffu8, - _ => fail!() - } - }; - - assert!(image.data.len() == data.len()); - - Some(Image(image.width as u32, image.height as u32, png::RGBA8, data)) + byte_swap(png::RGBA8, image.data); + Some(Image(image.width as u32, image.height as u32, png::RGBA8, image.data)) } stb_image::ImageF32(_image) => fail!(~"HDR images not implemented"), stb_image::Error => None diff --git a/src/test/ref/png_rgba_colorspace_a.html b/src/test/ref/png_rgba_colorspace_a.html new file mode 100644 index 00000000000..90b266ea332 --- /dev/null +++ b/src/test/ref/png_rgba_colorspace_a.html @@ -0,0 +1,8 @@ + + +Labyrinth was also a good movie because David Bowie and Muppets are cool + + + + + diff --git a/src/test/ref/png_rgba_colorspace_a.png b/src/test/ref/png_rgba_colorspace_a.png new file mode 100644 index 0000000000000000000000000000000000000000..9b9bd17fe479fa8615983574e386f90aec2f91fd GIT binary patch literal 510 zcmeAS@N?(olHy`uVBq!ia0vp^DIm!lvI6-E$sR$z z3=CCj3=9n|3=F@3LJcn%7)lKo7+xhXFj&oCU=S~uvn$XBD8ZKG?e4l#>C85nf_d18;EAvZrIGp!Q0h93)Knt>V^JYD@<);T3K0RVSb BnSuZS literal 0 HcmV?d00001 diff --git a/src/test/ref/png_rgba_colorspace_b.html b/src/test/ref/png_rgba_colorspace_b.html new file mode 100644 index 00000000000..c120145f8e8 --- /dev/null +++ b/src/test/ref/png_rgba_colorspace_b.html @@ -0,0 +1,8 @@ + + +Labyrinth was also a good movie because David Bowie and Muppets are cool + + +
+ +