using System; using System.IO; using com.codec.jpeg; using com.drew.metadata; using com.drew.metadata.jpeg; using com.drew.metadata.iptc; using com.drew.metadata.exif; /// /// This class was first written by Drew Noakes in Java. /// /// This is public domain software - that is, you can do whatever you want /// with it, and include it software that is licensed under the GNU or the /// BSD license, or whatever other licence you choose, including proprietary /// closed source licenses. I do ask that you leave this header in tact. /// /// If you make modifications to this code that you think would benefit the /// wider community, please send me a copy and I'll post it on my site. /// /// If you make use of this code, Drew Noakes will appreciate hearing /// about it: drew@drewnoakes.com /// /// Latest Java version of this software kept at /// http://drewnoakes.com/ /// /// The C# class was made by Ferret Renaud: /// renaud91@free.fr /// If you find a bug in the C# code, feel free to mail me. /// namespace com.drew.imaging.jpg { /// /// This class will extract MetaData from a picture. /// public class JpegMetadataReader { /// /// Reads MetaData from a stream /// /// where to read information /// the metadata object public static Metadata ReadMetadata(Stream aStream) { JpegSegmentReader segmentReader = new JpegSegmentReader(aStream); return ExtractJpegSegmentReaderMetadata(segmentReader); } /// /// Reads MetaData from a file /// /// where to read information /// the metadata object public static Metadata ReadMetadata(FileInfo aFile) { JpegSegmentReader segmentReader = new JpegSegmentReader(aFile); return ExtractJpegSegmentReaderMetadata(segmentReader); } /// /// Extracts metadata from a SegmentReader /// /// where to extract metadata /// the metadata found private static Metadata ExtractJpegSegmentReaderMetadata(JpegSegmentReader segmentReader) { Metadata metadata = new Metadata(); try { byte[] exifSegment = segmentReader.ReadSegment(JpegSegmentReader.SEGMENT_APP1); new ExifReader(exifSegment).Extract(metadata); } catch (JpegProcessingException ) { // in the interests of catching as much data as possible, continue // TODO lodge error message within exif directory? } try { byte[] iptcSegment = segmentReader.ReadSegment(JpegSegmentReader.SEGMENT_APPD); new IptcReader(iptcSegment).Extract(metadata); } catch (JpegProcessingException ) { // TODO log error message within iptc directory? } try { byte[] jpegSegment = segmentReader.ReadSegment(JpegSegmentReader.SEGMENT_SOF0); new JpegReader(jpegSegment).Extract(metadata); } catch (JpegProcessingException ) { // TODO log error message within jpeg directory? } try { byte[] jpegCommentSegment = segmentReader.ReadSegment(JpegSegmentReader.SEGMENT_COM); new JpegCommentReader(jpegCommentSegment).Extract(metadata); } catch (JpegProcessingException ) { // TODO log error message within jpegcomment directory? } return metadata; } /// /// Reads metadata from a JPEGDecodeParam object /// /// where to find metadata /// the metadata found public static Metadata ReadMetadata(JPEGDecodeParam decodeParam) { Metadata metadata = new Metadata(); // We should only really be seeing Exif in _data[0]... the 2D array exists // because markers can theoretically appear multiple times in the file. // TODO test this method byte[][] exifSegment = decodeParam.GetMarkerData(JPEGDecodeParam.APP1_MARKER); if (exifSegment != null && exifSegment[0].Length > 0) { new ExifReader(exifSegment[0]).Extract(metadata); } // similarly, use only the first IPTC segment byte[][] iptcSegment = decodeParam.GetMarkerData(JPEGDecodeParam.APPD_MARKER); if (iptcSegment != null && iptcSegment[0].Length > 0) { new IptcReader(iptcSegment[0]).Extract(metadata); } // NOTE: Unable to utilise JpegReader for the SOF0 frame here, as the decodeParam doesn't contain the byte[] // similarly, use only the first Jpeg Comment segment byte[][] jpegCommentSegment = decodeParam.GetMarkerData(JPEGDecodeParam.COMMENT_MARKER); if (jpegCommentSegment != null && jpegCommentSegment[0].Length > 0) { new JpegCommentReader(jpegCommentSegment[0]).Extract(metadata); } return metadata; } /// /// Constructor of the object /// /// Allways private JpegMetadataReader() : base() { throw new Exception("Do not use"); } } }