Ejemplo n.º 1
0
 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>();
 }
Ejemplo n.º 2
0
 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);
 }
Ejemplo n.º 3
0
        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;
		}
Ejemplo n.º 6
0
		/// <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;
		}
Ejemplo n.º 7
0
        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);
        }
Ejemplo n.º 8
0
        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);
        }
Ejemplo n.º 9
0
		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;
		}
Ejemplo n.º 10
0
		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;
		}
Ejemplo n.º 11
0
		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);
		}
Ejemplo n.º 12
0
        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);
        }
Ejemplo n.º 13
0
        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);
        }
Ejemplo n.º 14
0
        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);
        }
Ejemplo n.º 15
0
        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);
                    }
                }
            }
        }
Ejemplo n.º 16
0
 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));
 }
Ejemplo n.º 17
0
        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);
        }