Add the 2nd member to Value::Undefined to keep the offset of the value.

This commit is contained in:
KAMADA Ken'ichi 2017-08-04 21:15:19 +09:00
parent eba51f05c7
commit 078bfcdc78
6 changed files with 27 additions and 18 deletions

View File

@ -48,6 +48,7 @@
//! Major changes between 0.2.3 and 0.3 are listed below.
//!
//! * Enum Error has two new variants: TooBig and NotSupported.
//! * Value::Undefined has the 2nd member to keep the offset of the value.
pub use error::Error;
pub use jpeg::get_exif_attr as get_exif_attr_from_jpeg;

View File

@ -186,6 +186,6 @@ mod tests {
let file = File::open("tests/exif.jpg").unwrap();
let reader = Reader::new(&mut BufReader::new(&file)).unwrap();
assert_pat!(reader.get_field(tag::ExifVersion, false).unwrap().value,
Value::Undefined(b"0230"));
Value::Undefined(b"0230", _));
}
}

View File

@ -670,7 +670,7 @@ fn d_sensitivitytype(w: &mut fmt::Write, value: &Value) -> fmt::Result {
// ExifVersion (Exif 0x9000), FlashpixVersion (Exif 0xa000)
fn d_exifver(w: &mut fmt::Write, value: &Value) -> fmt::Result {
if let Value::Undefined(u) = *value {
if let Value::Undefined(u, _) = *value {
if u.len() == 4 {
if let Ok(major) = atou16(&u[0..2]) {
if let Ok(minor) = atou16(&u[2..4]) {
@ -688,7 +688,7 @@ fn d_exifver(w: &mut fmt::Write, value: &Value) -> fmt::Result {
// ComponentsConfiguration (Exif 0x9101)
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 {
try!(match x {
0 => w.write_char('_'),
@ -859,7 +859,7 @@ fn d_sensingmethod(w: &mut fmt::Write, value: &Value) -> fmt::Result {
// FileSource (Exif 0xa300)
fn d_filesrc(w: &mut fmt::Write, value: &Value) -> fmt::Result {
let s = match match *value {
Value::Undefined(s) => s.first().map(|&x| x),
Value::Undefined(s, _) => s.first().map(|&x| x),
_ => None,
} {
Some(0) => "others",
@ -874,7 +874,7 @@ fn d_filesrc(w: &mut fmt::Write, value: &Value) -> fmt::Result {
// SceneType (Exif 0xa301)
fn d_scenetype(w: &mut fmt::Write, value: &Value) -> fmt::Result {
let s = match match *value {
Value::Undefined(s) => s.first().map(|&x| x),
Value::Undefined(s, _) => s.first().map(|&x| x),
_ => None,
} {
Some(1) => "directly photographed image",
@ -1168,7 +1168,7 @@ fn d_gpsdifferential(w: &mut fmt::Write, value: &Value) -> fmt::Result {
fn d_ascii_in_undef(w: &mut fmt::Write, value: &Value) -> fmt::Result {
match *value {
Value::Undefined(s) => d_sub_ascii(w, s),
Value::Undefined(s, _) => d_sub_ascii(w, s),
_ => d_default(w, value),
}
}
@ -1205,7 +1205,7 @@ fn d_default(w: &mut fmt::Write, value: &Value) -> fmt::Result {
Value::Long(ref v) => d_sub_comma(w, v),
Value::Rational(ref v) => d_sub_comma(w, v),
Value::SByte(ref v) => d_sub_comma(w, v),
Value::Undefined(ref s) => d_sub_hex(w, s),
Value::Undefined(ref s, _) => d_sub_hex(w, s),
Value::SShort(ref v) => d_sub_comma(w, v),
Value::SLong(ref v) => d_sub_comma(w, v),
Value::SRational(ref v) => d_sub_comma(w, v),
@ -1304,7 +1304,7 @@ mod tests {
_ => panic!(),
}
match tag::FileSource.default_value() {
Some(Value::Undefined(v)) => assert_eq!(v, &[3]),
Some(Value::Undefined(v, _)) => assert_eq!(v, &[3]),
_ => panic!(),
}
match tag::GPSAltitudeRef.default_value() {

View File

@ -48,7 +48,12 @@ pub enum Value<'a> {
/// Vector of 8-bit signed integers. Unused in the Exif specification.
SByte(Vec<i8>),
/// Slice of 8-bit bytes.
Undefined(&'a [u8]),
///
/// The second member keeps the offset of the value in the Exif data.
/// The interpretation of the value does not generally depend on
/// the location, but if it does, the offset information helps.
/// When encoding Exif, it is ignored.
Undefined(&'a [u8], u32),
/// Vector of 16-bit signed integers. Unused in the Exif specification.
SShort(Vec<i16>),
/// Vector of 32-bit signed integers.
@ -77,7 +82,7 @@ impl<'a> Value<'a> {
///
/// ```
/// use exif::{Value, tag};
/// let val = Value::Undefined(b"0231");
/// let val = Value::Undefined(b"0231", 0);
/// assert_eq!(format!("{}", val.display_as(tag::ExifVersion)),
/// "2.31");
/// let val = Value::Short(vec![2]);
@ -177,7 +182,7 @@ impl<'a> From<&'a DefaultValue> for Option<Value<'a>> {
DefaultValue::Short(s) => Some(Value::Short(s.to_vec())),
DefaultValue::Rational(s) => Some(Value::Rational(
s.iter().map(|&t| tuple2rational(t)).collect())),
DefaultValue::Undefined(s) => Some(Value::Undefined(s)),
DefaultValue::Undefined(s) => Some(Value::Undefined(s, 0)),
DefaultValue::ContextDependent => None,
DefaultValue::Unspecified => None,
}
@ -361,7 +366,7 @@ fn parse_sbyte<'a>(data: &'a [u8], offset: usize, count: usize)
fn parse_undefined<'a>(data: &'a [u8], offset: usize, count: usize)
-> Value<'a> {
Value::Undefined(&data[offset .. offset + count])
Value::Undefined(&data[offset .. offset + count], offset as u32)
}
fn parse_sshort<'a, E>(data: &'a [u8], offset: usize, count: usize)
@ -546,7 +551,10 @@ mod tests {
for &(data, ans) in sets {
assert!((data.len() - 1) % unitlen == 0);
match parser(data, 1, (data.len() - 1) / unitlen) {
Value::Undefined(v) => assert_eq!(v, ans),
Value::Undefined(v, o) => {
assert_eq!(v, ans);
assert_eq!(o, 1);
},
v => panic!("wrong variant {:?}", v),
}
}

View File

@ -509,7 +509,7 @@ fn compose_value<E>(value: &Value)
vec.as_ptr() as *const u8, vec.len()) };
Ok((6, vec.len(), uslice.to_vec()))
},
Value::Undefined(ref s) =>
Value::Undefined(ref s, _) =>
Ok((7, s.len(), s.to_vec())),
Value::SShort(ref vec) => {
let mut buf = Vec::new();
@ -614,7 +614,7 @@ mod tests {
let exif_ver = Field {
tag: tag::ExifVersion,
thumbnail: false,
value: Value::Undefined(b"0231"),
value: Value::Undefined(b"0231", 0),
};
let mut writer = Writer::new();
let mut buf = Cursor::new(Vec::new());
@ -692,7 +692,7 @@ mod tests {
let exif_ver = Field {
tag: tag::ExifVersion,
thumbnail: false,
value: Value::Undefined(b"0231"),
value: Value::Undefined(b"0231", 0),
};
let gps_ver = Field {
tag: tag::GPSVersionID,
@ -772,7 +772,7 @@ mod tests {
(Value::SByte(vec![-2, -128]),
(6, 2, b"\xfe\x80".to_vec()),
(6, 2, b"\xfe\x80".to_vec())),
(Value::Undefined(b"abc"),
(Value::Undefined(b"abc", 0),
(7, 3, b"abc".to_vec()),
(7, 3, b"abc".to_vec())),
(Value::SShort(vec![-2, -0x8000]),

View File

@ -155,7 +155,7 @@ fn compare_field_value(value1: &Value, value2: &Value) {
},
(&Value::SByte(ref v1), &Value::SByte(ref v2)) =>
assert_eq!(v1, v2),
(&Value::Undefined(ref v1), &Value::Undefined(ref v2)) =>
(&Value::Undefined(ref v1, _), &Value::Undefined(ref v2, _)) =>
assert_eq!(v1, v2),
(&Value::SShort(ref v1), &Value::SShort(ref v2)) =>
assert_eq!(v1, v2),