Add the 2nd member to Value::Undefined to keep the offset of the value.
This commit is contained in:
parent
eba51f05c7
commit
078bfcdc78
|
@ -48,6 +48,7 @@
|
||||||
//! Major changes between 0.2.3 and 0.3 are listed below.
|
//! Major changes between 0.2.3 and 0.3 are listed below.
|
||||||
//!
|
//!
|
||||||
//! * Enum Error has two new variants: TooBig and NotSupported.
|
//! * 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 error::Error;
|
||||||
pub use jpeg::get_exif_attr as get_exif_attr_from_jpeg;
|
pub use jpeg::get_exif_attr as get_exif_attr_from_jpeg;
|
||||||
|
|
|
@ -186,6 +186,6 @@ mod tests {
|
||||||
let file = File::open("tests/exif.jpg").unwrap();
|
let file = File::open("tests/exif.jpg").unwrap();
|
||||||
let reader = Reader::new(&mut BufReader::new(&file)).unwrap();
|
let reader = Reader::new(&mut BufReader::new(&file)).unwrap();
|
||||||
assert_pat!(reader.get_field(tag::ExifVersion, false).unwrap().value,
|
assert_pat!(reader.get_field(tag::ExifVersion, false).unwrap().value,
|
||||||
Value::Undefined(b"0230"));
|
Value::Undefined(b"0230", _));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
14
src/tag.rs
14
src/tag.rs
|
@ -670,7 +670,7 @@ fn d_sensitivitytype(w: &mut fmt::Write, value: &Value) -> fmt::Result {
|
||||||
|
|
||||||
// ExifVersion (Exif 0x9000), FlashpixVersion (Exif 0xa000)
|
// ExifVersion (Exif 0x9000), FlashpixVersion (Exif 0xa000)
|
||||||
fn d_exifver(w: &mut fmt::Write, value: &Value) -> fmt::Result {
|
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 u.len() == 4 {
|
||||||
if let Ok(major) = atou16(&u[0..2]) {
|
if let Ok(major) = atou16(&u[0..2]) {
|
||||||
if let Ok(minor) = atou16(&u[2..4]) {
|
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)
|
// ComponentsConfiguration (Exif 0x9101)
|
||||||
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 {
|
try!(match x {
|
||||||
0 => w.write_char('_'),
|
0 => w.write_char('_'),
|
||||||
|
@ -859,7 +859,7 @@ fn d_sensingmethod(w: &mut fmt::Write, value: &Value) -> fmt::Result {
|
||||||
// FileSource (Exif 0xa300)
|
// FileSource (Exif 0xa300)
|
||||||
fn d_filesrc(w: &mut fmt::Write, value: &Value) -> fmt::Result {
|
fn d_filesrc(w: &mut fmt::Write, value: &Value) -> fmt::Result {
|
||||||
let s = match match *value {
|
let s = match match *value {
|
||||||
Value::Undefined(s) => s.first().map(|&x| x),
|
Value::Undefined(s, _) => s.first().map(|&x| x),
|
||||||
_ => None,
|
_ => None,
|
||||||
} {
|
} {
|
||||||
Some(0) => "others",
|
Some(0) => "others",
|
||||||
|
@ -874,7 +874,7 @@ fn d_filesrc(w: &mut fmt::Write, value: &Value) -> fmt::Result {
|
||||||
// SceneType (Exif 0xa301)
|
// SceneType (Exif 0xa301)
|
||||||
fn d_scenetype(w: &mut fmt::Write, value: &Value) -> fmt::Result {
|
fn d_scenetype(w: &mut fmt::Write, value: &Value) -> fmt::Result {
|
||||||
let s = match match *value {
|
let s = match match *value {
|
||||||
Value::Undefined(s) => s.first().map(|&x| x),
|
Value::Undefined(s, _) => s.first().map(|&x| x),
|
||||||
_ => None,
|
_ => None,
|
||||||
} {
|
} {
|
||||||
Some(1) => "directly photographed image",
|
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 {
|
fn d_ascii_in_undef(w: &mut fmt::Write, value: &Value) -> fmt::Result {
|
||||||
match *value {
|
match *value {
|
||||||
Value::Undefined(s) => d_sub_ascii(w, s),
|
Value::Undefined(s, _) => d_sub_ascii(w, s),
|
||||||
_ => d_default(w, value),
|
_ => 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::Long(ref v) => d_sub_comma(w, v),
|
||||||
Value::Rational(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::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::SShort(ref v) => d_sub_comma(w, v),
|
||||||
Value::SLong(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),
|
Value::SRational(ref v) => d_sub_comma(w, v),
|
||||||
|
@ -1304,7 +1304,7 @@ mod tests {
|
||||||
_ => panic!(),
|
_ => panic!(),
|
||||||
}
|
}
|
||||||
match tag::FileSource.default_value() {
|
match tag::FileSource.default_value() {
|
||||||
Some(Value::Undefined(v)) => assert_eq!(v, &[3]),
|
Some(Value::Undefined(v, _)) => assert_eq!(v, &[3]),
|
||||||
_ => panic!(),
|
_ => panic!(),
|
||||||
}
|
}
|
||||||
match tag::GPSAltitudeRef.default_value() {
|
match tag::GPSAltitudeRef.default_value() {
|
||||||
|
|
18
src/value.rs
18
src/value.rs
|
@ -48,7 +48,12 @@ pub enum Value<'a> {
|
||||||
/// Vector of 8-bit signed integers. Unused in the Exif specification.
|
/// Vector of 8-bit signed integers. Unused in the Exif specification.
|
||||||
SByte(Vec<i8>),
|
SByte(Vec<i8>),
|
||||||
/// Slice of 8-bit bytes.
|
/// 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.
|
/// Vector of 16-bit signed integers. Unused in the Exif specification.
|
||||||
SShort(Vec<i16>),
|
SShort(Vec<i16>),
|
||||||
/// Vector of 32-bit signed integers.
|
/// Vector of 32-bit signed integers.
|
||||||
|
@ -77,7 +82,7 @@ impl<'a> Value<'a> {
|
||||||
///
|
///
|
||||||
/// ```
|
/// ```
|
||||||
/// use exif::{Value, tag};
|
/// 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)),
|
/// assert_eq!(format!("{}", val.display_as(tag::ExifVersion)),
|
||||||
/// "2.31");
|
/// "2.31");
|
||||||
/// let val = Value::Short(vec![2]);
|
/// 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::Short(s) => Some(Value::Short(s.to_vec())),
|
||||||
DefaultValue::Rational(s) => Some(Value::Rational(
|
DefaultValue::Rational(s) => Some(Value::Rational(
|
||||||
s.iter().map(|&t| tuple2rational(t)).collect())),
|
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::ContextDependent => None,
|
||||||
DefaultValue::Unspecified => 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)
|
fn parse_undefined<'a>(data: &'a [u8], offset: usize, count: usize)
|
||||||
-> Value<'a> {
|
-> 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)
|
fn parse_sshort<'a, E>(data: &'a [u8], offset: usize, count: usize)
|
||||||
|
@ -546,7 +551,10 @@ mod tests {
|
||||||
for &(data, ans) in sets {
|
for &(data, ans) in sets {
|
||||||
assert!((data.len() - 1) % unitlen == 0);
|
assert!((data.len() - 1) % unitlen == 0);
|
||||||
match parser(data, 1, (data.len() - 1) / unitlen) {
|
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),
|
v => panic!("wrong variant {:?}", v),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -509,7 +509,7 @@ fn compose_value<E>(value: &Value)
|
||||||
vec.as_ptr() as *const u8, vec.len()) };
|
vec.as_ptr() as *const u8, vec.len()) };
|
||||||
Ok((6, vec.len(), uslice.to_vec()))
|
Ok((6, vec.len(), uslice.to_vec()))
|
||||||
},
|
},
|
||||||
Value::Undefined(ref s) =>
|
Value::Undefined(ref s, _) =>
|
||||||
Ok((7, s.len(), s.to_vec())),
|
Ok((7, s.len(), s.to_vec())),
|
||||||
Value::SShort(ref vec) => {
|
Value::SShort(ref vec) => {
|
||||||
let mut buf = Vec::new();
|
let mut buf = Vec::new();
|
||||||
|
@ -614,7 +614,7 @@ mod tests {
|
||||||
let exif_ver = Field {
|
let exif_ver = Field {
|
||||||
tag: tag::ExifVersion,
|
tag: tag::ExifVersion,
|
||||||
thumbnail: false,
|
thumbnail: false,
|
||||||
value: Value::Undefined(b"0231"),
|
value: Value::Undefined(b"0231", 0),
|
||||||
};
|
};
|
||||||
let mut writer = Writer::new();
|
let mut writer = Writer::new();
|
||||||
let mut buf = Cursor::new(Vec::new());
|
let mut buf = Cursor::new(Vec::new());
|
||||||
|
@ -692,7 +692,7 @@ mod tests {
|
||||||
let exif_ver = Field {
|
let exif_ver = Field {
|
||||||
tag: tag::ExifVersion,
|
tag: tag::ExifVersion,
|
||||||
thumbnail: false,
|
thumbnail: false,
|
||||||
value: Value::Undefined(b"0231"),
|
value: Value::Undefined(b"0231", 0),
|
||||||
};
|
};
|
||||||
let gps_ver = Field {
|
let gps_ver = Field {
|
||||||
tag: tag::GPSVersionID,
|
tag: tag::GPSVersionID,
|
||||||
|
@ -772,7 +772,7 @@ mod tests {
|
||||||
(Value::SByte(vec![-2, -128]),
|
(Value::SByte(vec![-2, -128]),
|
||||||
(6, 2, b"\xfe\x80".to_vec()),
|
(6, 2, b"\xfe\x80".to_vec()),
|
||||||
(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()),
|
||||||
(7, 3, b"abc".to_vec())),
|
(7, 3, b"abc".to_vec())),
|
||||||
(Value::SShort(vec![-2, -0x8000]),
|
(Value::SShort(vec![-2, -0x8000]),
|
||||||
|
|
|
@ -155,7 +155,7 @@ fn compare_field_value(value1: &Value, value2: &Value) {
|
||||||
},
|
},
|
||||||
(&Value::SByte(ref v1), &Value::SByte(ref v2)) =>
|
(&Value::SByte(ref v1), &Value::SByte(ref v2)) =>
|
||||||
assert_eq!(v1, 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),
|
assert_eq!(v1, v2),
|
||||||
(&Value::SShort(ref v1), &Value::SShort(ref v2)) =>
|
(&Value::SShort(ref v1), &Value::SShort(ref v2)) =>
|
||||||
assert_eq!(v1, v2),
|
assert_eq!(v1, v2),
|
||||||
|
|
Loading…
Reference in New Issue