' 52F530137941330A86743FDC2463D00A8136897C4EA247F83BF32CB903F8ADFC7A3590F417E410C2A0DCBA473419158E070D350B2881F54F6EDE05A777324181 ' sRipeTech ' 104395CD6D 2024-11-18 09:48:02 dbclose() newscript dir = app$path ' ----------------------------------- const appVersion = "2024-11-18" const appDescription = "Image META data decoder" dim myWindow = sob ("application","NEW",appDescription ) ' ----------------------------------- const TabChar = chr(0x09) const crChar = chr(0x0a) const readOnlyRGB = rgb ( 237, 229, 225 ) const greenBtnRGB = rgb ( 0x00, 0xff, 0x00 ) const FileSelectorFilter = "All Files \0*.*\0\0" dim decodeInfo ' -------------------- ' Define a callback to handle a click on the TOP Right "X" ' Callbacks are discussed in detail in the CALLBACK help option FUNCTION ClickMyWindow ( sobid ) ' delete the SOB myWindow and automatically deletes all of its child SOBs sob ( myWindow, "delete") quit END function ' Associate the callback with myWindow sob ( myWindow , "ON" , "CLICK" , "ClickMyWindow" ) ' ----------------------------------------------------- ' add a menu bar myWindow dim myMenuBar = sob (myWindow , "add" , "menu" , "bar" ) ' add horizonal menus to myMenuBar dim myMenuFile = sob (myMenuBar , "add" , "menu" , "Horizontal" , "File" ) dim myMenuOptions = sob (myMenuBar , "add" , "menu" , "Horizontal" , "Decode Options" ) dim myMenuFont = sob (myMenuBar , "add" , "menu" , "Horizontal" , "Font" ) dim myMenuHelp = sob (myMenuBar , "add" , "menu" , "Horizontal" , "Help" ) ' ----------------------------------------------------- ' add a menu item to the FILE menu ' Note: we are not going to explicitly remember the ID of the menu SOB we are about to create. ' This is a trick, see comment in about 4 lines! FUNCTION ClickGetFile ( sobid ) cbFile_File ( sobid ) END function sob ( myMenuFile , "add" , "menu" , "Vertical" , "Get image file" ) ' Associate a click / press on the File.Exit menu option with a callback handler ' Note: a SOB id of -1 always refers to the SOB used in the last SOB command ' If we did not have this, then we would have had to have a DIM in the previous SOB command line sob ( -1 , "ON" , "CLICK" , "ClickGetFile") ' ----------------------------------------------------- dim LastProcessedFileName = "" FUNCTION cbLastProcessed ( sobid ) IF !( LastProcessedFileName == "" ) then ShellExecute ( LastProcessedFileName) END Function sob ( myMenuFile , "add" , "menu" , "Vertical", "Default file handling" ) sob (-1 , "ON" , "CLICK" , "cbLastProcessed" ) ' ----------------------------------------------------- ' add a menu item to the FILE menu ' Note: we are not going to explicitly remember the ID of the menu SOB we are about to create. ' This is a trick, see comment in about 4 lines! sob ( myMenuFile , "add" , "menu" , "Vertical" , "Exit" ) ' Associate a click / press on the File.Exit menu option with a callback handler ' Note: a SOB id of -1 always refers to the SOB used in the last SOB command ' If we did not have this, then we would have had to have a DIM in the previous SOB command line sob ( -1 , "ON" , "CLICK" , "ClickMyWindow") ' ----------------------------------------------------- SOB ( myMenuOptions , "ADD" , "MENU" , "SPACER" ) ' ----------------------------------------------------- dim ShowMarkersFlag = 0 FUNCTION cbShowMarkers ( sobid ) dim newVal = ! SOB (sobid , "GET" , "CHECK" ) ShowMarkersFlag = newVal SOB (sobid , "SET" , "CHECK" , newVal ) END Function sob ( myMenuOptions , "add" , "menu" , "Vertical", "Show Markers+" ) sob (-1 , "ON" , "CLICK" , "cbShowMarkers" ) SOB (-1 , "TRIGGER" ) ' ----------------------------------------------------- dim ShowIFDFlag = 0 FUNCTION cbShowIFDs( sobid ) dim newVal = ! SOB (sobid , "GET" , "CHECK" ) ShowIFDFlag = newVal SOB (sobid , "SET" , "CHECK" , newVal ) END Function sob ( myMenuOptions , "add" , "menu" , "Vertical", "Show IFD Headers" ) sob (-1 , "ON" , "CLICK" , "cbShowIFDs" ) ' SOB (-1 , "TRIGGER" ) ' ----------------------------------------------------- dim ShowRawTagFlag = 0 FUNCTION cbShowRawTags( sobid ) dim newVal = ! SOB (sobid , "GET" , "CHECK" ) ShowRawTagFlag = newVal SOB (sobid , "SET" , "CHECK" , newVal ) END Function sob ( myMenuOptions , "add" , "menu" , "Vertical", "Show IFD Entries Raw" ) sob (-1 , "ON" , "CLICK" , "cbShowRawTags" ) ' SOB (-1 , "TRIGGER" ) ' ----------------------------------------------------- dim ShowTagFlag = 0 FUNCTION cbShowTags( sobid ) dim newVal = ! SOB (sobid , "GET" , "CHECK" ) ShowTagFlag = newVal SOB (sobid , "SET" , "CHECK" , newVal ) END Function sob ( myMenuOptions , "add" , "menu" , "Vertical", "Show IFD Entries Decoded" ) sob (-1 , "ON" , "CLICK" , "cbShowTags" ) SOB (-1 , "TRIGGER" ) ' ----------------------------------------------------- dim sobFontSize = sob ( myMenuFont , "add" , "menu" , "Vertical", " " ) sob ( -1 , "SET", "menu.GREY", 1 ) FUNCTION setFontSize ( useValue ) sob( sobFontSize , "SET", "TITLE", "Font size = " & useValue ) SOB (decodeInfo , "SET" , "ROW" , "TOP" ,0 ) END function FUNCTION cbFontBigger( sobid ) IF ( fontSize < 48) then fontSize = fontSize + 2 END if setFontSize ( fontSize) END Function sob ( myMenuFont , "add" , "menu" , "Vertical", "bigger" ) sob (-1 , "ON" , "CLICK" , "cbFontBigger" ) FUNCTION cbFontDefault( sobid ) fontSize = APP$ARG ( asc("F") ) setFontSize ( fontSize) END Function sob ( myMenuFont , "add" , "menu" , "Vertical", " default size" ) sob (-1 , "ON" , "CLICK" , "cbFontDefault" ) sob (-1 , "TRIGGER") FUNCTION cbFontSmaller( sobid ) IF ( fontSize > 3 ) then fontSize = fontSize - 2 END if setFontSize ( fontSize) END Function sob ( myMenuFont , "add" , "menu" , "Vertical", "smaller" ) sob (-1 , "ON" , "CLICK" , "cbFontSmaller" ) ' ----------------------------------------------------- SOB ( myMenuFont , "ADD" , "MENU" , "SPACER" ) ' ----------------------------------------------------- dim sobFontBold = sob ( myMenuFont , "add" , "menu" , "Vertical", " " ) sob ( -1 , "SET", "menu.GREY", 1 ) FUNCTION setFontBold ( useValue ) sob( sobFontBold , "SET", "TITLE", "Font bold = " & useValue ) SOB( decodeInfo , "SET" , "ROW" , "TOP" ,0 ) END function FUNCTION cbBoldDarkest( sobid ) fontBold = fontBold + 1000 setFontBold (fontBold) END Function sob ( myMenuFont , "add" , "menu" , "Vertical", "darkest" ) sob (-1 , "ON" , "CLICK" , "cbBoldDarkest" ) FUNCTION cbBoldDarker( sobid ) fontBold = fontBold + 100 setFontBold (fontBold) END Function sob ( myMenuFont , "add" , "menu" , "Vertical", "darker" ) sob (-1 , "ON" , "CLICK" , "cbBoldDarker" ) FUNCTION cbBoldDefault( sobid ) fontBold = 400 setFontBold (fontBold) END Function sob ( myMenuFont , "add" , "menu" , "Vertical", " default bold" ) sob (-1 , "ON" , "CLICK" , "cbBoldDefault" ) FUNCTION cbBoldlighter( sobid ) fontBold = fontBold - 100 setFontBold (fontBold) END Function sob ( myMenuFont , "add" , "menu" , "Vertical", "lighter" ) sob (-1 , "ON" , "CLICK" , "cbBoldlighter" ) ' ----------------------------------------------------- SOB ( myMenuFont , "ADD" , "MENU" , "SPACER" ) ' ----------------------------------------------------- FUNCTION cbNewInstance( sobid ) dim tmpNIDir = dir() dir = app$path NewInstance ( "\ F" & fontSize & " B" & FontBold ) dir= tmpNIDir END Function sob ( myMenuFont , "add" , "menu" , "Vertical", "New instance with this FONT SIZE/BOLD" ) sob (-1 , "ON" , "CLICK" , "cbNewInstance" ) ' ----------------------------------------------------- ' ----------------------------------------------------- ' Define a callback to handle a click on the Help.About menu option (not yet defined) FUNCTION ClickAbout ( sobid ) sob( decodeInfo , "empty") dim txt = "Decodes some of the META data in an image file." & crChar & appVersion & crChar txt = txt & crChar & "To decode a file drag and drop it on the green bar (above)." & crChar txt = txt & crChar txt = txt & crChar & "I developed this program because I wanted to know more about META data in images. " & crChar txt = txt & "There are other FAR BETTER programs that display image META data than this program. " & crChar txt = txt & crChar & "Irrespective, I learnt a lot developing this program and offer it to whoever might want it. " & crChar txt = txt & crChar txt = txt & crChar & "A double right click on this panel will reload the last decoded file." & crChar txt = txt & crChar txt = txt & crChar & "This program was written in the pwScripter script language." & crChar txt = txt & crChar & "For more about pwScripter please visit https://www.ripetech.com" txt = txt & crChar & "( menu: help / Browse website )" & crChar sob (decodeInfo,"add", "row" , txt ) SOB (decodeInfo,"SET" , "ROW" , "TOP" ,0 ) END Function dim sobAbout = sob ( myMenuHelp , "add" , "menu" , "Vertical", "About" ) sob ( -1 , "ON" , "CLICK" , "ClickAbout" ) ' ----------------------------------------------------- ' Define a callback to handle a click on the Help.Contact menu option (not yet defined) FUNCTION ClickContact ( sobid ) sob( decodeInfo , "empty") dim txt = "E-Mail: george.salisbury@ripetech.com" txt = txt & crChar & "Double right click on the info panel to return to last decode, " & crChar sob (decodeInfo,"add", "row" , txt ) report("TEST text to report") END Function sob ( myMenuHelp , "add" , "menu" , "Vertical" , "Contact" ) sob ( -1 ,"ON","CLICK", "ClickContact") ' ----------------------------------------------------- SOB ( myMenuHelp , "ADD" , "MENU" , "SPACER" ) ' ----------------------------------------------------- ' Define a callback to handle a click on the Help.Contact menu option (not yet defined) FUNCTION ClickOnline ( sobid ) ShellExecute ( "https://www.ripetech.com" ) END Function sob ( myMenuHelp , "add" , "menu" , "Vertical" , "Browse website" ) sob ( -1 ,"ON","CLICK", "ClickOnline") FUNCTION ClickDnLoad ( sobid ) ShellExecute ( "https://ripetech.com/downloads-and-script-files" ) END Function sob ( myMenuHelp , "add" , "menu" , "Vertical" , "Browse download website" ) sob ( -1 ,"ON","CLICK", "ClickDnLoad") ' ----------------------------------------------------- SOB ( myMenuHelp , "ADD" , "MENU" , "SPACER" ) ' Define a callback to handle a click on the Help.Contact menu option (not yet defined) FUNCTION ClickShowpwScripter ( sobid ) SOB (sobid , "SET" , "CHECK" , ! SOB (sobid , "GET" , "CHECK" ) ) SOB (pwSwindow , "SET" , "show" , SOB (sobid , "GET" , "CHECK" ) ) END Function sob ( myMenuHelp , "add" , "menu" , "Vertical" , "Show pwScripter" ) sob ( -1 ,"ON","CLICK", "ClickShowpwScripter") sob ( -1 ,"SET" , "CHECK" , 1) sob ( -1 ,"Trigger") ' ----------------------------------------------------- ' ' ----------------------------------------------------- ' Create a Container as a ROW of objects that have the same WIDTH dim appCOL = sob ( myWindow, "ADD", "CONTAINER", "COLUMN.w") ' ----------------------------------------------------- ' DATABASE part of the APP ' ----------------------------------------------------- dbopen ( "memory") create table markers ( code , abr , name , Description , AdditionalSize , ByteAlignment , d0 , d1 ) insert into markers values ( "0x0FFD8" , " SOI", "Start of Image" , " Start of compressed data" , 0 , "M" ,0,0 ) ' -------------------------------------------------------------------------------------------------- insert into markers values ( "0x0FFE0" , "APP0", "JFIF" , "" , 2 , "M" ,0,0 ) insert into markers values ( "0x0FFE1" , "APP1", "Application Segment 1" , "Exif attribute information" , 2 , "M" ,0,0 ) insert into markers values ( "0x0FFE2" , "APP2", "Application Segment 2" , "Exif extended data" , 2 , "M" ,0,0 ) insert into markers values ( "0x0FFE3" , "APP3", "Application Segment 3" , "Exif extended data" , 2 , "M" ,0,0 ) insert into markers values ( "0x0FFE4" , "APP4", "Application Segment 4" , "Exif extended data" , 2 , "M" ,0,0 ) insert into markers values ( "0x0FFE5" , "APP5", "Application Segment 5" , "Exif extended data" , 2 , "M" ,0,0 ) insert into markers values ( "0x0FFE6" , "APP6", "Application Segment 6" , "Exif extended data" , 2 , "M" ,0,0 ) insert into markers values ( "0x0FFE7" , "APP7", "Application Segment 7" , "Exif extended data" , 2 , "M" ,0,0 ) insert into markers values ( "0x0FFE8" , "APP8", "Application Segment 8" , "Exif extended data" , 2 , "M" ,0,0 ) insert into markers values ( "0x0FFE9" , "APP9", "Application Segment 9" , "Exif extended data" , 2 , "M" ,0,0 ) insert into markers values ( "0x0FFEA" , "APPA", "Application Segment A" , "Exif extended data" , 2 , "M" ,0,0 ) insert into markers values ( "0x0FFEB" , "APPB", "Application Segment B" , "Exif extended data" , 2 , "M" ,0,0 ) insert into markers values ( "0x0FFEC" , "APPC", "Application Segment C" , "Exif extended data" , 2 , "M" ,0,0 ) insert into markers values ( "0x0FFED" , "APPD", "Application Segment D" , "Exif extended data" , 2 , "M" ,0,0 ) insert into markers values ( "0x0FFEE" , "APPE", "Application Segment E" , "Exif extended data" , 2 , "M" ,0,0 ) insert into markers values ( "0x0FFEF" , "APPE", "Application Segment F" , "Exif extended data" , 2 , "M" ,0,0 ) ' -------------------------------------------------------------------------------------------------- insert into markers values ( "0x0FFC0" , "SOF0", "Start of Frame 0" , "Baseline DCT" , 2 , "M" ,0,0 ) insert into markers values ( "0x0FFC2" , "SOF0", "Start of Frame 2" , "Baseline DCT" , 2 , "M" ,0,0 ) insert into markers values ( "0x0FFC4" , " DHT", "Define Huffman Table" , "Huffman table definition" , 2 , "M" ,0,0 ) insert into markers values ( "0x0FFDB" , " DQT", "Define Quantization Table" , "Quantization table definition" , 2 , "M" ,0,0 ) ' -------------------------------------------------------------------------------------------------- insert into markers values ( "0x0FFD0" , "RST0", "Restart 0" , "Restart" , 2 , "M" ,0,0 ) insert into markers values ( "0x0FFD1" , "RST1", "Restart 1" , "Restart" , 2 , "M" ,0,0 ) insert into markers values ( "0x0FFD2" , "RST2", "Restart 2" , "Restart" , 2 , "M" ,0,0 ) insert into markers values ( "0x0FFD3" , "RST3", "Restart 3" , "Restart" , 2 , "M" ,0,0 ) insert into markers values ( "0x0FFD4" , "RST4", "Restart 4" , "Restart" , 2 , "M" ,0,0 ) insert into markers values ( "0x0FFD5" , "RST5", "Restart 5" , "Restart" , 2 , "M" ,0,0 ) insert into markers values ( "0x0FFD6" , "RST6", "Restart 6" , "Restart" , 2 , "M" ,0,0 ) insert into markers values ( "0x0FFD7" , "RST7", "Restart 7" , "Restart" , 2 , "M" ,0,0 ) '-------------------------------------------------------------------------------------------------- insert into markers values ( "0x0FFD9" , " EOI", "End of Image" , "End of compressed data" , 0 , "M" ,0,0 ) insert into markers values ( "0x0FFDD" , " DRI", "Define Restart Interval" , "Restart Interoperability definition" , 2 , "M" ,0,0 ) insert into markers values ( "0x0FFDA" , " SOS", "Start of Scan" , "Parameters relating to components" , 2 , "M" ,0,0 ) insert into markers values ( "0x0FFFE" , " COM", "Comment" , "Comment" , 2 , "M" ,0,0 ) ' https://www.loc.gov/preservation/digital/formats/content/tiff_tags.shtml create table tags ( tag , name , d0 ,d1 ) create table subtags ( tag , subTag , name ) insert into tags values ( 0x0001 , "Interoperability Index", 0 ,0 ) insert into tags values ( 0x0002 , "Interoperability Version", 0 ,0 ) insert into tags values ( 0x00FE , "NewSubfileType", 0 ,0 ) insert into tags values ( 0x00FF , "SubfileType", 0 ,0 ) insert into tags values ( 0x0100 , "ImageWidth", 0 ,0 ) insert into tags values ( 0x0101 , "ImageLength", 0 ,0 ) insert into tags values ( 0x0102 , "BitsPerSample", 0 ,0 ) insert into tags values ( 0x0103 , "Compression", 0 ,0 ) insert into subtags values (0x0103 , 0 , "Uncompressed, interleaved, 8 bits per sample" ) insert into subtags values (0x0103 , 1 , "Modified Huffman" ) insert into subtags values (0x0103 , 2 , "Modified READ" ) insert into subtags values (0x0103 , 3 , "Modified Modified READ" ) insert into subtags values (0x0103 , 4 , "JBIG" ) insert into subtags values (0x0103 , 5 , "JPEG" ) insert into tags values ( 0x0106 , "PhotometricInterpretation", 0 ,0 ) insert into tags values ( 0x010e , "ImageDescription", 0 ,0 ) insert into tags values ( 0x010f , "Make", 0 ,0 ) insert into tags values ( 0x0110 , "Model", 0 ,0 ) insert into tags values ( 0x0111 , "StripOffsets", 0 ,0 ) insert into tags values ( 0x0112 , "Orientation", 0 ,0 ) insert into subtags values (0x0112 , 1 , "Row 0 at TOP, Column 0 on LEFT" ) insert into subtags values (0x0112 , 2 , "Row 0 at TOP, Column 0 on RIGHT" ) insert into subtags values (0x0112 , 3 , "Row 0 at BOTTOM, Column 0 on RIGHT" ) insert into subtags values (0x0112 , 4 , "Row 0 at BOTTOM, Column 0 on LEFT" ) insert into subtags values (0x0112 , 5 , "Row 0 at LEFT, Column 0 on TOP" ) insert into subtags values (0x0112 , 6 , "Row 0 at RIGHT, Column 0 on TOP" ) insert into subtags values (0x0112 , 7 , "Row 0 at RIGHT, Column 0 on BOTTOM" ) insert into subtags values (0x0112 , 8 , "Row 0 at LEFT, Column 0 on BOTTOM" ) insert into tags values ( 0x0115 , "SamplesPerPixel", 0 ,0 ) insert into tags values ( 0x0116 , "RowsPerStrip", 0 ,0 ) insert into tags values ( 0x0117 , "StripByteCounts", 0 ,0 ) insert into tags values ( 0x011a , "XResolution", 0 ,0 ) insert into tags values ( 0x011b , "YResolution", 0 ,0 ) insert into tags values ( 0x011c , "PlanarConfiguration", 0 ,0 ) insert into tags values ( 0x0128 , "ResolutionUnit", 0 ,0 ) insert into subtags values (0x0128 , 1 , "None" ) insert into subtags values (0x0128 , 2 , "inches" ) insert into subtags values (0x0128 , 3 , "cm" ) insert into tags values ( 0x012d , "TransferFunction", 0 ,0 ) insert into tags values ( 0x0131 , "Software", 0 ,0 ) insert into tags values ( 0x0132 , "DateTime", 0 ,0 ) insert into tags values ( 0x013b , "Artist", 0 ,0 ) insert into tags values ( 0x013c , "HostComputer", 0 ,0 ) insert into tags values ( 0x013d , "Predictor", 0 ,0 ) insert into tags values ( 0x013e , "WhitePoint", 0 ,0 ) insert into tags values ( 0x013f , "PrimaryChromaticities", 0 ,0 ) insert into tags values ( 0x0140 , "ColorMap", 0 ,0 ) insert into tags values ( 0x0141 , "HalftoneHints", 0 ,0 ) insert into tags values ( 0x0142 , "TileWidth", 0 ,0 ) insert into tags values ( 0x0143 , "TileLength", 0 ,0 ) insert into tags values ( 0x0144 , "TileOffsets", 0 ,0 ) insert into tags values ( 0x0145 , "TileByteCounts", 0 ,0 ) insert into tags values ( 0x0146 , "BadFaxLines", 0 ,0 ) insert into tags values ( 0x0147 , "CleanFaxData", 0 ,0 ) insert into tags values ( 0x0148 , "ConsecutiveBadFaxLines", 0 ,0 ) ' insert into tags values ( 0x0149 , "WhitePoint", 0 ,0 ) insert into tags values ( 0x014a , "SubIFDs", 0 ,0 ) ' insert into tags values ( 0x014b , "WhitePoint", 0 ,0 ) insert into tags values ( 0x014c , "InkSet", 0 ,0 ) insert into tags values ( 0x014d , "InkNames", 0 ,0 ) insert into tags values ( 0x014e , "NumberOfInks", 0 ,0 ) 'insert into tags values ( 0x014f , "WhitePoint", 0 ,0 ) insert into tags values ( 0x0201 , "JPEGInterchangeFormat", 0 ,0 ) insert into tags values ( 0x0202 , "JPEGInterchangeFormatLength", 0 ,0 ) insert into tags values ( 0x0211 , "YCbCrCoefficients", 0 ,0 ) insert into tags values ( 0x0212 , "YCbCrSubSampling", 0 ,0 ) insert into tags values ( 0x0213 , "YCbCrPositioning", 0 ,0 ) insert into subtags values (0x0213 , 1 , "Centered" ) insert into subtags values (0x0213 , 2 , "Co-sited" ) insert into tags values ( 0x0214 , "ReferenceBlackWhite", 0 ,0 ) ' -------------------------------------------------------------------------------------- insert into tags values ( 0x08298 , "Copyright", 0 ,0 ) insert into tags values ( 0x0829a , "ExposureTime", 0 ,0 ) insert into tags values ( 0x0829d , "FNumber", 0 ,0 ) insert into tags values ( 0x08769 , "Exif IFD Pointer ", 0 ,0 ) insert into tags values ( 0x08822 , "ExposureProgram", 0 ,0 ) insert into subtags values (0x08822 , 0 , "Not Defined" ) insert into subtags values (0x08822 , 1 , "Manual" ) insert into subtags values (0x08822 , 2 , "Program AE" ) insert into subtags values (0x08822 , 3 , "Aperture-priority AE" ) insert into subtags values (0x08822 , 4 , "Shutter speed priority AE" ) insert into subtags values (0x08822 , 5 , "Creative (Slow speed)" ) insert into subtags values (0x08822 , 6 , "Action (High speed)" ) insert into subtags values (0x08822 , 7 , "Portrait" ) insert into subtags values (0x08822 , 8 , "Landscape" ) insert into subtags values (0x08822 , 9 , "Bulb" ) insert into tags values ( 0x08824 , "SpectralSensitivity", 0 ,0 ) insert into tags values ( 0x08825 , "GPSInfo IFD Pointer", 0 ,0 ) insert into tags values ( 0x08827 , "ISOSpeedRatings", 0 ,0 ) insert into tags values ( 0x08828 , "OECF", 0 ,0 ) insert into tags values ( 0x08830 , "SensitivityType", 0 ,0 ) insert into tags values ( 0x08831 , "StandardOutputSensitivity", 0 ,0 ) insert into tags values ( 0x08832 , "RecommendedExposureIndex", 0 ,0 ) insert into tags values ( 0x08833 , "ISOSpeed", 0 ,0 ) insert into tags values ( 0x08834 , "ISOSpeedLatitudeyyy", 0 ,0 ) insert into tags values ( 0x08835 , "ISOSpeedLatitudezzz", 0 ,0 ) ' -------------------------------------------------------------------------------------- insert into tags values ( 0x09000 , "ExifVersion", 0 ,0 ) insert into tags values ( 0x09003 , "DateTimeOriginal", 0 ,0 ) insert into tags values ( 0x09004 , "DateTimeDigitized", 0 ,0 ) insert into tags values ( 0x09010 , "OffsetTime", 0 ,0 ) insert into tags values ( 0x09011 , "OffsetTimeOriginal ", 0 ,0 ) insert into tags values ( 0x09012 , "OffsetTimeDigitized", 0 ,0 ) insert into tags values ( 0x09030 , "DateTimeOriginal", 0 ,0 ) insert into tags values ( 0x09101 , "ComponentsConfiguration", 0 ,0 ) insert into tags values ( 0x09102 , "CompressedBitsPerPixel", 0 ,0 ) insert into tags values ( 0x09201 , "ShutterSpeedValue", 0 ,0 ) insert into tags values ( 0x09202 , "ApertureValue", 0 ,0 ) insert into tags values ( 0x09203 , "BrightnessValue", 0 ,0 ) insert into tags values ( 0x09204 , "ExposureBiasValue", 0 ,0 ) insert into tags values ( 0x09205 , "MaxApertureRatioValue", 0 ,0 ) insert into tags values ( 0x09206 , "SubjectDistance", 0 ,0 ) insert into tags values ( 0x09207 , "MeteringMode", 0 ,0 ) insert into tags values ( 0x09208 , "LightSource", 0 ,0 ) insert into subtags values (0x09208 , 0 , "Unknown") insert into subtags values (0x09208 , 1 , "Daylight") insert into subtags values (0x09208 , 2 , "Fluorescent") insert into subtags values (0x09208 , 3 , "Tungsten (Incandescent)") insert into subtags values (0x09208 , 4 , "Flash") insert into subtags values (0x09208 , 9 , "Fine Weather") insert into subtags values (0x09208 , 10 , "Cloudy") insert into subtags values (0x09208 , 11 , "Shade") insert into subtags values (0x09208 , 12 , "Daylight Fluorescent") insert into subtags values (0x09208 , 13 , "Day White Fluorescent") insert into subtags values (0x09208 , 14 , "Cool White Fluorescent") insert into subtags values (0x09208 , 15 , "White Fluorescent") insert into subtags values (0x09208 , 16 , "Warm White Fluorescent") insert into subtags values (0x09208 , 17 , "Standard Light A") insert into subtags values (0x09208 , 18 , "Standard Light B") insert into subtags values (0x09208 , 19 , "Standard Light C") insert into subtags values (0x09208 , 20 , "D55") insert into subtags values (0x09208 , 21 , "D65") insert into subtags values (0x09208 , 22 , "D75") insert into subtags values (0x09208 , 23 , "D50") insert into subtags values (0x09208 , 24 , "ISO Studio Tungsten") insert into subtags values (0x09208 , 255 , "Other") insert into tags values ( 0x09209 , "Flash", 0 ,0 ) insert into subtags values (0x09209 , 0x0 , "No Flash" ) insert into subtags values (0x09209 , 0x1 , "Fired" ) insert into subtags values (0x09209 , 0x5 , "Fired, Return not detected" ) insert into subtags values (0x09209 , 0x7 , "Fired, Return detected" ) insert into subtags values (0x09209 , 0x8 , "On, Did not fire" ) insert into subtags values (0x09209 , 0x9 , "On, Fired" ) insert into subtags values (0x09209 , 0xd , "On, Return not detected" ) insert into subtags values (0x09209 , 0xf , "On, Return detected" ) insert into subtags values (0x09209 , 0x10 , "Off, Did not fire" ) insert into subtags values (0x09209 , 0x14 , "Off, Did not fire, Return not detected" ) insert into subtags values (0x09209 , 0x18 , "Auto, Did not fire" ) insert into subtags values (0x09209 , 0x19 , "Auto, Fired" ) insert into subtags values (0x09209 , 0x1d , "Auto, Fired, Return not detected" ) insert into subtags values (0x09209 , 0x1f , "Auto, Fired, Return detected" ) insert into subtags values (0x09209 , 0x20 , "No flash function" ) insert into subtags values (0x09209 , 0x30 , "Off, No flash function" ) insert into subtags values (0x09209 , 0x41 , "Fired, Red-eye reduction" ) insert into subtags values (0x09209 , 0x45 , "Fired, Red-eye reduction, Return not detected" ) insert into subtags values (0x09209 , 0x47 , "Fired, Red-eye reduction, Return detected" ) insert into subtags values (0x09209 , 0x49 , "On, Red-eye reduction" ) insert into subtags values (0x09209 , 0x4d , "On, Red-eye reduction, Return not detected" ) insert into subtags values (0x09209 , 0x4f , "On, Red-eye reduction, Return detected" ) insert into subtags values (0x09209 , 0x50 , "Off, Red-eye reduction" ) insert into subtags values (0x09209 , 0x58 , "Auto, Did not fire, Red-eye reduction" ) insert into subtags values (0x09209 , 0x59 , "Auto, Fired, Red-eye reduction" ) insert into subtags values (0x09209 , 0x5d , "Auto, Fired, Red-eye reduction, Return not detected" ) insert into subtags values (0x09209 , 0x5f , "Auto, Fired, Red-eye reduction, Return detected" ) insert into tags values ( 0x0920a , "FocalLength", 0 ,0 ) insert into tags values ( 0x09214 , "SubjectArea", 0 ,0 ) insert into tags values ( 0x0927C , "MakerNote", 0 ,0 ) insert into tags values ( 0x09286 , "UserComment", 0 ,0 ) insert into tags values ( 0x09290 , "SubSecTime", 0 ,0 ) insert into tags values ( 0x09291 , "SubSecTimeOriginal", 0 ,0 ) insert into tags values ( 0x09292 , "SubSecTimeDigitized", 0 ,0 ) ' -------------------------------------------------------------------------------------- insert into tags values ( 0x0A000 , "FlashpixVersion", 0 ,0 ) insert into tags values ( 0x0A001 , "ColorSpace", 0 ,0 ) insert into tags values ( 0x0A002 , "PixelXDimension", 0 ,0 ) insert into tags values ( 0x0A003 , "PixelYDimension", 0 ,0 ) insert into tags values ( 0x0A004 , "RelatedSoundFile", 0 ,0 ) insert into tags values ( 0x0A005 , "Interoperability IFD Pointer", 0 ,0 ) insert into tags values ( 0x0A20B , "FlashEnergy", 0 ,0 ) insert into tags values ( 0x0A20C , "SpatialFrequencyResponse", 0 ,0 ) insert into tags values ( 0x0A20E , "FocalPlaneXResolution", 0 ,0 ) insert into tags values ( 0x0A20F , "FocalPlaneYResolution", 0 ,0 ) insert into tags values ( 0x0A210 , "FocalPlaneResolutionUnit", 0 ,0 ) insert into tags values ( 0x0A214 , "SubjectLocation", 0 ,0 ) insert into tags values ( 0x0A215 , "ExposureIndex", 0 ,0 ) insert into tags values ( 0x0A217 , "SensingMethod", 0 ,0 ) insert into tags values ( 0x0A300 , "FileSource", 0 ,0 ) insert into subtags values (0x0A300 , 0 , "other" ) insert into subtags values (0x0A300 , 1 , "scanner of transparent type" ) insert into subtags values (0x0A300 , 2 , "scanner of reflex type" ) insert into subtags values (0x0A300 , 3 , "Digital still camera" ) insert into tags values ( 0x0A301 , "SceneType", 0 ,0 ) insert into subtags values (0x0A301 , 1 , "directly photographed image" ) insert into tags values ( 0x0A302 , "CFAPattern", 0 ,0 ) insert into tags values ( 0x0A401 , "CustomRendered", 0 ,0 ) insert into subtags values (0x0A401 , 0 , "Normal process" ) insert into subtags values (0x0A401 , 1 , "Custom process" ) insert into tags values ( 0x0A402 , "ExposureMode", 0 ,0 ) insert into subtags values (0x0A402 , 0 , "Auto exposure" ) insert into subtags values (0x0A402 , 1 , "Manual exposure" ) insert into subtags values (0x0A402 , 0 , "Auto bracket" ) insert into tags values ( 0x0A403 , "WhiteBalance", 0 ,0 ) insert into subtags values (0x0A403 , 0 , "Auto white balance" ) insert into subtags values (0x0A403 , 1 , "Manual white balance" ) insert into tags values ( 0x0A404 , "DigitalZoomRatio", 0 ,0 ) insert into tags values ( 0x0A405 , "FocalLengthIn35mmFilm", 0 ,0 ) insert into tags values ( 0x0A406 , "SceneCaptureType", 0 ,0 ) insert into subtags values (0x0A406 , 0 , "Standard" ) insert into subtags values (0x0A406 , 1 , "Landscape" ) insert into subtags values (0x0A406 , 2 , "Portrait" ) insert into subtags values (0x0A406 , 3 , "Night scene" ) insert into tags values ( 0x0A407 , "GainControl", 0 ,0 ) insert into subtags values (0x0A407 , 0 , "None" ) insert into subtags values (0x0A407 , 1 , "Low gain up" ) insert into subtags values (0x0A407 , 2 , "High gain up" ) insert into subtags values (0x0A407 , 3 , "Low gain down" ) insert into subtags values (0x0A407 , 4 , "High gain down" ) insert into tags values ( 0x0A408 , "Contrast", 0 ,0 ) insert into subtags values (0x0A408 , 0 , "Normal" ) insert into subtags values (0x0A408 , 1 , "Soft" ) insert into subtags values (0x0A408 , 2 , "Hard" ) insert into tags values ( 0x0A409 , "Saturation", 0 ,0 ) insert into subtags values (0x0A409 , 0 , "Normal" ) insert into subtags values (0x0A409 , 1 , "Low saturation" ) insert into subtags values (0x0A409 , 2 , "High saturation" ) insert into tags values ( 0x0A40A , "Sharpness", 0 ,0 ) insert into subtags values (0x0A40A , 0 , "Normal" ) insert into subtags values (0x0A40A , 1 , "Soft" ) insert into subtags values (0x0A40A , 2 , "Hard" ) insert into tags values ( 0x0A40B , "DeviceSettingDescription", 0 ,0 ) insert into tags values ( 0x0A40C , "SubjectDistanceRange", 0 ,0 ) insert into subtags values (0x0A40C , 0 , "unknown" ) insert into subtags values (0x0A40C , 1 , "Macro" ) insert into subtags values (0x0A40C , 2 , "Close view" ) insert into subtags values (0x0A40C , 3 , "Distant view" ) insert into tags values ( 0x0A420 , "ImageUniqueID", 0 ,0 ) insert into tags values ( 0x0A430 , "CameraOwnerName", 0 ,0 ) insert into tags values ( 0x0A431 , "BodySerialNumber", 0 ,0 ) insert into tags values ( 0x0A432 , "LensSpecification", 0 ,0 ) insert into tags values ( 0x0A433 , "LensMake", 0 ,0 ) insert into tags values ( 0x0A434 , "LensModel", 0 ,0 ) insert into tags values ( 0x0A435 , "LensSerialNumber", 0 ,0 ) insert into tags values ( 0x0A500 , "Gamma", 0 ,0 ) ' -------------------------------------------------------------------------------------- ' -------------------------------------------------------------------------------------- dim fSize dim fdata ' -------------------------------------------------------------------------------------- dim defaultEndian , currentEndian dim AddrOutFormat FUNCTION SetAddrOutFormat ( val ) AddrOutFormat = replace( "0x%.§lx" , "§", cstr(val) ) END function FUNCTION addrOutPut ( val ) returnValue = sprintf( AddrOutFormat , val) END function FUNCTION dump ( offset , optional len = 16 , optional leader = "" ) dim i i = 0 freestring = leader & hex(offset) & " = " FOR i = offset to offset+ len - 1 IF ( i == length ( fdata) ) then freestring = freestring & " EOL" EXIT for END if freestring = freestring + right( hex ( fdata(i)), 2) & " " NEXT i report = freestring END function FUNCTION getMsize (offset) getMsize = fdata ( offset + 0) * 0x0100 + fdata ( offset + 1 ) END function FUNCTION getMarker (offset ) returnValue = "" & hex ( getMsize (offset) ) END function FUNCTION getMuword (offset) returnValue = fdata ( offset + 0) * 0x0100 + fdata ( offset + 1 ) END function FUNCTION getUWORD ( offset ) as uword IF ( currentEndian == 0x49 ) then returnValue = 0x0100 * fdata ( offset + 1) + fdata ( offset + 0) ELSE returnValue = 0x0100 * fdata ( offset + 0) + fdata ( offset + 1) END if END FUNCTION FUNCTION getDWORD ( offset ) as DWORD IF ( currentEndian == 0x49 ) then returnValue = 0x01000000 * fdata ( offset + 3) + 0x010000 * fdata ( offset + 2) + 0x0100 * fdata ( offset + 1) + fdata ( offset + 0) ELSE returnValue = 0x01000000 * fdata ( offset + 0) + 0x010000 * fdata ( offset + 1) + 0x0100 * fdata ( offset + 2) + fdata ( offset + 3) END if END FUNCTION FUNCTION getAScii ( offset , len ) returnValue = "" dim char DO while ( len ) IF ( (fdata(offset ) == 0 ) AND ( len == 1 ) ) then ELSEIF ( fdata(offset ) == 0 ) then returnValue = returnValue & chr ( 0x0a) ELSEIF ( fdata(offset ) == asc (">") )then returnValue = returnValue & chr ( fdata(offset ) ) returnValue = returnValue & chr ( 0x0a) ELSE returnValue = returnValue & chr ( fdata(offset ) ) END if len = len - 1 offset = offset +1 LOOP END function FUNCTION getByte ( offset , optional len = 1) IF ( len == 1 ) then returnValue = fdata(offset ) offset = offset +1 ELSE returnValue = "" DO while ( len ) returnValue = returnValue & ( fdata(offset ) ) & " " len = len - 1 offset = offset +1 LOOP END if END function FUNCTION getByteAsHex ( offset , len ) returnValue = "" DO while ( len ) returnValue = returnValue & hex ( fdata(offset ) ) & " " len = len - 1 offset = offset +1 LOOP END function FUNCTION getUWords ( offset , optional len = 1 ) returnValue = "" IF ( len == 1 ) THEN returnValue = getUWord(offset ) offset = offset +2 ELSE DO while ( len ) returnValue = returnValue & hex ( getUWord(offset ) ) & " " len = len - 1 offset = offset +2 LOOP END IF END function FUNCTION getLong ( offset , len ) IF ( len == 1 ) then returnValue = getDWORD(offset ) offset = offset +4 ELSE returnValue = "" DO while ( len ) returnValue = returnValue & ( getDWORD(offset ) ) & " " len = len - 1 offset = offset +4 LOOP END if END function FUNCTION ifdLoop ( ifdOffset , TiffHdrOffset) dim tag, format , nbrComs , data dim i , aReal dim ifdPtr = 0 dim subTagQuery, subTag dim txt dim Nominator, denominator dim ifdCnt = getUWord ( ifdOffset ) ifdOffset = ifdOffset + 2 FOR i = 1 to ifdCnt ProgressToggle () tag = getUWord ( ifdOffset + 0 ) format = getUWord ( ifdOffset +2 ) nbrComs = getDWORD ( ifdOffset +4 ) data = getDWORD ( ifdOffset +8 ) txt = "" & AddrOutPut ( ifdOffset ) & " IDF Entry " & sprintf( "%.3lx" , i - 1 ) txt = txt & " Tag: " & sprintf( "0x%.4lx" , Tag ) txt = txt & " Format: " & format txt = txt & " Nbr Components: " & sprintf( "%.3lx" , nbrComs ) txt = txt & " Data: " & getByteAsHex ( ifdOffset +8 , 4 ) IF ( ShowRawTagFlag ) then report( txt) END if ' ------------------------------------------------------------ txt = "" ' to have only the decoded info WITHQUERY ( replace ( " select * from tags where tag = nbr " , "nbr", "" & tag ) ) txt = txt & wqText(2) & spaces ( 32 - length(wqtext(2)) ) END withquery IF ( txt == "" ) then txt = "Unspecified TAG " & right("" & hex(TAG),4) txt = txt & spaces ( 32 - length(txt) ) END IF ' ------------------------------------------------------------ IF ( nbrComs == 1 ) THEN SELECT CASE format CASE 1 ' BYTE subTag =getByte ( ifdOffset +8 , 1 ) CASE 3 ' SHORT 2 byte u-int subTag =getUWORD ( ifdOffset +8 ) CASE 4 ' LONG 4 byte u-int subTag =getLong ( ifdOffset +8 , 1 ) CASE 5 ' two LONGS nominator = getLong ( TiffHdrOffset + data ,1) denominator = getLong ( TiffHdrOffset + data + 4 , 1) IF ( denominator ) then subTag = nominator / denominator ELSE subTag = 0 END IF CASE else subTag = -1 END select IF ( subTag <> -1 ) then subTagQuery = replace ( " select name from subtags where tag = §nbr and subTag = §sub" , "§nbr", "" & tag ) sql ( replace (subTagQuery , "§sub" , "" & subTag ) ) IF ( qrSingleValue <> Empty) then txt = txt & " = " & qrSingleValue tag = -1 END IF END if ELSE END IF ' ------------------------------------------------------------ ' Do we have CUSTOM handling for this TAG SELECT CASE TAG CASE -1 CASE 0x08769 , 0x0a005 txt="" IF ( showIFDFlag ) then sql ( replace ( " select name from tags where tag = nbr " , "nbr", "" & tag ) ) report (AddrOutPut (TiffHdrOffset + data) & " IFD: " & qrSingleValue ) END if recurse ifdLoop ( TiffHdrOffset + data , TiffHdrOffset) CASE 0x0829a nominator = getLong ( TiffHdrOffset + data ,1) denominator = getLong ( TiffHdrOffset + data + 4 , 1) txt = txt & " = " & nominator & "/" & denominator CASE else IF ( nbrComs > 64 ) then nbrComs=64 END if IF ( format == 1 ) then ' BYTE IF ( nbrComs < 5 ) then txt = txt & " = " & getByte ( ifdOffset +8 , nbrComs ) ELSE txt = txt & " = " & getByte ( TiffHdrOffset + data , nbrComs ) END if ELSEIF ( format == 2 ) then ' ASCII IF ( nbrComs < 5 ) then txt = txt & " = " & getAScii ( ifdOffset +8 , nbrComs ) ELSE txt = txt & " = " & getAScii ( TiffHdrOffset + data , nbrComs ) END if ELSEIF ( format == 3 ) then ' SHORT 2 byte u-int IF ( nbrComs < 3 ) then txt = txt & " = " & getUWords ( ifdOffset +8 ,nbrComs ) ELSE txt = txt & " = " & getUWords ( TiffHdrOffset + data , nbrComs ) END if ELSEIF ( format == 4 ) then ' LONG 4 byte u-int IF ( nbrComs < 2 ) then txt = txt & " = " & getLong ( ifdOffset +8 ,nbrComs ) ELSE txt = txt & " = " & getLong ( TiffHdrOffset + data , nbrComs ) END if ELSEIF ( format == 5 ) then ' RATIONAL two LONGS numerator then denominator nominator = getLong ( TiffHdrOffset + data ,1) denominator = getLong ( TiffHdrOffset + data + 4 , 1) IF ( denominator ) then IF ( nbrComs == 1 ) then aReal = sprintf( "%.2f", (nominator / denominator) ) txt = txt & " = " & aReal ELSE txt = txt & " = " & "???? Format: " & format & " but with " & nbrComs & " component(s) " & getByteAsHex ( ifdOffset +8 , 4 ) END IF ELSE txt = txt & " = " & "undefined" END IF ELSEIF ( format == 7 ) then ' UNDEFINED 1 byte IF ( nbrComs < 5 ) then txt = txt & " = " & getByte ( ifdOffset +8 , nbrComs ) ELSE txt = txt & " = " & getByte ( TiffHdrOffset + data , nbrComs ) END if ELSEIF ( format == 9 ) then ' SLONG 4 byte s-int IF ( nbrComs < 2 ) then txt = txt & " = " & getLong ( ifdOffset +8 ,nbrComs ) ELSE txt = txt & " = " & getLong ( TiffHdrOffset + data , nbrComs ) END if ELSEIF ( format == 10 ) then ' SRATIONAL two SLONGS nominator = getLong ( TiffHdrOffset + data ,1) denominator = getLong ( TiffHdrOffset + data + 4 , 1) IF ( denominator ) then aReal = sprintf( "%.1f", (nominator / denominator) ) IF ( nbrComs == 1 ) then txt = txt & " = " & hex(nominator) & " / " & hex(denominator )& " " & aReal ELSE txt = txt & " = " & "???? Format: " & format & " but with " & nbrComs & " component(s) " & getByteAsHex ( ifdOffset +8 , 4 ) END IF ELSE txt = txt & " = " & "undefined" END IF ELSE txt = txt & " = " & "unexpected Format: " & format & ", with " & nbrComs & " component(s) " & getByteAsHex ( ifdOffset +8 , 4 ) END if END SELECT IF ( ShowTagFlag AND length(txt) ) then report ( txt ) END if ifdOffset = ifdOffset+ 12 NEXT i ifdLoop = TiffHdrOffset+ ifdPtr IF ( getDWORD ( ifdOffset +0 ) ) then IF ( showIFDFlag ) then report (AddrOutPut (TiffHdrOffset + getDWORD ( ifdOffset +0 ) ) & " IFD: " ) END if recurse ifdLoop ( TiffHdrOffset + getDWORD ( ifdOffset +0 ) , TiffHdrOffset) END if END function FUNCTION TiffHeaderHandler ( offset ) dim TiffHdrOffset = offset ' the TIFF ENDIAN info is 2 identical bytes, SO it does not matter if we ' use little or big endian to read it ! dim TiffBOM = getMuword ( TiffHdrOffset ) IF ( showMarkersFlag ) then report ( AddrOutPut (TiffHdrOffset) & " TIFF Header " & "Endian: " & hex ( TiffBOM ) ) END IF IF ( TiffBOM == 0x04949 ) THEN currentEndian = 0x49 ELSEIF ( TiffBOM == 0x04d4d ) THEN currentEndian = 0x4d ELSE report = "Invalid TIFF Byte order " EXIT function END if IF ( getUWord (TiffHdrOffset + 2 ) == 0x02a ) then ELSE report = "Invalid TIFF header: expected 0x02a " & hex ( getMsize (TiffHdrOffset + 2 ) ) EXIT function END if IF ( showIFDFlag ) then report (AddrOutPut (TiffHdrOffset + getDWORD (TiffHdrOffset + 4 )) & " IFD: 0" ) END if ifdLoop ( TiffHdrOffset + getDWORD (TiffHdrOffset + 4 ) ,TiffHdrOffset ) ' TIFF can change the ENDIAN, so reset it to be safe currentEndian = defaultEndian END function FUNCTION APP0Handle ( offset , datasize) dim txt = "" IF ( showMarkersFlag ) then dump ( offset ,datasize +2 , "APP0: " ) END if offset = offset + 2 report = "APP0 header" report = TabChar & "FieldCount: " & getUword (offset +0 ) report = TabChar & "Identifier: " & getAscii( offset + 2,5 ) report = TabChar & "Version: " & Hex(getUword (offset +7)) dim units = getByte (offset + 9, 1 ) dim UnitsTxt= "unknown ("&hex(units) &")" SELECT CASE CASE 0 UnitsTxt="unspecified" CASE 1 UnitsTxt="dots per inch" CASE 2 UnitsTxt="dots per cm" END SELECT report = TabChar & "Units: " & UnitsTxt report = TabChar & "Hdensity: " & getUword (offset +10) report = TabChar & "Vdensity: " & getUword (offset +12) report = TabChar & "HthumbnailA: " & getByte (offset +14) report = TabChar & "VthumbnailA: " & getByte (offset +15) IF ( datasize == 16 ) then report = tabChar & "No further APP0 information present." ELSE report = tabChar & "No further APP0 handled implemented." END IF END FUNCTION FUNCTION APP1Handle ( offset , datasize) ' coud be EXIF or XMP offset = offset + 4 IF ( ( getAscii ( offset,4) == "Exif" ) and ( fdata(offset+4) == 0x00 ) ) then IF ( showMarkersFlag ) then Report = "APP1 hosts an EXIF" END IF TiffHeaderHandler ( offset + 6 ) ELSE ' dump ( offset ) report = getascii( offset, datasize) END IF END function FUNCTION COMHandle ( offset , datasize) dim COMoffset = offset dim index = COMoffset + 4 freestring = "" dim i FOR i = 0 to datasize-3 ' -3 because INCLUSIVE ! freestring = freestring & chr( fdata(index + i ) ) NEXT i report = freestring END function FUNCTION SOSHandle ( offset , datasize ) as qword ' scan till have 0xff, 0xd9 returnValue = ArrayFind ( fdata, 0x0ff, offset + 12, 0xd9 ) IF ( returnValue == -1 ) then returnValue = offset + 12 ELSE IF ( ShowMarkersFlag ) then report ("Data in image scan: " & hex ( returnValue - offset - 12 ) & " Bytes" ) END IF report ( AddrOutPut (returnValue) & " MARKER: " & right("0x0FFD9",4) & " = " & " EOI , " & "End of Image" & " , " & "End of compressed data" & " , Datasize = " & 0 ) returnValue = returnValue + 2 END if END function FUNCTION startHere ( offset ) dim outPut dim DataSize , i , j dim fSize = ubound ( fdata ) IF ( fdata(0) <> 0x0ff ) then UserError(crChar & "First byte not 0x0ff. File is probably not an image file.") END if DO while ( fSize > offset ) ' we expect that OFFSET points to a VALID MARKER ' i.e. 0x0FF , 0x?? so get the 2 bytes as big endian i = 0 ' to indicate FAILURE WITHQUERY ( replace ( "select * from markers where code = 'mValue'" , "mValue" , hex(getMuword(offset))) ) ProgressToggle () i = 1 ' to indicate SUCCESS Datasize = 0 outPut = AddrOutPut (offset) & " MARKER: " & right(wqText(1),4) & " = " & wqtext(2) & " , " & wqtext(3) & " , " & wqtext(4) ' --------------------------- ' get byte alignment rule IF ( wqInt(5) ) then defaultEndian = asc(wqText(6)) currentEndian = defaultEndian DataSize = getUword( offset + 2 ) outPut = outPut & " , Datasize = " & hex(Datasize) & " Endian = " & wqText(6) END IF ' --------------------------- report = output ' --------------------------- ' do we have a CUSTOM handler for the current MARKER IF ( wqText(2) == "APP0" ) then APP0Handle ( offset , datasize ) offset = offset + Datasize + 2 ' move to next MARKER ELSEIF ( wqText(2) == "APP1" ) then APP1Handle ( offset , datasize) offset = offset + Datasize + 2 ' move to next MARKER ELSEIF ( wqText(2) == " COM" ) then COMHandle ( offset, datasize ) offset = offset + Datasize + 2 ' move to next MARKER ELSEIF ( wqText(2) == " SOS" ) then offset = SOSHandle ( offset, datasize ) ELSE offset = offset + Datasize + 2 ' move to next MARKER END IF END withQuery ' --------------------------- IF ( ! I ) then IF ( fData(offset) == 0x0ff ) then report ("Unknown MARKER: " ) ELSE report ("Expected 0x0ff not found " ) END IF i = fSize - offset IF ( i > 11 ) THEN i = 12 END IF dump ( offset , i , "??" ) ' IMPORTANT: must pass over the current OFFSET offset++ END IF ' --------------------------- ' test for next MARKER IF ( fSize > offset ) then IF ( fData(offset) == 0x0ff ) then ' normal condition, MARKER directly following MARKER ELSE ' possible error ' scan for a MARKER (= 0x0ff) i = ArrayFind ( fdata, 0x0ff, offset ) IF ( i == -1 ) then report ( "No marker found in remaining " & (fsize - offset) & " bytes of the file." ) offset = fSize ' force termination ELSE offset = i IF ( ShowMarkersFlag ) then report ( "Next MARKER not contiguous, found at: " & hex ( i ) ) END if END IF END IF END if LOOP END function FUNCTION decodeFile ( fName , sobOut) sob (btnFile,"SET", "RGB" , greenBtnRGB ) fSize = fileSize ( fName ) SetAddrOutFormat ( length( "" & hex(fsize) ) - 3 ) report ( "File size " & Hex( fsize ) & crChar ) set fdata = byteArray ( fsize ) fileRead ( fname , fdata , fSize ) startHere ( 0 ) END function ' -------------------- SOB ( "OVERRIDE" , "STYLE+" , 0x00002000) dim btnFile = sob ( appCOL , "add" , "button" , "push" , chr(0xa) ) sob ( -1 , "SET", "TITLE" , "Drop a file on this bar, or press this bar for a file explorer" ) ' -------------------- FUNCTION processFile ( fName ) LastProcessedFileName = fname report () report( fName ) ProgressClear( ) ProgressText(appDescription, 0 ) ProgressText(fname, 1 ) progressShow (1) sob (decodeInfo,"SET", "SHOW", 0 ) TRY decodeFile ( fName , decodeInfo ) report(crChar & "Processing Finished normally " ) CATCH IF ( LastError == 113 ) then ' triggered via the Progress dialog CANCEL button sob (decodeInfo,"add", "row" , "Processing interrupted by user" & crChar ) ELSEIF ( LastError == 423 ) then ' triggered by a UserError command sob (decodeInfo,"add", "row" , "Error: " & errortext(lasterror) & crChar ) ELSE ' programming error sob (decodeInfo,"add", "row" , "An error occurred: " & errortext(lasterror) & crChar ) sob (decodeInfo,"add", "row" , "Error line: " & errorline & crChar ) END if END TRY progressShow (0) SOB (decodeInfo , "SET" , "ROW" , "TOP" ,0 ) sob (decodeInfo , "SET" , "SHOW", 1 ) END FUNCTION ' -------------------- FUNCTION cbFile_File ( sobid ) sob (decodeInfo,"empty") dim midiFile = FileSel ( , FileSelectorFilter ) IF ( midiFile <> "" ) then processFile ( midiFile ) END IF END Function sob ( btnFile ,"ON","CLICK", "cbFile_File") FUNCTION cbBtn_File ( sobid ) sob (decodeInfo,"empty") IF GetDropCount then processFile ( getDropData(1) ) END if END Function sob (btnFile,"ON","DROP.FILE", "cbBtn_File") sob (btnFile,"SET", "RGB" , greenBtnRGB ) ' -------------------- decodeInfo = sob(appCOL,"add","Edit.rows" , "define the minimum width", 10 ) RedirectReportingTo ( decodeInfo ) sob (-1 , "SET" , "RW" , 0 ) sob (-1,"empty") sob (-1,"add", "row" , crChar ) sob (-1,"add", "row" , crChar ) sob (-1,"SET", "RGB" , readOnlyRGB) ' -------------------- ' change the FONT of the decodeInfo panel to a monospaced font! font("default") font("SET" ,"HEIGHT" , APP$ARG ( asc("F") ) ) font("SET" ,"WEIGHT" , APP$ARG ( asc("B") ) ) font("SET" ,"FaceName" , "Courier New" ) dim myFont = Font("CREATE") sob ( decodeInfo, "SET", "FONT" , myFont ) setFontBold ( fontBold ) ' -------------------- ' use a Double right mouse click as a trigger to decode the current file again FUNCTION cbdecodeInfo_mouseclicks ( sobid, clickValue, row , col ) IF ! (clickValue == 6) then exit function IF (LastProcessedFileName == "") then EXIT function END if sob (decodeInfo,"empty") processFile ( LastProcessedFileName ) END function sob ( decodeInfo,"ON","MOUSECLICKS", "cbdecodeInfo_mouseclicks") ' -------------------- SOB (pwSwindow , "SET" , "show" , 0 ) sob ( sobAbout, "trigger")