Example #1
0
        /// <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));
        }
Example #2
0
 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);
 }
Example #3
0
        /// <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);
        }
Example #4
0
        /// <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);
        }
Example #5
0
        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);
        }
Example #6
0
        /// <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);
        }