/// <summary> /// MPヘッダを読みだす /// </summary> /// <param name="buffer"></param> /// <param name="o">オフセット</param> /// <returns></returns> private MPHeader DecodeMPHeader(byte[] buffer, int o) { Endian endian = GetEndian(buffer, o); uint firstIFDOffset = BitConverterEx.ToUInt32(buffer, o + 4, endian); return(new MPHeader(endian, firstIFDOffset)); }
public MPEntryValue(byte[] bytes, int startIndex, Endian endian) { ImageAttr = (uint)BitConverterEx.ToInt32(bytes, startIndex + 0, endian); ImageSize = (uint)BitConverterEx.ToInt32(bytes, startIndex + 4, endian); ImageDataOffset = (uint)BitConverterEx.ToInt32(bytes, startIndex + 8, endian); DependentImage1 = (ushort)BitConverterEx.ToInt16(bytes, startIndex + 12, endian); DependentImage2 = (ushort)BitConverterEx.ToInt16(bytes, startIndex + 14, endian); }
/// <summary> /// MP個別情報IFDの読み出し /// </summary> /// <param name="buffer"></param> /// <param name="o">オフセット</param> /// <param name="offsetStart">オフセット基準位置</param> /// <param name="endian"></param> /// <returns></returns> private MPIndividualAttributesIFD DecodeMPIndAttrIFD(byte[] buffer, int o, int offsetStart, Endian endian) { // バイト列からIFDのフィールド個数を読み込み MPIndividualAttributesIFD indAttr = new MPIndividualAttributesIFD { Count = BitConverterEx.ToUInt16(buffer, o + 0, endian), }; // count個分フィールドを読み込み、Tagの値に従って適当なプロパティに設定 for (int i = 0; i < indAttr.Count; i++) { int offset = o + 2 * (12 * i); IFD ifd = new IFD(buffer, o + 2 + (12 * i), offsetStart, endian); switch (ifd.Tag) { case 45056: indAttr.MPFVersion = ifd; break; case 45313: indAttr.MPIndividualNum = ifd; break; case 45569: indAttr.PanOrientation = ifd; break; case 45570: indAttr.PanOverlap_H = ifd; break; case 45571: indAttr.PanOverlap_V = ifd; break; case 45572: indAttr.BaseViewpointNum = ifd; break; case 45573: indAttr.ConvergenceAngle = ifd; break; case 45574: indAttr.BaselineLength = ifd; break; case 45575: indAttr.VerticalDivergence = ifd; break; case 45576: indAttr.AxisDistance_X = ifd; break; case 45577: indAttr.AxisDistance_Y = ifd; break; case 45578: indAttr.AxisDistance_Z = ifd; break; case 45579: indAttr.YawAngle = ifd; break; case 45580: indAttr.PitchAngle = ifd; break; case 45581: indAttr.RollAngle = ifd; break; default: throw new Exception(string.Format("無効なMP個別情報IFDのTag({0})です", ifd.Tag)); } } // 普通は0 indAttr.NextIFDOffset = BitConverterEx.ToUInt32(this.buffer, o + 2 + (12 * indAttr.Count), endian); return(indAttr); }
/// <summary> /// MPインデックスIFDの読み出し /// </summary> /// <param name="buffer"></param> /// <param name="o">オフセット</param> /// <param name="endian"></param> /// <returns></returns> private MPIndexIFD DecodeMPIndexIFD(byte[] buffer, int o, int offsetStart, Endian endian) { // バイト列から読み込み MPIndexIFD index = new MPIndexIFD { Count = BitConverterEx.ToUInt16(buffer, o, endian), MPFVersion = new IFD(buffer, o + 2, offsetStart, endian), NumberOfImages = new IFD(buffer, o + 14, offsetStart, endian), MPEntry = new IFD(buffer, o + 26, offsetStart, endian), }; // タグ番号をチェック if (index.MPFVersion.Tag != 45056) { throw new Exception("MPFVersionのデコードに失敗しました"); } if (index.NumberOfImages.Tag != 45057) { throw new Exception("NumberOfImagesのデコードに失敗しました"); } if (index.MPEntry.Tag != 45058) { throw new Exception("MPEntryのデコードに失敗しました"); } // 個別画像ユニークIDリスト以下は省略されて存在しないかもしれない if (index.Count > 3) { index.ImageUIDList = new IFD(buffer, o + 38, offsetStart, endian); index.TotalFrames = new IFD(this.buffer, o + 50, offsetStart, endian); index.NextIFDOffset = BitConverterEx.ToUInt32(buffer, o + 62, endian); } else if (index.Count == 3) { index.ImageUIDList = null; index.TotalFrames = null; index.NextIFDOffset = BitConverterEx.ToUInt32(buffer, o + 38, endian); } else { throw new InvalidOperationException("MPインデックスIFDの解析に失敗しました"); } return(index); }
public IFD(byte[] bytes, int o, int offsetStart, Endian endian) { Tag = (ushort)BitConverterEx.ToInt16(bytes, o + 0, endian); Type = (IFDType)BitConverterEx.ToInt16(bytes, o + 2, endian); Count = (uint)BitConverterEx.ToInt32(bytes, o + 4, endian); Offset = new byte[4]; Array.Copy(bytes, o + 8, Offset, 0, Offset.Length); if (BitConverter.IsLittleEndian ^ endian == Endian.Little) { Array.Reverse(Offset); } // 長さが4バイトを超えるときは、Valueをオフセットとして扱う int typeSize = GetSizeOf(Type); if (typeSize * Count > 4) { Value = new byte[typeSize * Count]; Array.Copy(bytes, offsetStart + OffsetUInt32, Value, 0, Value.Length); } //Value = (uint)BitConverterEx.ToInt32(bytes, startIndex + 8, endian); }
/// <summary> /// バイト配列内の指定位置にあるバイト列から構造体に変換する /// </summary> /// <param name="value">バイト配列</param> /// <param name="startIndex">value 内の開始位置</param> /// <param name="endian">エンディアン</param> /// <returns></returns> public static object ToStruct(byte[] value, int startIndex, Endian endian, Type type) { if (!type.IsValueType) { throw new ArgumentException(); } // プリミティブ型は専用メソッドへ飛ばす TypeCode code = Type.GetTypeCode(type); switch (code) { case TypeCode.Boolean: return(ToBoolean(value, startIndex, endian)); case TypeCode.Byte: return(value[startIndex]); case TypeCode.Char: return(ToChar(value, startIndex, endian)); case TypeCode.Double: return(ToDouble(value, startIndex, endian)); case TypeCode.Int16: return(ToInt16(value, startIndex, endian)); case TypeCode.Int32: return(ToInt32(value, startIndex, endian)); case TypeCode.Int64: return(ToInt64(value, startIndex, endian)); case TypeCode.SByte: return(value[startIndex]); case TypeCode.Single: return(ToSingle(value, startIndex, endian)); case TypeCode.UInt16: return(ToUInt16(value, startIndex, endian)); case TypeCode.UInt32: return(ToUInt32(value, startIndex, endian)); case TypeCode.UInt64: return(ToUInt64(value, startIndex, endian)); default: break; // 多分その他のstructなので以下処理する } // 構造体の全フィールドを取得 FieldInfo[] fields = type.GetFields(BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public); // 型情報から新規インスタンスを生成 (返却値) object obj = Activator.CreateInstance(type); int offset = 0; foreach (FieldInfo info in fields) { // フィールドの値をバイト列から1つ取得し、objの同じフィールドに設定 Type fieldType = info.FieldType; if (!fieldType.IsValueType) { throw new InvalidOperationException(); } object fieldValue = BitConverterEx.ToStruct(value, startIndex + offset, endian, fieldType); info.SetValue(obj, fieldValue); // 次のフィールド値を見るためフィールドのバイトサイズ分進める offset += Marshal.SizeOf(fieldType); } return(obj); }