Skip to content

Commit

Permalink
Support 16 bit per channel image buffers
Browse files Browse the repository at this point in the history
Add 16 bit buffers for all 16 bit types in ColorType. Include these as
supported types in DynamicImage. These 16 bit images are currently only
supported with u16 representation; changing this would require
specialization and macroing of color conversions.

Load 16 bit PNGs at full bit depth rather than squashing to 8 bit.

Note that tests will not pass until upgrading to a release of image-png
including image-rs/image-png#174.

Closes image-rs#560.
Closes image-rs#665.
Closes image-rs#940.
  • Loading branch information
aschampion committed Nov 27, 2019
1 parent 9342a0b commit 88f929d
Show file tree
Hide file tree
Showing 12 changed files with 540 additions and 98 deletions.
3 changes: 2 additions & 1 deletion Cargo.toml
Expand Up @@ -29,10 +29,11 @@ name = "image"
path = "./src/lib.rs"

[dependencies]
byteorder = "1.2.1"
byteorder = "1.3.2"
num-iter = "0.1.32"
num-rational = { version = "0.2.1", default-features = false }
num-traits = "0.2.0"
zerocopy = "0.2.8"

[dependencies.gif]
version = "0.10.0"
Expand Down
43 changes: 26 additions & 17 deletions src/buffer.rs
Expand Up @@ -4,12 +4,14 @@ use std::ops::{Deref, DerefMut, Index, IndexMut, Range};
use std::path::Path;
use std::slice::{Chunks, ChunksMut};

use color::{ColorType, FromColor, Luma, LumaA, Rgb, Rgba, Bgr, Bgra};
use color::{ChannelsType, ColorType, FromColor, Luma, LumaA, Rgb, Rgba, Bgr, Bgra};
use flat::{FlatSamples, SampleLayout};
use dynimage::{save_buffer, save_buffer_with_format};
use image::{GenericImage, GenericImageView, ImageFormat, ImageResult};
use traits::Primitive;
use utils::expand_packed;
use zerocopy::AsBytes;


/// A generalized pixel.
///
Expand Down Expand Up @@ -42,13 +44,10 @@ pub trait Pixel: Copy + Clone {
Self::COLOR_MODEL
}

/// ColorType for this pixel format
const COLOR_TYPE: ColorType;
/// Channels for this pixel format
const CHANNELS_TYPE: ChannelsType;
/// Returns the ColorType for this pixel format
#[deprecated(note="please use COLOR_TYPE associated constant")]
fn color_type() -> ColorType {
Self::COLOR_TYPE
}
fn color_type() -> ColorType;

/// Returns the channels of this pixel as a 4 tuple. If the pixel
/// has less than 4 channels the remainder is filled with the maximum value
Expand Down Expand Up @@ -655,7 +654,7 @@ where
FlatSamples {
samples: self.data,
layout,
color_hint: Some(P::COLOR_TYPE),
color_hint: Some(P::color_type()),
}
}

Expand All @@ -669,7 +668,7 @@ where
FlatSamples {
samples: self.data.as_ref(),
layout,
color_hint: Some(P::COLOR_TYPE),
color_hint: Some(P::color_type()),
}
}
}
Expand Down Expand Up @@ -745,8 +744,9 @@ where

impl<P, Container> ImageBuffer<P, Container>
where
P: Pixel<Subpixel = u8> + 'static,
Container: Deref<Target = [u8]>,
P: Pixel + 'static,
P::Subpixel: AsBytes,
Container: Deref<Target = [P::Subpixel]>,
{
/// Saves the buffer to a file at the path specified.
///
Expand All @@ -759,18 +759,19 @@ where
// This is valid as the subpixel is u8.
save_buffer(
path,
self,
self.as_bytes(),
self.width(),
self.height(),
<P as Pixel>::COLOR_TYPE,
<P as Pixel>::color_type(),
)
}
}

impl<P, Container> ImageBuffer<P, Container>
where
P: Pixel<Subpixel = u8> + 'static,
Container: Deref<Target = [u8]>,
P: Pixel + 'static,
P::Subpixel: AsBytes,
Container: Deref<Target = [P::Subpixel]>,
{
/// Saves the buffer to a file at the specified path in
/// the specified format.
Expand All @@ -784,10 +785,10 @@ where
// This is valid as the subpixel is u8.
save_buffer_with_format(
path,
self,
self.as_bytes(),
self.width(),
self.height(),
<P as Pixel>::COLOR_TYPE,
<P as Pixel>::color_type(),
format,
)
}
Expand Down Expand Up @@ -1076,6 +1077,14 @@ pub type GrayAlphaImage = ImageBuffer<LumaA<u8>, Vec<u8>>;
pub(crate) type BgrImage = ImageBuffer<Bgr<u8>, Vec<u8>>;
/// Sendable Bgr + alpha channel image buffer
pub(crate) type BgraImage = ImageBuffer<Bgra<u8>, Vec<u8>>;
/// Sendable 16-bit Rgb image buffer
pub type Rgb16Image = ImageBuffer<Rgb<u16>, Vec<u16>>;
/// Sendable 16-bit Rgb + alpha channel image buffer
pub type Rgba16Image = ImageBuffer<Rgba<u16>, Vec<u16>>;
/// Sendable 16-bit grayscale image buffer
pub type Gray16Image = ImageBuffer<Luma<u16>, Vec<u16>>;
/// Sendable 16-bit grayscale + alpha channel image buffer
pub type GrayAlpha16Image = ImageBuffer<LumaA<u16>, Vec<u16>>;

#[cfg(test)]
mod test {
Expand Down

0 comments on commit 88f929d

Please sign in to comment.