Here is a proof of concept code for reading EXIF information from Jpeg images. It is a bit long winded as not all image tags follow the EXIF standard so I wanted to be able to show the raw data as well as the decoded tag info.
There is still a lot to do, I would like to be able to edit a tag so I can develop my Image database ( I would like to be able to search images for locations (GPS) or info I have embedded into the image so that I could display all the images from Xmas 2024 or all pictures with animals etc.)
I would like to be able to read the info from images taken on my mobile phone but I have a few other thing to get right first. ( if anyone has already done that please let me know. )
The Preference file is just a text file with the name of the directory where your images are stored. ( easy to create )
I know that the math can be improved and that it could be optimised, as I said its a proof of concept. It works on SAM 460 and my PC albeit with some format issues.
Feel free to use it in your project but a bit of credit would be nice.
So here it is, have fun and help me improve it.
Code: Select all
/*** Information about this app *******************************************************************/
@APPTITLE "EXIF Reader"
@APPVERSION "$VER: 1.0.0 (02.01.25)"
@APPCOPYRIGHT "(C) 2025 by Leo den Hollander"
@APPAUTHOR "Leo den Hollander"
@APPDESCRIPTION "EXIF Reader"
;*** EXIF Tag references *************************************************************************************
; https://exiftool.org/TagNames/EXIF.html
; https://www.media.mit.edu/pia/Research/deepview/exif.html
; https://web.archive.org/web/20190624045241if_/http://www.cipa.jp:80/std/documents/e/DC-008-Translation-2019-E.pdf
; *** Enable DPI-awareness so that our GUI looks sharp even on high DPI monitors *****************************
@OPTIONS {DPIAware = True}
; *** Setup ESC to exit program *****************************************************************************
EscapeQuit(True)
; *** This script requires the RapaGUI plugin ****************************************************************
@REQUIRE "RapaGUI", {Link = True}
; *** Define Global Variables *******************************************************************************
Global Next_OffSet
Global IDFOffSet
Global TName$
Global THex$
Global TDec$
; *** Setup ESC EXIF tag Table ******************************************************************************
Dim TagData[32]
; *** Setup Graphics for Picture Display *********************************************************************
CreateBrush(2, 400, 300, #BLACK)
; *** Setup GUI **********************************************************************************************
moai.CreateApp([[<?xml version="1.0" encoding="iso-8859-1"?>
<application id="app">
<window id="mainwin" title=" EXIF Veiwer " margin="0" width="1280" height="768" notify="closerequest">
<vgroup color="#99D2CB">
<vgroup>
<vspace height="5"/>
<hgroup>
<hspace Width="5"/>
<vgroup frame="1">
<text>Image Files</text>
<listview Id="files" Notify="Active; DoubleClick">
<column Title=" File Name " width="100"/>
<column Title=" File Type " width="50"/>
<column Title= "File Size " width="70"/>
</listview>
</vgroup>
<vspace height="5"/>
<vgroup frame="1">
<text>Registered Tags</text>
<vgroup weight="80">
<listview Id="tags">
<column Title=" Tag No " width="50"/>
<column Title=" Tag Name "/>
<column Title=" Tag Data "/>
</listview>
</vgroup>
<text>Unregistered Tags ... </text>
<vgroup weight="20">
<listview Id="noinfo">
<column Title=" Tag Id " width="50"/>
<column Title=" Tag No "/>
</listview>
</vgroup>
</vgroup>
<vgroup Frame="1">
<text>Image</text>
<hgroup>
<hollywood display="1" width="400" Height="300"/>
</hgroup>
<vspace height="5"/>
<text>File Load Tag Data Summary ... </text>
<texteditor Id="filetype" height="400"></texteditor>
<vspace height="5"/>
<hgroup>
<button ID="clear"> Clear </button>
<hspace Width="5"/>
<button ID="preferences"> Preferences </button>
</hgroup>
</vgroup>
</hgroup>
<vspace height="5"/>
</vgroup>
</vgroup>
</window>
<window Id="prefs" Title=" EXIF Veiwer Preferences" Margin="0" Width="700" Height="300" Closegadget="false"
Sizegadget="false" Minimizegadget="false" Maximizegadget="false" Open="false">
<vgroup color="#99D2CB" frame="1">
<hspace width="10"/>
<vgroup frame="1">
<vspace height="10"/>
<text align="center"> Please select the Default Directory for Startup.</text>
<vspace height="10"/>
<hgroup>
<hspace width="10"/>
<text Weight="10">Default Directory</text>
<poppath Id="examine"></poppath>
<hspace width="10"/>
</hgroup>
<vspace height="10"/>
</vgroup>
<hgroup frame="1">
<hspace width="10"/>
<button ID="save"> Save Directory </button>
<hspace Width="80"/>
<button ID="restore"> Restore Directory </button>
<hspace Width="80"/>
<button ID="cancel"> Cancel Preferences </button>
<hspace width="10"/>
</hgroup>
<vspace height="5"/>
</vgroup>
</window>
</application>
]])
; *** Load Program Preferences *******************************************************************************
Function F_Load_Preferences()
OpenFile(2, "Exif-Prefs.txt", #MODE_READ)
Global ProgDir$ = ReadLine(2)
CloseFile(2)
EndFunction
; *** Load Picture Files *************************************************************************************
Function F_Load_Pictures()
dd = OpenDirectory(Nil, ProgDir$)
e = NextDirectoryEntry(dd)
While e <> Nil
If e.type = #DOSTYPE_FILE
If LowerStr(RightStr(e.name, 3)) = "jpg" Or LowerStr(RightStr(e.name, 3)) = "tif"
moai.DoMethod("files", "Insert", "Bottom", e.name, RightStr(e.name, 3), e.size )
EndIf
EndIf
e = NextDirectoryEntry(dd)
Wend
CloseDirectory(dd)
EndFunction
; *** Clear all Lists **********************************************************************************
Function F_Clear_All()
moai.DoMethod("filetype", "Clear")
moai.DoMethod("tags", "Clear")
moai.DoMethod("noinfo", "Clear")
DisplayBrush(2, 0, 0)
EndFunction
; *** Get Tag Name ***************************************************************************
Function Check_Tag()
Switch TagNo
Case 270
TagName = " Description: "
F_Get_2()
Case 271
TagName = " Make: "
F_Get_2()
Case 272
TagName = " Model: "
F_Get_2()
Case 273
TagName = " Strip Offsets: "
F_Get_2()
Case 274
TagName = " Orientation: "
TagData[0] = " Unknown"
TagData[1] = " Horizontal (normal)"
TagData[2] = " Mirror horizontal"
TagData[3] = " Rotate 180"
TagData[4] = " Mirror vertical"
TagData[5] = " Mirror horizontal and rotate 270 CW"
TagData[6] = " Rotate 90 CW"
TagData[7] = " Mirror horizontal and rotate 90 CW"
TagData[8] = " Rotate 270 CW"
A$ = TagData[Dat]
Case 277
TagName = " Sample Per Pixel: "
F_Get_2()
Case 278
TagName = " Rows per Strip: "
F_Get_2()
Case 282
TagName = " Res X: "
F_Get_5()
Case 283
TagName = " Res Y: "
F_Get_5()
Case 296
TagName = " Res-Units: "
TagData[0] = " Unknown"
TagData[1] = " None"
TagData[2] = " inches"
TagData[3] = " cm"
A$ = TagData[Dat]
Case 305
TagName = " CreatorTool: "
F_Get_2()
Case 306
TagName = " ModifyDate: "
F_Get_2()
Case 531
TagName = " YCbCrPositioning: "
TagData[0] = " Unknown"
TagData[1] = " Centered"
TagData[2] = " Co-sited"
A$ = TagData[Dat]
Case 33434
TagName = " Exposure Time: "
Seek(1, dat + 12)
A = 0
D = 0
B1 = ReadByte(1, #ENCODING_UTF8)
B2 = ReadByte(1, #ENCODING_UTF8)
B3 = ReadByte(1, #ENCODING_UTF8)
B4 = ReadByte(1, #ENCODING_UTF8)
C1 = ReadByte(1, #ENCODING_UTF8)
C2 = ReadByte(1, #ENCODING_UTF8)
C3 = ReadByte(1, #ENCODING_UTF8)
C4 = ReadByte(1, #ENCODING_UTF8)
If ByteChr(P12) .. ByteChr(P13) = "MM"
A = (B1*1024) + (B2*512) + (B3*256) + B4
D = (C1*1024) + (C2*512) + (C3*256) + C4
D$ = Val(D/A)
Else
A = (B4*1024) + (B3*512) + (B2*256) + B1
D = (C4*1024) + (C3*512) + (C2*256) + C1
D$ = Val(D/A)
EndIf
A$ = "1/" .. D$
Case 33437
TagName = " F Number: "
Seek(1, dat + 12)
A = 0
D = 0
B1 = ReadByte(1, #ENCODING_UTF8)
B2 = ReadByte(1, #ENCODING_UTF8)
B3 = ReadByte(1, #ENCODING_UTF8)
B4 = ReadByte(1, #ENCODING_UTF8)
C1 = ReadByte(1, #ENCODING_UTF8)
C2 = ReadByte(1, #ENCODING_UTF8)
C3 = ReadByte(1, #ENCODING_UTF8)
C4 = ReadByte(1, #ENCODING_UTF8)
A = (B4*1024) + (B3*512) + (B2*256) + B1
D = (C4*1024) + (C3*512) + (C2*256) + C1
D$ = Val(A/D)
A$ = "1/" .. D$
Case 34665
TagName = " EXIF Sub IFD Offset: "
F_Get_4()
IDFOffSet = Dat
Case 34850
TagName = " Exposure Program: "
TagData[0] = " Not Defined"
TagData[1] = " Manual"
TagData[2] = " Program AE"
TagData[3] = " Aperture-priority AE"
TagData[4] = " Shutter speed priority AE"
TagData[5] = " Creative (Slow speed)"
TagData[6] = " Action (High speed)"
TagData[7] = " Portrait"
TagData[8] = " Landscape"
TagData[9] = " Bulb"
A$ = TagData[Dat]
Case 34855
TagName = " ISO Speed Rating: "
F_Get_3()
Case 34864
TagName = " Sensitivity Type:"
TagData[0] = " Unknown"
TagData[1] = " Standard Output Sensitivity"
TagData[2] = " Recommended Exposure Index"
TagData[3] = " ISO Speed"
TagData[4] = " Standard Output Sensitivity and Recommended Exposure Index"
TagData[5] = " Standard Output Sensitivity and ISO Speed"
TagData[6] = " Recommended Exposure Index and ISO Speed"
TagData[7] = " Standard Output Sensitivity, Recommended Exposure Index and ISO Speed"
A$ = TagData[Dat]
Case 36864
TagName = " Exif Version: "
F_Get_2()
Case 36867
TagName = " Date Time Original: "
F_Get_2()
Case 36868
TagName = " Date Time Digitized: "
F_Get_2()
Case 37121
TagName = " Component Config: "
TagData[0] = "-"
TagData[1] = "Y"
TagData[2] = "Cb"
TagData[3] = "Cr"
TagData[4] = "R"
TagData[5] = "G"
TagData[6] = "B"
A$ = TagData[T8] .. TagData[T9] .. TagData[T10]
Case 37122
TagName = " Compressed Bit Per Pixel: "
F_Get_5()
A$ = A$ .. "/1"
Case 37377
TagName = " Shutter Speed Value: "
Seek(1, dat + 12)
A = 0
D = 0
B1 = ReadByte(1, #ENCODING_UTF8)
B2 = ReadByte(1, #ENCODING_UTF8)
B3 = ReadByte(1, #ENCODING_UTF8)
B4 = ReadByte(1, #ENCODING_UTF8)
C1 = ReadByte(1, #ENCODING_UTF8)
C2 = ReadByte(1, #ENCODING_UTF8)
C3 = ReadByte(1, #ENCODING_UTF8)
C4 = ReadByte(1, #ENCODING_UTF8)
A = (B4*1024) + (B3*512) + (B2*256) + B1
D = (C4*1024) + (C3*512) + (C2*256) + C1
D$ = Val(D/A)
A$ = "1/" .. D$
Case 37378
TagName = " Aperture Value: "
F_Get_10()
Case 37379
TagName = " Brightness Value: "
F_Get_10()
A = TrimStr(A, "0", 1)
A = TrimStr(A, "0", 0)
If Val(A) <> 0
A$ = "EV" .. A/10
Else
A$ = "EV" .. "0.0"
EndIf
Case 37380
TagName = " Exposure Bias Value: "
F_Get_10()
A = TrimStr(A, "0", 1)
A = TrimStr(A, "0", 0)
If Val(A) <> 0
A$ = "EV" .. A/10
Else
A$ = "EV" .. "0.0"
EndIf
Case 37381
TagName = " Max Aperture Value: "
Seek(1, dat + 12)
A = 0
D = 0
B1 = ReadByte(1, #ENCODING_UTF8)
B2 = ReadByte(1, #ENCODING_UTF8)
B3 = ReadByte(1, #ENCODING_UTF8)
B4 = ReadByte(1, #ENCODING_UTF8)
C1 = ReadByte(1, #ENCODING_UTF8)
C2 = ReadByte(1, #ENCODING_UTF8)
C3 = ReadByte(1, #ENCODING_UTF8)
C4 = ReadByte(1, #ENCODING_UTF8)
A = (B4*1024) + (B3*512) + (B2*256) + B1
D = (C4*1024) + (C3*512) + (C2*256) + C1
D$ = Val(A/D)
A$ = "1/" .. D$
Case 37382
TagName = " Subject Distance: "
F_Get_3()
Case 37383
TagName = " Metering Mode: "
TagData[0] = " Unknown"
TagData[1] = " Average"
TagData[2] = " Center-weighted average"
TagData[3] = " Spot"
TagData[4] = " Multi-spot"
TagData[5] = " Multi-segment"
TagData[6] = " Partial"
TagData[7] = " 255 = Other"
If Dat > 7 Then Dat = 7
A$ = TagData[Dat]
Case 37384
TagName = " Light Source: "
TagData[0] = " Unknown"
TagData[1] = " Daylight"
TagData[2] = " Fluorescent"
TagData[3] = " Tungsten"
TagData[4] = " Flash"
TagData[5] = " Fine Weather: "
TagData[6] = " Cloudy"
TagData[7] = " Shade"
TagData[8] = " Daylight Fluorescent"
TagData[9] = " Day White Fluorescent"
TagData[10] = " Cool White Fluorescent"
TagData[11] = " White Fluorescent: "
TagData[12] = " Warm White Fluorescent"
TagData[13] = " Standard Light A"
TagData[14] = " Standard Light B"
TagData[15] = " Standard Light C"
TagData[16] = " Fluorescent"
If Dat > 167 Then Dat = 0
A$ = TagData[Dat]
Case 37385
TagName = " Flash: "
TagData[0] = " No Flash"
TagData[1] = " Fired"
TagData[5] = " Fired, No Return"
TagData[7] = " Fired, Return"
TagData[8] = " On, Did not Fire"
TagData[9] = " On, Fired "
TagData[13] = " On, Return not detected"
TagData[15] = " On, return Detected"
TagData[16] = " Off, Did not Fire"
TagData[17] = " Off, Did Not Fire"
TagData[18] = " Auto, Did not Fire"
TagData[19] = " Auto, Fired "
A$ = TagData[Dat]
Case 37386
TagName = " Focal Length: "
F_Get_5()
A$ = A$ .."mm"
Case 37396
TagName = " Subject Area: "
Seek(1, dat + 12)
A = 0
D = 0
B1 = ReadByte(1, #ENCODING_UTF8)
B2 = ReadByte(1, #ENCODING_UTF8)
B3 = ReadByte(1, #ENCODING_UTF8)
B4 = ReadByte(1, #ENCODING_UTF8)
C1 = ReadByte(1, #ENCODING_UTF8)
C2 = ReadByte(1, #ENCODING_UTF8)
C3 = ReadByte(1, #ENCODING_UTF8)
C4 = ReadByte(1, #ENCODING_UTF8)
A$ = (B2 * 256) + B1..","..(B4 * 256) + B3..","..(C2 * 256) + C1..","..(C4 * 256) + C3
Case 40960
TagName = " Flash Pix Version: "
F_Get_7()
Case 40961
TagName = " Colour Space: "
TagData[0] = " Unknown "
TagData[1] = " sRGB "
A$ = TagData[Dat]
Case 40962
TagName = " Exif Image Width: "
A$ = Dat
Case 40963
TagName = " Exif Image Height: "
A$ = Dat
Case 40964
TagName = " Related Sound File: "
F_Get_2()
Case 40965
TagName = " Exif Interoperablity Offset: "
F_Get_4()
Case 41486
TagName = " Focal Plane X Resolution: "
Case 41487
TagName = " Focal Plane Y Resolution: "
Case 41488
TagName = " Focal plane Resolution Unit: "
TagData[0] = " None"
TagData[1] = " inches"
TagData[2] = " cm"
TagData[3] = " mm"
TagData[4] = " um"
A$ = TagData[Dat]
Case 41495
TagName = " Sensing Method: "
TagData[0] = " Not defined"
TagData[1] = " One-chip color area"
TagData[2] = " Two-chip color area"
TagData[3] = " Three-chip color area"
TagData[4] = " Color sequential area"
TagData[5] = " Trilinear"
TagData[6] = " Color sequential linear"
A$ = TagData[Dat]
Case 41728
TagName = " File Source: "
TagData[0] = " Unknown"
TagData[1] = " Film Scanner"
TagData[2] = " Reflection Film Camera"
TagData[3] = " Digital Camera"
If ByteChr(P12) .. ByteChr(P13) = "MM"
Dat = Val((T9 * 256) + T8)
EndIf
A$ = TagData[Dat]
Case 41729
TagName = " Scene Type: "
TagData[0] = " Unknown"
TagData[1] = " Directly Photographed"
If ByteChr(P12) .. ByteChr(P13) = "MM"
Dat = Val((T9 * 256) + T8)
EndIf
A$ = TagData[Dat]
Case 41985
TagName = " Custom Rendered:"
TagData[0] = " Unknown"
TagData[1] = " Custom Process"
TagData[2] = " Custom "
A$ = TagData[Dat]
Case 41986
TagName = " Exposuer Mode:"
TagData[0] = " Auto"
TagData[1] = " Manual"
TagData[2] = " Auto Bracket"
A$ = TagData[Dat]
Case 41987
TagName = " White balance:"
TagData[0] = " Auto"
TagData[1] = " Manual"
A$ = TagData[Dat]
Case 41988
TagName = " Digital Zoom Ratio:"
Seek(1, dat + 12)
A = 0
D = 0
B1 = ReadByte(1, #ENCODING_UTF8)
B2 = ReadByte(1, #ENCODING_UTF8)
B3 = ReadByte(1, #ENCODING_UTF8)
B4 = ReadByte(1, #ENCODING_UTF8)
C1 = ReadByte(1, #ENCODING_UTF8)
C2 = ReadByte(1, #ENCODING_UTF8)
C3 = ReadByte(1, #ENCODING_UTF8)
C4 = ReadByte(1, #ENCODING_UTF8)
A = (B4*1024) + (B3*512) + (B2*256) + B1
D = (C4*1024) + (C3*512) + (C2*256) + C1
D$ = Val(D)
A$ = "0/" .. D$
Case 41989
TagName = " Focal Length (35 mm Format):"
F_Get_3()
A$ = A$ .. "mm"
Case 41990
TagName = " Scene Capture Type:"
TagData[0] = " Standard"
TagData[1] = " Landscape"
TagData[2] = " Portrait"
TagData[3] = " Night"
TagData[4] = " Other"
A$ = TagData[Dat]
Case 41991
TagName = " Gain Control:"
TagData[0] = " None:"
TagData[1] = " Low gain up"
TagData[2] = " High gain up"
TagData[3] = " Low gain down"
TagData[4] = " High gain down"
A$ = TagData[Dat]
Case 41992
TagName = " Contrast:"
TagData[0] = " Normal"
TagData[1] = " Low"
TagData[2] = " High"
A$ = TagData[Dat]
Case 41993
TagName = " Saturation:"
TagData[0] = " Normal"
TagData[1] = " Low"
TagData[2] = " High"
A$ = TagData[Dat]
Case 41994
TagName = " Sharpness:"
TagData[0] = " Normal"
TagData[1] = " Soft"
TagData[2] = " Hard"
A$ = TagData[Dat]
Case 41995
TagName = " Device Setting Description:"
Case 41996
TagName = " Subject Distance Range:"
TagData[0] = " Unknown"
TagData[1] = " Macro"
TagData[2] = " Close"
TagData[3] = " Distant"
A$ = TagData[Dat]
Case 42016
TagName = " Image Unique ID:"
Case 42032
TagName = " Owner Name:"
Case 42033
TagName = " Body Serial Number:"
Case 42034
TagName = " Lens Info:"
Case 42035
TagName = " Lens Make:"
Case 42036
TagName = " Lens Model:"
Case 42037
TagName = " Lens Serial Number:"
Case 42038
TagName = " Image Title:"
Case 42039
TagName = " Photgrapher :"
Case 42040
TagName = " Image Editor:"
Case 50341
TagName = " PrintIM OffSet: "
F_Get_7()
Default
moai.DoMethod("noinfo", "Insert", "Bottom", HexStr(TagNo), TagNo)
EndSwitch
If TagName <> ""
moai.DoMethod("filetype", "Insert", Chr(13) .. "\27bTag " .. HexStr(TagNo) .. " (" .. TagNo .. ") :- " .. TagName$ ..
"Type: " .. Type .. " Number: " .. Numb .. " Data: " .. Dat, "Bottom")
moai.DoMethod("tags", "Insert", "Bottom", TagNo, TagName, A$)
EndIf
TagName$ = ""
A$ = ""
EndFunction
; *** Read Tag 2 *****************************************************************************
Function F_Get_2()
If Numb > 5
If Numb > 1024 Then Numb = 1024
Seek(1, dat + 12)
A$ = ""
For t = 1 To numb
B = ReadByte(1, #ENCODING_UTF8)
B$ = ByteChr(B)
A$ = A$ .. B$
Next
Else
A$ = ByteChr(T8) .. ByteChr(T9) .. ByteChr(T10) .. ByteChr(T11)
EndIf
D$ = A$
EndFunction
; *** Read Tag 3 **********************************************************************************
Function F_Get_3()
A$ = Dat
EndFunction
; *** Read Tag 4 **********************************************************************************
Function F_Get_4()
A$ = Dat
EndFunction
; *** Read Tag 5 **********************************************************************************
Function F_Get_5()
Seek(1, dat + 12)
A = 0
D = 0
For Local t = 1 To (numb * 4)
B = ReadByte(1, #ENCODING_UTF8)
A = A + B
Next
A$ = Val(A)
For Local t = 1 To (numb * 4)
C = ReadByte(1, #ENCODING_UTF8)
D = D + C
Next
C$ = Val(D)
D$ = C$ .. "/" .. A$
EndFunction
; *** Read Tag 7 **********************************************************************************
Function F_Get_7()
Seek(1, dat + 12)
A$ = ""
AA = 0
For Local t = 1 To numb
B = ReadByte(1, #ENCODING_UTF8)
AA = AA + Val(B)
Next
A$ = AA
EndFunction
; *** Read Tag Type 10 **********************************************************************************
Function F_Get_10()
Seek(1, dat + 12)
A = 0
For t = 1 To 4
B = ReadByte(1, #ENCODING_UTF8)
B$ = ByteChr(B)
A = A .. B
Next
A$ = A
EndFunction
; *** Read EXIF Header Tags **********************************************************************************
Function F_Read_Exif(SelectedFile$)
Counter = 0
A = 0
A$ = ""
IDFOffSet = 0
OpenFile(1, SelectedFile$)
P0 = ReadByte(1)
P1 = ReadByte(1)
If P0 = 255 And P1 = 216
moai.DoMethod("filetype", "insert", "\27bSOI Marker found. " .. HexStr(P0) .. " " ..
HexStr(P1) .. Chr(13), "Bottom")
P2 = ReadByte(1)
P3 = ReadByte(1)
If P2 = 255 And P3 = 225
moai.DoMethod("filetype", "insert", "\27bAPP1 Marker found. " ..
HexStr(P2) .. " " .. HexStr(P3) .. Chr(13), "Bottom")
P4 = ReadByte(1)
P5 = ReadByte(1)
moai.DoMethod("filetype", "insert", " APP1 Marker size : " .. HexStr(P4) .. " " ..
HexStr(P5) .. Chr(13), "Bottom")
moai.DoMethod("filetype", "insert", "\27bExif Header Found. " .. Chr(13), "Bottom")
P6 = ReadByte(1)
P7 = ReadByte(1)
P8 = ReadByte(1)
P9 = ReadByte(1)
moai.DoMethod("filetype", "Insert", " " .. ByteChr(P6) .. ByteChr(P7) .. ByteChr(P8) ..
ByteChr(P9) .. " : ", "Bottom")
moai.DoMethod("filetype", "Insert", " " .. HexStr(P6) .. HexStr(P7) .. HexStr(P8) ..
HexStr(P9) .. Chr(13), "Bottom")
P10 = ReadByte(1)
P11 = ReadByte(1)
moai.DoMethod("filetype", "insert", "\27bTIFF Header found. " .. Chr(13), "Bottom")
counter = 12
P12 = ReadByte(1)
P13 = ReadByte(1)
moai.DoMethod("filetype", "insert", " Align format : " .. Chr(P12) ..
Chr(P13) .. " - ", "Bottom")
If ByteChr(p12)..ByteChr(P13) = "MM"
moai.DoMethod("filetype", "Insert", " Motorola Format" .. Chr(13), "Bottom")
P14 = ReadByte(1)
P15 = ReadByte(1)
moai.DoMethod("filetype", "insert", " TAG Marker : " .. P14 .. P15 .. " : " ..
HexStr(P14) .. " " .. HexStr(P15) .. Chr(13), "Bottom")
P16 = ReadByte(1)
P17 = ReadByte(1)
Off_H = ReadByte(1)
Off_L = ReadByte(1)
moai.DoMethod("filetype", "insert", " Offset to IFD0 : " .. Off_H .. Off_L .. " : " ..
HexStr(Off_H) .. " " .. HexStr(Off_l) .. Chr(13), "Bottom")
ElseIf ByteChr(p12) .. ByteChr(P13) = "II"
moai.DoMethod("filetype", "Insert", " Intel Format ".. Chr(13), "Bottom")
P14 = ReadByte(1)
P15 = ReadByte(1)
moai.DoMethod("filetype", "insert", " TAG Marker : " .. P15 .. P14 .. " : " ..
HexStr(P15) .. " " .. HexStr(P14) .. Chr(13), "Bottom")
Off_L = ReadByte(1)
Off_H = ReadByte(1)
P18 = ReadByte(1)
P19 = ReadByte(1)
moai.DoMethod("filetype", "insert", " Offset to IFD0 : " .. Off_H .. Off_L .. " : " ..
HexStr(Off_H) .. " " .. HexStr(Off_L) .. Chr(13), "Bottom")
EndIf
Next_OffSet = Val((Off_H * 256) + Off_L)
Counter = Counter + Next_OffSet
Seek(1, Counter)
moai.DoMethod("filetype", "Insert", Chr(13) .. "\27bIFD Tags:" .. Chr(13), "Bottom")
If ByteChr(P12) .. ByteChr(P13) = "MM"
NT_H = ReadByte(1)
NT_L = ReadByte(1)
ElseIf ByteChr(P12) .. ByteChr(P13) = "II"
NT_L = ReadByte(1)
NT_H = ReadByte(1)
EndIf
No_Tags = Val((NT_H * 256) + NT_L)
moai.DoMethod("filetype", "Insert","\27bNo. of Tags in IFD0 : " .. No_Tags ..
" : \27n" .. HexStr(NT_H) .. HexStr(NT_L) .. Chr(13), "Bottom")
Counter = Counter + 2
For NT = 1 To No_Tags
T0 = ReadByte(1)
T1 = ReadByte(1)
T2 = ReadByte(1)
T3 = ReadByte(1)
T4 = ReadByte(1)
T5 = ReadByte(1)
T6 = ReadByte(1)
T7 = ReadByte(1)
T8 = ReadByte(1)
T9 = ReadByte(1)
T10 = ReadByte(1)
T11 = ReadByte(1)
If ByteChr(P12) .. ByteChr(P13) = "MM"
TagNo = (T0 * 256) + T1
Type = Val((T2 * 256) + T3)
Numb = Val((T6 * 256) + T7)
Dat = Val((T8 * 256) + T9) + Val((T10 * 256) + T11)
; Dat = Val((T10 * 256) + T11)
ElseIf ByteChr(P12) .. ByteChr(P13) = "II"
TagNo = T0 + (T1 * 256)
Type = Val(T2 + (T3 * 256))
Numb = Val(T4 + (T5 * 256))
Dat = Val(T8 + (T9 * 256))
EndIf
Check_Tag()
Counter = Counter + 12
Seek(1, Counter)
Next
If IDFOffSet > 0
F_Read_IFD0()
EndIf
Else
moai.DoMethod("filetype", "insert", "\27b NO APP1 Marker found. " .. Chr(13), "Bottom")
EndIf
Else
moai.DoMethod("filetype", "insert", "\27b NO SOI Marker found. " .. Chr(13), "Bottom")
EndIf
EndFunction
; *** Read the Tags in IFD0 **********************************************************************
Function F_Read_IFD0()
If ByteChr(P12) .. ByteChr(P13) = "MM"
Seek(1, IDFOffSet + 12)
NT_H = ReadByte(1)
NT_L = ReadByte(1)
No_Tags = Val(NT_L + (NT_H * 256))
ElseIf ByteChr(P12) .. ByteChr(P13) = "II"
Seek(1, IDFOffSet + 12)
NT_L = ReadByte(1)
NT_H = ReadByte(1)
No_Tags = Val(NT_L + (NT_H * 256))
EndIf
moai.DoMethod("filetype", "Insert", Chr(13) .. Chr(13) .. "\27bNo. of Tags in Sub IFD0 : " .. No_Tags ..
" : \27n" .. HexStr(NT_H) .. HexStr(NT_L) .. Chr(13), "Bottom")
Seek(1, IDFOffSet + 14)
Counter = IDFOffSet + 14
For NT = 1 To No_Tags
T0 = ReadByte(1)
T1 = ReadByte(1)
T2 = ReadByte(1)
T3 = ReadByte(1)
T4 = ReadByte(1)
T5 = ReadByte(1)
T6 = ReadByte(1)
T7 = ReadByte(1)
T8 = ReadByte(1)
T9 = ReadByte(1)
T10 = ReadByte(1)
T11 = ReadByte(1)
If ByteChr(P12) .. ByteChr(P13) = "MM"
TagNo = (T0 * 256) + T1
Type = Val((T2 * 256) + T3)
Numb = Val((T6 * 256) + T7)
Dat = Val((T8 * 256) + T9) + Val((T10 * 256) + T11)
ElseIf ByteChr(P12) .. ByteChr(P13) = "II"
TagNo = T0 + (T1 * 256)
Type = Val(T2 + (T3 * 256))
Numb = Val(T4 + (T5 * 256))
Dat = Val(T8 + (T9 * 256))
EndIf
Check_Tag()
Counter = Counter + 12
Seek(1, Counter)
Next
EndFunction
; *** Read the Tags in PrintIM **********************************************************************
Function F_Read_PrintIM()
If ByteChr(P12) .. ByteChr(P13) = "MM"
Seek(1, PCounter + PrintIMOffSet + 12)
NT_H = ReadByte(1)
NT_L = ReadByte(1)
No_Tags = Val(NT_L + (NT_H * 256))
ElseIf ByteChr(P12) .. ByteChr(P13) = "II"
Seek(1, PCounter + PrintIMOffSet + 12)
NT_L = ReadByte(1)
NT_H = ReadByte(1)
No_Tags = Val(NT_L + (NT_H * 256))
EndIf
moai.DoMethod("filetype", "Insert", "\27bNo. of Tags in PrintIM IFD : " .. No_Tags ..
" : \27n" .. HexStr(NT_H) .. HexStr(NT_L) .. Chr(13), "Bottom")
Seek(1, PintIMOffSet + 14)
PCounter = PrintIMOffSet + 14
For NT = 1 To No_Tags
T0 = ReadByte(1)
T1 = ReadByte(1)
T2 = ReadByte(1)
T3 = ReadByte(1)
T4 = ReadByte(1)
T5 = ReadByte(1)
T6 = ReadByte(1)
T7 = ReadByte(1)
T8 = ReadByte(1)
T9 = ReadByte(1)
T10 = ReadByte(1)
T11 = ReadByte(1)
If ByteChr(P12) .. ByteChr(P13) = "MM"
TagNo = (T0 * 256) + T1
Type = Val((T2 * 256) + T3)
Numb = Val((T6 * 256) + T7)
Dat = Val((T10 * 1024) + (T11 * 512)) + Val((T8 * 256) + T9)
ElseIf ByteChr(P12) .. ByteChr(P13) = "II"
TagNo = T0 + (T1 * 256)
Type = Val(T2 + (T3 * 256))
Numb = Val(T4 + (T5 * 256))
Dat = Val(T8 + (T9 * 256))
EndIf
F_Get_Tag_Name()
moai.DoMethod("filetype", "insert", "\27b NO APP1 Marker found. " .. Chr(13), "Bottom")
moai.DoMethod("filetype", "insert", "\27b NO SOI Marker found. " .. Chr(13), "Bottom")
Next
EndFunction
/***********************************************************************************************************/
/*** RAPAGUI Events ****************************************************************************************/
/***********************************************************************************************************/
Function Rapa_Events(msg)
Switch msg.action
Case "RapaGUI"
Switch msg.attribute
Case "Pressed"
Switch msg.id
Case "clear"
F_Clear_All()
Case "preferences"
moai.Set("prefs", "Open", True)
moai.Set("examine", "Path", ProgDir$)
Case "save"
ProgDir$ = moai.Get("examine", "Path")
OpenFile(2, "Exif-Prefs.txt", #MODE_WRITE)
WriteLine(2, ProgDir$)
CloseFile(2)
moai.DoMethod("Files", "Clear")
F_Load_Pictures()
moai.Set("prefs", "Open", False)
Case "restore"
moai.Set("examine", "Path", "")
moai.Set("examine", "Path", ProgDir$)
Case "cancel"
moai.Set("prefs", "Open", False)
EndSwitch
Case "Active":
Switch msg.id
Case "files"
Pos = moai.Get("files", "Active")
Col1$, Col2$, Clo3$ = moai.DoMethod("files", "GetEntry", Pos)
EndSwitch
Case "DoubleClick":
Switch msg.id
Case "files"
Pos = moai.Get("files", "Active")
SelectedFile$, Col2$, Col3$ = moai.DoMethod("files", "GetEntry", Pos)
SelectedFile$ = ProgDir$ .. SelectedFile$
F_Clear_All()
F_Read_Exif(SelectedFile$)
CloseFile(1)
LoadBrush(1, SelectedFile$)
DisplayBrush(1, 0, 0, {Width=400, Height=300})
EndSwitch
Case "CloseRequest"
Switch msg.id
Case "mainwin"
moai.Set("mainwin", "Open", False)
End
EndSwitch
EndSwitch
EndSwitch
EndFunction
; *** Listen to these events *********************************************************************************
InstallEventHandler({RapaGUI = Rapa_Events})
; *** Program Setup ******************************************************************************************
F_Load_Preferences()
F_Load_Pictures()
; *** Main Loop **********************************************************************************************
Repeat
WaitEvent
Forever
Leo