練習帳@blog

これからは写真中心で行きたい

IFD.cls

VERSION 1.0 CLASS
BEGIN
MultiUse = -1 'True
END
Attribute VB_Name = "IFD"
Attribute VB_GlobalNameSpace = False
Attribute VB_Creatable = False
Attribute VB_PredeclaredId = False
Attribute VB_Exposed = False
Option Explicit
Public endian As String
Public TagI As String
Public TypeI As String
Public Count As Integer
Public Data As String

Public DataOffset As String
Private component As Variant
Private datalengrth As Long

'TypeIの値の意味
'Value Format Bytes/component
'1 unsigned byte 1
'2 ascii strings 1
'3 unsigned short 2
'4 unsigned long 4
'5 unsigned rational 8
'6 signed byte 1
'7 undefined 1
'8 signed short 2
'9 signed long 4
'10 signed rational 8
'11 single float 4
'12 double float 8


Public Sub readIFD(ExifData1() As Byte, IFDPoint As Long)
Dim CHD As Integer
Dim re As Long
Dim tempUC As String
Dim tempDEG As Double
Dim tempMIN As Double
Dim tempSEC As Double
Dim temp As Double
Dim ra As Long
Dim Byte2Str As New ByteExchange
Dim Byte2StrNE As New ByteExchange
Dim UCdataoffset As Long


'各タイプに対するデータ長(単位 Byte) 0はダミー
component = Array(0, 1, 1, 2, 4, 8, 1, 1, 2, 4, 8, 4, 8)
Byte2Str.endian = endian
Byte2StrNE.endian = "MM" 'エンディアンに依存しないデータの変換用
'IFDタグの読み込み
TagI = Byte2Str.endianHex(ExifData1, IFDPoint, 2)
TypeI = Byte2Str.endianHex(ExifData1, IFDPoint + 2, 2)
Count = Byte2Str.endianHex(ExifData1, IFDPoint + 4, 4)
DataOffset = Byte2Str.endianHex(ExifData1, IFDPoint + 8, 4)

datalengrth = component(CLng(TypeI)) * Count
If datalengrth > 4 Then
Select Case CLng(TypeI)
Case 7
'このタイプのデータは、エンディアンに依存しない
'0x9286 UserComment undefined "ユーザーコメントが格納されます。ImageDescriptionタグと違って、こちらはJIS2バイトコード
'Unicode等での記述が許されており、最初の8バイトが文字コードを示します。
'0x41,0x53,0x43,0x49,0x49,0x00,0x00,0x00':ASCII
'0x4a,0x49,0x53,0x00,0x00,0x00,0x00,0x00':JIS
'0x55,0x4e,0x49,0x43,0x4f,0x44,0x45,0x00':Unicode
'0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00':Undefined"
UCdataoffset = CLng(DataOffset) + 8
Select Case Byte2StrNE.endianHex(ExifData1, CLng(DataOffset), 8)
'Ascii
Case "&H4153434949000000"
Data = Byte2StrNE.endianHex(ExifData1, UCdataoffset, datalengrth - 8)

'Unicode
Case "&H554E49434F444500"
Data = Byte2StrNE.endianHex(ExifData1, UCdataoffset, datalengrth - 8)

'Undefined (SJISの場合はデコード)
Case "&H0000000000000000"
'Shift_JIS決めうちです(;´Д`)
For re = UCdataoffset To UCdataoffset + datalengrth - 8 Step 2
CHD = CLng(ExifData1(re)) '2バイトコード判定用(SJIS)
If (CHD >= CLng(&H81) And CHD <= CLng(&H9F)) Or (CHD >= CLng(&HE0) And CHD <= CLng(&HEA)) Then
tempUC = Chr("&H" & Hex(ExifData1(re)) & Hex(ExifData1(re + 1)))
Else
tempUC = Chr("&H" & Hex(ExifData1(re)))
re = re - 1
End If
Data = Data & tempUC
Next
Case Else
Data = Byte2StrNE.endianHex(ExifData1, CLng(DataOffset), datalengrth)
End Select
'Type Asciiの場合の処理(shift jisのみエンコード)
Case 2
For re = CLng(DataOffset) To CLng(DataOffset) + datalengrth - 1 Step 2
CHD = CLng(ExifData1(re))
If (CHD >= CLng(&H81) And CHD <= CLng(&H9F)) Or (CHD >= CLng(&HE0) And CHD <= CLng(&HEA)) Then
tempUC = Chr("&H" & Hex(ExifData1(re)) & Hex(ExifData1(re + 1)))
Else
tempUC = Chr("&H" & Hex(ExifData1(re)))
re = re - 1
End If
Data = Data & tempUC
Next
'Type Rationalの処理(緯度経度の場合はデータ変換)
Case 5
If Count = 3 Then
temp = CLng(Byte2Str.endianHex(ExifData1, CLng(DataOffset), 4)) / CLng(Byte2Str.endianHex(ExifData1, CLng(DataOffset) + 4, 4))
tempDEG = Fix(temp)
temp = (temp - tempDEG) * 60 + CLng(Byte2Str.endianHex(ExifData1, CLng(DataOffset) + 8, 4)) / CLng(Byte2Str.endianHex(ExifData1, CLng(DataOffset) + 8 + 4, 4))
tempMIN = Fix(temp)
tempSEC = Fix(100 * (temp - tempMIN) * 60 + CLng(Byte2Str.endianHex(ExifData1, CLng(DataOffset) + 16, 4)) / CLng(Byte2Str.endianHex(ExifData1, CLng(DataOffset) + 16 + 4, 4))) / 100
Data = tempDEG & ":" & tempMIN & ":" & tempSEC
Else
For ra = 1 To Count
Data = Data & CLng(Byte2StrNE.endianHex(ExifData1, CLng(DataOffset), 4)) & "/" & CLng(Byte2StrNE.endianHex(ExifData1, CLng(DataOffset) + 4 * ra, 4)) & "::"
Next
End If
Case Else
'それ以外の場合はそのまま。
Data = Byte2StrNE.endianHex(ExifData1, CLng(DataOffset), datalengrth)

End Select
Else
If CLng(TypeI) = 2 Then
Data = Chr(CLng(Byte2Str.endianHex(ExifData1, IFDPoint + 8, 2))) & Chr(CLng(Byte2Str.endianHex(ExifData1, IFDPoint + 10, 2)))
Else
Data = DataOffset
End If
End If

End Sub