From 26a64361b39a6f79680d10d29aee3385ed2b1c43 Mon Sep 17 00:00:00 2001 From: KAMADA Ken'ichi Date: Thu, 12 Oct 2017 22:55:56 +0900 Subject: [PATCH] Add `Tag::TagName`s and deprecate `tag::TagName`s. --- examples/reading.rs | 18 +++++++------- src/lib.rs | 2 ++ src/reader.rs | 3 +-- src/tag.rs | 30 ++++++++++++++++------- src/tiff.rs | 7 +++--- src/value.rs | 6 ++--- src/writer.rs | 58 ++++++++++++++++++++++----------------------- tests/rwrcmp.rs | 18 +++++++------- 8 files changed, 77 insertions(+), 65 deletions(-) diff --git a/examples/reading.rs b/examples/reading.rs index f01ff13..65ab9b3 100644 --- a/examples/reading.rs +++ b/examples/reading.rs @@ -29,7 +29,7 @@ extern crate exif; use std::fs::File; use std::io::BufReader; -use exif::{DateTime, Reader, Value, tag}; +use exif::{DateTime, Reader, Value, Tag}; fn main() { let file = File::open("tests/exif.jpg").unwrap(); @@ -37,11 +37,11 @@ fn main() { // To obtain a string representation, `Value::display_as` can be used // for any tag. - let tag_list = [tag::ExifVersion, - tag::PixelXDimension, - tag::XResolution, - tag::ImageDescription, - tag::DateTime]; + let tag_list = [Tag::ExifVersion, + Tag::PixelXDimension, + Tag::XResolution, + Tag::ImageDescription, + Tag::DateTime]; for &tag in tag_list.iter() { if let Some(field) = reader.get_field(tag, false) { println!("{}: {}", field.tag, field.value.display_as(field.tag)); @@ -50,7 +50,7 @@ fn main() { // To get unsigned integer value(s) from either of BYTE, SHORT, // or LONG, `Value::get_uint` or `Value::iter_uint` can be used. - if let Some(field) = reader.get_field(tag::PixelXDimension, false) { + if let Some(field) = reader.get_field(Tag::PixelXDimension, false) { if let Some(width) = field.value.get_uint(0) { println!("Valid width of the image is {}.", width); } @@ -58,7 +58,7 @@ fn main() { // To convert a Rational or SRational to an f64, `Rational::to_f64` // or `SRational::to_f64` can be used. - if let Some(field) = reader.get_field(tag::XResolution, false) { + if let Some(field) = reader.get_field(Tag::XResolution, false) { match field.value { Value::Rational(ref vec) if !vec.is_empty() => println!("X resolution is {}.", vec[0].to_f64()), @@ -67,7 +67,7 @@ fn main() { } // To parse a DateTime-like field, `DateTime::from_ascii` can be used. - if let Some(field) = reader.get_field(tag::DateTime, false) { + if let Some(field) = reader.get_field(Tag::DateTime, false) { match field.value { Value::Ascii(ref vec) if !vec.is_empty() => { if let Ok(datetime) = DateTime::from_ascii(vec[0]) { diff --git a/src/lib.rs b/src/lib.rs index cc2980b..9ec03f6 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -50,6 +50,8 @@ //! * Enum Error has two new variants: TooBig and NotSupported. //! * Value::Undefined has the 2nd member to keep the offset of the value. //! * Struct DateTime has two new fields: nanosecond and offset. +//! * The tag constants have been changed to associated constants of +//! struct `Tag`. Use `Tag::TagName` instead of `tag::TagName`. pub use error::Error; pub use jpeg::get_exif_attr as get_exif_attr_from_jpeg; diff --git a/src/reader.rs b/src/reader.rs index 3f22fd0..8be1da4 100644 --- a/src/reader.rs +++ b/src/reader.rs @@ -130,7 +130,6 @@ mod tests { use std::fs::File; use std::io::BufReader; use value::Value; - use tag_priv::constants as tag; use super::*; static TIFF_ASCII: &'static [u8] = @@ -185,7 +184,7 @@ mod tests { fn get_field() { 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, + assert_pat!(reader.get_field(Tag::ExifVersion, false).unwrap().value, Value::Undefined(b"0230", _)); } } diff --git a/src/tag.rs b/src/tag.rs index 638c853..14b172f 100644 --- a/src/tag.rs +++ b/src/tag.rs @@ -31,6 +31,10 @@ use value::Value; use util::{atou16, isupper}; /// A tag of a TIFF field. +/// +/// Some well-known tags are provided as associated constants of +/// this type. The constant names follow the Exif specification +/// but not the Rust naming conventions. // // This is not an enum to keep safety and API stability, while // supporting unknown tag numbers. This comment is based on the @@ -130,6 +134,15 @@ macro_rules! generate_well_known_tag_constants { // . pub mod constants { use super::{Context, Tag}; + $($( + $( #[$attr] )* + #[allow(non_upper_case_globals)] + #[deprecated(since = "0.3.0", note = "use `Tag::TagName` instead of `tag::TagName`")] + pub const $name: Tag = Tag($ctx, $num); + )+)+ + } + + impl Tag { $($( $( #[$attr] )* #[allow(non_upper_case_globals)] @@ -165,7 +178,7 @@ macro_rules! generate_well_known_tag_constants { fn get_tag_info(tag: Tag) -> Option<&'static tag_info::TagInfo> { match tag { $($( - constants::$name => Some(&tag_info::$name), + Tag::$name => Some(&tag_info::$name), )+)+ _ => None, } @@ -1269,7 +1282,6 @@ fn d_sub_ascii(w: &mut fmt::Write, bytes: &[u8]) -> fmt::Result { #[cfg(test)] mod tests { - use tag; use value::Rational; use super::*; @@ -1283,19 +1295,19 @@ mod tests { } // Matching against a constant. Test if this compiles. match Tag(Context::Tiff, 0x132) { - tag::DateTime => {}, + Tag::DateTime => {}, _ => panic!("failed to match Tag"), } } #[test] fn default_value() { - assert_pat!(tag::DateTime.default_value(), None); - match tag::BitsPerSample.default_value() { + assert_pat!(Tag::DateTime.default_value(), None); + match Tag::BitsPerSample.default_value() { Some(Value::Short(v)) => assert_eq!(v, &[8, 8, 8]), _ => panic!(), } - match tag::XResolution.default_value() { + match Tag::XResolution.default_value() { Some(Value::Rational(v)) => { assert_eq!(v.len(), 1); assert_eq!(v[0].num, 72); @@ -1303,15 +1315,15 @@ mod tests { }, _ => panic!(), } - match tag::FileSource.default_value() { + match Tag::FileSource.default_value() { Some(Value::Undefined(v, _)) => assert_eq!(v, &[3]), _ => panic!(), } - match tag::GPSAltitudeRef.default_value() { + match Tag::GPSAltitudeRef.default_value() { Some(Value::Byte(v)) => assert_eq!(v, &[0]), _ => panic!(), } - match tag::GPSSpeedRef.default_value() { + match Tag::GPSSpeedRef.default_value() { Some(Value::Ascii(v)) => assert_eq!(v, &[b"K"]), _ => panic!(), } diff --git a/src/tiff.rs b/src/tiff.rs index d7bfe13..af6f827 100644 --- a/src/tiff.rs +++ b/src/tiff.rs @@ -28,7 +28,6 @@ use std::fmt; use endian::{Endian, BigEndian, LittleEndian}; use error::Error; -use tag; use tag_priv::{Context, Tag}; use value::Value; use value::get_type_info; @@ -120,11 +119,11 @@ fn parse_ifd<'a, E>(fields: &mut Vec>, data: &'a [u8], // recursively defined. let tag = Tag(ctx, tag); match tag { - tag::ExifIFDPointer => try!(parse_child_ifd::( + Tag::ExifIFDPointer => try!(parse_child_ifd::( fields, data, &val, Context::Exif, thumbnail)), - tag::GPSInfoIFDPointer => try!(parse_child_ifd::( + Tag::GPSInfoIFDPointer => try!(parse_child_ifd::( fields, data, &val, Context::Gps, thumbnail)), - tag::InteropIFDPointer => try!(parse_child_ifd::( + Tag::InteropIFDPointer => try!(parse_child_ifd::( fields, data, &val, Context::Interop, thumbnail)), _ => fields.push(Field { tag: tag, thumbnail: thumbnail, value: val }), diff --git a/src/value.rs b/src/value.rs index 4f1289c..73888e1 100644 --- a/src/value.rs +++ b/src/value.rs @@ -81,12 +81,12 @@ impl<'a> Value<'a> { /// # Examples /// /// ``` - /// use exif::{Value, tag}; + /// use exif::{Value, Tag}; /// 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"); /// let val = Value::Short(vec![2]); - /// assert_eq!(format!("{}", val.display_as(tag::ResolutionUnit)), + /// assert_eq!(format!("{}", val.display_as(Tag::ResolutionUnit)), /// "pixels per inch"); /// ``` #[inline] diff --git a/src/writer.rs b/src/writer.rs index 6cd6781..41710e1 100644 --- a/src/writer.rs +++ b/src/writer.rs @@ -31,7 +31,7 @@ use std::slice; use endian::{Endian, BigEndian, LittleEndian}; use error::Error; -use tag_priv::{Context, Tag, constants as tag}; +use tag_priv::{Context, Tag}; use tiff::{Field, TIFF_BE_SIG, TIFF_LE_SIG}; use value::Value; @@ -97,17 +97,17 @@ impl<'a> Writer<'a> { pub fn push_field(&mut self, field: &'a Field) { match *field { // Ignore the tags for the internal data structure. - Field { tag: tag::ExifIFDPointer, .. } | - Field { tag: tag::GPSInfoIFDPointer, .. } | - Field { tag: tag::InteropIFDPointer, .. } => {}, + Field { tag: Tag::ExifIFDPointer, .. } | + Field { tag: Tag::GPSInfoIFDPointer, .. } | + Field { tag: Tag::InteropIFDPointer, .. } => {}, // These tags are synthesized from the actual strip/tile data. - Field { tag: tag::StripOffsets, .. } | - Field { tag: tag::StripByteCounts, .. } | - Field { tag: tag::TileOffsets, .. } | - Field { tag: tag::TileByteCounts, .. } => {}, + Field { tag: Tag::StripOffsets, .. } | + Field { tag: Tag::StripByteCounts, .. } | + Field { tag: Tag::TileOffsets, .. } | + Field { tag: Tag::TileByteCounts, .. } => {}, // These tags are synthesized from the actual JPEG thumbnail. - Field { tag: tag::JPEGInterchangeFormat, .. } | - Field { tag: tag::JPEGInterchangeFormatLength, .. } => {}, + Field { tag: Tag::JPEGInterchangeFormat, .. } | + Field { tag: Tag::JPEGInterchangeFormatLength, .. } => {}, // Other normal tags. Field { tag: Tag(Context::Tiff, _), thumbnail: false, .. } => self.tiff_fields.push(field), @@ -246,13 +246,13 @@ fn synthesize_fields(w: &mut W, ws: WriterState, thumbnail: bool, if let Some(strips) = ws.strips { strip_offsets = Field { - tag: tag::StripOffsets, + tag: Tag::StripOffsets, thumbnail: thumbnail, value: Value::Long(vec![0; strips.len()]), }; ws.tiff_fields.push(&strip_offsets); strip_byte_counts = Field { - tag: tag::StripByteCounts, + tag: Tag::StripByteCounts, thumbnail: thumbnail, value: Value::Long( strips.iter().map(|s| s.len() as u32).collect()), @@ -261,13 +261,13 @@ fn synthesize_fields(w: &mut W, ws: WriterState, thumbnail: bool, } if let Some(tiles) = ws.tiles { tile_offsets = Field { - tag: tag::TileOffsets, + tag: Tag::TileOffsets, thumbnail: thumbnail, value: Value::Long(vec![0; tiles.len()]), }; ws.tiff_fields.push(&tile_offsets); tile_byte_counts = Field { - tag: tag::TileByteCounts, + tag: Tag::TileByteCounts, thumbnail: thumbnail, value: Value::Long( tiles.iter().map(|s| s.len() as u32).collect()), @@ -276,13 +276,13 @@ fn synthesize_fields(w: &mut W, ws: WriterState, thumbnail: bool, } if let Some(jpeg) = ws.jpeg { jpeg_offset = Field { - tag: tag::JPEGInterchangeFormat, + tag: Tag::JPEGInterchangeFormat, thumbnail: thumbnail, value: Value::Long(vec![0]), }; ws.tiff_fields.push(&jpeg_offset); jpeg_length = Field { - tag: tag::JPEGInterchangeFormatLength, + tag: Tag::JPEGInterchangeFormatLength, thumbnail: thumbnail, value: Value::Long(vec![jpeg.len() as u32]), }; @@ -301,7 +301,7 @@ fn synthesize_fields(w: &mut W, ws: WriterState, thumbnail: bool, if exif_fields_len > 0 { ws.exif_ifd_offset = try!(reserve_ifd(w, exif_fields_len)); exif_in_tiff = Field { - tag: tag::ExifIFDPointer, + tag: Tag::ExifIFDPointer, thumbnail: thumbnail, value: Value::Long(vec![ws.exif_ifd_offset]), }; @@ -310,7 +310,7 @@ fn synthesize_fields(w: &mut W, ws: WriterState, thumbnail: bool, if gps_fields_len > 0 { ws.gps_ifd_offset = try!(reserve_ifd(w, gps_fields_len)); gps_in_tiff = Field { - tag: tag::GPSInfoIFDPointer, + tag: Tag::GPSInfoIFDPointer, thumbnail: thumbnail, value: Value::Long(vec![ws.gps_ifd_offset]), }; @@ -319,7 +319,7 @@ fn synthesize_fields(w: &mut W, ws: WriterState, thumbnail: bool, if interop_fields_len > 0 { ws.interop_ifd_offset = try!(reserve_ifd(w, interop_fields_len)); interop_in_exif = Field { - tag: tag::InteropIFDPointer, + tag: Tag::InteropIFDPointer, thumbnail: thumbnail, value: Value::Long(vec![ws.interop_ifd_offset]), }; @@ -442,19 +442,19 @@ fn write_ifd_and_fields( try!(E::writeu32(&mut ifd, valofs)); try!(w.write_all(&valbuf)); } - if f.tag == tag::StripOffsets { + if f.tag == Tag::StripOffsets { strip_offsets_offset = match valbuf.len() { 0...4 => ifd_offset + ifd.len() as u32 - 4, _ => try!(get_offset(w)) - valbuf.len() as u32, }; } - if f.tag == tag::TileOffsets { + if f.tag == Tag::TileOffsets { tile_offsets_offset = match valbuf.len() { 0...4 => ifd_offset + ifd.len() as u32 - 4, _ => try!(get_offset(w)) - valbuf.len() as u32, }; } - if f.tag == tag::JPEGInterchangeFormat { + if f.tag == Tag::JPEGInterchangeFormat { jpeg_offset = ifd_offset + ifd.len() as u32 - 4; } } @@ -594,7 +594,7 @@ mod tests { #[test] fn primary() { let image_desc = Field { - tag: tag::ImageDescription, + tag: Tag::ImageDescription, thumbnail: false, value: Value::Ascii(vec![b"Sample"]), }; @@ -613,7 +613,7 @@ mod tests { #[test] fn primary_exif_only() { let exif_ver = Field { - tag: tag::ExifVersion, + tag: Tag::ExifVersion, thumbnail: false, value: Value::Undefined(b"0231", 0), }; @@ -686,22 +686,22 @@ mod tests { #[test] fn primary_and_thumbnail() { let image_desc = Field { - tag: tag::ImageDescription, + tag: Tag::ImageDescription, thumbnail: false, value: Value::Ascii(vec![b"Sample"]), }; let exif_ver = Field { - tag: tag::ExifVersion, + tag: Tag::ExifVersion, thumbnail: false, value: Value::Undefined(b"0231", 0), }; let gps_ver = Field { - tag: tag::GPSVersionID, + tag: Tag::GPSVersionID, thumbnail: false, value: Value::Byte(vec![2, 3, 0, 0]), }; let interop_index = Field { - tag: tag::InteroperabilityIndex, + tag: Tag::InteroperabilityIndex, thumbnail: false, value: Value::Ascii(vec![b"ABC"]), }; @@ -738,7 +738,7 @@ mod tests { #[test] fn write_twice() { let image_desc = Field { - tag: tag::ImageDescription, + tag: Tag::ImageDescription, thumbnail: false, value: Value::Ascii(vec![b"Sample"]), }; diff --git a/tests/rwrcmp.rs b/tests/rwrcmp.rs index 26a905c..b1a8ae7 100644 --- a/tests/rwrcmp.rs +++ b/tests/rwrcmp.rs @@ -37,7 +37,7 @@ use std::path::Path; #[cfg(not(test))] use exif::Error; -use exif::{Reader, Value, tag}; +use exif::{Reader, Value, Tag}; use exif::experimental::Writer; #[test] @@ -122,8 +122,8 @@ fn rwr_compare

