コード例 #1
0
    /// <summary>
    ///     Reads the APP0 section containing JFIF metadata.
    /// </summary>
    private void ReadJFIFAPP0()
    {
        // Find the APP0 section containing JFIF metadata
        _jfifApp0 = Sections.Find(a => a.Marker == JPEGMarker.APP0 &&
                                  a.Header.Length >= 5 &&
                                  Encoding.ASCII.GetString(a.Header, 0, 5) == "JFIF\0");

        // If there is no APP0 section, return.
        if (_jfifApp0 == null)
        {
            return;
        }

        var            header   = _jfifApp0.Header;
        BitConverterEx jfifConv = BitConverterEx.BigEndian;

        // Version
        var version = jfifConv.ToUInt16(header, 5);

        Properties.Add(new JFIFVersion(ExifTag.JFIFVersion, version));

        // Units
        var unit = header[7];

        Properties.Add(new ExifEnumProperty <JFIFDensityUnit>(ExifTag.JFIFUnits, (JFIFDensityUnit)unit));

        // X and Y densities
        var xdensity = jfifConv.ToUInt16(header, 8);

        Properties.Add(new ExifUShort(ExifTag.XDensity, xdensity));
        var ydensity = jfifConv.ToUInt16(header, 10);

        Properties.Add(new ExifUShort(ExifTag.YDensity, ydensity));

        // Thumbnails pixel count
        var xthumbnail = header[12];

        Properties.Add(new ExifByte(ExifTag.JFIFXThumbnail, xthumbnail));
        var ythumbnail = header[13];

        Properties.Add(new ExifByte(ExifTag.JFIFYThumbnail, ythumbnail));

        // Read JFIF thumbnail
        var n             = xthumbnail * ythumbnail;
        var jfifThumbnail = new byte[n];

        Array.Copy(header, 14, jfifThumbnail, 0, n);
        Properties.Add(new JFIFThumbnailProperty(ExifTag.JFIFThumbnail, new JFIFThumbnail(JFIFThumbnail.ImageFormat.JPEG, jfifThumbnail)));
    }
コード例 #2
0
    /// <summary>
    ///     Returns a <see cref="ImageFileDirectoryEntry" /> initialized from the given byte data.
    /// </summary>
    /// <param name="data">The data.</param>
    /// <param name="offset">The offset into <paramref name="data" />.</param>
    /// <param name="byteOrder">The byte order of <paramref name="data" />.</param>
    /// <returns>A <see cref="ImageFileDirectoryEntry" /> initialized from the given byte data.</returns>
    public static ImageFileDirectoryEntry FromBytes(byte[] data, uint offset, BitConverterEx.ByteOrder byteOrder)
    {
        // Tag ID
        var tag = BitConverterEx.ToUInt16(data, offset, byteOrder, BitConverterEx.SystemByteOrder);

        // Tag Type
        var type = BitConverterEx.ToUInt16(data, offset + 2, byteOrder, BitConverterEx.SystemByteOrder);

        // Count of Type
        var count = BitConverterEx.ToUInt32(data, offset + 4, byteOrder, BitConverterEx.SystemByteOrder);

        // Field value or offset to field data
        var value = new byte[4];

        Array.Copy(data, offset + 8, value, 0, 4);

        // Calculate the bytes we need to read
        var baselength  = GetBaseLength(type);
        var totallength = count * baselength;

        // If field value does not fit in 4 bytes
        // the value field is an offset to the actual
        // field value
        if (totallength > 4)
        {
            var dataoffset = BitConverterEx.ToUInt32(value, 0, byteOrder, BitConverterEx.SystemByteOrder);
            value = new byte[totallength];
            Array.Copy(data, dataoffset, value, 0, totallength);
        }

        // Reverse array order if byte orders are different
        if (byteOrder != BitConverterEx.SystemByteOrder)
        {
            for (uint i = 0; i < count; i++)
            {
                var val = new byte[baselength];
                Array.Copy(value, i * baselength, val, 0, baselength);
                Array.Reverse(val);
                Array.Copy(val, 0, value, i * baselength, baselength);
            }
        }

        return(new ImageFileDirectoryEntry(tag, type, count, value));
    }
