1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99
//! RExif is a native Rust create, written to extract EXIF data from JPEG and TIFF images. //! //! Note that it is in very early stages of development. Any sort of feedback is welcome! //! //! The crate contains a //! sample binary called 'rexiftool' that accepts files as arguments and prints the EXIF data. It gives //! a rough idea on how to use the crate. Get some sample images and run //! //! //! `cargo run [image file 1] [image file 2] ...` //! //! //! To learn to use this crate, start by the documentation of function `parse_file()`, //! and the struct `ExifData` that is returned by the parser. The rest falls more or less into place. //! //! Code sample lightly edited from src/bin.rs: //! //! ``` //! use std::error::Error; //! let file_name = "foo.jpg"; //! match rexif::parse_file(&file_name) { //! Ok(exif) => { //! println!("{} {} exif entries: {}", file_name, //! exif.mime, exif.entries.len()); //! //! for entry in &exif.entries { //! println!(" {}: {}", //! entry.tag, //! entry.value_more_readable); //! } //! }, //! Err(e) => { //! print!("Error in {}: {}", &file_name, e) //! } //! } //! ``` use std::fs::File; use std::io::{Seek,SeekFrom,Read}; use std::path::Path; mod lowlevel; mod rational; pub use self::rational::*; mod types; pub use self::types::*; mod types_impl; pub use self::types_impl::*; mod image; use self::image::*; mod ifdformat; mod tiff; use self::tiff::*; mod exifreadable; mod exifpost; mod exif; /// Parse a byte buffer that should contain a TIFF or JPEG image. /// Tries to detect format and parse EXIF data. pub fn parse_buffer(contents: &[u8]) -> ExifResult { let mime = detect_type(contents); let d = match mime { "" => return Err(ExifError::FileTypeUnknown), "image/jpeg" => { let (offset, size) = find_embedded_tiff_in_jpeg(contents)?; // println!("Offset {} size {}", offset, size); parse_tiff(&contents[offset .. offset + size])? }, _ => { parse_tiff(contents)? } }; Ok(ExifData { mime: mime.to_string(), entries: d, }) } /// Try to read and parse an open file that is expected to contain an image pub fn read_file(f: &mut File) -> ExifResult { f.seek(SeekFrom::Start(0))?; // TODO: should read only the relevant parts of a file, // and pass a StringIO-like object instead of a Vec buffer let mut contents: Vec<u8> = Vec::new(); f.read_to_end(&mut contents)?; parse_buffer(&contents) } /// Opens an image (passed as a file name), tries to read and parse it. pub fn parse_file<P: AsRef<Path>>(fname: P) -> ExifResult { read_file(&mut File::open(fname)?) }