Ejemplo n.º 1
0
		private static void ProcessKodakMakernote(KodakMakernoteDirectory directory, int tagValueOffset, RandomAccessReader reader)
		{
			// Kodak's makernote is not in IFD format. It has values at fixed offsets.
			int dataOffset = tagValueOffset + 8;
			try
			{
				directory.SetString(KodakMakernoteDirectory.TagKodakModel, reader.GetString(dataOffset, 8));
				directory.SetInt(KodakMakernoteDirectory.TagQuality, reader.GetUInt8(dataOffset + 9));
				directory.SetInt(KodakMakernoteDirectory.TagBurstMode, reader.GetUInt8(dataOffset + 10));
				directory.SetInt(KodakMakernoteDirectory.TagImageWidth, reader.GetUInt16(dataOffset + 12));
				directory.SetInt(KodakMakernoteDirectory.TagImageHeight, reader.GetUInt16(dataOffset + 14));
				directory.SetInt(KodakMakernoteDirectory.TagYearCreated, reader.GetUInt16(dataOffset + 16));
				directory.SetByteArray(KodakMakernoteDirectory.TagMonthDayCreated, reader.GetBytes(dataOffset + 18, 2));
				directory.SetByteArray(KodakMakernoteDirectory.TagTimeCreated, reader.GetBytes(dataOffset + 20, 4));
				directory.SetInt(KodakMakernoteDirectory.TagBurstMode2, reader.GetUInt16(dataOffset + 24));
				directory.SetInt(KodakMakernoteDirectory.TagShutterMode, reader.GetUInt8(dataOffset + 27));
				directory.SetInt(KodakMakernoteDirectory.TagMeteringMode, reader.GetUInt8(dataOffset + 28));
				directory.SetInt(KodakMakernoteDirectory.TagSequenceNumber, reader.GetUInt8(dataOffset + 29));
				directory.SetInt(KodakMakernoteDirectory.TagFNumber, reader.GetUInt16(dataOffset + 30));
				directory.SetLong(KodakMakernoteDirectory.TagExposureTime, reader.GetUInt32(dataOffset + 32));
				directory.SetInt(KodakMakernoteDirectory.TagExposureCompensation, reader.GetInt16(dataOffset + 36));
				directory.SetInt(KodakMakernoteDirectory.TagFocusMode, reader.GetUInt8(dataOffset + 56));
				directory.SetInt(KodakMakernoteDirectory.TagWhiteBalance, reader.GetUInt8(dataOffset + 64));
				directory.SetInt(KodakMakernoteDirectory.TagFlashMode, reader.GetUInt8(dataOffset + 92));
				directory.SetInt(KodakMakernoteDirectory.TagFlashFired, reader.GetUInt8(dataOffset + 93));
				directory.SetInt(KodakMakernoteDirectory.TagIsoSetting, reader.GetUInt16(dataOffset + 94));
				directory.SetInt(KodakMakernoteDirectory.TagIso, reader.GetUInt16(dataOffset + 96));
				directory.SetInt(KodakMakernoteDirectory.TagTotalZoom, reader.GetUInt16(dataOffset + 98));
				directory.SetInt(KodakMakernoteDirectory.TagDateTimeStamp, reader.GetUInt16(dataOffset + 100));
				directory.SetInt(KodakMakernoteDirectory.TagColorMode, reader.GetUInt16(dataOffset + 102));
				directory.SetInt(KodakMakernoteDirectory.TagDigitalZoom, reader.GetUInt16(dataOffset + 104));
				directory.SetInt(KodakMakernoteDirectory.TagSharpness, reader.GetInt8(dataOffset + 107));
			}
			catch (IOException ex)
			{
				directory.AddError("Error processing Kodak makernote data: " + ex.Message);
			}
		}