コード例 #3
0
ファイル: ExifFile.cs プロジェクト: Sinsyne/Global
        /// <summary>
        /// 读取包含的Exif元数据APP1部分
        /// </summary>
        private void ReadAPP1()
        {
            // Find the APP1 section containing Exif metadata
            app1 = file.Sections.Find(a => (a.Marker == JPEGMarker.APP1) &&
                                      (Encoding.ASCII.GetString(a.Header, 0, 6) == "Exif\0\0"));

            // If there is no APP1 section, add a new one after the last APP0 section (if any).
            if (app1 == null)
            {
                int insertionIndex = file.Sections.FindLastIndex(a => a.Marker == JPEGMarker.APP0);
                if (insertionIndex == -1)
                {
                    insertionIndex = 0;
                }
                insertionIndex++;
                ByteOrder = BitConverterEx.ByteOrder.BigEndian;
                app1      = new JPEGSection(JPEGMarker.APP1);
                file.Sections.Insert(insertionIndex, app1);
                return;
            }

            byte[] header = app1.Header;
            SortedList <int, IFD> ifdqueue = new SortedList <int, IFD>();

            makerNoteOffset = 0;

            // TIFF header
            int tiffoffset = 6;

            if (header[tiffoffset] == 0x49)
            {
                ByteOrder = BitConverterEx.ByteOrder.LittleEndian;
            }
            else
            {
                ByteOrder = BitConverterEx.ByteOrder.BigEndian;
            }
            BitConverterEx conv = new BitConverterEx(ByteOrder, BitConverterEx.ByteOrder.System);

            // Offset to 0th IFD
            int ifd0offset = (int)conv.ToUInt32(header, tiffoffset + 4);

            ifdqueue.Add(ifd0offset, IFD.Zeroth);

            int thumboffset = -1;
            int thumblength = 0;
            int thumbtype   = -1;

            // Read IFDs
            while (ifdqueue.Count != 0)
            {
                int ifdoffset  = tiffoffset + ifdqueue.Keys[0];
                IFD currentifd = ifdqueue.Values[0];
                ifdqueue.RemoveAt(0);

                // Field count
                ushort fieldcount = conv.ToUInt16(header, ifdoffset);
                for (short i = 0; i < fieldcount; i++)
                {
                    // Read field info
                    int    fieldoffset = ifdoffset + 2 + 12 * i;
                    ushort tag         = conv.ToUInt16(header, fieldoffset);
                    ushort type        = conv.ToUInt16(header, fieldoffset + 2);
                    uint   count       = conv.ToUInt32(header, fieldoffset + 4);
                    byte[] value       = new byte[4];
                    Array.Copy(header, fieldoffset + 8, value, 0, 4);

                    // Fields containing offsets to other IFDs
                    if (currentifd == IFD.Zeroth && tag == 0x8769)
                    {
                        int exififdpointer = (int)conv.ToUInt32(value, 0);
                        ifdqueue.Add(exififdpointer, IFD.EXIF);
                    }
                    else if (currentifd == IFD.Zeroth && tag == 0x8825)
                    {
                        int gpsifdpointer = (int)conv.ToUInt32(value, 0);
                        ifdqueue.Add(gpsifdpointer, IFD.GPS);
                    }
                    else if (currentifd == IFD.EXIF && tag == 0xa005)
                    {
                        int interopifdpointer = (int)conv.ToUInt32(value, 0);
                        ifdqueue.Add(interopifdpointer, IFD.Interop);
                    }

                    // Save the offset to maker note data
                    if (currentifd == IFD.EXIF && tag == 37500)
                    {
                        makerNoteOffset = conv.ToUInt32(value, 0);
                    }

                    // Calculate the bytes we need to read
                    uint baselength = 0;
                    if (type == 1 || type == 2 || type == 7)
                    {
                        baselength = 1;
                    }
                    else if (type == 3)
                    {
                        baselength = 2;
                    }
                    else if (type == 4 || type == 9)
                    {
                        baselength = 4;
                    }
                    else if (type == 5 || type == 10)
                    {
                        baselength = 8;
                    }
                    uint totallength = count * baselength;

                    // If field value does not fit in 4 bytes
                    // the value field is an offset to the actual
                    // field value
                    int fieldposition = 0;
                    if (totallength > 4)
                    {
                        fieldposition = tiffoffset + (int)conv.ToUInt32(value, 0);
                        value         = new byte[totallength];
                        Array.Copy(header, fieldposition, value, 0, totallength);
                    }

                    // Compressed thumbnail data
                    if (currentifd == IFD.First && tag == 0x201)
                    {
                        thumbtype   = 0;
                        thumboffset = (int)conv.ToUInt32(value, 0);
                    }
                    else if (currentifd == IFD.First && tag == 0x202)
                    {
                        thumblength = (int)conv.ToUInt32(value, 0);
                    }

                    // Uncompressed thumbnail data
                    if (currentifd == IFD.First && tag == 0x111)
                    {
                        thumbtype = 1;
                        // Offset to first strip
                        if (type == 3)
                        {
                            thumboffset = (int)conv.ToUInt16(value, 0);
                        }
                        else
                        {
                            thumboffset = (int)conv.ToUInt32(value, 0);
                        }
                    }
                    else if (currentifd == IFD.First && tag == 0x117)
                    {
                        thumblength = 0;
                        for (int j = 0; j < count; j++)
                        {
                            if (type == 3)
                            {
                                thumblength += (int)conv.ToUInt16(value, 0);
                            }
                            else
                            {
                                thumblength += (int)conv.ToUInt32(value, 0);
                            }
                        }
                    }

                    // Create the exif property from the interop data
                    ExifProperty prop = ExifPropertyFactory.Get(tag, type, count, value, ByteOrder, currentifd);
                    Properties.Add(prop.Tag, prop);
                }

                // 1st IFD pointer
                int firstifdpointer = (int)conv.ToUInt32(header, ifdoffset + 2 + 12 * fieldcount);
                if (firstifdpointer != 0)
                {
                    ifdqueue.Add(firstifdpointer, IFD.First);
                }
                // Read thumbnail
                if (thumboffset != -1 && thumblength != 0 && Thumbnail == null)
                {
                    if (thumbtype == 0)
                    {
                        using (MemoryStream ts = new MemoryStream(header, tiffoffset + thumboffset, thumblength))
                        {
                            Thumbnail = new JPEGFile(ts);
                        }
                    }
                }
            }
        }
コード例 #4
0
    /// <summary>
    ///     Reads the APP1 section containing Exif metadata.
    /// </summary>
    private void ReadExifAPP1()
    {
        // Find the APP1 section containing Exif metadata
        _exifApp1 = Sections.Find(a => a.Marker == JPEGMarker.APP1 &&
                                  a.Header.Length >= 6 &&
                                  Encoding.ASCII.GetString(a.Header, 0, 6) == "Exif\0\0");

        // If there is no APP1 section, add a new one after the last APP0 section (if any).
        if (_exifApp1 == null)
        {
            var insertionIndex = Sections.FindLastIndex(a => a.Marker == JPEGMarker.APP0);
            if (insertionIndex == -1)
            {
                insertionIndex = 0;
            }

            insertionIndex++;
            _exifApp1 = new JPEGSection(JPEGMarker.APP1);
            Sections.Insert(insertionIndex, _exifApp1);
            if (BitConverterEx.SystemByteOrder == BitConverterEx.ByteOrder.LittleEndian)
            {
                ByteOrder = BitConverterEx.ByteOrder.LittleEndian;
            }
            else
            {
                ByteOrder = BitConverterEx.ByteOrder.BigEndian;
            }

            return;
        }

        var header   = _exifApp1.Header;
        var ifdqueue = new SortedList <int, IFD>();

        _makerNoteOffset = 0;

        // TIFF header
        var tiffoffset = 6;

        if (header[tiffoffset] == 0x49 && header[tiffoffset + 1] == 0x49)
        {
            ByteOrder = BitConverterEx.ByteOrder.LittleEndian;
        }
        else if (header[tiffoffset] == 0x4D && header[tiffoffset + 1] == 0x4D)
        {
            ByteOrder = BitConverterEx.ByteOrder.BigEndian;
        }
        else
        {
            throw new NotValidExifFileException();
        }

        // TIFF header may have a different byte order
        BitConverterEx.ByteOrder tiffByteOrder = ByteOrder;
        if (BitConverterEx.LittleEndian.ToUInt16(header, tiffoffset + 2) == 42)
        {
            tiffByteOrder = BitConverterEx.ByteOrder.LittleEndian;
        }
        else if (BitConverterEx.BigEndian.ToUInt16(header, tiffoffset + 2) == 42)
        {
            tiffByteOrder = BitConverterEx.ByteOrder.BigEndian;
        }
        else
        {
            throw new NotValidExifFileException();
        }

        // Offset to 0th IFD
        var ifd0offset = (int)BitConverterEx.ToUInt32(header, tiffoffset + 4, tiffByteOrder, BitConverterEx.SystemByteOrder);

        ifdqueue.Add(ifd0offset, IFD.Zeroth);

        var conv        = new BitConverterEx(ByteOrder, BitConverterEx.SystemByteOrder);
        var thumboffset = -1;
        var thumblength = 0;
        var thumbtype   = -1;

        // Read IFDs
        while (ifdqueue.Count != 0)
        {
            var ifdoffset  = tiffoffset + ifdqueue.Keys[0];
            IFD currentifd = ifdqueue.Values[0];
            ifdqueue.RemoveAt(0);

            // Field count
            var fieldcount = conv.ToUInt16(header, ifdoffset);
            for (short i = 0; i < fieldcount; i++)
            {
                // Read field info
                var fieldoffset = ifdoffset + 2 + (12 * i);
                var tag         = conv.ToUInt16(header, fieldoffset);
                var type        = conv.ToUInt16(header, fieldoffset + 2);
                var count       = conv.ToUInt32(header, fieldoffset + 4);
                var value       = new byte[4];
                Array.Copy(header, fieldoffset + 8, value, 0, 4);

                // Fields containing offsets to other IFDs
                if (currentifd == IFD.Zeroth && tag == 0x8769)
                {
                    var exififdpointer = (int)conv.ToUInt32(value, 0);
                    ifdqueue.Add(exififdpointer, IFD.EXIF);
                }
                else if (currentifd == IFD.Zeroth && tag == 0x8825)
                {
                    var gpsifdpointer = (int)conv.ToUInt32(value, 0);
                    ifdqueue.Add(gpsifdpointer, IFD.GPS);
                }
                else if (currentifd == IFD.EXIF && tag == 0xa005)
                {
                    var interopifdpointer = (int)conv.ToUInt32(value, 0);
                    ifdqueue.Add(interopifdpointer, IFD.Interop);
                }

                // Save the offset to maker note data
                if (currentifd == IFD.EXIF && tag == 37500)
                {
                    _makerNoteOffset = conv.ToUInt32(value, 0);
                }

                // Calculate the bytes we need to read
                uint baselength = 0;
                if (type == 1 || type == 2 || type == 7)
                {
                    baselength = 1;
                }
                else if (type == 3)
                {
                    baselength = 2;
                }
                else if (type == 4 || type == 9)
                {
                    baselength = 4;
                }
                else if (type == 5 || type == 10)
                {
                    baselength = 8;
                }

                var totallength = count * baselength;

                // If field value does not fit in 4 bytes
                // the value field is an offset to the actual
                // field value
                var fieldposition = 0;
                if (totallength > 4)
                {
                    fieldposition = tiffoffset + (int)conv.ToUInt32(value, 0);
                    value         = new byte[totallength];
                    Array.Copy(header, fieldposition, value, 0, totallength);
                }

                // Compressed thumbnail data
                if (currentifd == IFD.First && tag == 0x201)
                {
                    thumbtype   = 0;
                    thumboffset = (int)conv.ToUInt32(value, 0);
                }
                else if (currentifd == IFD.First && tag == 0x202)
                {
                    thumblength = (int)conv.ToUInt32(value, 0);
                }

                // Uncompressed thumbnail data
                if (currentifd == IFD.First && tag == 0x111)
                {
                    thumbtype = 1;

                    // Offset to first strip
                    if (type == 3)
                    {
                        thumboffset = conv.ToUInt16(value, 0);
                    }
                    else
                    {
                        thumboffset = (int)conv.ToUInt32(value, 0);
                    }
                }
                else if (currentifd == IFD.First && tag == 0x117)
                {
                    thumblength = 0;
                    for (var j = 0; j < count; j++)
                    {
                        if (type == 3)
                        {
                            thumblength += conv.ToUInt16(value, 0);
                        }
                        else
                        {
                            thumblength += (int)conv.ToUInt32(value, 0);
                        }
                    }
                }

                // Create the exif property from the interop data
                ExifProperty prop = ExifPropertyFactory.Get(tag, type, count, value, ByteOrder, currentifd, Encoding);
                Properties.Add(prop);
            }

            // 1st IFD pointer
            var firstifdpointer = (int)conv.ToUInt32(header, ifdoffset + 2 + (12 * fieldcount));
            if (firstifdpointer != 0)
            {
                ifdqueue.Add(firstifdpointer, IFD.First);
            }

            // Read thumbnail
            if (thumboffset != -1 && thumblength != 0 && Thumbnail == null)
            {
                if (thumbtype == 0)
                {
                    using (var ts = new MemoryStream(header, tiffoffset + thumboffset, thumblength))
                    {
                        Thumbnail = FromStream(ts);
                    }
                }
            }
        }
    }
