Example #1
0
        private void ProcessExif(byte[] section)
        {
            int idx = 6;

            if (section[idx++] != 0 ||
                section[idx++] != 0)
            {
                // "Exif" is not followed by 2 null bytes.
                return;
            }

            if (section[idx] == 'I' && section[idx + 1] == 'I')
            {
                // intel order
                littleEndian = true;
            }
            else
            {
                if (section[idx] == 'M' && section[idx + 1] == 'M')
                {
                    littleEndian = false;
                }
                else
                {
                    // unknown order...
                    return;
                }
            }
            idx += 2;

            int a = ExifIO.ReadUShort(section, idx, littleEndian);

            idx += 2;

            if (a != 0x002A)
            {
                // bad start...
                return;
            }

            a    = ExifIO.ReadInt(section, idx, littleEndian);
            idx += 4;

            if (a < 8 || a > 16)
            {
                if (a < 16 || a > section.Length - 16)
                {
                    // invalid offset
                    return;
                }
            }

            ProcessExifDir(section, a + 8, 8, section.Length - 8, 0, ExifIFD.Exif);
        }
Example #2
0
        private void ProcessExif(byte[] section, long sectionStart)
        {
            int num1 = 6;

            byte[] numArray1 = section;
            int    index1    = num1;
            int    num2      = 1;
            int    num3      = index1 + num2;

            if ((int)numArray1[index1] != 0)
            {
                return;
            }
            byte[] numArray2 = section;
            int    index2    = num3;
            int    num4      = 1;
            int    index3    = index2 + num4;

            if ((int)numArray2[index2] != 0)
            {
                return;
            }
            if ((int)section[index3] == 73 && (int)section[index3 + 1] == 73)
            {
                this.littleEndian = true;
            }
            else
            {
                if ((int)section[index3] != 77 || (int)section[index3 + 1] != 77)
                {
                    return;
                }
                this.littleEndian = false;
            }
            this.info.LittleEndian = this.littleEndian;
            int offset1 = index3 + 2;
            int num5    = (int)ExifIO.ReadUShort(section, offset1, this.littleEndian);
            int offset2 = offset1 + 2;

            if (num5 != 42)
            {
                return;
            }
            int num6 = ExifIO.ReadInt(section, offset2, this.littleEndian);
            int num7 = offset2 + 4;

            if ((num6 < 8 || num6 > 16) && (num6 < 16 || num6 > section.Length - 16))
            {
                return;
            }
            this.ProcessExifDir(section, num6 + 8, 8, section.Length - 8, 0, ExifIFD.Exif, sectionStart);
        }
Example #3
0
        public ExifTag(byte[] section, int sectionOffset, int offsetBase, int length, bool littleEndian)
        {
            this.IsValid = false;
            this.Tag     = ExifIO.ReadUShort(section, sectionOffset, littleEndian);
            int format = ExifIO.ReadUShort(section, sectionOffset + 2, littleEndian);

            if (format < 1 || format > 12)
            {
                return;
            }
            this.Format     = (ExifTagFormat)format;
            this.Components = ExifIO.ReadInt(section, sectionOffset + 4, littleEndian);
            if (this.Components > 0x10000)
            {
                return;
            }
            this.LittleEndian = littleEndian;

            int byteCount   = this.Components * BytesPerFormat[format];
            int valueOffset = 0;

            if (byteCount > 4)
            {
                int offsetVal = ExifIO.ReadInt(section, sectionOffset + 8, littleEndian);
                if (offsetVal + byteCount > length)
                {
                    // bad offset...
                    return;
                }
                valueOffset = offsetBase + offsetVal;
            }
            else
            {
                valueOffset = sectionOffset + 8;
            }
            this.Data = new byte[byteCount];
            Array.Copy(section, valueOffset, this.Data, 0, byteCount);
            this.IsValid = true;
        }
Example #4
0
        public ExifTag(byte[] section, int sectionOffset, int offsetBase, int length, bool littleEndian)
        {
            this.IsValid = false;
            this.Tag     = (int)ExifIO.ReadUShort(section, sectionOffset, littleEndian);
            int index = (int)ExifIO.ReadUShort(section, sectionOffset + 2, littleEndian);

            if (index < 1 || index > 12)
            {
                return;
            }
            this.Format     = (ExifTagFormat)index;
            this.Components = ExifIO.ReadInt(section, sectionOffset + 4, littleEndian);
            if (this.Components > 65536)
            {
                return;
            }
            this.LittleEndian = littleEndian;
            int length1 = this.Components * ExifTag.BytesPerFormat[index];
            int sourceIndex;

            if (length1 > 4)
            {
                int num = ExifIO.ReadInt(section, sectionOffset + 8, littleEndian);
                if (num + length1 > length)
                {
                    return;
                }
                sourceIndex = offsetBase + num;
            }
            else
            {
                sourceIndex = sectionOffset + 8;
            }
            this.Data        = new byte[length1];
            this.ValueOffset = (long)sourceIndex;
            Array.Copy((Array)section, sourceIndex, (Array)this.Data, 0, length1);
            this.IsValid = true;
        }
Example #5
0
 private ushort ReadUShort(int offset)
 {
     return(ExifIO.ReadUShort(Data, offset, LittleEndian));
 }
Example #6
0
 private double ReadDouble(int offset)
 {
     return(ExifIO.ReadDouble(Data, offset, LittleEndian));
 }
