private void ShowData(IFDEntry ifde) { var count = ifde.count; Console.Write("{0:X8} {1:X4} {2:X4} {3:X8} {4:X8} {5,27} {6,9} ", ifde.filePosition, ifde.originalTag, (int)ifde.fieldType, count, ifde.dataOffset, ifde.tag, ifde.fieldType); bool truncated = false; switch (ifde.fieldType) { case IFDEntry.FieldType.ASCII: if (32 < count) { count = 32; truncated = true; } for (int i = 0; i < count; ++i) { var b = ifde.data[i]; Console.Write((char)b); } break; case IFDEntry.FieldType.BYTE: case IFDEntry.FieldType.SBYTE: case IFDEntry.FieldType.UNDEFINED: if (12 < count) { count = 12; truncated = true; } for (int i = 0; i < count; ++i) { var b = ifde.data[i]; Console.Write("{0:X2} ", b); } break; case IFDEntry.FieldType.SHORT: case IFDEntry.FieldType.SSHORT: if (8 < count) { count = 8; truncated = true; } for (int i = 0; i < count; ++i) { var b = BitConverter.ToInt16(ifde.data, i * 2); Console.Write("{0:X4} ", b); } break; case IFDEntry.FieldType.FLOAT: if (4 < count) { count = 4; truncated = true; } for (int i = 0; i < count; ++i) { var b = BitConverter.ToSingle(ifde.data, i * 4); Console.Write("{0:G4} ", b); } break; case IFDEntry.FieldType.LONG: case IFDEntry.FieldType.SLONG: if (4 < count) { count = 4; truncated = true; } for (int i = 0; i < count; ++i) { var b = BitConverter.ToInt32(ifde.data, i * 4); Console.Write("{0:X8} ", b); } break; case IFDEntry.FieldType.DOUBLE: /*if (4 < count) { * count = 4; * truncated = true; * }*/ for (int i = 0; i < count; ++i) { var b = BitConverter.ToDouble(ifde.data, i * 8); Console.Write("{0:G4} ", b); } break; case IFDEntry.FieldType.RATIONAL: case IFDEntry.FieldType.SRATIONAL: /*if (3 < count) { * count = 3; * truncated = true; * }*/ for (int i = 0; i < count; ++i) { var n = BitConverter.ToInt32(ifde.data, i * 8 + 0); var d = BitConverter.ToInt32(ifde.data, i * 8 + 4); Console.Write("{0}/{1} ", n, d); } break; case IFDEntry.FieldType.Unknown: break; } if (truncated) { Console.Write("... "); } // 特殊なタグの表示。 switch (ifde.tag) { case IFDEntry.Tag.PhotometricInterpretation: if (Enum.IsDefined(typeof(IFDEntry.PhotometricInterpretationType), (int)ifde.dataOffset)) { var v = (IFDEntry.PhotometricInterpretationType)ifde.dataOffset; Console.Write("{0}", v); } break; case IFDEntry.Tag.Compression: if (Enum.IsDefined(typeof(IFDEntry.CompressionType), (int)ifde.dataOffset)) { var v = (IFDEntry.CompressionType)ifde.dataOffset; Console.Write("{0}", v); } break; case IFDEntry.Tag.Orientation: if (Enum.IsDefined(typeof(IFDEntry.OrientationType), (int)ifde.dataOffset)) { var v = (IFDEntry.OrientationType)ifde.dataOffset; Console.Write("{0}", v); } break; case IFDEntry.Tag.PlanarConfiguration: if (Enum.IsDefined(typeof(IFDEntry.PlanarConfigurationType), (int)ifde.dataOffset)) { var v = (IFDEntry.PlanarConfigurationType)ifde.dataOffset; Console.Write("{0}", v); } break; case IFDEntry.Tag.CFALayout: if (Enum.IsDefined(typeof(IFDEntry.CFALayoutType), (int)ifde.dataOffset)) { var v = (IFDEntry.CFALayoutType)ifde.dataOffset; Console.Write("{0}", v); } break; case IFDEntry.Tag.SampleFormat: if (Enum.IsDefined(typeof(IFDEntry.SampleFormatType), (int)ifde.dataOffset)) { var v = (IFDEntry.SampleFormatType)ifde.dataOffset; Console.Write("{0}", v); } break; case IFDEntry.Tag.CFARepeatPatternDim: if (ifde.count != 2 || ifde.fieldType != IFDEntry.FieldType.SHORT) { Console.Write("Error: CFARepeatPatternDim malformat"); } else { var sa = ifde.GetDataAsUShortArray(); Console.Write("Row={0} Cols={1}", sa[0], sa[1]); } break; case IFDEntry.Tag.ImageWidth: if (ifde.count != 1) { Console.Write("Error: ImageWidth malformat"); } else { Console.Write("Width={0}pixel", ifde.dataOffset); } break; case IFDEntry.Tag.BitsPerSample: if (ifde.fieldType != IFDEntry.FieldType.SHORT) { Console.Write("Error: BitsPerSample malformat"); } else { Console.Write(", In decimal: "); var sa = ifde.GetDataAsUShortArray(); for (int i = 0; i < sa.Length; ++i) { Console.Write("{0} ", sa[i]); } } break; case IFDEntry.Tag.ISOSpeedRatings: if (ifde.fieldType != IFDEntry.FieldType.SHORT) { } else { Console.Write(", In decimal: "); var sa = ifde.GetDataAsUShortArray(); Console.Write("{0} ", sa[0]); } break; case IFDEntry.Tag.ImageLength: if (ifde.count != 1) { Console.Write("Error: ImageLength malformat"); } else { Console.Write("Height={0}pixel", ifde.dataOffset); } break; case IFDEntry.Tag.CFAPlaneColor: if (ifde.fieldType != IFDEntry.FieldType.BYTE) { Console.Write("Error: CFAPlaneColor malformat"); } else { var ba = ifde.GetDataAsByteArray(); for (int i = 0; i < ba.Length; ++i) { if (Enum.IsDefined(typeof(IFDEntry.CFAPatternType), (int)ba[i])) { var v = (IFDEntry.CFAPatternType)(int) ba[i]; Console.Write("{0} ", v); } } } break; case IFDEntry.Tag.CFAPattern: { var ba = ifde.GetDataAsByteArray(); for (int i = 0; i < ba.Length; ++i) { if (Enum.IsDefined(typeof(IFDEntry.CFAPatternType), (int)ba[i])) { var v = (IFDEntry.CFAPatternType)(int) ba[i]; Console.Write("{0} ", v); } } } break; case IFDEntry.Tag.LightSource: case IFDEntry.Tag.CalibrationIlluminant1: case IFDEntry.Tag.CalibrationIlluminant2: if (Enum.IsDefined(typeof(IFDEntry.LightSourceType), (int)ifde.dataOffset)) { var v = (IFDEntry.LightSourceType)ifde.dataOffset; Console.Write("{0} ", v); } else { Console.Write("reserved "); } break; default: break; } Console.WriteLine(""); }
private bool ReadIFDEntry(BinaryReader br, IFDType ifdt, out IFDEntry ifdEntry) { long pos = br.BaseStream.Position; uint originalTag = ReadUInt16(br); int t = (int)originalTag; if (ifdt == IFDType.Gps) { t += 0x10000; } else { mAppearedTags.Add(t); } int f = ReadUInt16(br); int count = ReadInt32(br); uint dataOffset = ReadUInt32(br); var tag = IFDEntry.Tag.Unknown; if (Enum.IsDefined(typeof(IFDEntry.Tag), t)) { tag = (IFDEntry.Tag)t; } var ft = IFDEntry.FieldType.Unknown; if (Enum.IsDefined(typeof(IFDEntry.FieldType), f)) { ft = (IFDEntry.FieldType)f; } int dataBytes = IFDEntry.DataBytes(ft, count); if (4 < dataBytes) { // dataOffset==データが置いてある位置。 long cur = br.BaseStream.Position; br.BaseStream.Seek(dataOffset, SeekOrigin.Begin); ifdEntry = CreateIFDEntry(br, tag, ft, count); ifdEntry.dataOffset = dataOffset; br.BaseStream.Seek(cur, SeekOrigin.Begin); } else { // dataPosをもう一度データとして読む。 long cur = br.BaseStream.Position; br.BaseStream.Seek(pos + 8, SeekOrigin.Begin); ifdEntry = CreateIFDEntry(br, tag, ft, count); br.BaseStream.Seek(cur, SeekOrigin.Begin); } ifdEntry.originalTag = originalTag; ifdEntry.filePosition = pos; return(true); }