コード例 #5
0
    /// <summary>
    ///     Creates an ExifProperty from the given interoperability parameters.
    /// </summary>
    /// <param name="tag">The tag id of the exif property.</param>
    /// <param name="type">The type id of the exif property.</param>
    /// <param name="count">Byte or component count.</param>
    /// <param name="value">Field data as an array of bytes.</param>
    /// <param name="byteOrder">Byte order of value.</param>
    /// <param name="ifd">IFD section containing this property.</param>
    /// <param name="encoding">The encoding to be used for text metadata when the source encoding is unknown.</param>
    /// <returns>an ExifProperty initialized from the interoperability parameters.</returns>
    public static ExifProperty Get(ushort tag, ushort type, uint count, byte[] value, BitConverterEx.ByteOrder byteOrder, IFD ifd, Encoding encoding)
    {
        var conv = new BitConverterEx(byteOrder, BitConverterEx.SystemByteOrder);

        // Find the exif tag corresponding to given tag id
        ExifTag etag = ExifTagFactory.GetExifTag(ifd, tag);

        if (ifd == IFD.Zeroth)
        {
            // Compression
            if (tag == 0x103)
            {
                return(new ExifEnumProperty <Compression>(ExifTag.Compression, (Compression)conv.ToUInt16(value, 0)));
            }

            // PhotometricInterpretation
            if (tag == 0x106)
            {
                return(new ExifEnumProperty <PhotometricInterpretation>(
                           ExifTag.PhotometricInterpretation,
                           (PhotometricInterpretation)conv.ToUInt16(value, 0)));
            }

            // Orientation
            if (tag == 0x112)
            {
                return(new ExifEnumProperty <Orientation>(ExifTag.Orientation, (Orientation)conv.ToUInt16(value, 0)));
            }

            // PlanarConfiguration
            if (tag == 0x11c)
            {
                return(new ExifEnumProperty <PlanarConfiguration>(
                           ExifTag.PlanarConfiguration,
                           (PlanarConfiguration)conv.ToUInt16(value, 0)));
            }

            // YCbCrPositioning
            if (tag == 0x213)
            {
                return(new ExifEnumProperty <YCbCrPositioning>(
                           ExifTag.YCbCrPositioning,
                           (YCbCrPositioning)conv.ToUInt16(value, 0)));
            }

            // ResolutionUnit
            if (tag == 0x128)
            {
                return(new ExifEnumProperty <ResolutionUnit>(
                           ExifTag.ResolutionUnit,
                           (ResolutionUnit)conv.ToUInt16(value, 0)));
            }

            // DateTime
            if (tag == 0x132)
            {
                return(new ExifDateTime(ExifTag.DateTime, ExifBitConverter.ToDateTime(value)));
            }

            if (tag == 0x9c9b || tag == 0x9c9c || // Windows tags
                tag == 0x9c9d || tag == 0x9c9e || tag == 0x9c9f)
            {
                return(new WindowsByteString(
                           etag,
                           Encoding.Unicode.GetString(value).TrimEnd(Constants.CharArrays.NullTerminator)));
            }
        }
        else if (ifd == IFD.EXIF)
        {
            // ExifVersion
            if (tag == 0x9000)
            {
                return(new ExifVersion(ExifTag.ExifVersion, ExifBitConverter.ToAscii(value, Encoding.ASCII)));
            }

            // FlashpixVersion
            if (tag == 0xa000)
            {
                return(new ExifVersion(ExifTag.FlashpixVersion, ExifBitConverter.ToAscii(value, Encoding.ASCII)));
            }

            // ColorSpace
            if (tag == 0xa001)
            {
                return(new ExifEnumProperty <ColorSpace>(ExifTag.ColorSpace, (ColorSpace)conv.ToUInt16(value, 0)));
            }

            // UserComment
            if (tag == 0x9286)
            {
                // Default to ASCII
                Encoding enc = Encoding.ASCII;
                bool     hasenc;
                if (value.Length < 8)
                {
                    hasenc = false;
                }
                else
                {
                    hasenc = true;
                    var encstr = enc.GetString(value, 0, 8);
                    if (string.Compare(encstr, "ASCII\0\0\0", StringComparison.OrdinalIgnoreCase) == 0)
                    {
                        enc = Encoding.ASCII;
                    }
                    else if (string.Compare(encstr, "JIS\0\0\0\0\0", StringComparison.OrdinalIgnoreCase) == 0)
                    {
                        enc = Encoding.GetEncoding("Japanese (JIS 0208-1990 and 0212-1990)");
                    }
                    else if (string.Compare(encstr, "Unicode\0", StringComparison.OrdinalIgnoreCase) == 0)
                    {
                        enc = Encoding.Unicode;
                    }
                    else
                    {
                        hasenc = false;
                    }
                }

                var val = (hasenc ? enc.GetString(value, 8, value.Length - 8) : enc.GetString(value)).Trim(
                    Constants.CharArrays.NullTerminator);

                return(new ExifEncodedString(ExifTag.UserComment, val, enc));
            }

            // DateTimeOriginal
            if (tag == 0x9003)
            {
                return(new ExifDateTime(ExifTag.DateTimeOriginal, ExifBitConverter.ToDateTime(value)));
            }

            // DateTimeDigitized
            if (tag == 0x9004)
            {
                return(new ExifDateTime(ExifTag.DateTimeDigitized, ExifBitConverter.ToDateTime(value)));
            }

            // ExposureProgram
            if (tag == 0x8822)
            {
                return(new ExifEnumProperty <ExposureProgram>(
                           ExifTag.ExposureProgram,
                           (ExposureProgram)conv.ToUInt16(value, 0)));
            }

            // MeteringMode
            if (tag == 0x9207)
            {
                return(new ExifEnumProperty <MeteringMode>(ExifTag.MeteringMode, (MeteringMode)conv.ToUInt16(value, 0)));
            }

            // LightSource
            if (tag == 0x9208)
            {
                return(new ExifEnumProperty <LightSource>(ExifTag.LightSource, (LightSource)conv.ToUInt16(value, 0)));
            }

            // Flash
            if (tag == 0x9209)
            {
                return(new ExifEnumProperty <Flash>(ExifTag.Flash, (Flash)conv.ToUInt16(value, 0), true));
            }

            // SubjectArea
            if (tag == 0x9214)
            {
                if (count == 3)
                {
                    return(new ExifCircularSubjectArea(
                               ExifTag.SubjectArea,
                               ExifBitConverter.ToUShortArray(value, (int)count, byteOrder)));
                }

                if (count == 4)
                {
                    return(new ExifRectangularSubjectArea(
                               ExifTag.SubjectArea,
                               ExifBitConverter.ToUShortArray(value, (int)count, byteOrder)));
                }

                return(new ExifPointSubjectArea(
                           ExifTag.SubjectArea,
                           ExifBitConverter.ToUShortArray(value, (int)count, byteOrder)));
            }

            // FocalPlaneResolutionUnit
            if (tag == 0xa210)
            {
                return(new ExifEnumProperty <ResolutionUnit>(
                           ExifTag.FocalPlaneResolutionUnit,
                           (ResolutionUnit)conv.ToUInt16(value, 0),
                           true));
            }

            // SubjectLocation
            if (tag == 0xa214)
            {
                return(new ExifPointSubjectArea(
                           ExifTag.SubjectLocation,
                           ExifBitConverter.ToUShortArray(value, (int)count, byteOrder)));
            }

            // SensingMethod
            if (tag == 0xa217)
            {
                return(new ExifEnumProperty <SensingMethod>(
                           ExifTag.SensingMethod,
                           (SensingMethod)conv.ToUInt16(value, 0),
                           true));
            }

            // FileSource
            if (tag == 0xa300)
            {
                return(new ExifEnumProperty <FileSource>(ExifTag.FileSource, (FileSource)conv.ToUInt16(value, 0), true));
            }

            // SceneType
            if (tag == 0xa301)
            {
                return(new ExifEnumProperty <SceneType>(ExifTag.SceneType, (SceneType)conv.ToUInt16(value, 0), true));
            }

            // CustomRendered
            if (tag == 0xa401)
            {
                return(new ExifEnumProperty <CustomRendered>(
                           ExifTag.CustomRendered,
                           (CustomRendered)conv.ToUInt16(value, 0),
                           true));
            }

            // ExposureMode
            if (tag == 0xa402)
            {
                return(new ExifEnumProperty <ExposureMode>(ExifTag.ExposureMode, (ExposureMode)conv.ToUInt16(value, 0), true));
            }

            // WhiteBalance
            if (tag == 0xa403)
            {
                return(new ExifEnumProperty <WhiteBalance>(ExifTag.WhiteBalance, (WhiteBalance)conv.ToUInt16(value, 0), true));
            }

            // SceneCaptureType
            if (tag == 0xa406)
            {
                return(new ExifEnumProperty <SceneCaptureType>(
                           ExifTag.SceneCaptureType,
                           (SceneCaptureType)conv.ToUInt16(value, 0),
                           true));
            }

            // GainControl
            if (tag == 0xa407)
            {
                return(new ExifEnumProperty <GainControl>(ExifTag.GainControl, (GainControl)conv.ToUInt16(value, 0), true));
            }

            // Contrast
            if (tag == 0xa408)
            {
                return(new ExifEnumProperty <Contrast>(ExifTag.Contrast, (Contrast)conv.ToUInt16(value, 0), true));
            }

            // Saturation
            if (tag == 0xa409)
            {
                return(new ExifEnumProperty <Saturation>(ExifTag.Saturation, (Saturation)conv.ToUInt16(value, 0), true));
            }

            // Sharpness
            if (tag == 0xa40a)
            {
                return(new ExifEnumProperty <Sharpness>(ExifTag.Sharpness, (Sharpness)conv.ToUInt16(value, 0), true));
            }

            // SubjectDistanceRange
            if (tag == 0xa40c)
            {
                return(new ExifEnumProperty <SubjectDistanceRange>(
                           ExifTag.SubjectDistanceRange,
                           (SubjectDistanceRange)conv.ToUInt16(value, 0),
                           true));
            }
        }
        else if (ifd == IFD.GPS)
        {
            // GPSVersionID
            if (tag == 0)
            {
                return(new ExifVersion(ExifTag.GPSVersionID, ExifBitConverter.ToString(value)));
            }

            // GPSLatitudeRef
            if (tag == 1)
            {
                return(new ExifEnumProperty <GPSLatitudeRef>(ExifTag.GPSLatitudeRef, (GPSLatitudeRef)value[0]));
            }

            // GPSLatitude
            if (tag == 2)
            {
                return(new GPSLatitudeLongitude(
                           ExifTag.GPSLatitude,
                           ExifBitConverter.ToURationalArray(value, (int)count, byteOrder)));
            }

            // GPSLongitudeRef
            if (tag == 3)
            {
                return(new ExifEnumProperty <GPSLongitudeRef>(ExifTag.GPSLongitudeRef, (GPSLongitudeRef)value[0]));
            }

            // GPSLongitude
            if (tag == 4)
            {
                return(new GPSLatitudeLongitude(
                           ExifTag.GPSLongitude,
                           ExifBitConverter.ToURationalArray(value, (int)count, byteOrder)));
            }

            // GPSAltitudeRef
            if (tag == 5)
            {
                return(new ExifEnumProperty <GPSAltitudeRef>(ExifTag.GPSAltitudeRef, (GPSAltitudeRef)value[0]));
            }

            // GPSTimeStamp
            if (tag == 7)
            {
                return(new GPSTimeStamp(
                           ExifTag.GPSTimeStamp,
                           ExifBitConverter.ToURationalArray(value, (int)count, byteOrder)));
            }

            // GPSStatus
            if (tag == 9)
            {
                return(new ExifEnumProperty <GPSStatus>(ExifTag.GPSStatus, (GPSStatus)value[0]));
            }

            // GPSMeasureMode
            if (tag == 10)
            {
                return(new ExifEnumProperty <GPSMeasureMode>(ExifTag.GPSMeasureMode, (GPSMeasureMode)value[0]));
            }

            // GPSSpeedRef
            if (tag == 12)
            {
                return(new ExifEnumProperty <GPSSpeedRef>(ExifTag.GPSSpeedRef, (GPSSpeedRef)value[0]));
            }

            // GPSTrackRef
            if (tag == 14)
            {
                return(new ExifEnumProperty <GPSDirectionRef>(ExifTag.GPSTrackRef, (GPSDirectionRef)value[0]));
            }

            // GPSImgDirectionRef
            if (tag == 16)
            {
                return(new ExifEnumProperty <GPSDirectionRef>(ExifTag.GPSImgDirectionRef, (GPSDirectionRef)value[0]));
            }

            // GPSDestLatitudeRef
            if (tag == 19)
            {
                return(new ExifEnumProperty <GPSLatitudeRef>(ExifTag.GPSDestLatitudeRef, (GPSLatitudeRef)value[0]));
            }

            // GPSDestLatitude
            if (tag == 20)
            {
                return(new GPSLatitudeLongitude(
                           ExifTag.GPSDestLatitude,
                           ExifBitConverter.ToURationalArray(value, (int)count, byteOrder)));
            }

            // GPSDestLongitudeRef
            if (tag == 21)
            {
                return(new ExifEnumProperty <GPSLongitudeRef>(ExifTag.GPSDestLongitudeRef, (GPSLongitudeRef)value[0]));
            }

            // GPSDestLongitude
            if (tag == 22)
            {
                return(new GPSLatitudeLongitude(
                           ExifTag.GPSDestLongitude,
                           ExifBitConverter.ToURationalArray(value, (int)count, byteOrder)));
            }

            // GPSDestBearingRef
            if (tag == 23)
            {
                return(new ExifEnumProperty <GPSDirectionRef>(ExifTag.GPSDestBearingRef, (GPSDirectionRef)value[0]));
            }

            // GPSDestDistanceRef
            if (tag == 25)
            {
                return(new ExifEnumProperty <GPSDistanceRef>(ExifTag.GPSDestDistanceRef, (GPSDistanceRef)value[0]));
            }

            // GPSDate
            if (tag == 29)
            {
                return(new ExifDateTime(ExifTag.GPSDateStamp, ExifBitConverter.ToDateTime(value, false)));
            }

            // GPSDifferential
            if (tag == 30)
            {
                return(new ExifEnumProperty <GPSDifferential>(
                           ExifTag.GPSDifferential,
                           (GPSDifferential)conv.ToUInt16(value, 0)));
            }
        }
        else if (ifd == IFD.Interop)
        {
            // InteroperabilityIndex
            if (tag == 1)
            {
                return(new ExifAscii(ExifTag.InteroperabilityIndex, ExifBitConverter.ToAscii(value, Encoding.ASCII), Encoding.ASCII));
            }

            // InteroperabilityVersion
            if (tag == 2)
            {
                return(new ExifVersion(
                           ExifTag.InteroperabilityVersion,
                           ExifBitConverter.ToAscii(value, Encoding.ASCII)));
            }
        }
        else if (ifd == IFD.First)
        {
            // Compression
            if (tag == 0x103)
            {
                return(new ExifEnumProperty <Compression>(
                           ExifTag.ThumbnailCompression,
                           (Compression)conv.ToUInt16(value, 0)));
            }

            // PhotometricInterpretation
            if (tag == 0x106)
            {
                return(new ExifEnumProperty <PhotometricInterpretation>(
                           ExifTag.ThumbnailPhotometricInterpretation,
                           (PhotometricInterpretation)conv.ToUInt16(value, 0)));
            }

            // Orientation
            if (tag == 0x112)
            {
                return(new ExifEnumProperty <Orientation>(
                           ExifTag.ThumbnailOrientation,
                           (Orientation)conv.ToUInt16(value, 0)));
            }

            // PlanarConfiguration
            if (tag == 0x11c)
            {
                return(new ExifEnumProperty <PlanarConfiguration>(
                           ExifTag.ThumbnailPlanarConfiguration,
                           (PlanarConfiguration)conv.ToUInt16(value, 0)));
            }

            // YCbCrPositioning
            if (tag == 0x213)
            {
                return(new ExifEnumProperty <YCbCrPositioning>(
                           ExifTag.ThumbnailYCbCrPositioning,
                           (YCbCrPositioning)conv.ToUInt16(value, 0)));
            }

            // ResolutionUnit
            if (tag == 0x128)
            {
                return(new ExifEnumProperty <ResolutionUnit>(
                           ExifTag.ThumbnailResolutionUnit,
                           (ResolutionUnit)conv.ToUInt16(value, 0)));
            }

            // DateTime
            if (tag == 0x132)
            {
                return(new ExifDateTime(ExifTag.ThumbnailDateTime, ExifBitConverter.ToDateTime(value)));
            }
        }

        // 1 = BYTE An 8-bit unsigned integer.
        if (type == 1)
        {
            if (count == 1)
            {
                return(new ExifByte(etag, value[0]));
            }

            return(new ExifByteArray(etag, value));
        }

        // 2 = ASCII An 8-bit byte containing one 7-bit ASCII code.
        if (type == 2)
        {
            return(new ExifAscii(etag, ExifBitConverter.ToAscii(value, encoding), encoding));
        }

        // 3 = SHORT A 16-bit (2-byte) unsigned integer.
        if (type == 3)
        {
            if (count == 1)
            {
                return(new ExifUShort(etag, conv.ToUInt16(value, 0)));
            }

            return(new ExifUShortArray(etag, ExifBitConverter.ToUShortArray(value, (int)count, byteOrder)));
        }

        // 4 = LONG A 32-bit (4-byte) unsigned integer.
        if (type == 4)
        {
            if (count == 1)
            {
                return(new ExifUInt(etag, conv.ToUInt32(value, 0)));
            }

            return(new ExifUIntArray(etag, ExifBitConverter.ToUIntArray(value, (int)count, byteOrder)));
        }

        // 5 = RATIONAL Two LONGs. The first LONG is the numerator and the second LONG expresses the denominator.
        if (type == 5)
        {
            if (count == 1)
            {
                return(new ExifURational(etag, ExifBitConverter.ToURational(value, byteOrder)));
            }

            return(new ExifURationalArray(etag, ExifBitConverter.ToURationalArray(value, (int)count, byteOrder)));
        }

        // 7 = UNDEFINED An 8-bit byte that can take any value depending on the field definition.
        if (type == 7)
        {
            return(new ExifUndefined(etag, value));
        }

        // 9 = SLONG A 32-bit (4-byte) signed integer (2's complement notation).
        if (type == 9)
        {
            if (count == 1)
            {
                return(new ExifSInt(etag, conv.ToInt32(value, 0)));
            }

            return(new ExifSIntArray(etag, ExifBitConverter.ToSIntArray(value, (int)count, byteOrder)));
        }

        // 10 = SRATIONAL Two SLONGs. The first SLONG is the numerator and the second SLONG is the denominator.
        if (type == 10)
        {
            if (count == 1)
            {
                return(new ExifSRational(etag, ExifBitConverter.ToSRational(value, byteOrder)));
            }

            return(new ExifSRationalArray(etag, ExifBitConverter.ToSRationalArray(value, (int)count, byteOrder)));
        }

        throw new ArgumentException("Unknown property type.");
    }
