Replace try!() with ?

This commit is contained in:
Kornel 2018-04-16 04:11:08 +01:00 committed by KAMADA Ken'ichi
parent c2912228c9
commit 9c45d1903a
7 changed files with 126 additions and 126 deletions

View File

@ -41,8 +41,8 @@ fn main() {
} }
fn dump_file(path: &Path) -> Result<(), exif::Error> { fn dump_file(path: &Path) -> Result<(), exif::Error> {
let file = try!(File::open(path)); let file = File::open(path)?;
let reader = try!(exif::Reader::new(&mut BufReader::new(&file))); let reader = exif::Reader::new(&mut BufReader::new(&file))?;
println!("{}", path.display()); println!("{}", path.display());
for f in reader.fields() { for f in reader.fields() {

View File

@ -64,18 +64,18 @@ pub fn get_exif_attr<R>(reader: &mut R)
fn get_exif_attr_sub<R>(reader: &mut R) fn get_exif_attr_sub<R>(reader: &mut R)
-> Result<Vec<u8>, Error> where R: io::BufRead { -> Result<Vec<u8>, Error> where R: io::BufRead {
let mut soi = [0u8; 2]; let mut soi = [0u8; 2];
try!(reader.read_exact(&mut soi)); reader.read_exact(&mut soi)?;
if soi != [marker::P, marker::SOI] { if soi != [marker::P, marker::SOI] {
return Err(Error::InvalidFormat("Not a JPEG file")); return Err(Error::InvalidFormat("Not a JPEG file"));
} }
loop { loop {
// Find a marker prefix. Discard non-ff bytes, which appear if // Find a marker prefix. Discard non-ff bytes, which appear if
// we are in the scan data after SOS or we are out of sync. // we are in the scan data after SOS or we are out of sync.
try!(reader.read_until(marker::P, &mut Vec::new())); reader.read_until(marker::P, &mut Vec::new())?;
// Get a marker code. // Get a marker code.
let mut code; let mut code;
loop { loop {
code = try!(read8(reader)); code = read8(reader)?;
if code != marker::P { break; } if code != marker::P { break; }
} }
// Continue or return early on stand-alone markers. // Continue or return early on stand-alone markers.
@ -86,12 +86,12 @@ fn get_exif_attr_sub<R>(reader: &mut R)
_ => {}, _ => {},
} }
// Read marker segments. // Read marker segments.
let seglen = try!(read16(reader)); let seglen = read16(reader)?;
if seglen < 2 { if seglen < 2 {
return Err(Error::InvalidFormat("Invalid segment length")); return Err(Error::InvalidFormat("Invalid segment length"));
} }
let mut seg = Vec::new(); let mut seg = Vec::new();
try!(reader.by_ref().take(seglen as u64 - 2).read_to_end(&mut seg)); reader.by_ref().take(seglen as u64 - 2).read_to_end(&mut seg)?;
if code == marker::APP1 && seg.starts_with(&EXIF_ID) { if code == marker::APP1 && seg.starts_with(&EXIF_ID) {
return Ok(seg.split_off(EXIF_ID.len())); return Ok(seg.split_off(EXIF_ID.len()));
} }

View File

@ -68,13 +68,13 @@ impl Reader {
-> Result<Reader, Error> where R: io::BufRead { -> Result<Reader, Error> where R: io::BufRead {
// Parse the data. // Parse the data.
let mut buf = Vec::new(); let mut buf = Vec::new();
try!(reader.by_ref().take(4).read_to_end(&mut buf)); reader.by_ref().take(4).read_to_end(&mut buf)?;
if jpeg::is_jpeg(&buf) { if jpeg::is_jpeg(&buf) {
let exif_buf = try!(jpeg::get_exif_attr( let exif_buf = jpeg::get_exif_attr(
&mut buf.as_mut_slice().chain(reader))); &mut buf.as_mut_slice().chain(reader))?;
buf = exif_buf; buf = exif_buf;
} else if tiff::is_tiff(&buf) { } else if tiff::is_tiff(&buf) {
try!(reader.read_to_end(&mut buf)); reader.read_to_end(&mut buf)?;
} else { } else {
return Err(Error::InvalidFormat("Unknown image format")); return Err(Error::InvalidFormat("Unknown image format"));
} }
@ -82,7 +82,7 @@ impl Reader {
// Cheat on the type system and erase the lifetime by transmute(). // Cheat on the type system and erase the lifetime by transmute().
// The scope releases the inner `v` to unborrow `buf`. // The scope releases the inner `v` to unborrow `buf`.
let (fields, le) = { let (fields, le) = {
let (v, le) = try!(tiff::parse_exif(&buf)); let (v, le) = tiff::parse_exif(&buf)?;
(unsafe { mem::transmute::<Vec<Field>, Vec<Field>>(v) }, le) }; (unsafe { mem::transmute::<Vec<Field>, Vec<Field>>(v) }, le) };
// Initialize the HashMap of all fields. // Initialize the HashMap of all fields.

View File

@ -652,7 +652,7 @@ fn d_exptime(w: &mut fmt::Write, value: &Value) -> fmt::Result {
// FNumber (Exif 0x829d) // FNumber (Exif 0x829d)
fn d_fnumber(w: &mut fmt::Write, value: &Value) -> fmt::Result { fn d_fnumber(w: &mut fmt::Write, value: &Value) -> fmt::Result {
try!(w.write_str("f/")); w.write_str("f/")?;
d_decimal(w, value) d_decimal(w, value)
} }
@ -709,7 +709,7 @@ fn d_exifver(w: &mut fmt::Write, value: &Value) -> fmt::Result {
fn d_cpntcfg(w: &mut fmt::Write, value: &Value) -> fmt::Result { fn d_cpntcfg(w: &mut fmt::Write, value: &Value) -> fmt::Result {
if let Value::Undefined(u, _) = *value { if let Value::Undefined(u, _) = *value {
for &x in u { for &x in u {
try!(match x { match x {
0 => w.write_char('_'), 0 => w.write_char('_'),
1 => w.write_char('Y'), 1 => w.write_char('Y'),
2 => w.write_str("Cb"), 2 => w.write_str("Cb"),
@ -718,7 +718,7 @@ fn d_cpntcfg(w: &mut fmt::Write, value: &Value) -> fmt::Result {
5 => w.write_char('G'), 5 => w.write_char('G'),
6 => w.write_char('B'), 6 => w.write_char('B'),
_ => w.write_char('?'), _ => w.write_char('?'),
}); }?;
} }
return Ok(()); return Ok(());
} }
@ -1202,7 +1202,7 @@ fn d_decimal(w: &mut fmt::Write, value: &Value) -> fmt::Result {
#[inline(never)] #[inline(never)]
fn d_unknown(w: &mut fmt::Write, value: &Value, prefix: &str) -> fmt::Result { fn d_unknown(w: &mut fmt::Write, value: &Value, prefix: &str) -> fmt::Result {
try!(w.write_str(prefix)); w.write_str(prefix)?;
d_default(w, value) d_default(w, value)
} }
@ -1213,10 +1213,10 @@ fn d_default(w: &mut fmt::Write, value: &Value) -> fmt::Result {
let mut first = true; let mut first = true;
for x in v { for x in v {
if !first { if !first {
try!(w.write_str(", ")); w.write_str(", ")?;
} }
first = false; first = false;
try!(d_sub_ascii(w, x)); d_sub_ascii(w, x)?;
} }
Ok(()) Ok(())
}, },
@ -1240,10 +1240,10 @@ fn d_sub_comma<T>(w: &mut fmt::Write, slice: &[T])
-> fmt::Result where T: fmt::Display { -> fmt::Result where T: fmt::Display {
let mut first = true; let mut first = true;
for x in slice { for x in slice {
try!(match first { match first {
true => write!(w, "{}", x), true => write!(w, "{}", x),
false => write!(w, ", {}", x), false => write!(w, ", {}", x),
}); }?;
first = false; first = false;
} }
Ok(()) Ok(())
@ -1254,33 +1254,33 @@ fn d_sub_comma_f64<T>(w: &mut fmt::Write, slice: &[T])
let mut first = true; let mut first = true;
for &x in slice { for &x in slice {
let x: f64 = x.into(); let x: f64 = x.into();
try!(match first { match first {
true => write!(w, "{}", x), true => write!(w, "{}", x),
false => write!(w, ", {}", x), false => write!(w, ", {}", x),
}); }?;
first = false; first = false;
} }
Ok(()) Ok(())
} }
fn d_sub_hex(w: &mut fmt::Write, bytes: &[u8]) -> fmt::Result { fn d_sub_hex(w: &mut fmt::Write, bytes: &[u8]) -> fmt::Result {
try!(w.write_str("0x")); w.write_str("0x")?;
for x in bytes { for x in bytes {
try!(write!(w, "{:02x}", x)); write!(w, "{:02x}", x)?;
} }
Ok(()) Ok(())
} }
fn d_sub_ascii(w: &mut fmt::Write, bytes: &[u8]) -> fmt::Result { fn d_sub_ascii(w: &mut fmt::Write, bytes: &[u8]) -> fmt::Result {
try!(w.write_char('"')); w.write_char('"')?;
for &c in bytes { for &c in bytes {
match c { match c {
b'\\' | b'"' => { b'\\' | b'"' => {
try!(w.write_char('\\')); w.write_char('\\')?;
try!(w.write_char(c as char)); w.write_char(c as char)?;
}, },
0x20...0x7e => try!(w.write_char(c as char)), 0x20...0x7e => w.write_char(c as char)?,
_ => try!(write!(w, "\\x{:02x}", c)), _ => write!(w, "\\x{:02x}", c)?,
} }
} }
w.write_char('"') w.write_char('"')

View File

@ -76,7 +76,7 @@ fn parse_exif_sub<E>(data: &[u8])
} }
let ifd_offset = E::loadu32(data, 4) as usize; let ifd_offset = E::loadu32(data, 4) as usize;
let mut fields = Vec::new(); let mut fields = Vec::new();
try!(parse_ifd::<E>(&mut fields, data, ifd_offset, Context::Tiff, false)); parse_ifd::<E>(&mut fields, data, ifd_offset, Context::Tiff, false)?;
Ok(fields) Ok(fields)
} }
@ -100,8 +100,8 @@ fn parse_ifd<'a, E>(fields: &mut Vec<Field<'a>>, data: &'a [u8],
let cnt = E::loadu32(data, offset + 2 + i * 12 + 4) as usize; let cnt = E::loadu32(data, offset + 2 + i * 12 + 4) as usize;
let valofs_at = offset + 2 + i * 12 + 8; let valofs_at = offset + 2 + i * 12 + 8;
let (unitlen, parser) = get_type_info::<E>(typ); let (unitlen, parser) = get_type_info::<E>(typ);
let vallen = try!(unitlen.checked_mul(cnt).ok_or( let vallen = unitlen.checked_mul(cnt).ok_or(
Error::InvalidFormat("Invalid entry count"))); Error::InvalidFormat("Invalid entry count"))?;
let val; let val;
if unitlen == 0 { if unitlen == 0 {
val = Value::Unknown(typ, cnt as u32, valofs_at as u32); val = Value::Unknown(typ, cnt as u32, valofs_at as u32);
@ -119,12 +119,12 @@ fn parse_ifd<'a, E>(fields: &mut Vec<Field<'a>>, data: &'a [u8],
// recursively defined. // recursively defined.
let tag = Tag(ctx, tag); let tag = Tag(ctx, tag);
match tag { match tag {
Tag::ExifIFDPointer => try!(parse_child_ifd::<E>( Tag::ExifIFDPointer => parse_child_ifd::<E>(
fields, data, &val, Context::Exif, thumbnail)), fields, data, &val, Context::Exif, thumbnail)?,
Tag::GPSInfoIFDPointer => try!(parse_child_ifd::<E>( Tag::GPSInfoIFDPointer => parse_child_ifd::<E>(
fields, data, &val, Context::Gps, thumbnail)), fields, data, &val, Context::Gps, thumbnail)?,
Tag::InteropIFDPointer => try!(parse_child_ifd::<E>( Tag::InteropIFDPointer => parse_child_ifd::<E>(
fields, data, &val, Context::Interop, thumbnail)), fields, data, &val, Context::Interop, thumbnail)?,
_ => fields.push(Field { tag: tag, thumbnail: thumbnail, _ => fields.push(Field { tag: tag, thumbnail: thumbnail,
value: val }), value: val }),
} }
@ -150,8 +150,8 @@ fn parse_child_ifd<'a, E>(fields: &mut Vec<Field<'a>>, data: &'a [u8],
// A pointer field has type == LONG and count == 1, so the // A pointer field has type == LONG and count == 1, so the
// value (IFD offset) must be embedded in the "value offset" // value (IFD offset) must be embedded in the "value offset"
// element of the field. // element of the field.
let ofs = try!(pointer.get_uint(0).ok_or( let ofs = pointer.get_uint(0).ok_or(
Error::InvalidFormat("Invalid pointer"))) as usize; Error::InvalidFormat("Invalid pointer"))? as usize;
parse_ifd::<E>(fields, data, ofs, ctx, thumbnail) parse_ifd::<E>(fields, data, ofs, ctx, thumbnail)
} }
@ -198,12 +198,12 @@ impl DateTime {
return Err(Error::InvalidFormat("Invalid DateTime delimiter")); return Err(Error::InvalidFormat("Invalid DateTime delimiter"));
} }
Ok(DateTime { Ok(DateTime {
year: try!(atou16(&data[0..4])), year: atou16(&data[0..4])?,
month: try!(atou16(&data[5..7])) as u8, month: atou16(&data[5..7])? as u8,
day: try!(atou16(&data[8..10])) as u8, day: atou16(&data[8..10])? as u8,
hour: try!(atou16(&data[11..13])) as u8, hour: atou16(&data[11..13])? as u8,
minute: try!(atou16(&data[14..16])) as u8, minute: atou16(&data[14..16])? as u8,
second: try!(atou16(&data[17..19])) as u8, second: atou16(&data[17..19])? as u8,
nanosecond: None, nanosecond: None,
offset: None, offset: None,
}) })
@ -217,7 +217,7 @@ impl DateTime {
if c == b' ' { if c == b' ' {
break; break;
} }
subsec = subsec * 10 + try!(ctou32(c)); subsec = subsec * 10 + ctou32(c)?;
ndigits += 1; ndigits += 1;
if ndigits >= 9 { if ndigits >= 9 {
break; break;
@ -243,8 +243,8 @@ impl DateTime {
} else if data[3] != b':' { } else if data[3] != b':' {
return Err(Error::InvalidFormat("Invalid OffsetTime delimiter")); return Err(Error::InvalidFormat("Invalid OffsetTime delimiter"));
} }
let hour = try!(atou16(&data[1..3])); let hour = atou16(&data[1..3])?;
let min = try!(atou16(&data[4..6])); let min = atou16(&data[4..6])?;
let offset = (hour * 60 + min) as i16; let offset = (hour * 60 + min) as i16;
self.offset = Some(match data[0] { self.offset = Some(match data[0] {
b'+' => offset, b'+' => offset,

View File

@ -40,7 +40,7 @@ pub fn read8<R>(reader: &mut R) -> Result<u8, io::Error> where R: io::Read {
pub fn read16<R>(reader: &mut R) -> Result<u16, io::Error> where R: io::Read { pub fn read16<R>(reader: &mut R) -> Result<u16, io::Error> where R: io::Read {
let mut buf: [u8; 2] = unsafe { ::std::mem::uninitialized() }; let mut buf: [u8; 2] = unsafe { ::std::mem::uninitialized() };
try!(reader.read_exact(&mut buf)); reader.read_exact(&mut buf)?;
Ok(((buf[0] as u16) << 8) + buf[1] as u16) Ok(((buf[0] as u16) << 8) + buf[1] as u16)
} }

View File

@ -182,11 +182,11 @@ impl<'a> Writer<'a> {
-> Result<(), Error> where W: Write + Seek { -> Result<(), Error> where W: Write + Seek {
// TIFF signature and the offset of the 0th IFD. // TIFF signature and the offset of the 0th IFD.
if little_endian { if little_endian {
try!(w.write_all(&TIFF_LE_SIG)); w.write_all(&TIFF_LE_SIG)?;
try!(LittleEndian::writeu32(w, 8)); LittleEndian::writeu32(w, 8)?;
} else { } else {
try!(w.write_all(&TIFF_BE_SIG)); w.write_all(&TIFF_BE_SIG)?;
try!(BigEndian::writeu32(w, 8)); BigEndian::writeu32(w, 8)?;
} }
// Write the primary image. // Write the primary image.
@ -204,7 +204,7 @@ impl<'a> Writer<'a> {
jpeg: None, jpeg: None,
}; };
let next_ifd_offset_offset = let next_ifd_offset_offset =
try!(synthesize_fields(w, ws, false, little_endian)); synthesize_fields(w, ws, false, little_endian)?;
// Do not output the thumbnail IFD if there are no data in it. // Do not output the thumbnail IFD if there are no data in it.
let thumbnail_absent = let thumbnail_absent =
@ -215,18 +215,18 @@ impl<'a> Writer<'a> {
self.tn_strips == None && self.tn_strips == None &&
self.tn_jpeg == None; self.tn_jpeg == None;
if thumbnail_absent { if thumbnail_absent {
try!(w.flush()); w.flush()?;
return Ok(()); return Ok(());
} }
let next_ifd_offset = try!(pad_and_get_offset(w)); let next_ifd_offset = pad_and_get_offset(w)?;
let origpos = try!(w.seek(SeekFrom::Current(0))); let origpos = w.seek(SeekFrom::Current(0))?;
try!(w.seek(SeekFrom::Start(next_ifd_offset_offset as u64))); w.seek(SeekFrom::Start(next_ifd_offset_offset as u64))?;
match little_endian { match little_endian {
false => try!(BigEndian::writeu32(w, next_ifd_offset)), false => BigEndian::writeu32(w, next_ifd_offset)?,
true => try!(LittleEndian::writeu32(w, next_ifd_offset)), true => LittleEndian::writeu32(w, next_ifd_offset)?,
} }
try!(w.seek(SeekFrom::Start(origpos))); w.seek(SeekFrom::Start(origpos))?;
// Write the thumbnail image. // Write the thumbnail image.
let ws = WriterState { let ws = WriterState {
@ -242,9 +242,9 @@ impl<'a> Writer<'a> {
tiles: None, tiles: None,
jpeg: self.tn_jpeg, jpeg: self.tn_jpeg,
}; };
try!(synthesize_fields(w, ws, true, little_endian)); synthesize_fields(w, ws, true, little_endian)?;
try!(w.flush()); w.flush()?;
Ok(()) Ok(())
} }
} }
@ -319,9 +319,9 @@ fn synthesize_fields<W>(w: &mut W, ws: WriterState, thumbnail: bool,
match gps_fields_len { 0 => 0, _ => 1 } + match gps_fields_len { 0 => 0, _ => 1 } +
match exif_fields_len { 0 => 0, _ => 1 }; match exif_fields_len { 0 => 0, _ => 1 };
ws.tiff_ifd_offset = try!(reserve_ifd(w, tiff_fields_len)); ws.tiff_ifd_offset = reserve_ifd(w, tiff_fields_len)?;
if exif_fields_len > 0 { if exif_fields_len > 0 {
ws.exif_ifd_offset = try!(reserve_ifd(w, exif_fields_len)); ws.exif_ifd_offset = reserve_ifd(w, exif_fields_len)?;
exif_in_tiff = Field { exif_in_tiff = Field {
tag: Tag::ExifIFDPointer, tag: Tag::ExifIFDPointer,
thumbnail: thumbnail, thumbnail: thumbnail,
@ -330,7 +330,7 @@ fn synthesize_fields<W>(w: &mut W, ws: WriterState, thumbnail: bool,
ws.tiff_fields.push(&exif_in_tiff); ws.tiff_fields.push(&exif_in_tiff);
} }
if gps_fields_len > 0 { if gps_fields_len > 0 {
ws.gps_ifd_offset = try!(reserve_ifd(w, gps_fields_len)); ws.gps_ifd_offset = reserve_ifd(w, gps_fields_len)?;
gps_in_tiff = Field { gps_in_tiff = Field {
tag: Tag::GPSInfoIFDPointer, tag: Tag::GPSInfoIFDPointer,
thumbnail: thumbnail, thumbnail: thumbnail,
@ -339,7 +339,7 @@ fn synthesize_fields<W>(w: &mut W, ws: WriterState, thumbnail: bool,
ws.tiff_fields.push(&gps_in_tiff); ws.tiff_fields.push(&gps_in_tiff);
} }
if interop_fields_len > 0 { if interop_fields_len > 0 {
ws.interop_ifd_offset = try!(reserve_ifd(w, interop_fields_len)); ws.interop_ifd_offset = reserve_ifd(w, interop_fields_len)?;
interop_in_exif = Field { interop_in_exif = Field {
tag: Tag::InteropIFDPointer, tag: Tag::InteropIFDPointer,
thumbnail: thumbnail, thumbnail: thumbnail,
@ -364,54 +364,54 @@ fn write_image<W, E>(w: &mut W, ws: WriterState)
-> Result<u32, Error> where W: Write + Seek, E: Endian { -> Result<u32, Error> where W: Write + Seek, E: Endian {
let (next_ifd_offset_offset, let (next_ifd_offset_offset,
strip_offsets_offset, tile_offsets_offset, jpeg_offset) = strip_offsets_offset, tile_offsets_offset, jpeg_offset) =
try!(write_ifd_and_fields::<_, E>( write_ifd_and_fields::<_, E>(
w, &ws.tiff_fields, ws.tiff_ifd_offset)); w, &ws.tiff_fields, ws.tiff_ifd_offset)?;
if ws.exif_fields.len() > 0 { if ws.exif_fields.len() > 0 {
try!(write_ifd_and_fields::<_, E>( write_ifd_and_fields::<_, E>(
w, &ws.exif_fields, ws.exif_ifd_offset)); w, &ws.exif_fields, ws.exif_ifd_offset)?;
} }
if ws.gps_fields.len() > 0 { if ws.gps_fields.len() > 0 {
try!(write_ifd_and_fields::<_, E>( write_ifd_and_fields::<_, E>(
w, &ws.gps_fields, ws.gps_ifd_offset)); w, &ws.gps_fields, ws.gps_ifd_offset)?;
} }
if ws.interop_fields.len() > 0 { if ws.interop_fields.len() > 0 {
try!(write_ifd_and_fields::<_, E>( write_ifd_and_fields::<_, E>(
w, &ws.interop_fields, ws.interop_ifd_offset)); w, &ws.interop_fields, ws.interop_ifd_offset)?;
} }
if let Some(strips) = ws.strips { if let Some(strips) = ws.strips {
let mut strip_offsets = Vec::new(); let mut strip_offsets = Vec::new();
for strip in strips { for strip in strips {
strip_offsets.push(try!(get_offset(w))); strip_offsets.push(get_offset(w)?);
try!(w.write_all(strip)); w.write_all(strip)?;
} }
let origpos = try!(w.seek(SeekFrom::Current(0))); let origpos = w.seek(SeekFrom::Current(0))?;
try!(w.seek(SeekFrom::Start(strip_offsets_offset as u64))); w.seek(SeekFrom::Start(strip_offsets_offset as u64))?;
for ofs in strip_offsets { for ofs in strip_offsets {
try!(E::writeu32(w, ofs)); E::writeu32(w, ofs)?;
} }
try!(w.seek(SeekFrom::Start(origpos))); w.seek(SeekFrom::Start(origpos))?;
} }
if let Some(tiles) = ws.tiles { if let Some(tiles) = ws.tiles {
let mut tile_offsets = Vec::new(); let mut tile_offsets = Vec::new();
for tile in tiles { for tile in tiles {
tile_offsets.push(try!(get_offset(w))); tile_offsets.push(get_offset(w)?);
try!(w.write_all(tile)); w.write_all(tile)?;
} }
let origpos = try!(w.seek(SeekFrom::Current(0))); let origpos = w.seek(SeekFrom::Current(0))?;
try!(w.seek(SeekFrom::Start(tile_offsets_offset as u64))); w.seek(SeekFrom::Start(tile_offsets_offset as u64))?;
for ofs in tile_offsets { for ofs in tile_offsets {
try!(E::writeu32(w, ofs)); E::writeu32(w, ofs)?;
} }
try!(w.seek(SeekFrom::Start(origpos))); w.seek(SeekFrom::Start(origpos))?;
} }
if let Some(jpeg) = ws.jpeg { if let Some(jpeg) = ws.jpeg {
let offset = try!(get_offset(w)); let offset = get_offset(w)?;
try!(w.write_all(jpeg)); w.write_all(jpeg)?;
let origpos = try!(w.seek(SeekFrom::Current(0))); let origpos = w.seek(SeekFrom::Current(0))?;
try!(w.seek(SeekFrom::Start(jpeg_offset as u64))); w.seek(SeekFrom::Start(jpeg_offset as u64))?;
try!(E::writeu32(w, offset)); E::writeu32(w, offset)?;
try!(w.seek(SeekFrom::Start(origpos))); w.seek(SeekFrom::Start(origpos))?;
} }
Ok(next_ifd_offset_offset) Ok(next_ifd_offset_offset)
@ -421,11 +421,11 @@ fn write_image<W, E>(w: &mut W, ws: WriterState)
// returns the offset of the IFD. // returns the offset of the IFD.
fn reserve_ifd<W>(w: &mut W, count: usize) fn reserve_ifd<W>(w: &mut W, count: usize)
-> Result<u32, Error> where W: Write + Seek { -> Result<u32, Error> where W: Write + Seek {
let ifdpos = try!(get_offset(w)); let ifdpos = get_offset(w)?;
assert!(ifdpos % 2 == 0); assert!(ifdpos % 2 == 0);
// The number of entries (2) + array of entries (12 * n) + // The number of entries (2) + array of entries (12 * n) +
// the next IFD pointer (4). // the next IFD pointer (4).
try!(w.seek(SeekFrom::Current(2 + count as i64 * 12 + 4))); w.seek(SeekFrom::Current(2 + count as i64 * 12 + 4))?;
Ok(ifdpos) Ok(ifdpos)
} }
@ -442,38 +442,38 @@ fn write_ifd_and_fields<W, E>(
let mut ifd = Vec::new(); let mut ifd = Vec::new();
// Write the number of entries. // Write the number of entries.
try!(E::writeu16(&mut ifd, fields.len() as u16)); E::writeu16(&mut ifd, fields.len() as u16)?;
// Write the fields. // Write the fields.
for f in fields { for f in fields {
let (typ, cnt, mut valbuf) = try!(compose_value::<E>(&f.value)); let (typ, cnt, mut valbuf) = compose_value::<E>(&f.value)?;
if cnt as u32 as usize != cnt { if cnt as u32 as usize != cnt {
return Err(Error::TooBig("Too long array")); return Err(Error::TooBig("Too long array"));
} }
try!(E::writeu16(&mut ifd, f.tag.number())); E::writeu16(&mut ifd, f.tag.number())?;
try!(E::writeu16(&mut ifd, typ)); E::writeu16(&mut ifd, typ)?;
try!(E::writeu32(&mut ifd, cnt as u32)); E::writeu32(&mut ifd, cnt as u32)?;
// Embed the value itself into the offset, or // Embed the value itself into the offset, or
// encode as an offset and the value. // encode as an offset and the value.
if valbuf.len() <= 4 { if valbuf.len() <= 4 {
valbuf.resize(4, 0); valbuf.resize(4, 0);
try!(ifd.write_all(&valbuf)); ifd.write_all(&valbuf)?;
} else { } else {
// The value must begin on a word boundary. [TIFF6, Section 2: // The value must begin on a word boundary. [TIFF6, Section 2:
// TIFF Structure, Image File Directory, IFD Entry, p. 15] // TIFF Structure, Image File Directory, IFD Entry, p. 15]
let valofs = try!(pad_and_get_offset(w)); let valofs = pad_and_get_offset(w)?;
try!(E::writeu32(&mut ifd, valofs)); E::writeu32(&mut ifd, valofs)?;
try!(w.write_all(&valbuf)); w.write_all(&valbuf)?;
} }
if f.tag == Tag::StripOffsets { if f.tag == Tag::StripOffsets {
strip_offsets_offset = match valbuf.len() { strip_offsets_offset = match valbuf.len() {
0...4 => ifd_offset + ifd.len() as u32 - 4, 0...4 => ifd_offset + ifd.len() as u32 - 4,
_ => try!(get_offset(w)) - valbuf.len() as u32, _ => get_offset(w)? - valbuf.len() as u32,
}; };
} }
if f.tag == Tag::TileOffsets { if f.tag == Tag::TileOffsets {
tile_offsets_offset = match valbuf.len() { tile_offsets_offset = match valbuf.len() {
0...4 => ifd_offset + ifd.len() as u32 - 4, 0...4 => ifd_offset + ifd.len() as u32 - 4,
_ => try!(get_offset(w)) - valbuf.len() as u32, _ => get_offset(w)? - valbuf.len() as u32,
}; };
} }
if f.tag == Tag::JPEGInterchangeFormat { if f.tag == Tag::JPEGInterchangeFormat {
@ -482,10 +482,10 @@ fn write_ifd_and_fields<W, E>(
} }
// Write the next IFD pointer. // Write the next IFD pointer.
let next_ifd_offset_offset = ifd_offset + ifd.len() as u32; let next_ifd_offset_offset = ifd_offset + ifd.len() as u32;
try!(E::writeu32(&mut ifd, 0)); E::writeu32(&mut ifd, 0)?;
// Write the IFD. // Write the IFD.
try!(write_at(w, &ifd, ifd_offset)); write_at(w, &ifd, ifd_offset)?;
Ok((next_ifd_offset_offset, Ok((next_ifd_offset_offset,
strip_offsets_offset, tile_offsets_offset, jpeg_offset)) strip_offsets_offset, tile_offsets_offset, jpeg_offset))
@ -508,22 +508,22 @@ fn compose_value<E>(value: &Value)
Value::Short(ref vec) => { Value::Short(ref vec) => {
let mut buf = Vec::new(); let mut buf = Vec::new();
for &v in vec { for &v in vec {
try!(E::writeu16(&mut buf, v)); E::writeu16(&mut buf, v)?;
} }
Ok((3, vec.len(), buf)) Ok((3, vec.len(), buf))
}, },
Value::Long(ref vec) => { Value::Long(ref vec) => {
let mut buf = Vec::new(); let mut buf = Vec::new();
for &v in vec { for &v in vec {
try!(E::writeu32(&mut buf, v)); E::writeu32(&mut buf, v)?;
} }
Ok((4, vec.len(), buf)) Ok((4, vec.len(), buf))
}, },
Value::Rational(ref vec) => { Value::Rational(ref vec) => {
let mut buf = Vec::new(); let mut buf = Vec::new();
for v in vec { for v in vec {
try!(E::writeu32(&mut buf, v.num)); E::writeu32(&mut buf, v.num)?;
try!(E::writeu32(&mut buf, v.denom)); E::writeu32(&mut buf, v.denom)?;
} }
Ok((5, vec.len(), buf)) Ok((5, vec.len(), buf))
}, },
@ -537,36 +537,36 @@ fn compose_value<E>(value: &Value)
Value::SShort(ref vec) => { Value::SShort(ref vec) => {
let mut buf = Vec::new(); let mut buf = Vec::new();
for &v in vec { for &v in vec {
try!(E::writeu16(&mut buf, v as u16)); E::writeu16(&mut buf, v as u16)?;
} }
Ok((8, vec.len(), buf)) Ok((8, vec.len(), buf))
}, },
Value::SLong(ref vec) => { Value::SLong(ref vec) => {
let mut buf = Vec::new(); let mut buf = Vec::new();
for &v in vec { for &v in vec {
try!(E::writeu32(&mut buf, v as u32)); E::writeu32(&mut buf, v as u32)?;
} }
Ok((9, vec.len(), buf)) Ok((9, vec.len(), buf))
}, },
Value::SRational(ref vec) => { Value::SRational(ref vec) => {
let mut buf = Vec::new(); let mut buf = Vec::new();
for v in vec { for v in vec {
try!(E::writeu32(&mut buf, v.num as u32)); E::writeu32(&mut buf, v.num as u32)?;
try!(E::writeu32(&mut buf, v.denom as u32)); E::writeu32(&mut buf, v.denom as u32)?;
} }
Ok((10, vec.len(), buf)) Ok((10, vec.len(), buf))
}, },
Value::Float(ref vec) => { Value::Float(ref vec) => {
let mut buf = Vec::new(); let mut buf = Vec::new();
for &v in vec { for &v in vec {
try!(E::writeu32(&mut buf, unsafe { mem::transmute(v) })); E::writeu32(&mut buf, unsafe { mem::transmute(v) })?;
} }
Ok((11, vec.len(), buf)) Ok((11, vec.len(), buf))
}, },
Value::Double(ref vec) => { Value::Double(ref vec) => {
let mut buf = Vec::new(); let mut buf = Vec::new();
for &v in vec { for &v in vec {
try!(E::writeu64(&mut buf, unsafe { mem::transmute(v) })); E::writeu64(&mut buf, unsafe { mem::transmute(v) })?;
} }
Ok((12, vec.len(), buf)) Ok((12, vec.len(), buf))
}, },
@ -577,22 +577,22 @@ fn compose_value<E>(value: &Value)
fn write_at<W>(w: &mut W, buf: &[u8], offset: u32) fn write_at<W>(w: &mut W, buf: &[u8], offset: u32)
-> io::Result<()> where W: Write + Seek { -> io::Result<()> where W: Write + Seek {
let orig = try!(w.seek(SeekFrom::Current(0))); let orig = w.seek(SeekFrom::Current(0))?;
try!(w.seek(SeekFrom::Start(offset as u64))); w.seek(SeekFrom::Start(offset as u64))?;
try!(w.write_all(buf)); w.write_all(buf)?;
try!(w.seek(SeekFrom::Start(orig))); w.seek(SeekFrom::Start(orig))?;
Ok(()) Ok(())
} }
// Aligns `w` to the two-byte (word) boundary and returns the new offset. // Aligns `w` to the two-byte (word) boundary and returns the new offset.
fn pad_and_get_offset<W>(w: &mut W) fn pad_and_get_offset<W>(w: &mut W)
-> Result<u32, Error> where W: Write + Seek { -> Result<u32, Error> where W: Write + Seek {
let mut pos = try!(w.seek(SeekFrom::Current(0))); let mut pos = w.seek(SeekFrom::Current(0))?;
if pos >= (1 << 32) - 1 { if pos >= (1 << 32) - 1 {
return Err(Error::TooBig("Offset too large")); return Err(Error::TooBig("Offset too large"));
} }
if pos % 2 != 0 { if pos % 2 != 0 {
try!(w.write_all(&[0])); w.write_all(&[0])?;
pos += 1; pos += 1;
} }
Ok(pos as u32) Ok(pos as u32)
@ -600,7 +600,7 @@ fn pad_and_get_offset<W>(w: &mut W)
fn get_offset<W>(w: &mut W) fn get_offset<W>(w: &mut W)
-> Result<u32, Error> where W: Write + Seek { -> Result<u32, Error> where W: Write + Seek {
let pos = try!(w.seek(SeekFrom::Current(0))); let pos = w.seek(SeekFrom::Current(0))?;
if pos as u32 as u64 != pos { if pos as u32 as u64 != pos {
return Err(Error::TooBig("Offset too large")); return Err(Error::TooBig("Offset too large"));
} }