public virtual void SetUp() { Com.Drew.Metadata.Metadata metadata = ExifReaderTest.ProcessBytes("Tests/Data/nikonMakernoteType1.jpg.app1"); _nikonDirectory = metadata.GetDirectory <NikonType1MakernoteDirectory>(); _exifSubIFDDirectory = metadata.GetDirectory <ExifSubIFDDirectory>(); _exifIFD0Directory = metadata.GetDirectory <ExifIFD0Directory>(); _thumbDirectory = metadata.GetDirectory <ExifThumbnailDirectory>(); }
public virtual void SetUp() { Com.Drew.Metadata.Metadata metadata = ExifReaderTest.ProcessBytes("Tests/Data/nikonMakernoteType2b.jpg.app1"); _nikonDirectory = metadata.GetDirectory <NikonType2MakernoteDirectory>(); _exifIFD0Directory = metadata.GetDirectory <ExifIFD0Directory>(); _exifSubIFDDirectory = metadata.GetDirectory <ExifSubIFDDirectory>(); _thumbDirectory = metadata.GetDirectory <ExifThumbnailDirectory>(); NUnit.Framework.Assert.IsNotNull(_nikonDirectory); NUnit.Framework.Assert.IsNotNull(_exifSubIFDDirectory); }
public virtual void TestResolution() { Com.Drew.Metadata.Metadata metadata = ExifReaderTest.ProcessBytes("Tests/Data/withUncompressedRGBThumbnail.jpg.app1"); ExifThumbnailDirectory thumbnailDirectory = metadata.GetDirectory <ExifThumbnailDirectory>(); NUnit.Framework.Assert.IsNotNull(thumbnailDirectory); Sharpen.Tests.AreEqual(72, thumbnailDirectory.GetInt(ExifThumbnailDirectory.TagXResolution)); ExifIFD0Directory exifIFD0Directory = metadata.GetDirectory <ExifIFD0Directory>(); NUnit.Framework.Assert.IsNotNull(exifIFD0Directory); Sharpen.Tests.AreEqual(216, exifIFD0Directory.GetInt(ExifIFD0Directory.TagXResolution)); }
public virtual void TestDifferenceImageAndThumbnailOrientations() { // This metadata contains different orientations for the thumbnail and the main image. // These values used to be merged into a single directory, causing errors. // This unit test demonstrates correct behaviour. Com.Drew.Metadata.Metadata metadata = ProcessBytes("Tests/Data/repeatedOrientationTagWithDifferentValues.jpg.app1"); ExifIFD0Directory ifd0Directory = metadata.GetDirectory <ExifIFD0Directory>(); ExifThumbnailDirectory thumbnailDirectory = metadata.GetDirectory <ExifThumbnailDirectory>(); NUnit.Framework.Assert.IsNotNull(ifd0Directory); NUnit.Framework.Assert.IsNotNull(thumbnailDirectory); Sharpen.Tests.AreEqual(1, ifd0Directory.GetInt(ExifIFD0Directory.TagOrientation)); Sharpen.Tests.AreEqual(8, thumbnailDirectory.GetInt(ExifThumbnailDirectory.TagOrientation)); }
public static AdobeJpegDirectory ProcessBytes(string filePath) { Com.Drew.Metadata.Metadata metadata = new Com.Drew.Metadata.Metadata(); new AdobeJpegReader().Extract(new SequentialByteArrayReader(FileUtil.ReadBytes(filePath)), metadata); AdobeJpegDirectory directory = metadata.GetDirectory<AdobeJpegDirectory>(); NUnit.Framework.Assert.IsNotNull(directory); return directory; }
/// <exception cref="System.IO.IOException"/> public static XmpDirectory ProcessApp1Bytes(string filePath) { Com.Drew.Metadata.Metadata metadata = new Com.Drew.Metadata.Metadata(); new XmpReader().Extract(FileUtil.ReadBytes(filePath), metadata, JpegSegmentType.App1); XmpDirectory directory = metadata.GetDirectory<XmpDirectory>(); NUnit.Framework.Assert.IsNotNull(directory); return directory; }
public static JpegDirectory ProcessBytes(string filePath) { Com.Drew.Metadata.Metadata metadata = new Com.Drew.Metadata.Metadata(); new JpegReader().Extract(FileUtil.ReadBytes(filePath), metadata, JpegSegmentType.Sof0); JpegDirectory directory = metadata.GetDirectory <JpegDirectory>(); NUnit.Framework.Assert.IsNotNull(directory); return(directory); }
public static AdobeJpegDirectory ProcessBytes(string filePath) { Com.Drew.Metadata.Metadata metadata = new Com.Drew.Metadata.Metadata(); new AdobeJpegReader().Extract(new SequentialByteArrayReader(FileUtil.ReadBytes(filePath)), metadata); AdobeJpegDirectory directory = metadata.GetDirectory <AdobeJpegDirectory>(); NUnit.Framework.Assert.IsNotNull(directory); return(directory); }
public static GifHeaderDirectory ProcessBytes(string file) { Com.Drew.Metadata.Metadata metadata = new Com.Drew.Metadata.Metadata(); InputStream stream = new FileInputStream(file); new GifReader().Extract(new Com.Drew.Lang.StreamReader(stream), metadata); stream.Close(); GifHeaderDirectory directory = metadata.GetDirectory<GifHeaderDirectory>(); NUnit.Framework.Assert.IsNotNull(directory); return directory; }
public static PsdHeaderDirectory ProcessBytes(string file) { Com.Drew.Metadata.Metadata metadata = new Com.Drew.Metadata.Metadata(); RandomAccessFile randomAccessFile = new RandomAccessFile(new FilePath(file), "r"); new PsdReader().Extract(new RandomAccessFileReader(randomAccessFile), metadata); randomAccessFile.Close(); PsdHeaderDirectory directory = metadata.GetDirectory<PsdHeaderDirectory>(); NUnit.Framework.Assert.IsNotNull(directory); return directory; }
public virtual void TestExtract() { sbyte[] app2Bytes = FileUtil.ReadBytes("Tests/Data/iccDataInvalid1.jpg.app2"); // ICC data starts after a 14-byte preamble sbyte[] icc = TestHelper.SkipBytes(app2Bytes, 14); Com.Drew.Metadata.Metadata metadata = new Com.Drew.Metadata.Metadata(); new IccReader().Extract(new ByteArrayReader(icc), metadata); IccDirectory directory = metadata.GetDirectory<IccDirectory>(); NUnit.Framework.Assert.IsNotNull(directory); }
public virtual void TestExtract() { sbyte[] app2Bytes = FileUtil.ReadBytes("Tests/Data/iccDataInvalid1.jpg.app2"); // ICC data starts after a 14-byte preamble sbyte[] icc = TestHelper.SkipBytes(app2Bytes, 14); Com.Drew.Metadata.Metadata metadata = new Com.Drew.Metadata.Metadata(); new IccReader().Extract(new ByteArrayReader(icc), metadata); IccDirectory directory = metadata.GetDirectory <IccDirectory>(); NUnit.Framework.Assert.IsNotNull(directory); }
public static PsdHeaderDirectory ProcessBytes(string file) { Com.Drew.Metadata.Metadata metadata = new Com.Drew.Metadata.Metadata(); RandomAccessFile randomAccessFile = new RandomAccessFile(new FilePath(file), "r"); new PsdReader().Extract(new RandomAccessFileReader(randomAccessFile), metadata); randomAccessFile.Close(); PsdHeaderDirectory directory = metadata.GetDirectory <PsdHeaderDirectory>(); NUnit.Framework.Assert.IsNotNull(directory); return(directory); }
public static GifHeaderDirectory ProcessBytes(string file) { Com.Drew.Metadata.Metadata metadata = new Com.Drew.Metadata.Metadata(); InputStream stream = new FileInputStream(file); new GifReader().Extract(new Com.Drew.Lang.StreamReader(stream), metadata); stream.Close(); GifHeaderDirectory directory = metadata.GetDirectory <GifHeaderDirectory>(); NUnit.Framework.Assert.IsNotNull(directory); return(directory); }
private static void ExtractTiff(RandomAccessReader reader, Com.Drew.Metadata.Metadata metadata, Com.Drew.Metadata.Directory firstDirectory, int tiffHeaderOffset) { // this should be either "MM" or "II" string byteOrderIdentifier = reader.GetString(tiffHeaderOffset, 2); if ("MM".Equals(byteOrderIdentifier)) { reader.SetMotorolaByteOrder(true); } else { if ("II".Equals(byteOrderIdentifier)) { reader.SetMotorolaByteOrder(false); } else { firstDirectory.AddError("Unclear distinction between Motorola/Intel byte ordering: " + byteOrderIdentifier); return; } } // Check the next two values for correctness. int tiffMarker = reader.GetUInt16(2 + tiffHeaderOffset); int standardTiffMarker = unchecked ((int)(0x002A)); int olympusRawTiffMarker = unchecked ((int)(0x4F52)); // for ORF files int panasonicRawTiffMarker = unchecked ((int)(0x0055)); // for RW2 files if (tiffMarker != standardTiffMarker && tiffMarker != olympusRawTiffMarker && tiffMarker != panasonicRawTiffMarker) { firstDirectory.AddError("Unexpected TIFF marker after byte order identifier: 0x" + Sharpen.Extensions.ToHexString(tiffMarker)); return; } int firstIfdOffset = reader.GetInt32(4 + tiffHeaderOffset) + tiffHeaderOffset; // David Ekholm sent a digital camera image that has this problem // TODO getLength should be avoided as it causes RandomAccessStreamReader to read to the end of the stream if (firstIfdOffset >= reader.GetLength() - 1) { firstDirectory.AddError("First Exif directory offset is beyond end of Exif data segment"); // First directory normally starts 14 bytes in -- try it here and catch another error in the worst case firstIfdOffset = 14; } ICollection <int> processedIfdOffsets = new HashSet <int>(); ProcessIFD(firstDirectory, processedIfdOffsets, firstIfdOffset, tiffHeaderOffset, metadata, reader); // after the extraction process, if we have the correct tags, we may be able to store thumbnail information ExifThumbnailDirectory thumbnailDirectory = metadata.GetDirectory <ExifThumbnailDirectory>(); if (thumbnailDirectory != null && thumbnailDirectory.ContainsTag(ExifThumbnailDirectory.TagThumbnailCompression)) { int?offset = thumbnailDirectory.GetInteger(ExifThumbnailDirectory.TagThumbnailOffset); int?length = thumbnailDirectory.GetInteger(ExifThumbnailDirectory.TagThumbnailLength); if (offset != null && length != null) { try { sbyte[] thumbnailData = reader.GetBytes(tiffHeaderOffset + offset.Value, length.Value); thumbnailDirectory.SetThumbnailData(thumbnailData); } catch (IOException ex) { firstDirectory.AddError("Invalid thumbnail data specification: " + ex.Message); } } } }
private void Validate(Com.Drew.Metadata.Metadata metadata) { Com.Drew.Metadata.Directory directory = metadata.GetDirectory <ExifSubIFDDirectory>(); NUnit.Framework.Assert.IsNotNull(directory); Sharpen.Tests.AreEqual("80", directory.GetString(ExifSubIFDDirectory.TagIsoEquivalent)); }
private static void ProcessMakernote(int makernoteOffset, ICollection <int> processedIfdOffsets, int tiffHeaderOffset, Com.Drew.Metadata.Metadata metadata, RandomAccessReader reader) { // Determine the camera model and makernote format Com.Drew.Metadata.Directory ifd0Directory = metadata.GetDirectory <ExifIFD0Directory>(); if (ifd0Directory == null) { return; } string cameraMake = ifd0Directory.GetString(ExifIFD0Directory.TagMake); string firstThreeChars = reader.GetString(makernoteOffset, 3); string firstFourChars = reader.GetString(makernoteOffset, 4); string firstFiveChars = reader.GetString(makernoteOffset, 5); string firstSixChars = reader.GetString(makernoteOffset, 6); string firstSevenChars = reader.GetString(makernoteOffset, 7); string firstEightChars = reader.GetString(makernoteOffset, 8); string firstTwelveChars = reader.GetString(makernoteOffset, 12); bool byteOrderBefore = reader.IsMotorolaByteOrder(); if ("OLYMP".Equals(firstFiveChars) || "EPSON".Equals(firstFiveChars) || "AGFA".Equals(firstFourChars)) { // Olympus Makernote // Epson and Agfa use Olympus makernote standard: http://www.ozhiker.com/electronics/pjmt/jpeg_info/ ProcessIFD(metadata.GetOrCreateDirectory <OlympusMakernoteDirectory>(), processedIfdOffsets, makernoteOffset + 8, tiffHeaderOffset, metadata, reader); } else { if (cameraMake != null && Sharpen.Extensions.Trim(cameraMake).ToUpper().StartsWith("NIKON")) { if ("Nikon".Equals(firstFiveChars)) { switch (reader.GetUInt8(makernoteOffset + 6)) { case 1: { /* There are two scenarios here: * Type 1: ** * :0000: 4E 69 6B 6F 6E 00 01 00-05 00 02 00 02 00 06 00 Nikon........... * :0010: 00 00 EC 02 00 00 03 00-03 00 01 00 00 00 06 00 ................ * Type 3: ** * :0000: 4E 69 6B 6F 6E 00 02 00-00 00 4D 4D 00 2A 00 00 Nikon....MM.*... * :0010: 00 08 00 1E 00 01 00 07-00 00 00 04 30 32 30 30 ............0200 */ ProcessIFD(metadata.GetOrCreateDirectory <NikonType1MakernoteDirectory>(), processedIfdOffsets, makernoteOffset + 8, tiffHeaderOffset, metadata, reader); break; } case 2: { ProcessIFD(metadata.GetOrCreateDirectory <NikonType2MakernoteDirectory>(), processedIfdOffsets, makernoteOffset + 18, makernoteOffset + 10, metadata, reader); break; } default: { ifd0Directory.AddError("Unsupported Nikon makernote data ignored."); break; } } } else { // The IFD begins with the first Makernote byte (no ASCII name). This occurs with CoolPix 775, E990 and D1 models. ProcessIFD(metadata.GetOrCreateDirectory <NikonType2MakernoteDirectory>(), processedIfdOffsets, makernoteOffset, tiffHeaderOffset, metadata, reader); } } else { if ("SONY CAM".Equals(firstEightChars) || "SONY DSC".Equals(firstEightChars)) { ProcessIFD(metadata.GetOrCreateDirectory <SonyType1MakernoteDirectory>(), processedIfdOffsets, makernoteOffset + 12, tiffHeaderOffset, metadata, reader); } else { if ("SEMC MS\u0000\u0000\u0000\u0000\u0000".Equals(firstTwelveChars)) { // force MM for this directory reader.SetMotorolaByteOrder(true); // skip 12 byte header + 2 for "MM" + 6 ProcessIFD(metadata.GetOrCreateDirectory <SonyType6MakernoteDirectory>(), processedIfdOffsets, makernoteOffset + 20, tiffHeaderOffset, metadata, reader); } else { if ("SIGMA\u0000\u0000\u0000".Equals(firstEightChars) || "FOVEON\u0000\u0000".Equals(firstEightChars)) { ProcessIFD(metadata.GetOrCreateDirectory <SigmaMakernoteDirectory>(), processedIfdOffsets, makernoteOffset + 10, tiffHeaderOffset, metadata, reader); } else { if ("KDK".Equals(firstThreeChars)) { reader.SetMotorolaByteOrder(firstSevenChars.Equals("KDK INFO")); ProcessKodakMakernote(metadata.GetOrCreateDirectory <KodakMakernoteDirectory>(), makernoteOffset, reader); } else { if (Sharpen.Runtime.EqualsIgnoreCase("Canon", cameraMake)) { ProcessIFD(metadata.GetOrCreateDirectory <CanonMakernoteDirectory>(), processedIfdOffsets, makernoteOffset, tiffHeaderOffset, metadata, reader); } else { if (cameraMake != null && cameraMake.ToUpper().StartsWith("CASIO")) { if ("QVC\u0000\u0000\u0000".Equals(firstSixChars)) { ProcessIFD(metadata.GetOrCreateDirectory <CasioType2MakernoteDirectory>(), processedIfdOffsets, makernoteOffset + 6, tiffHeaderOffset, metadata, reader); } else { ProcessIFD(metadata.GetOrCreateDirectory <CasioType1MakernoteDirectory>(), processedIfdOffsets, makernoteOffset, tiffHeaderOffset, metadata, reader); } } else { if ("FUJIFILM".Equals(firstEightChars) || Sharpen.Runtime.EqualsIgnoreCase("Fujifilm", cameraMake)) { // Note that this also applies to certain Leica cameras, such as the Digilux-4.3 reader.SetMotorolaByteOrder(false); // the 4 bytes after "FUJIFILM" in the makernote point to the start of the makernote // IFD, though the offset is relative to the start of the makernote, not the TIFF // header (like everywhere else) int ifdStart = makernoteOffset + reader.GetInt32(makernoteOffset + 8); ProcessIFD(metadata.GetOrCreateDirectory <FujifilmMakernoteDirectory>(), processedIfdOffsets, ifdStart, makernoteOffset, metadata, reader); } else { if (cameraMake != null && cameraMake.ToUpper().StartsWith("MINOLTA")) { // Cases seen with the model starting with MINOLTA in capitals seem to have a valid Olympus makernote // area that commences immediately. ProcessIFD(metadata.GetOrCreateDirectory <OlympusMakernoteDirectory>(), processedIfdOffsets, makernoteOffset, tiffHeaderOffset, metadata, reader); } else { if ("KYOCERA".Equals(firstSevenChars)) { // http://www.ozhiker.com/electronics/pjmt/jpeg_info/kyocera_mn.html ProcessIFD(metadata.GetOrCreateDirectory <KyoceraMakernoteDirectory>(), processedIfdOffsets, makernoteOffset + 22, tiffHeaderOffset, metadata, reader); } else { if ("LEICA".Equals(firstFiveChars)) { reader.SetMotorolaByteOrder(false); if ("Leica Camera AG".Equals(cameraMake)) { ProcessIFD(metadata.GetOrCreateDirectory <LeicaMakernoteDirectory>(), processedIfdOffsets, makernoteOffset + 8, tiffHeaderOffset, metadata, reader); } else { if ("LEICA".Equals(cameraMake)) { // Some Leica cameras use Panasonic makernote tags ProcessIFD(metadata.GetOrCreateDirectory <PanasonicMakernoteDirectory>(), processedIfdOffsets, makernoteOffset + 8, tiffHeaderOffset, metadata, reader); } } } else { if ("Panasonic\u0000\u0000\u0000".Equals(reader.GetString(makernoteOffset, 12))) { // NON-Standard TIFF IFD Data using Panasonic Tags. There is no Next-IFD pointer after the IFD // Offsets are relative to the start of the TIFF header at the beginning of the EXIF segment // more information here: http://www.ozhiker.com/electronics/pjmt/jpeg_info/panasonic_mn.html ProcessIFD(metadata.GetOrCreateDirectory <PanasonicMakernoteDirectory>(), processedIfdOffsets, makernoteOffset + 12, tiffHeaderOffset, metadata, reader); } else { if ("AOC\u0000".Equals(firstFourChars)) { // NON-Standard TIFF IFD Data using Casio Type 2 Tags // IFD has no Next-IFD pointer at end of IFD, and // Offsets are relative to the start of the current IFD tag, not the TIFF header // Observed for: // - Pentax ist D ProcessIFD(metadata.GetOrCreateDirectory <CasioType2MakernoteDirectory>(), processedIfdOffsets, makernoteOffset + 6, makernoteOffset, metadata, reader); } else { if (cameraMake != null && (cameraMake.ToUpper().StartsWith("PENTAX") || cameraMake.ToUpper().StartsWith("ASAHI"))) { // NON-Standard TIFF IFD Data using Pentax Tags // IFD has no Next-IFD pointer at end of IFD, and // Offsets are relative to the start of the current IFD tag, not the TIFF header // Observed for: // - PENTAX Optio 330 // - PENTAX Optio 430 ProcessIFD(metadata.GetOrCreateDirectory <PentaxMakernoteDirectory>(), processedIfdOffsets, makernoteOffset, makernoteOffset, metadata, reader); } else { // } else if ("KC".equals(firstTwoChars) || "MINOL".equals(firstFiveChars) || "MLY".equals(firstThreeChars) || "+M+M+M+M".equals(firstEightChars)) { // // This Konica data is not understood. Header identified in accordance with information at this site: // // http://www.ozhiker.com/electronics/pjmt/jpeg_info/minolta_mn.html // // TODO add support for minolta/konica cameras // exifDirectory.addError("Unsupported Konica/Minolta data ignored."); if ("SANYO\x0\x1\x0".Equals(firstEightChars)) { ProcessIFD(metadata.GetOrCreateDirectory <SanyoMakernoteDirectory>(), processedIfdOffsets, makernoteOffset + 8, makernoteOffset, metadata, reader); } } } } } } } } } } } } } } } } // The makernote is not comprehended by this library. // If you are reading this and believe a particular camera's image should be processed, get in touch. reader.SetMotorolaByteOrder(byteOrderBefore); }