コード例 #6
0
    /// <summary>
    ///     Returns a <see cref="ImageFileDirectory" /> initialized from the given byte data.
    /// </summary>
    /// <param name="data">The data.</param>
    /// <param name="offset">The offset into <paramref name="data" />.</param>
    /// <param name="byteOrder">The byte order of <paramref name="data" />.</param>
    /// <returns>A <see cref="ImageFileDirectory" /> initialized from the given byte data.</returns>
    public static ImageFileDirectory FromBytes(byte[] data, uint offset, BitConverterEx.ByteOrder byteOrder)
    {
        var ifd  = new ImageFileDirectory();
        var conv = new BitConverterEx(byteOrder, BitConverterEx.SystemByteOrder);

        var stripOffsets = new List <uint>();
        var stripLengths = new List <uint>();

        // Count
        var fieldcount = conv.ToUInt16(data, offset);

        // Read fields
        for (uint i = 0; i < fieldcount; i++)
        {
            var fieldoffset = offset + 2 + (12 * i);
            var field       = ImageFileDirectoryEntry.FromBytes(data, fieldoffset, byteOrder);
            ifd.Fields.Add(field);

            // Read strip offsets
            if (field.Tag == 273)
            {
                var baselen = field.Data.Length / (int)field.Count;
                for (uint j = 0; j < field.Count; j++)
                {
                    var val = new byte[baselen];
                    Array.Copy(field.Data, j * baselen, val, 0, baselen);
                    var stripOffset = field.Type == 3 ? BitConverter.ToUInt16(val, 0) : BitConverter.ToUInt32(val, 0);
                    stripOffsets.Add(stripOffset);
                }
            }

            // Read strip lengths
            if (field.Tag == 279)
            {
                var baselen = field.Data.Length / (int)field.Count;
                for (uint j = 0; j < field.Count; j++)
                {
                    var val = new byte[baselen];
                    Array.Copy(field.Data, j * baselen, val, 0, baselen);
                    var stripLength = field.Type == 3 ? BitConverter.ToUInt16(val, 0) : BitConverter.ToUInt32(val, 0);
                    stripLengths.Add(stripLength);
                }
            }
        }

        // Save strips
        if (stripOffsets.Count != stripLengths.Count)
        {
            throw new NotValidTIFFileException();
        }

        for (var i = 0; i < stripOffsets.Count; i++)
        {
            ifd.Strips.Add(new TIFFStrip(data, stripOffsets[i], stripLengths[i]));
        }

        // Offset to next ifd
        ifd.NextIFDOffset = conv.ToUInt32(data, offset + 2 + (12 * fieldcount));

        return(ifd);
    }
