Fix string encoding and clean up

This commit is contained in:
Birk Tjelmeland committed 2019-02-26 11:09:54 +01:00
1 parent addfaa5692
commit 098b799a62
3 files changed
+36 -35

No files matched your search

+8 -22
View File
@@ -7,68 +7,54 @@ pub trait ColorType {
/// The value of the tiff tag `PhotometricInterpretation`
const TIFF_VALUE: PhotometricInterpretation;
/// The value of the tiff tag `BitsPerSample`
fn bits_per_sample() -> Vec<u16>;
const BITS_PER_SAMPLE: &'static [u16];
}
pub struct Gray8;
impl ColorType for Gray8 {
type Inner = u8;
const TIFF_VALUE: PhotometricInterpretation = PhotometricInterpretation::BlackIsZero;
fn bits_per_sample() -> Vec<u16> {
vec![8]
}
const BITS_PER_SAMPLE: &'static [u16] = &[8];
}
pub struct Gray16;
impl ColorType for Gray16 {
type Inner = u16;
const TIFF_VALUE: PhotometricInterpretation = PhotometricInterpretation::BlackIsZero;
fn bits_per_sample() -> Vec<u16> {
vec![16]
}
const BITS_PER_SAMPLE: &'static [u16] = &[16];
}
pub struct RGB8;
impl ColorType for RGB8 {
type Inner = u8;
const TIFF_VALUE: PhotometricInterpretation = PhotometricInterpretation::RGB;
fn bits_per_sample() -> Vec<u16> {
vec![8,8,8]
}
const BITS_PER_SAMPLE: &'static [u16] = &[8, 8, 8];
}
pub struct RGB16;
impl ColorType for RGB16 {
type Inner = u16;
const TIFF_VALUE: PhotometricInterpretation = PhotometricInterpretation::RGB;
fn bits_per_sample() -> Vec<u16> {
vec![16,16,16]
}
const BITS_PER_SAMPLE: &'static [u16] = &[16, 16, 16];
}
pub struct RGBA8;
impl ColorType for RGBA8 {
type Inner = u8;
const TIFF_VALUE: PhotometricInterpretation = PhotometricInterpretation::RGB;
fn bits_per_sample() -> Vec<u16> {
vec![8,8,8,8]
}
const BITS_PER_SAMPLE: &'static [u16] = &[8, 8, 8, 8];
}
pub struct RGBA16;
impl ColorType for RGBA16 {
type Inner = u16;
const TIFF_VALUE: PhotometricInterpretation = PhotometricInterpretation::RGB;
fn bits_per_sample() -> Vec<u16> {
vec![16,16,16,16]
}
const BITS_PER_SAMPLE: &'static [u16] = &[16, 16, 16, 16];
}
pub struct CMYK8;
impl ColorType for CMYK8 {
type Inner = u8;
const TIFF_VALUE: PhotometricInterpretation = PhotometricInterpretation::CMYK;
fn bits_per_sample() -> Vec<u16> {
vec![8,8,8,8]
}
const BITS_PER_SAMPLE: &'static [u16] = &[8, 8, 8, 8];
}
+24 -11
View File
@@ -36,7 +36,7 @@ pub trait TiffValue {
fn write<W: Write>(&self, writer: &mut TiffWriter<W>) -> TiffResult<()>;
}
impl TiffValue for &[u8] {
impl TiffValue for [u8] {
const BYTE_LEN: u32 = 1;
const FIELD_TYPE: ifd::Type = ifd::Type::BYTE;
@@ -50,7 +50,7 @@ impl TiffValue for &[u8] {
}
}
impl TiffValue for &[u16] {
impl TiffValue for [u16] {
const BYTE_LEN: u32 = 2;
const FIELD_TYPE: ifd::Type = ifd::Type::SHORT;
@@ -68,7 +68,7 @@ impl TiffValue for &[u16] {
}
}
impl TiffValue for &[u32] {
impl TiffValue for [u32] {
const BYTE_LEN: u32 = 4;
const FIELD_TYPE: ifd::Type = ifd::Type::LONG;
@@ -86,7 +86,7 @@ impl TiffValue for &[u32] {
}
}
impl TiffValue for &[Rational] {
impl TiffValue for [Rational] {
const BYTE_LEN: u32 = 8;
const FIELD_TYPE: ifd::Type = ifd::Type::RATIONAL;
@@ -95,7 +95,7 @@ impl TiffValue for &[Rational] {
}
fn write<W: Write>(&self, writer: &mut TiffWriter<W>) -> TiffResult<()> {
for x in *self {
for x in self {
x.write(writer)?;
}
Ok(())
@@ -168,7 +168,7 @@ impl TiffValue for str {
}
fn write<W: Write>(&self, writer: &mut TiffWriter<W>) -> TiffResult<()> {
if self.is_ascii() {
if self.is_ascii() && !self.bytes().any(|b| b == 0) {
writer.write_bytes(self.as_bytes())?;
writer.write_u8(0)?;
Ok(())
@@ -179,6 +179,19 @@ impl TiffValue for str {
}
}
impl<'a, T: TiffValue + ?Sized> TiffValue for &'a T {
const BYTE_LEN: u32 = T::BYTE_LEN;
const FIELD_TYPE: ifd::Type = T::FIELD_TYPE;
fn count(&self) -> u32 {
(*self).count()
}
fn write<W: Write>(&self, writer: &mut TiffWriter<W>) -> TiffResult<()> {
(*self).write(writer)
}
}
/// Tiff encoder.
///
/// With this type you can get a `DirectoryEncoder` or a `ImageEncoder`
@@ -224,7 +237,7 @@ impl<W: Write + Seek> TiffEncoder<W> {
}
/// Convenience function to write an entire image from memory.
pub fn write_image<'a, C: ColorType>(&mut self, width: u32, height: u32, data: &'a [C::Inner]) -> TiffResult<()> where &'a [C::Inner]: TiffValue {
pub fn write_image<C: ColorType>(&mut self, width: u32, height: u32, data: &[C::Inner]) -> TiffResult<()> where [C::Inner]: TiffValue {
let encoder = DirectoryEncoder::new(&mut self.writer)?;
let mut image: ImageEncoder<W, C> = ImageEncoder::new(encoder, width, height).unwrap();
@@ -381,7 +394,7 @@ pub struct ImageEncoder<'a, W: Write + Seek, C: ColorType> {
impl<'a, W: Write + Seek, T: ColorType> ImageEncoder<'a, W, T> {
fn new(mut encoder: DirectoryEncoder<'a, W>, width: u32, height: u32) -> TiffResult<ImageEncoder<'a, W, T>> {
let row_samples = u64::from(width) * <T>::bits_per_sample().len() as u64;
let row_samples = u64::from(width) * <T>::BITS_PER_SAMPLE.len() as u64;
let row_bytes = row_samples * u64::from(<T::Inner>::BYTE_LEN);
// As per tiff spec each strip should be about 8k long
@@ -393,12 +406,12 @@ impl<'a, W: Write + Seek, T: ColorType> ImageEncoder<'a, W, T> {
encoder.write_tag(Tag::ImageLength, height);
encoder.write_tag(Tag::Compression, 1u16);
encoder.write_tag(Tag::BitsPerSample, &<T>::bits_per_sample() as &[u16]);
encoder.write_tag(Tag::BitsPerSample, <T>::BITS_PER_SAMPLE);
encoder.write_tag(Tag::PhotometricInterpretation, <T>::TIFF_VALUE as u16);
encoder.write_tag(Tag::RowsPerStrip, rows_per_strip as u32);
encoder.write_tag(Tag::SamplesPerPixel, <T>::bits_per_sample().len() as u16);
encoder.write_tag(Tag::SamplesPerPixel, <T>::BITS_PER_SAMPLE.len() as u16);
encoder.write_tag(Tag::XResolution, Rational {n: 1, d: 1});
encoder.write_tag(Tag::YResolution, Rational {n: 1, d: 1});
encoder.write_tag(Tag::ResolutionUnit, 1u16);
@@ -430,7 +443,7 @@ impl<'a, W: Write + Seek, T: ColorType> ImageEncoder<'a, W, T> {
}
/// Write a single strip.
pub fn write_strip<'b>(&mut self, value: &'b [T::Inner]) -> TiffResult<()> where &'b [T::Inner]: TiffValue {
pub fn write_strip(&mut self, value: &[T::Inner]) -> TiffResult<()> where [T::Inner]: TiffValue {
// TODO: Compression
let samples = self.next_strip_sample_count();
assert_eq!(value.len() as u64, samples);
+4 -2
View File
@@ -77,8 +77,10 @@ impl<W: Write> TiffWriter<W> {
}
pub fn pad_word_boundary(&mut self) -> Result<(), io::Error> {
while self.offset % 4 != 0 {
self.writer.write_u8(0)?;
if self.offset % 4 != 0 {
let padding = [0, 0, 0];
let padd_len = 4 - (self.offset % 4);
self.writer.write_all(&padding[..padd_len as usize])?;
}
Ok(())