Compare commits

..
4 Commits
Author SHA1 Message Date
HeroicKatora 1c2e57a22a Merge pull request #45 from image-rs/release-0.3.1
Bump version to 0.3.1
2019-05-26 03:23:55 +02:00
Andreas Molzer 2c7f329115 Bump version to 0.3.1
There are no function changes from 0.3 but the compiler requirements
have been lowered. This avoids having to make a decision on `image`
right now, which would delay valuable bug fixes and improvements.
2019-05-26 02:01:12 +02:00
HeroicKatora c9675360cf Merge pull request #44 from birktj/rustc-version
Change minimal rustc version to 1.24.1
2019-05-26 01:35:47 +02:00
Birk Tjelmeland 514b7cddaa Change minimal rustc version to 1.24.1 2019-05-03 23:12:29 +02:00
8 changed files with 49 additions and 40 deletions

No files matched your search

+4 -3
View File
@@ -1,5 +1,6 @@
language: rust language: rust
rust: rust:
- stable - 1.24.1
- beta - stable
- nightly - beta
- nightly
+1 -1
View File
@@ -1,6 +1,6 @@
[package] [package]
name = "tiff" name = "tiff"
version = "0.3.0" version = "0.3.1"
authors = [ authors = [
"ccgn", "ccgn",
"bvssvni <bvssvni@gmail.com>", "bvssvni <bvssvni@gmail.com>",
+6 -5
View File
@@ -2,6 +2,7 @@
use std::collections::HashMap; use std::collections::HashMap;
use std::io::{self, Read, Seek}; use std::io::{self, Read, Seek};
use std::mem;
use super::stream::{ByteOrder, EndianReader, SmartReader}; use super::stream::{ByteOrder, EndianReader, SmartReader};
use {TiffError, TiffFormatError, TiffResult, TiffUnsupportedError}; use {TiffError, TiffFormatError, TiffResult, TiffUnsupportedError};
@@ -27,9 +28,9 @@ macro_rules! tags {
} }
} }
pub fn to_u16(&self) -> u16 { pub fn to_u16(&self) -> u16 {
match self { match *self {
$( Tag::$tag => $val, )* $( Tag::$tag => $val, )*
Tag::Unknown(n) => *n, Tag::Unknown(n) => n,
} }
} }
} }
@@ -174,7 +175,7 @@ impl Entry {
])) ]))
} }
(Type::SHORT, n) => { (Type::SHORT, n) => {
if n as usize > limits.decoding_buffer_size / std::mem::size_of::<Value>() { if n as usize > limits.decoding_buffer_size / mem::size_of::<Value>() {
return Err(TiffError::LimitsExceeded); return Err(TiffError::LimitsExceeded);
} }
let mut v = Vec::with_capacity(n as usize); let mut v = Vec::with_capacity(n as usize);
@@ -186,7 +187,7 @@ impl Entry {
} }
(Type::LONG, 1) => Ok(Unsigned(try!(self.r(bo).read_u32()))), (Type::LONG, 1) => Ok(Unsigned(try!(self.r(bo).read_u32()))),
(Type::LONG, n) => { (Type::LONG, n) => {
if n as usize > limits.decoding_buffer_size / std::mem::size_of::<Value>() { if n as usize > limits.decoding_buffer_size / mem::size_of::<Value>() {
return Err(TiffError::LimitsExceeded); return Err(TiffError::LimitsExceeded);
} }
let mut v = Vec::with_capacity(n as usize); let mut v = Vec::with_capacity(n as usize);
@@ -203,7 +204,7 @@ impl Entry {
Ok(Rational(numerator, denominator)) Ok(Rational(numerator, denominator))
} }
(Type::RATIONAL, n) => { (Type::RATIONAL, n) => {
if n as usize > limits.decoding_buffer_size / std::mem::size_of::<Value>() { if n as usize > limits.decoding_buffer_size / mem::size_of::<Value>() {
return Err(TiffError::LimitsExceeded); return Err(TiffError::LimitsExceeded);
} }
let mut v = Vec::with_capacity(n as usize); let mut v = Vec::with_capacity(n as usize);
+7 -6
View File
@@ -1,6 +1,7 @@
use num_traits::{FromPrimitive, Num}; use num_traits::{FromPrimitive, Num};
use std::collections::HashMap; use std::collections::HashMap;
use std::io::{self, Read, Seek}; use std::io::{self, Read, Seek};
use std::cmp;
use {ColorType, TiffError, TiffFormatError, TiffResult, TiffUnsupportedError}; use {ColorType, TiffError, TiffFormatError, TiffResult, TiffUnsupportedError};
@@ -38,7 +39,7 @@ impl DecodingResult {
} }
pub fn as_buffer(&mut self, start: usize) -> DecodingBuffer { pub fn as_buffer(&mut self, start: usize) -> DecodingBuffer {
match self { match *self {
DecodingResult::U8(ref mut buf) => DecodingBuffer::U8(&mut buf[start..]), DecodingResult::U8(ref mut buf) => DecodingBuffer::U8(&mut buf[start..]),
DecodingResult::U16(ref mut buf) => DecodingBuffer::U16(&mut buf[start..]), DecodingResult::U16(ref mut buf) => DecodingBuffer::U16(&mut buf[start..]),
} }
@@ -55,14 +56,14 @@ pub enum DecodingBuffer<'a> {
impl<'a> DecodingBuffer<'a> { impl<'a> DecodingBuffer<'a> {
fn len(&self) -> usize { fn len(&self) -> usize {
match self { match *self {
DecodingBuffer::U8(ref buf) => buf.len(), DecodingBuffer::U8(ref buf) => buf.len(),
DecodingBuffer::U16(ref buf) => buf.len(), DecodingBuffer::U16(ref buf) => buf.len(),
} }
} }
fn byte_len(&self) -> usize { fn byte_len(&self) -> usize {
match self { match *self {
DecodingBuffer::U8(_) => 1, DecodingBuffer::U8(_) => 1,
DecodingBuffer::U16(_) => 2, DecodingBuffer::U16(_) => 2,
} }
@@ -72,7 +73,7 @@ impl<'a> DecodingBuffer<'a> {
where where
'a: 'b, 'a: 'b,
{ {
match self { match *self {
DecodingBuffer::U8(ref mut buf) => DecodingBuffer::U8(buf), DecodingBuffer::U8(ref mut buf) => DecodingBuffer::U8(buf),
DecodingBuffer::U16(ref mut buf) => DecodingBuffer::U16(buf), DecodingBuffer::U16(ref mut buf) => DecodingBuffer::U16(buf),
} }
@@ -661,7 +662,7 @@ impl<R: Read + Seek> Decoder<R> {
.get_tag_u32(ifd::Tag::RowsPerStrip) .get_tag_u32(ifd::Tag::RowsPerStrip)
.unwrap_or(self.height) as usize; .unwrap_or(self.height) as usize;
let strip_height = std::cmp::min( let strip_height = cmp::min(
rows_per_strip, rows_per_strip,
self.height as usize - index * rows_per_strip, self.height as usize - index * rows_per_strip,
); );
@@ -716,7 +717,7 @@ impl<R: Read + Seek> Decoder<R> {
.get_tag_u32(ifd::Tag::RowsPerStrip) .get_tag_u32(ifd::Tag::RowsPerStrip)
.unwrap_or(self.height) as usize; .unwrap_or(self.height) as usize;
let strip_height = std::cmp::min( let strip_height = cmp::min(
rows_per_strip, rows_per_strip,
self.height as usize - index * rows_per_strip, self.height as usize - index * rows_per_strip,
); );
+1 -1
View File
@@ -1,4 +1,4 @@
use crate::decoder::PhotometricInterpretation; use decoder::PhotometricInterpretation;
/// Trait for different colortypes that can be encoded. /// Trait for different colortypes that can be encoded.
pub trait ColorType { pub trait ColorType {
+26 -20
View File
@@ -2,8 +2,8 @@ use byteorder::NativeEndian;
use std::collections::BTreeMap; use std::collections::BTreeMap;
use std::io::{Seek, Write}; use std::io::{Seek, Write};
use crate::decoder::ifd::{self, Tag}; use decoder::ifd::{self, Tag};
use crate::error::{TiffError, TiffFormatError, TiffResult}; use error::{TiffError, TiffFormatError, TiffResult};
pub mod colortype; pub mod colortype;
mod writer; mod writer;
@@ -61,7 +61,7 @@ impl TiffValue for [u16] {
fn write<W: Write>(&self, writer: &mut TiffWriter<W>) -> TiffResult<()> { fn write<W: Write>(&self, writer: &mut TiffWriter<W>) -> TiffResult<()> {
// We write using nativeedian so this sould be safe // We write using nativeedian so this sould be safe
let slice = let slice =
unsafe { std::slice::from_raw_parts(self.as_ptr() as *const u8, self.len() * 2) }; unsafe { ::std::slice::from_raw_parts(self.as_ptr() as *const u8, self.len() * 2) };
writer.write_bytes(slice)?; writer.write_bytes(slice)?;
Ok(()) Ok(())
} }
@@ -78,7 +78,7 @@ impl TiffValue for [u32] {
fn write<W: Write>(&self, writer: &mut TiffWriter<W>) -> TiffResult<()> { fn write<W: Write>(&self, writer: &mut TiffWriter<W>) -> TiffResult<()> {
// We write using nativeedian so this sould be safe // We write using nativeedian so this sould be safe
let slice = let slice =
unsafe { std::slice::from_raw_parts(self.as_ptr() as *const u8, self.len() * 4) }; unsafe { ::std::slice::from_raw_parts(self.as_ptr() as *const u8, self.len() * 4) };
writer.write_bytes(slice)?; writer.write_bytes(slice)?;
Ok(()) Ok(())
} }
@@ -199,6 +199,8 @@ impl<'a, T: TiffValue + ?Sized> TiffValue for &'a T {
/// # Examples /// # Examples
/// ``` /// ```
/// # extern crate tempfile; /// # extern crate tempfile;
/// # extern crate tiff;
/// # fn main() {
/// # let mut file = tempfile::tempfile().unwrap(); /// # let mut file = tempfile::tempfile().unwrap();
/// # let image_data = vec![0; 100*100*3]; /// # let image_data = vec![0; 100*100*3];
/// use tiff::encoder::*; /// use tiff::encoder::*;
@@ -206,6 +208,7 @@ impl<'a, T: TiffValue + ?Sized> TiffValue for &'a T {
/// let mut tiff = TiffEncoder::new(&mut file).unwrap(); /// let mut tiff = TiffEncoder::new(&mut file).unwrap();
/// ///
/// tiff.write_image::<colortype::RGB8>(100, 100, &image_data).unwrap(); /// tiff.write_image::<colortype::RGB8>(100, 100, &image_data).unwrap();
/// # }
/// ``` /// ```
pub struct TiffEncoder<W> { pub struct TiffEncoder<W> {
writer: TiffWriter<W>, writer: TiffWriter<W>,
@@ -248,12 +251,12 @@ impl<W: Write + Seek> TiffEncoder<W> {
[C::Inner]: TiffValue, [C::Inner]: TiffValue,
{ {
let num_pix = (width as usize).checked_mul(height as usize) let num_pix = (width as usize).checked_mul(height as usize)
.ok_or_else(|| std::io::Error::new( .ok_or_else(|| ::std::io::Error::new(
std::io::ErrorKind::InvalidInput, ::std::io::ErrorKind::InvalidInput,
"Image width * height exceeds usize"))?; "Image width * height exceeds usize"))?;
if data.len() < num_pix { if data.len() < num_pix {
return Err(std::io::Error::new( return Err(::std::io::Error::new(
std::io::ErrorKind::InvalidData, ::std::io::ErrorKind::InvalidData,
"Input data slice is undersized for provided dimensions").into()); "Input data slice is undersized for provided dimensions").into());
} }
@@ -274,7 +277,7 @@ impl<W: Write + Seek> TiffEncoder<W> {
/// ///
/// You should call `finish` on this when you are finished with it. /// You should call `finish` on this when you are finished with it.
/// Encoding can silently fail while this is dropping. /// Encoding can silently fail while this is dropping.
pub struct DirectoryEncoder<'a, W: Write + Seek> { pub struct DirectoryEncoder<'a, W: 'a + Write + Seek> {
writer: &'a mut TiffWriter<W>, writer: &'a mut TiffWriter<W>,
dropped: bool, dropped: bool,
// We use BTreeMap to make sure tags are written in correct order // We use BTreeMap to make sure tags are written in correct order
@@ -282,7 +285,7 @@ pub struct DirectoryEncoder<'a, W: Write + Seek> {
ifd: BTreeMap<u16, (u16, u32, Vec<u8>)>, ifd: BTreeMap<u16, (u16, u32, Vec<u8>)>,
} }
impl<'a, W: Write + Seek> DirectoryEncoder<'a, W> { impl<'a, W: 'a + Write + Seek> DirectoryEncoder<'a, W> {
fn new(writer: &'a mut TiffWriter<W>) -> TiffResult<DirectoryEncoder<'a, W>> { fn new(writer: &'a mut TiffWriter<W>) -> TiffResult<DirectoryEncoder<'a, W>> {
writer.pad_word_boundary()?; writer.pad_word_boundary()?;
let ifd_pointer_pos = writer.offset(); let ifd_pointer_pos = writer.offset();
@@ -310,7 +313,7 @@ impl<'a, W: Write + Seek> DirectoryEncoder<'a, W> {
fn write_directory(&mut self) -> TiffResult<u64> { fn write_directory(&mut self) -> TiffResult<u64> {
// Start by writing out all values // Start by writing out all values
for (_, _, ref mut bytes) in self.ifd.values_mut() { for &mut (_, _, ref mut bytes) in self.ifd.values_mut() {
if bytes.len() > 4 { if bytes.len() > 4 {
let offset = self.writer.offset(); let offset = self.writer.offset();
self.writer.write_bytes(bytes)?; self.writer.write_bytes(bytes)?;
@@ -327,7 +330,7 @@ impl<'a, W: Write + Seek> DirectoryEncoder<'a, W> {
let offset = self.writer.offset(); let offset = self.writer.offset();
self.writer.write_u16(self.ifd.len() as u16)?; self.writer.write_u16(self.ifd.len() as u16)?;
for (tag, (field_type, count, offset)) in self.ifd.iter() { for (tag, &(ref field_type, ref count, ref offset)) in self.ifd.iter() {
self.writer.write_u16(*tag)?; self.writer.write_u16(*tag)?;
self.writer.write_u16(*field_type)?; self.writer.write_u16(*field_type)?;
self.writer.write_u32(*count)?; self.writer.write_u32(*count)?;
@@ -382,6 +385,8 @@ impl<'a, W: Write + Seek> Drop for DirectoryEncoder<'a, W> {
/// # Examples /// # Examples
/// ``` /// ```
/// # extern crate tempfile; /// # extern crate tempfile;
/// # extern crate tiff;
/// # fn main() {
/// # let mut file = tempfile::tempfile().unwrap(); /// # let mut file = tempfile::tempfile().unwrap();
/// # let image_data = vec![0; 100*100*3]; /// # let image_data = vec![0; 100*100*3];
/// use tiff::encoder::*; /// use tiff::encoder::*;
@@ -396,8 +401,9 @@ impl<'a, W: Write + Seek> Drop for DirectoryEncoder<'a, W> {
/// idx += sample_count; /// idx += sample_count;
/// } /// }
/// image.finish().unwrap(); /// image.finish().unwrap();
/// # }
/// ``` /// ```
pub struct ImageEncoder<'a, W: Write + Seek, C: ColorType> { pub struct ImageEncoder<'a, W: 'a + Write + Seek, C: ColorType> {
encoder: DirectoryEncoder<'a, W>, encoder: DirectoryEncoder<'a, W>,
strip_idx: u64, strip_idx: u64,
strip_count: u64, strip_count: u64,
@@ -407,10 +413,10 @@ pub struct ImageEncoder<'a, W: Write + Seek, C: ColorType> {
strip_offsets: Vec<u32>, strip_offsets: Vec<u32>,
strip_byte_count: Vec<u32>, strip_byte_count: Vec<u32>,
dropped: bool, dropped: bool,
_phantom: std::marker::PhantomData<C>, _phantom: ::std::marker::PhantomData<C>,
} }
impl<'a, W: Write + Seek, T: ColorType> ImageEncoder<'a, W, T> { impl<'a, W: 'a + Write + Seek, T: ColorType> ImageEncoder<'a, W, T> {
fn new( fn new(
mut encoder: DirectoryEncoder<'a, W>, mut encoder: DirectoryEncoder<'a, W>,
width: u32, width: u32,
@@ -448,7 +454,7 @@ impl<'a, W: Write + Seek, T: ColorType> ImageEncoder<'a, W, T> {
strip_offsets: Vec::new(), strip_offsets: Vec::new(),
strip_byte_count: Vec::new(), strip_byte_count: Vec::new(),
dropped: false, dropped: false,
_phantom: std::marker::PhantomData, _phantom: ::std::marker::PhantomData,
}) })
} }
@@ -458,8 +464,8 @@ impl<'a, W: Write + Seek, T: ColorType> ImageEncoder<'a, W, T> {
return 0; return 0;
} }
let start_row = std::cmp::min(u64::from(self.height), self.strip_idx * self.rows_per_strip); let start_row = ::std::cmp::min(u64::from(self.height), self.strip_idx * self.rows_per_strip);
let end_row = std::cmp::min( let end_row = ::std::cmp::min(
u64::from(self.height), u64::from(self.height),
(self.strip_idx + 1) * self.rows_per_strip, (self.strip_idx + 1) * self.rows_per_strip,
); );
@@ -475,8 +481,8 @@ impl<'a, W: Write + Seek, T: ColorType> ImageEncoder<'a, W, T> {
// TODO: Compression // TODO: Compression
let samples = self.next_strip_sample_count(); let samples = self.next_strip_sample_count();
if value.len() as u64 != samples { if value.len() as u64 != samples {
return Err(std::io::Error::new( return Err(::std::io::Error::new(
std::io::ErrorKind::InvalidData, ::std::io::ErrorKind::InvalidData,
"Slice is wrong size for strip").into()); "Slice is wrong size for strip").into());
} }
+1 -1
View File
@@ -1,4 +1,4 @@
use crate::error::TiffResult; use error::TiffResult;
use byteorder::{BigEndian, ByteOrder, LittleEndian, NativeEndian, WriteBytesExt}; use byteorder::{BigEndian, ByteOrder, LittleEndian, NativeEndian, WriteBytesExt};
use std::io::{self, Seek, SeekFrom, Write}; use std::io::{self, Seek, SeekFrom, Write};
+3 -3
View File
@@ -1,6 +1,6 @@
extern crate tiff; extern crate tiff;
use tiff::decoder::{ifd::Tag, ifd::Value, Decoder, DecodingResult}; use tiff::decoder::{ifd, Decoder, DecodingResult};
use tiff::ColorType; use tiff::ColorType;
use std::fs::File; use std::fs::File;
@@ -52,9 +52,9 @@ fn test_string_tags() {
let path = format!("./tests/images/{}", filename); let path = format!("./tests/images/{}", filename);
let img_file = File::open(path).expect("can't open file"); let img_file = File::open(path).expect("can't open file");
let mut decoder = Decoder::new(img_file).expect("Cannot create decoder"); let mut decoder = Decoder::new(img_file).expect("Cannot create decoder");
let software = decoder.get_tag(Tag::Software).unwrap(); let software = decoder.get_tag(ifd::Tag::Software).unwrap();
match software { match software {
Value::Ascii(s) => assert_eq!( ifd::Value::Ascii(s) => assert_eq!(
s, s,
String::from("GraphicsMagick 1.2 unreleased Q16 http://www.GraphicsMagick.org/") String::from("GraphicsMagick 1.2 unreleased Q16 http://www.GraphicsMagick.org/")
), ),