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); }
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); }
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; }
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; }
private ushort ReadUShort(int offset) { return(ExifIO.ReadUShort(Data, offset, LittleEndian)); }
private double ReadDouble(int offset) { return(ExifIO.ReadDouble(Data, offset, LittleEndian)); }
private float ReadSingle(int offset) { return(ExifIO.ReadSingle(Data, offset, LittleEndian)); }
private uint ReadUInt(int offset) { return(ExifIO.ReadUInt(Data, offset, LittleEndian)); }
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); } }
private int ReadInt(int offset) { return(ExifIO.ReadInt(this.Data, offset, this.LittleEndian)); }
private short ReadShort(int offset) { return(ExifIO.ReadShort(this.Data, offset, this.LittleEndian)); }
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); }