Example #7
0
 private float ReadSingle(int offset)
 {
     return(ExifIO.ReadSingle(Data, offset, LittleEndian));
 }
Example #8
0
 private uint ReadUInt(int offset)
 {
     return(ExifIO.ReadUInt(Data, offset, LittleEndian));
 }
Example #9
0
        private void ProcessExifDir(byte[] section, int offsetDir, int offsetBase, int length, int depth, ExifIFD ifd)
        {
            if (depth > 4)
            {
                // corrupted Exif header...
                return;
            }

            ushort numEntries = ExifIO.ReadUShort(section, offsetDir, littleEndian);

            if (offsetDir + 2 + 12 * numEntries >= offsetDir + length)
            {
                // too long
                return;
            }

            int offset = 0;

            for (int de = 0; de < numEntries; ++de)
            {
                offset = DirOffset(offsetDir, de);
                ExifTag exifTag = new ExifTag(section, offset, offsetBase, length, littleEndian);

                if (!exifTag.IsValid)
                {
                    continue;
                }

                switch (exifTag.Tag)
                {
                case (int)ExifIFD.Exif:
                {
                    int dirStart = offsetBase + exifTag.GetInt(0);
                    if (dirStart <= offsetBase + length)
                    {
                        ProcessExifDir(section, dirStart, offsetBase, length, depth + 1, ExifIFD.Exif);
                    }
                } break;

                case (int)ExifIFD.Gps:
                {
                    int dirStart = offsetBase + exifTag.GetInt(0);
                    if (dirStart <= offsetBase + length)
                    {
                        ProcessExifDir(section, dirStart, offsetBase, length, depth + 1, ExifIFD.Gps);
                    }
                } break;

                default:
                {
                    exifTag.Populate(info, ifd);
                } break;
                }
            }

            // final link defined?
            offset = DirOffset(offsetDir, numEntries) + 4;
            if (offset <= offsetBase + length)
            {
                offset = ExifIO.ReadInt(section, offsetDir + 2 + 12 * numEntries, littleEndian);
                if (offset > 0)
                {
                    int subDirStart = offsetBase + offset;
                    if (subDirStart <= offsetBase + length && subDirStart >= offsetBase)
                    {
                        ProcessExifDir(section, subDirStart, offsetBase, length, depth + 1, ifd);
                    }
                }
            }

            if (info.ThumbnailData == null && info.ThumbnailOffset > 0 && info.ThumbnailSize > 0)
            {
                // store it.
                info.ThumbnailData = new byte[info.ThumbnailSize];
                Array.Copy(section, offsetBase + info.ThumbnailOffset, info.ThumbnailData, 0, info.ThumbnailSize);
            }
        }
Example #10
0
 private int ReadInt(int offset)
 {
     return(ExifIO.ReadInt(this.Data, offset, this.LittleEndian));
 }
Example #11
0
 private short ReadShort(int offset)
 {
     return(ExifIO.ReadShort(this.Data, offset, this.LittleEndian));
 }
Example #12
0
        private void ProcessExifDir(byte[] section, int offsetDir, int offsetBase, int length, int depth, ExifIFD ifd, long sectionStart)
        {
            if (depth > 4)
            {
                return;
            }
            ushort num1 = ExifIO.ReadUShort(section, offsetDir, this.littleEndian);

            if (offsetDir + 2 + 12 * (int)num1 >= offsetDir + length)
            {
                return;
            }
            for (int num2 = 0; num2 < (int)num1; ++num2)
            {
                int     sectionOffset = this.DirOffset(offsetDir, num2);
                ExifTag exifTag       = new ExifTag(section, sectionOffset, offsetBase, length, this.littleEndian);
                if (exifTag.IsValid)
                {
                    switch (exifTag.Tag)
                    {
                    case 34665:
                        int offsetDir1 = offsetBase + exifTag.GetInt(0);
                        if (offsetDir1 <= offsetBase + length)
                        {
                            this.ProcessExifDir(section, offsetDir1, offsetBase, length, depth + 1, ExifIFD.Exif, sectionStart);
                            continue;
                        }
                        continue;

                    case 34853:
                        int offsetDir2 = offsetBase + exifTag.GetInt(0);
                        if (offsetDir2 <= offsetBase + length)
                        {
                            this.ProcessExifDir(section, offsetDir2, offsetBase, length, depth + 1, ExifIFD.Gps, sectionStart);
                            continue;
                        }
                        continue;

                    default:
                        exifTag.Populate(this.info, ifd, sectionStart);
                        continue;
                    }
                }
            }
            if (this.DirOffset(offsetDir, (int)num1) + 4 <= offsetBase + length)
            {
                int num2 = ExifIO.ReadInt(section, offsetDir + 2 + 12 * (int)num1, this.littleEndian);
                if (num2 > 0)
                {
                    int offsetDir1 = offsetBase + num2;
                    if (offsetDir1 <= offsetBase + length && offsetDir1 >= offsetBase)
                    {
                        this.ProcessExifDir(section, offsetDir1, offsetBase, length, depth + 1, ifd, sectionStart);
                    }
                }
            }
            if (this.info.ThumbnailData != null || this.info.ThumbnailOffset <= 0 || this.info.ThumbnailSize <= 0)
            {
                return;
            }
            this.info.ThumbnailData = new byte[this.info.ThumbnailSize];
            Array.Copy((Array)section, offsetBase + this.info.ThumbnailOffset, (Array)this.info.ThumbnailData, 0, this.info.ThumbnailSize);
        }