Not sure if it works correct.
Code: Select all
Global TestFile.s="d:\tmp\P1030506.jpg"
CompilerIf Not #PB_Compiler_Thread
MessageRequester("Info", "You need to set the Thread-Save flag!")
End
CompilerEndIf
; Define
EnableExplicit
#ExifDateFormat="%YYYY:%MM:%DD %HH:%II:%SS"
#ExifMinimumFileSize=256
#ExifSOF=$FFD8
#ExifApp1=$FFE1
#ExifApp2=$FFE2
#ExifHeaderOffset=6
#ExifHeaderIFDLen=12
#ExifHeaderTagExif=-#ExifHeaderOffset
#ExifHeaderTagEndian=#ExifHeaderTagExif+6
#ExifHeaderTagIFD=#ExifHeaderTagExif+10
#ExifJpgSOF=$FFC0
#ExifJpgSOS=$FFDA
#ExifJpgCOM=$FFFE
#ExifJpgCommentMaxLength=2000
DataSection
ExifTypeBytes:
Data.b 1,1,1,2,4,8,1,1,2,4,8,4,8 ; Bytegröße der einzelnen Exif-Datentypen
EndDataSection
;
Enumeration
#ExifGlobal
#ExifMain
#ExifMosaic
#ExifThreads
EndEnumeration
;
Structure ExifInfoType
ExifMemory.i
ExifDataSize.i
ExifOffset.i
ExifEndian.i
JpgWidth.i
JpgHeight.i
JpgComment.s
Date.i
IntDate.i
Rotation.i
Width.i
Height.i
Information.s
EndStructure
;
Global ExifDim.i=#ExifThreads
Global NewList ExifInfo.ExifInfoType()
; EndDefine
Macro Long(x)
((x)&$FFFFFFFF)
EndMacro
Macro Word(x)
((x)&$FFFF)
EndMacro
Procedure SwapWord(w.w)
ProcedureReturn ( ((w&$FF)<<8)|((w>>8)&$FF) )
EndProcedure
Procedure.s ExifGetString(*ExifInfo.ExifInfoType, offset)
If offset>=#Null And offset<*ExifInfo\ExifDataSize
ProcedureReturn PeekS(*ExifInfo\ExifMemory+#ExifHeaderOffset+offset)
Else
ProcedureReturn ""
EndIf
EndProcedure
Procedure.l ExifGetLong(*ExifInfo.ExifInfoType, offset)
Protected w.l
If offset>=-#ExifHeaderOffset And offset<*ExifInfo\ExifDataSize
w=PeekL(*ExifInfo\ExifMemory+#ExifHeaderOffset+offset); #### \ExifMemory=Null ?! ####
If *ExifInfo\ExifEndian
ProcedureReturn w&$FFFFFFFF
Else
ProcedureReturn ((w&$FF)<<24)|((w&$FF00)<<8)|((w&$FF0000)>>8)|((w>>24)&$FF)
EndIf
Else
ProcedureReturn 0
EndIf
EndProcedure
Procedure.w ExifGetWord(*ExifInfo.ExifInfoType, offset)
Protected w.w
If offset>=#Null And offset<*ExifInfo\ExifDataSize
w=PeekW(*ExifInfo\ExifMemory+#ExifHeaderOffset+offset)
If *ExifInfo\ExifEndian
ProcedureReturn w&$FFFF
Else
ProcedureReturn (((w&$FF)<<8)|((w>>8)&$FF))
EndIf
Else
ProcedureReturn 0
EndIf
EndProcedure
Procedure.f ExifGetRational(*ExifInfo.ExifInfoType, offset)
Protected a.l,b.l
If offset>=#Null And offset<*ExifInfo\ExifDataSize
a=ExifGetLong(*ExifInfo, offset)
b=ExifGetLong(*ExifInfo, offset+4)
ProcedureReturn a/b
Else
ProcedureReturn 0
EndIf
EndProcedure
Procedure.s ExifGetRationalString(*ExifInfo.ExifInfoType, offset)
Protected a.l,b.l
If offset>=#Null And offset<*ExifInfo\ExifDataSize
a=ExifGetLong(*ExifInfo, offset)
b=ExifGetLong(*ExifInfo, offset+4)
If b>1
ProcedureReturn Str(a)+"/"+Str(b)
Else
ProcedureReturn Str(a)
EndIf
Else
ProcedureReturn "-"
EndIf
EndProcedure
Procedure ExifGetDirectory(*ExifInfo.ExifInfoType, offset)
Protected IFDTag
Protected IFDOffset
Protected MemOffset
Protected n
Protected x
n=ExifGetWord(*ExifInfo, offset)
; Debug ">> "+Hex(nr)+" - "+Hex(offset)
While n
n-1
MemOffset=n*#ExifHeaderIFDLen+2+offset
IFDTag=Word(ExifGetWord(*ExifInfo, MemOffset))
IFDOffset=MemOffset+8
If Long(ExifGetWord(*ExifInfo, MemOffset+4))*PeekB(?ExifTypeBytes+Word(ExifGetWord(*ExifInfo, MemOffset+2)))>4
IFDOffset=Long(ExifGetLong(*ExifInfo, IFDOffset))
EndIf
Select IFDTag
Case $8769; IFD1-Directory
ExifGetDirectory(*ExifInfo, Long(ExifGetLong(*ExifInfo, IFDOffset)))
Case $0112; Image Rotation
*ExifInfo\Rotation=ExifGetWord(*ExifInfo, IFDOffset)
Case $0132; Image creation date (Exif Internal)
*ExifInfo\IntDate=ParseDate(#ExifDateFormat,ExifGetString(*ExifInfo, IFDOffset))
Case $9003; Image creation date (Original)
*ExifInfo\Date=ParseDate(#ExifDateFormat,ExifGetString(*ExifInfo, IFDOffset))
Case $A002; Image Width
*ExifInfo\Width=ExifGetWord(*ExifInfo, IFDOffset)
Case $A003; Image Height
*ExifInfo\Height=ExifGetWord(*ExifInfo, IFDOffset)
Case $C6D2; Image Information (Panasonic)
*ExifInfo\Information=PeekS(*ExifInfo\ExifMemory+#ExifHeaderOffset+IFDOffset)
EndSelect
Wend
EndProcedure
Procedure ExifGetFileInfo(*ExifInfo.ExifInfoType, File.s)
Protected Header
Protected Ready
Protected Daten
Protected FileHandle
With *ExifInfo
\IntDate=0; #### Invalid Memory Access ####
\JpgHeight=0
\JpgWidth=0
\JpgComment=""
\Date=0
\Rotation=0
\Width=0
\Height=0
\Information=""
If LCase(Right(File,4))=".jpg"
FileHandle = ReadFile(#PB_Any, File)
If FileHandle
If SwapWord(ReadWord(FileHandle))=#ExifSOF
Header=SwapWord(ReadWord(FileHandle))
If Header=#ExifApp1
\ExifDataSize=SwapWord(ReadWord(FileHandle))-2; #### Array index out of bounds ####
\ExifMemory=AllocateMemory(\ExifDataSize)
If \ExifMemory
If ReadData(FileHandle,\ExifMemory,\ExifDataSize)=\ExifDataSize
\ExifEndian=#Null
Debug Hex(ExifGetLong(*ExifInfo, #ExifHeaderTagExif))
If ExifGetLong(*ExifInfo, #ExifHeaderTagExif)= $45786966;'Exif'
\ExifEndian=(PeekA(\ExifMemory+#ExifHeaderOffset+#ExifHeaderTagEndian)&$FF)-'M'
ExifGetDirectory(*ExifInfo, ExifGetLong(*ExifInfo,#ExifHeaderTagIFD))
EndIf
EndIf
FreeMemory(\ExifMemory)
EndIf
Else
FileSeek(FileHandle,2);
EndIf
Repeat
Protected h=SwapWord(ReadWord(FileHandle))
Debug "Header 0x"+Hex(h)+" at Position "+Hex(Loc(FileHandle))
Select h
Case #ExifJpgSOF;
Daten=SwapWord(ReadWord(FileHandle))
If Daten=$11
Daten=ReadByte(FileHandle)
\JpgHeight=SwapWord(ReadWord(FileHandle))
\JpgWidth=SwapWord(ReadWord(FileHandle))
FileSeek(FileHandle,10,#PB_Relative)
Ready+1
Else
FileSeek(FileHandle,Daten-2,#PB_Relative)
EndIf
Case #ExifJpgCOM;
Daten=SwapWord(ReadWord(FileHandle))
\JpgComment=ReadString(FileHandle,#PB_Ascii,Daten-2)
Ready+1
Case #ExifJpgSOF To #ExifJpgCOM;
FileSeek(FileHandle,SwapWord(ReadWord(FileHandle))-2,#PB_Relative)
Case #ExifJpgSOS;
Ready+10
Default;
Ready+100
EndSelect
Until Ready>1
EndIf
CloseFile(FileHandle)
EndIf
EndIf
EndWith
EndProcedure
Procedure ExifToolSetInformation(nr)
AddElement(ExifInfo())
ExifGetFileInfo(@ExifInfo(), TestFile)
With ExifInfo()
SetGadgetItemText(0,nr,FormatDate(#ExifDateFormat,\Date),1)
SetGadgetItemText(0,nr,Str(\Width)+" x "+Str(\Height),2)
SetGadgetItemText(0,nr,Str(\Rotation),3)
SetGadgetItemText(0,nr,\Information,4)
SetGadgetItemText(0,nr,\JpgComment,5)
EndWith
EndProcedure
Procedure Main()
Protected i.i
OpenWindow(0, 0, 0, 640,800,"*", #PB_Window_SystemMenu)
ListIconGadget(0,0,0,640,800,"1",30)
For i=1 To 5
AddGadgetColumn(0,i,Chr('0'+i),120)
Next i
For i=0 To 999
AddGadgetItem(0,i,Str(i))
CreateThread(@ExifToolSetInformation(),i)
;WindowEvent()
Next i
Repeat
Until WaitWindowEvent()=#PB_Event_CloseWindow
EndProcedure
Main()
Also the compare to 'Exif' was not working.