Ejemplo n.º 2
0
        /// <exception cref="System.IO.IOException"/>
        private bool ProcessMakernote(int makernoteOffset, [NotNull] ICollection<int?> processedIfdOffsets, int tiffHeaderOffset, [NotNull] RandomAccessReader reader)
        {
            // Determine the camera model and makernote format.
            Com.Drew.Metadata.Directory ifd0Directory = _metadata.GetFirstDirectoryOfType<ExifIFD0Directory>();
            if (ifd0Directory == null)
            {
                return false;
            }
            string cameraMake = ifd0Directory.GetString(ExifIFD0Directory.TagMake);
            string firstTwoChars = reader.GetString(makernoteOffset, 2);
            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/
                PushDirectory(typeof(OlympusMakernoteDirectory));
                TiffReader.ProcessIfd(this, reader, processedIfdOffsets, makernoteOffset + 8, tiffHeaderOffset);
            }
            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.
                    PushDirectory(typeof(OlympusMakernoteDirectory));
                    TiffReader.ProcessIfd(this, reader, processedIfdOffsets, makernoteOffset, tiffHeaderOffset);
                }
                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
                 */
                                    PushDirectory(typeof(NikonType1MakernoteDirectory));
                                    TiffReader.ProcessIfd(this, reader, processedIfdOffsets, makernoteOffset + 8, tiffHeaderOffset);
                                    break;
                                }

                                case 2:
                                {
                                    PushDirectory(typeof(NikonType2MakernoteDirectory));
                                    TiffReader.ProcessIfd(this, reader, processedIfdOffsets, makernoteOffset + 18, makernoteOffset + 10);
                                    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.
                            PushDirectory(typeof(NikonType2MakernoteDirectory));
                            TiffReader.ProcessIfd(this, reader, processedIfdOffsets, makernoteOffset, tiffHeaderOffset);
                        }
                    }
                    else
                    {
                        if ("SONY CAM".Equals(firstEightChars) || "SONY DSC".Equals(firstEightChars))
                        {
                            PushDirectory(typeof(SonyType1MakernoteDirectory));
                            TiffReader.ProcessIfd(this, reader, processedIfdOffsets, makernoteOffset + 12, tiffHeaderOffset);
                        }
                        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
                                PushDirectory(typeof(SonyType6MakernoteDirectory));
                                TiffReader.ProcessIfd(this, reader, processedIfdOffsets, makernoteOffset + 20, tiffHeaderOffset);
                            }
                            else
                            {
                                if ("SIGMA\u0000\u0000\u0000".Equals(firstEightChars) || "FOVEON\u0000\u0000".Equals(firstEightChars))
                                {
                                    PushDirectory(typeof(SigmaMakernoteDirectory));
                                    TiffReader.ProcessIfd(this, reader, processedIfdOffsets, makernoteOffset + 10, tiffHeaderOffset);
                                }
                                else
                                {
                                    if ("KDK".Equals(firstThreeChars))
                                    {
                                        reader.SetMotorolaByteOrder(firstSevenChars.Equals("KDK INFO"));
                                        KodakMakernoteDirectory directory = new KodakMakernoteDirectory();
                                        _metadata.AddDirectory(directory);
                                        ProcessKodakMakernote(directory, makernoteOffset, reader);
                                    }
                                    else
                                    {
                                        if (Sharpen.Runtime.EqualsIgnoreCase("Canon", cameraMake))
                                        {
                                            PushDirectory(typeof(CanonMakernoteDirectory));
                                            TiffReader.ProcessIfd(this, reader, processedIfdOffsets, makernoteOffset, tiffHeaderOffset);
                                        }
                                        else
                                        {
                                            if (cameraMake != null && cameraMake.ToUpper().StartsWith("CASIO"))
                                            {
                                                if ("QVC\u0000\u0000\u0000".Equals(firstSixChars))
                                                {
                                                    PushDirectory(typeof(CasioType2MakernoteDirectory));
                                                    TiffReader.ProcessIfd(this, reader, processedIfdOffsets, makernoteOffset + 6, tiffHeaderOffset);
                                                }
                                                else
                                                {
                                                    PushDirectory(typeof(CasioType1MakernoteDirectory));
                                                    TiffReader.ProcessIfd(this, reader, processedIfdOffsets, makernoteOffset, tiffHeaderOffset);
                                                }
                                            }
                                            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);
                                                    PushDirectory(typeof(FujifilmMakernoteDirectory));
                                                    TiffReader.ProcessIfd(this, reader, processedIfdOffsets, ifdStart, makernoteOffset);
                                                }
                                                else
                                                {
                                                    if ("KYOCERA".Equals(firstSevenChars))
                                                    {
                                                        // http://www.ozhiker.com/electronics/pjmt/jpeg_info/kyocera_mn.html
                                                        PushDirectory(typeof(KyoceraMakernoteDirectory));
                                                        TiffReader.ProcessIfd(this, reader, processedIfdOffsets, makernoteOffset + 22, tiffHeaderOffset);
                                                    }
                                                    else
                                                    {
                                                        if ("LEICA".Equals(firstFiveChars))
                                                        {
                                                            reader.SetMotorolaByteOrder(false);
                                                            if ("Leica Camera AG".Equals(cameraMake))
                                                            {
                                                                PushDirectory(typeof(LeicaMakernoteDirectory));
                                                                TiffReader.ProcessIfd(this, reader, processedIfdOffsets, makernoteOffset + 8, tiffHeaderOffset);
                                                            }
                                                            else
                                                            {
                                                                if ("LEICA".Equals(cameraMake))
                                                                {
                                                                    // Some Leica cameras use Panasonic makernote tags
                                                                    PushDirectory(typeof(PanasonicMakernoteDirectory));
                                                                    TiffReader.ProcessIfd(this, reader, processedIfdOffsets, makernoteOffset + 8, tiffHeaderOffset);
                                                                }
                                                                else
                                                                {
                                                                    return false;
                                                                }
                                                            }
                                                        }
                                                        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
                                                                PushDirectory(typeof(PanasonicMakernoteDirectory));
                                                                TiffReader.ProcessIfd(this, reader, processedIfdOffsets, makernoteOffset + 12, tiffHeaderOffset);
                                                            }
                                                            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
                                                                    PushDirectory(typeof(CasioType2MakernoteDirectory));
                                                                    TiffReader.ProcessIfd(this, reader, processedIfdOffsets, makernoteOffset + 6, makernoteOffset);
                                                                }
                                                                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
                                                                        PushDirectory(typeof(PentaxMakernoteDirectory));
                                                                        TiffReader.ProcessIfd(this, reader, processedIfdOffsets, makernoteOffset, makernoteOffset);
                                                                    }
                                                                    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))
                                                                        {
                                                                            PushDirectory(typeof(SanyoMakernoteDirectory));
                                                                            TiffReader.ProcessIfd(this, reader, processedIfdOffsets, makernoteOffset + 8, makernoteOffset);
                                                                        }
                                                                        else
                                                                        {
                                                                            if (cameraMake != null && cameraMake.ToLower().StartsWith("ricoh"))
                                                                            {
                                                                                if (firstTwoChars.Equals("Rv") || firstThreeChars.Equals("Rev"))
                                                                                {
                                                                                    // This is a textual format, where the makernote bytes look like:
                                                                                    //   Rv0103;Rg1C;Bg18;Ll0;Ld0;Aj0000;Bn0473800;Fp2E00:������������������������������
                                                                                    //   Rv0103;Rg1C;Bg18;Ll0;Ld0;Aj0000;Bn0473800;Fp2D05:������������������������������
                                                                                    //   Rv0207;Sf6C84;Rg76;Bg60;Gg42;Ll0;Ld0;Aj0004;Bn0B02900;Fp10B8;Md6700;Ln116900086D27;Sv263:0000000000000000000000��
                                                                                    // This format is currently unsupported
                                                                                    return false;
                                                                                }
                                                                                else
                                                                                {
                                                                                    if (Sharpen.Runtime.EqualsIgnoreCase(firstFiveChars, "Ricoh"))
                                                                                    {
                                                                                        // Always in Motorola byte order
                                                                                        reader.SetMotorolaByteOrder(true);
                                                                                        PushDirectory(typeof(RicohMakernoteDirectory));
                                                                                        TiffReader.ProcessIfd(this, reader, processedIfdOffsets, makernoteOffset + 8, makernoteOffset);
                                                                                    }
                                                                                }
                                                                            }
                                                                            else
                                                                            {
                                                                                // 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.
                                                                                return false;
                                                                            }
                                                                        }
                                                                    }
                                                                }
                                                            }
                                                        }
                                                    }
                                                }
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
            reader.SetMotorolaByteOrder(byteOrderBefore);
            return true;
        }