コード例 #7
0
        /// <summary>
        /// Creates an ExifProperty from the given interoperability parameters.
        /// </summary>
        /// <param name="tag">The tag id of the exif property.</param>
        /// <param name="type">The type id of the exif property.</param>
        /// <param name="count">Byte or component count.</param>
        /// <param name="value">Field data as an array of bytes.</param>
        /// <param name="byteOrder">Byte order of value.</param>
        /// <param name="ifd">IFD section containing this propery.</param>
        /// <returns>an ExifProperty initialized from the interoperability parameters.</returns>
        public static ExifProperty Get(ushort tag, ushort type, uint count, byte[] value, BitConverterEx.ByteOrder byteOrder, IFD ifd)
        {
            BitConverterEx conv = new BitConverterEx(byteOrder, BitConverterEx.ByteOrder.System);

            if (ifd == IFD.Zeroth)
            {
                if (tag == 0x103) // Compression
                {
                    return(new ExifEnumProperty <Compression>(ExifTag.Compression, (Compression)conv.ToUInt16(value, 0)));
                }
                else if (tag == 0x106) // PhotometricInterpretation
                {
                    return(new ExifEnumProperty <PhotometricInterpretation>(ExifTag.PhotometricInterpretation, (PhotometricInterpretation)conv.ToUInt16(value, 0)));
                }
                else if (tag == 0x112) // Orientation
                {
                    return(new ExifEnumProperty <Orientation>(ExifTag.Orientation, (Orientation)conv.ToUInt16(value, 0)));
                }
                else if (tag == 0x11c) // PlanarConfiguration
                {
                    return(new ExifEnumProperty <PlanarConfiguration>(ExifTag.PlanarConfiguration, (PlanarConfiguration)conv.ToUInt16(value, 0)));
                }
                else if (tag == 0x213) // YCbCrPositioning
                {
                    return(new ExifEnumProperty <YCbCrPositioning>(ExifTag.YCbCrPositioning, (YCbCrPositioning)conv.ToUInt16(value, 0)));
                }
                else if (tag == 0x128) // ResolutionUnit
                {
                    return(new ExifEnumProperty <ResolutionUnit>(ExifTag.ResolutionUnit, (ResolutionUnit)conv.ToUInt16(value, 0)));
                }
                else if (tag == 0x132) // DateTime
                {
                    return(new ExifDateTime(ExifTag.DateTime, ExifBitConverter.ToDateTime(value)));
                }
            }
            else if (ifd == IFD.EXIF)
            {
                if (tag == 0x9000) // ExifVersion
                {
                    return(new ExifVersion(ExifTag.ExifVersion, ExifBitConverter.ToAscii(value)));
                }
                else if (tag == 0xa000) // FlashpixVersion
                {
                    return(new ExifVersion(ExifTag.FlashpixVersion, ExifBitConverter.ToAscii(value)));
                }
                else if (tag == 0xa001) // ColorSpace
                {
                    return(new ExifEnumProperty <ColorSpace>(ExifTag.ColorSpace, (ColorSpace)conv.ToUInt16(value, 0)));
                }
                else if (tag == 0x9286) // UserComment
                {
                    byte[] encbytes = new byte[8];
                    byte[] strbytes = new byte[value.Length - 8];
                    Array.Copy(value, encbytes, 8);
                    Array.Copy(value, 8, strbytes, 0, value.Length - 8);
                    Encoding enc    = Encoding.ASCII;
                    string   encstr = enc.GetString(encbytes);
                    if (encstr == "ASCII\0\0\0")
                    {
                        enc = Encoding.ASCII;
                    }
                    else if (encstr == "JIS\0\0\0\0\0")
                    {
                        enc = Encoding.GetEncoding("Japanese (JIS 0208-1990 and 0212-1990)");
                    }
                    else if (encstr == "Unicode\0")
                    {
                        enc = Encoding.Unicode;
                    }
                    else
                    {
                        enc = null;
                    }

                    int len = Array.IndexOf(strbytes, (byte)0);
                    if (len == -1)
                    {
                        len = strbytes.Length;
                    }
                    return(new ExifEncodedString(ExifTag.UserComment, (enc == null ? Encoding.ASCII.GetString(strbytes, 0, len) : enc.GetString(strbytes, 0, len)), enc));
                }
                else if (tag == 0x9003) // DateTimeOriginal
                {
                    return(new ExifDateTime(ExifTag.DateTimeOriginal, ExifBitConverter.ToDateTime(value)));
                }
                else if (tag == 0x9004) // DateTimeDigitized
                {
                    return(new ExifDateTime(ExifTag.DateTimeDigitized, ExifBitConverter.ToDateTime(value)));
                }
                else if (tag == 0x8822) // ExposureProgram
                {
                    return(new ExifEnumProperty <ExposureProgram>(ExifTag.ExposureProgram, (ExposureProgram)conv.ToUInt16(value, 0)));
                }
                else if (tag == 0x9207) // MeteringMode
                {
                    return(new ExifEnumProperty <MeteringMode>(ExifTag.MeteringMode, (MeteringMode)conv.ToUInt16(value, 0)));
                }
                else if (tag == 0x9208) // LightSource
                {
                    return(new ExifEnumProperty <LightSource>(ExifTag.LightSource, (LightSource)conv.ToUInt16(value, 0)));
                }
                else if (tag == 0x9209) // Flash
                {
                    return(new ExifEnumProperty <Flash>(ExifTag.Flash, (Flash)conv.ToUInt16(value, 0), true));
                }
                else if (tag == 0x9214) // SubjectArea
                {
                    if (count == 3)
                    {
                        return(new ExifCircularSubjectArea(ExifTag.SubjectArea, ExifBitConverter.ToUShortArray(value, (int)count, byteOrder)));
                    }
                    else if (count == 4)
                    {
                        return(new ExifRectangularSubjectArea(ExifTag.SubjectArea, ExifBitConverter.ToUShortArray(value, (int)count, byteOrder)));
                    }
                    else // count == 2
                    {
                        return(new ExifPointSubjectArea(ExifTag.SubjectArea, ExifBitConverter.ToUShortArray(value, (int)count, byteOrder)));
                    }
                }
                else if (tag == 0xa210) // FocalPlaneResolutionUnit
                {
                    return(new ExifEnumProperty <ResolutionUnit>(ExifTag.FocalPlaneResolutionUnit, (ResolutionUnit)conv.ToUInt16(value, 0), true));
                }
                else if (tag == 0xa214) // SubjectLocation
                {
                    return(new ExifPointSubjectArea(ExifTag.SubjectLocation, ExifBitConverter.ToUShortArray(value, (int)count, byteOrder)));
                }
                else if (tag == 0xa217) // SensingMethod
                {
                    return(new ExifEnumProperty <SensingMethod>(ExifTag.SensingMethod, (SensingMethod)conv.ToUInt16(value, 0), true));
                }
                else if (tag == 0xa300) // FileSource
                {
                    return(new ExifEnumProperty <FileSource>(ExifTag.FileSource, (FileSource)conv.ToUInt16(value, 0), true));
                }
                else if (tag == 0xa301) // SceneType
                {
                    return(new ExifEnumProperty <SceneType>(ExifTag.SceneType, (SceneType)conv.ToUInt16(value, 0), true));
                }
                else if (tag == 0xa401) // CustomRendered
                {
                    return(new ExifEnumProperty <CustomRendered>(ExifTag.CustomRendered, (CustomRendered)conv.ToUInt16(value, 0), true));
                }
                else if (tag == 0xa402) // ExposureMode
                {
                    return(new ExifEnumProperty <ExposureMode>(ExifTag.ExposureMode, (ExposureMode)conv.ToUInt16(value, 0), true));
                }
                else if (tag == 0xa403) // WhiteBalance
                {
                    return(new ExifEnumProperty <WhiteBalance>(ExifTag.WhiteBalance, (WhiteBalance)conv.ToUInt16(value, 0), true));
                }
                else if (tag == 0xa406) // SceneCaptureType
                {
                    return(new ExifEnumProperty <SceneCaptureType>(ExifTag.SceneCaptureType, (SceneCaptureType)conv.ToUInt16(value, 0), true));
                }
                else if (tag == 0xa407) // GainControl
                {
                    return(new ExifEnumProperty <GainControl>(ExifTag.GainControl, (GainControl)conv.ToUInt16(value, 0), true));
                }
                else if (tag == 0xa408) // Contrast
                {
                    return(new ExifEnumProperty <Contrast>(ExifTag.Contrast, (Contrast)conv.ToUInt16(value, 0), true));
                }
                else if (tag == 0xa409) // Saturation
                {
                    return(new ExifEnumProperty <Saturation>(ExifTag.Saturation, (Saturation)conv.ToUInt16(value, 0), true));
                }
                else if (tag == 0xa40a) // Sharpness
                {
                    return(new ExifEnumProperty <Sharpness>(ExifTag.Sharpness, (Sharpness)conv.ToUInt16(value, 0), true));
                }
                else if (tag == 0xa40c) // SubjectDistanceRange
                {
                    return(new ExifEnumProperty <SubjectDistanceRange>(ExifTag.SubjectDistance, (SubjectDistanceRange)conv.ToUInt16(value, 0), true));
                }
            }
            else if (ifd == IFD.GPS)
            {
                if (tag == 0) // GPSVersionID
                {
                    return(new ExifVersion(ExifTag.GPSVersionID, ExifBitConverter.ToString(value)));
                }
                else if (tag == 1) // GPSLatitudeRef
                {
                    return(new ExifEnumProperty <GPSLatitudeRef>(ExifTag.GPSLatitudeRef, (GPSLatitudeRef)value[0]));
                }
                else if (tag == 2) // GPSLatitude
                {
                    return(new GPSLatitudeLongitude(ExifTag.GPSLatitude, ExifBitConverter.ToURationalArray(value, (int)count, byteOrder)));
                }
                else if (tag == 3) // GPSLongitudeRef
                {
                    return(new ExifEnumProperty <GPSLongitudeRef>(ExifTag.GPSLongitudeRef, (GPSLongitudeRef)value[0]));
                }
                else if (tag == 4) // GPSLongitude
                {
                    return(new GPSLatitudeLongitude(ExifTag.GPSLongitude, ExifBitConverter.ToURationalArray(value, (int)count, byteOrder)));
                }
                else if (tag == 5) // GPSAltitudeRef
                {
                    return(new ExifEnumProperty <GPSAltitudeRef>(ExifTag.GPSAltitudeRef, (GPSAltitudeRef)value[0]));
                }
                else if (tag == 7) // GPSTimeStamp
                {
                    return(new GPSTimeStamp(ExifTag.GPSTimeStamp, ExifBitConverter.ToURationalArray(value, (int)count, byteOrder)));
                }
                else if (tag == 9) // GPSStatus
                {
                    return(new ExifEnumProperty <GPSStatus>(ExifTag.GPSStatus, (GPSStatus)value[0]));
                }
                else if (tag == 10) // GPSMeasureMode
                {
                    return(new ExifEnumProperty <GPSMeasureMode>(ExifTag.GPSMeasureMode, (GPSMeasureMode)value[0]));
                }
                else if (tag == 12) // GPSSpeedRef
                {
                    return(new ExifEnumProperty <GPSSpeedRef>(ExifTag.GPSSpeedRef, (GPSSpeedRef)value[0]));
                }
                else if (tag == 14) // GPSTrackRef
                {
                    return(new ExifEnumProperty <GPSDirectionRef>(ExifTag.GPSTrackRef, (GPSDirectionRef)value[0]));
                }
                else if (tag == 16) // GPSImgDirectionRef
                {
                    return(new ExifEnumProperty <GPSDirectionRef>(ExifTag.GPSImgDirectionRef, (GPSDirectionRef)value[0]));
                }
                else if (tag == 19) // GPSDestLatitudeRef
                {
                    return(new ExifEnumProperty <GPSLatitudeRef>(ExifTag.GPSDestLatitudeRef, (GPSLatitudeRef)value[0]));
                }
                else if (tag == 20) // GPSDestLatitude
                {
                    return(new GPSLatitudeLongitude(ExifTag.GPSDestLatitude, ExifBitConverter.ToURationalArray(value, (int)count, byteOrder)));
                }
                else if (tag == 21) // GPSDestLongitudeRef
                {
                    return(new ExifEnumProperty <GPSLongitudeRef>(ExifTag.GPSDestLongitudeRef, (GPSLongitudeRef)value[0]));
                }
                else if (tag == 22) // GPSDestLongitude
                {
                    return(new GPSLatitudeLongitude(ExifTag.GPSDestLongitude, ExifBitConverter.ToURationalArray(value, (int)count, byteOrder)));
                }
                else if (tag == 23) // GPSDestBearingRef
                {
                    return(new ExifEnumProperty <GPSDirectionRef>(ExifTag.GPSDestBearingRef, (GPSDirectionRef)value[0]));
                }
                else if (tag == 25) // GPSDestDistanceRef
                {
                    return(new ExifEnumProperty <GPSDistanceRef>(ExifTag.GPSDestDistanceRef, (GPSDistanceRef)value[0]));
                }
                else if (tag == 29) // GPSDate
                {
                    return(new ExifDateTime(ExifTag.GPSDateStamp, ExifBitConverter.ToDateTime(value, false)));
                }
                else if (tag == 30) // GPSDifferential
                {
                    return(new ExifEnumProperty <GPSDifferential>(ExifTag.GPSDifferential, (GPSDifferential)conv.ToUInt16(value, 0)));
                }
            }
            else if (ifd == IFD.Interop)
            {
                if (tag == 1) // InteroperabilityIndex
                {
                    return(new ExifAscii(ExifTag.InteroperabilityIndex, ExifBitConverter.ToAscii(value)));
                }
                else if (tag == 2) // InteroperabilityVersion
                {
                    return(new ExifVersion(ExifTag.InteroperabilityVersion, ExifBitConverter.ToAscii(value)));
                }
            }
            else if (ifd == IFD.First)
            {
                if (tag == 0x103) // Compression
                {
                    return(new ExifEnumProperty <Compression>(ExifTag.ThumbnailCompression, (Compression)conv.ToUInt16(value, 0)));
                }
                else if (tag == 0x106) // PhotometricInterpretation
                {
                    return(new ExifEnumProperty <PhotometricInterpretation>(ExifTag.ThumbnailPhotometricInterpretation, (PhotometricInterpretation)conv.ToUInt16(value, 0)));
                }
                else if (tag == 0x112) // Orientation
                {
                    return(new ExifEnumProperty <Orientation>(ExifTag.ThumbnailOrientation, (Orientation)conv.ToUInt16(value, 0)));
                }
                else if (tag == 0x11c) // PlanarConfiguration
                {
                    return(new ExifEnumProperty <PlanarConfiguration>(ExifTag.ThumbnailPlanarConfiguration, (PlanarConfiguration)conv.ToUInt16(value, 0)));
                }
                else if (tag == 0x213) // YCbCrPositioning
                {
                    return(new ExifEnumProperty <YCbCrPositioning>(ExifTag.ThumbnailYCbCrPositioning, (YCbCrPositioning)conv.ToUInt16(value, 0)));
                }
                else if (tag == 0x128) // ResolutionUnit
                {
                    return(new ExifEnumProperty <ResolutionUnit>(ExifTag.ThumbnailResolutionUnit, (ResolutionUnit)conv.ToUInt16(value, 0)));
                }
                else if (tag == 0x132) // DateTime
                {
                    return(new ExifDateTime(ExifTag.ThumbnailDateTime, ExifBitConverter.ToDateTime(value)));
                }
            }

            // Find the exif tag corresponding to given tag id
            ExifTag etag = ExifTagFactory.GetExifTag(ifd, tag);

            if (type == 1) // 1 = BYTE An 8-bit unsigned integer.
            {
                if (count == 1)
                {
                    return(new ExifByte(etag, value[0]));
                }
                else
                {
                    return(new ExifByteArray(etag, value));
                }
            }
            else if (type == 2) // 2 = ASCII An 8-bit byte containing one 7-bit ASCII code.
            {
                return(new ExifAscii(etag, ExifBitConverter.ToAscii(value)));
            }
            else if (type == 3) // 3 = SHORT A 16-bit (2-byte) unsigned integer.
            {
                if (count == 1)
                {
                    return(new ExifUShort(etag, conv.ToUInt16(value, 0)));
                }
                else
                {
                    return(new ExifUShortArray(etag, ExifBitConverter.ToUShortArray(value, (int)count, byteOrder)));
                }
            }
            else if (type == 4) // 4 = LONG A 32-bit (4-byte) unsigned integer.
            {
                if (count == 1)
                {
                    return(new ExifUInt(etag, conv.ToUInt32(value, 0)));
                }
                else
                {
                    return(new ExifUIntArray(etag, ExifBitConverter.ToUIntArray(value, (int)count, byteOrder)));
                }
            }
            else if (type == 5) // 5 = RATIONAL Two LONGs. The first LONG is the numerator and the second LONG expresses the denominator.
            {
                if (count == 1)
                {
                    return(new ExifURational(etag, ExifBitConverter.ToURational(value, byteOrder)));
                }
                else
                {
                    return(new ExifURationalArray(etag, ExifBitConverter.ToURationalArray(value, (int)count, byteOrder)));
                }
            }
            else if (type == 7) // 7 = UNDEFINED An 8-bit byte that can take any value depending on the field definition.
            {
                return(new ExifUndefined(etag, value));
            }
            else if (type == 9) // 9 = SLONG A 32-bit (4-byte) signed integer (2's complement notation).
            {
                if (count == 1)
                {
                    return(new ExifSInt(etag, conv.ToInt32(value, 0)));
                }
                else
                {
                    return(new ExifSIntArray(etag, ExifBitConverter.ToSIntArray(value, (int)count, byteOrder)));
                }
            }
            else if (type == 10) // 10 = SRATIONAL Two SLONGs. The first SLONG is the numerator and the second SLONG is the denominator.
            {
                if (count == 1)
                {
                    return(new ExifSRational(etag, ExifBitConverter.ToSRational(value, byteOrder)));
                }
                else
                {
                    return(new ExifSRationalArray(etag, ExifBitConverter.ToSRationalArray(value, (int)count, byteOrder)));
                }
            }
            else
            {
                throw new ArgumentException("Unknown property type.");
            }
        }
コード例 #8
0
 public static ushort ReadUInt16(this FileStream stream, bool isLittleEndian)
 {
     return(stream.Read(bytes => BitConverterEx.ToUInt16(bytes, 0, isLittleEndian)));
 }