(path: P) where P: AsRef { assert_eq!(f1.tag, f2.tag); assert_eq!(f1.thumbnail, f2.thumbnail); match f1.tag { - tag::StripOffsets | tag::TileOffsets | - tag::JPEGInterchangeFormat => continue, + Tag::StripOffsets | Tag::TileOffsets | + Tag::JPEGInterchangeFormat => continue, _ => {}, } compare_field_value(&f1.value, &f2.value); @@ -177,9 +177,9 @@ fn compare_field_value(value1: &Value, value2: &Value) { } fn get_strips(reader: &Reader, thumbnail: bool) -> Option> { - let offsets = reader.get_field(tag::StripOffsets, thumbnail) + let offsets = reader.get_field(Tag::StripOffsets, thumbnail) .and_then(|f| f.value.iter_uint()); - let counts = reader.get_field(tag::StripByteCounts, thumbnail) + let counts = reader.get_field(Tag::StripByteCounts, thumbnail) .and_then(|f| f.value.iter_uint()); let (offsets, counts) = match (offsets, counts) { (Some(offsets), Some(counts)) => (offsets, counts), @@ -194,9 +194,9 @@ fn get_strips(reader: &Reader, thumbnail: bool) -> Option> { } fn get_tiles(reader: &Reader, thumbnail: bool) -> Option> { - let offsets = reader.get_field(tag::TileOffsets, thumbnail) + let offsets = reader.get_field(Tag::TileOffsets, thumbnail) .and_then(|f| f.value.iter_uint()); - let counts = reader.get_field(tag::TileByteCounts, thumbnail) + let counts = reader.get_field(Tag::TileByteCounts, thumbnail) .and_then(|f| f.value.iter_uint()); let (offsets, counts) = match (offsets, counts) { (Some(offsets), Some(counts)) => (offsets, counts), @@ -211,9 +211,9 @@ fn get_tiles(reader: &Reader, thumbnail: bool) -> Option> { } fn get_jpeg(reader: &Reader, thumbnail: bool) -> Option<&[u8]> { - let offset = reader.get_field(tag::JPEGInterchangeFormat, thumbnail) + let offset = reader.get_field(Tag::JPEGInterchangeFormat, thumbnail) .and_then(|f| f.value.get_uint(0)); - let len = reader.get_field(tag::JPEGInterchangeFormatLength, thumbnail) + let len = reader.get_field(Tag::JPEGInterchangeFormatLength, thumbnail) .and_then(|f| f.value.get_uint(0)); let (offset, len) = match (offset, len) { (Some(offset), Some(len)) => (offset as usize, len as usize),