Support 64-bit encoding
Note that this adds the LONG8 data type from BigTIFF because of bounds requiring TiffValue. However, this datatype should not actually be written to tags.
This commit is contained in:
1 parent
0c53e1066a
commit
8c4cea5d97
4 files changed
+115
No files matched your search
@@ -122,6 +122,8 @@ pub enum Type(u16) {
|
||||
SSHORT = 8,
|
||||
SLONG = 9,
|
||||
SRATIONAL = 10,
|
||||
/// BigTIFF 64-bit unsigned integer
|
||||
LONG8 = 16,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -31,6 +31,13 @@ impl ColorType for Gray32 {
|
||||
const BITS_PER_SAMPLE: &'static [u16] = &[32];
|
||||
}
|
||||
|
||||
pub struct Gray64;
|
||||
impl ColorType for Gray64 {
|
||||
type Inner = u64;
|
||||
const TIFF_VALUE: PhotometricInterpretation = PhotometricInterpretation::BlackIsZero;
|
||||
const BITS_PER_SAMPLE: &'static [u16] = &[64];
|
||||
}
|
||||
|
||||
pub struct RGB8;
|
||||
impl ColorType for RGB8 {
|
||||
type Inner = u8;
|
||||
@@ -52,6 +59,13 @@ impl ColorType for RGB32 {
|
||||
const BITS_PER_SAMPLE: &'static [u16] = &[32, 32, 32];
|
||||
}
|
||||
|
||||
pub struct RGB64;
|
||||
impl ColorType for RGB64 {
|
||||
type Inner = u64;
|
||||
const TIFF_VALUE: PhotometricInterpretation = PhotometricInterpretation::RGB;
|
||||
const BITS_PER_SAMPLE: &'static [u16] = &[64, 64, 64];
|
||||
}
|
||||
|
||||
pub struct RGBA8;
|
||||
impl ColorType for RGBA8 {
|
||||
type Inner = u8;
|
||||
@@ -73,6 +87,13 @@ impl ColorType for RGBA32 {
|
||||
const BITS_PER_SAMPLE: &'static [u16] = &[32, 32, 32, 32];
|
||||
}
|
||||
|
||||
pub struct RGBA64;
|
||||
impl ColorType for RGBA64 {
|
||||
type Inner = u16;
|
||||
const TIFF_VALUE: PhotometricInterpretation = PhotometricInterpretation::RGB;
|
||||
const BITS_PER_SAMPLE: &'static [u16] = &[64, 64, 64, 64];
|
||||
}
|
||||
|
||||
pub struct CMYK8;
|
||||
impl ColorType for CMYK8 {
|
||||
type Inner = u8;
|
||||
|
||||
@@ -142,6 +142,23 @@ impl TiffValue for [i32] {
|
||||
}
|
||||
}
|
||||
|
||||
impl TiffValue for [u64] {
|
||||
const BYTE_LEN: u32 = 8;
|
||||
const FIELD_TYPE: ifd::Type = ifd::Type::LONG8;
|
||||
|
||||
fn count(&self) -> u32 {
|
||||
self.len() as u32
|
||||
}
|
||||
|
||||
fn write<W: Write>(&self, writer: &mut TiffWriter<W>) -> TiffResult<()> {
|
||||
// We write using nativeedian so this sould be safe
|
||||
let slice =
|
||||
unsafe { ::std::slice::from_raw_parts(self.as_ptr() as *const u8, self.len() * 8) };
|
||||
writer.write_bytes(slice)?;
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
impl TiffValue for [Rational] {
|
||||
const BYTE_LEN: u32 = 8;
|
||||
const FIELD_TYPE: ifd::Type = ifd::Type::RATIONAL;
|
||||
@@ -258,6 +275,20 @@ impl TiffValue for i32 {
|
||||
}
|
||||
}
|
||||
|
||||
impl TiffValue for u64 {
|
||||
const BYTE_LEN: u32 = 8;
|
||||
const FIELD_TYPE: ifd::Type = ifd::Type::LONG8;
|
||||
|
||||
fn count(&self) -> u32 {
|
||||
1
|
||||
}
|
||||
|
||||
fn write<W: Write>(&self, writer: &mut TiffWriter<W>) -> TiffResult<()> {
|
||||
writer.write_u64(*self)?;
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
impl TiffValue for Rational {
|
||||
const BYTE_LEN: u32 = 8;
|
||||
const FIELD_TYPE: ifd::Type = ifd::Type::RATIONAL;
|
||||
|
||||
@@ -238,6 +238,67 @@ fn test_rgb_u32_roundtrip() {
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_gray_u64_roundtrip() {
|
||||
let img_file =
|
||||
File::open("./tests/images/gradient-1c-64b.tiff").expect("Cannot find test image!");
|
||||
let mut decoder = Decoder::new(img_file).expect("Cannot create decoder");
|
||||
assert_eq!(decoder.colortype().unwrap(), ColorType::Gray(64));
|
||||
|
||||
let image_data = match decoder.read_image().unwrap() {
|
||||
DecodingResult::U64(res) => res,
|
||||
_ => panic!("Wrong data type"),
|
||||
};
|
||||
|
||||
let mut file = tempfile::tempfile().unwrap();
|
||||
{
|
||||
let mut tiff = TiffEncoder::new(&mut file).unwrap();
|
||||
|
||||
let (width, height) = decoder.dimensions().unwrap();
|
||||
tiff.write_image::<colortype::Gray64>(width, height, &image_data)
|
||||
.unwrap();
|
||||
}
|
||||
file.seek(SeekFrom::Start(0)).unwrap();
|
||||
{
|
||||
let mut decoder = Decoder::new(&mut file).unwrap();
|
||||
if let DecodingResult::U64(img_res) = decoder.read_image().unwrap() {
|
||||
assert_eq!(image_data, img_res);
|
||||
} else {
|
||||
panic!("Wrong data type");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_rgb_u64_roundtrip() {
|
||||
let img_file = File::open("./tests/images/gradient-3c-64b.tiff").expect("Cannot find test image!");
|
||||
let mut decoder = Decoder::new(img_file).expect("Cannot create decoder");
|
||||
assert_eq!(decoder.colortype().unwrap(), ColorType::RGB(64));
|
||||
|
||||
let image_data = match decoder.read_image().unwrap() {
|
||||
DecodingResult::U64(res) => res,
|
||||
_ => panic!("Wrong data type"),
|
||||
};
|
||||
|
||||
let mut file = tempfile::tempfile().unwrap();
|
||||
{
|
||||
let mut tiff = TiffEncoder::new(&mut file).unwrap();
|
||||
|
||||
let (width, height) = decoder.dimensions().unwrap();
|
||||
tiff.write_image::<colortype::RGB64>(width, height, &image_data)
|
||||
.unwrap();
|
||||
}
|
||||
file.seek(SeekFrom::Start(0)).unwrap();
|
||||
{
|
||||
let mut decoder = Decoder::new(&mut file).unwrap();
|
||||
if let DecodingResult::U64(img_res) = decoder.read_image().unwrap() {
|
||||
assert_eq!(image_data, img_res);
|
||||
} else {
|
||||
panic!("Wrong data type");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_multiple_byte() {
|
||||
let mut data = Cursor::new(Vec::new());
|
||||
|
||||
Reference in new issue
Block a user