This movie script will attempt to determine the format and resolution of a graphic file, by directly reading the header.
This file was originally hosted on the InvisibleThreads website until 2008. It has now been archived. The original layout and formatting for this document is missing from the archives — sorry!
The script currently only reads and determines .BMP, .GIF and .TGA files. The script is meant as an example to demonstrate the process, and can easily be modified to read any type of graphic image file.
This movie script will attempt to determine the format and resolution of a graphic file, by directly reading the header.
Copy and paste the source code below into a movie script.
-- Determine Graphic File Resolution
-- Copyright (c) 2001 Kendall Anderson. All rights reserved.
-- http://invisiblethreads.com
-----------
-- OVERVIEW
-----------
-- Code to read the width/height of a specified graphic file
-- Currently only identifies .BMP, .GIF, .TGA because these formats
-- can be parsed in a very similar way (easily identifiable header,
-- seek to specific location and read data).
-- Note that the .TGA recognition is a little dodgy, so it is tested
-- last, after other formats. (it depends on matching a single number only)
-- Other formats (.JPG, .TIF) require a (little) bit more parsing
-- and could be easily incorporated. This code is meant to serve as
-- an example of the process.
-- Details about file formats found at: http://www.wotsit.org
---------------
-- CODE HISTORY
---------------
-- Nov 17 2001: Kendall Anderson: Initial design and coding
------------------------------------------------------------------------------------
------------------------------------------------------------------------------------
-- given a filename, try to determine the type of graphic file
-- and if successful return the image resolution as a property list
-- [ #width: integer width, #height: integer height ]
on _GetResolution dFilename
--register(xtra "binaryio","your serial num here") -- this should only be done once, elsewhere!
oFile = new(xtra "binaryio")
dErr = openfile(oFile, 1, dFilename)
sType = _DetermineFileType(oFile)
if (sType = 0) then
put "Unidentified file format"
lRes = [ #width: 0, #height: 0 ]
else
lRes = _GetFileResolution(oFile, sType)
put "File type: " & sType
put "Image resolution: w: " & lRes.width & ", h: " & lRes.height
end if
oFile = void
return lRes
end
-- given a file pointer reference, try to determine what kind
-- of file this is by reading the header information
on _DetermineFileType oFile
-- lHeader format:
-- start location of header, # chars to read, text(s) to match
lHeaders = [:]
lHeaders.addProp(#bmp, [ 0, 2, [ "BM", "BA", "CI", "CP", "IC", "PT" ] ])
lHeaders.addProp(#gif, [ 0, 3, [ "GIF" ] ])
lHeaders.addProp(#tga, [ 2, 1, [ numtochar(1), numtochar(2), numtochar(9), numtochar(10) ]])
sType = 0
repeat with i = 1 to lHeaders.count -- check each type until we get a match
bFound = _CheckHeader(oFile, lHeaders[i])
if (bFound) then
sType = lHeaders.getPropAt(i)
exit repeat
end if
end repeat
return sType
end
-- given a file pointer reference and the type of the file,
-- read the image resolution (location of data dependent on file type)
on _GetFileResolution oFile, sType
-- configure location of width value, and length of data for different file types
-- lDetails format:
-- start location of width data, # of bytes for data
-- assumes height data occurs immediately after width, in same format
lDetails = [:]
lDetails.addProp(#bmp, [ 18, #long ])
lDetails.addProp(#gif, [ 6, #short ])
lDetails.addProp(#tga, [ 12, #short ])
return (_ReadResolution(oFile, lDetails[sType]))
end
-- given file pointer, try to read header data to verify file type
on _CheckHeader oFile, lData
bMatch = FALSE
dOffset = lData[1] -- offset where we check for match
dLength = lData[2] -- # of bytes to read
lValid = lData[3] -- list of valid matching strings
-- check id header
setFilePosition(oFile, dOffset)
sID = readBytes(oFile, dLength)
repeat with dItem in lValid -- check for valid matches
if (sID = dItem) then -- if valid match
bMatch = TRUE
exit repeat -- exit loop
end if
end repeat
return bMatch
end
-- given file pointer and data describing location of resolution data,
-- read resolution data and return as proplist
on _ReadResolution oFile, lData
dOffset = lData[1] -- offset where we find data
sType = lData[2] -- data type: #short (2 bytes) or #long (4 bytes)
setFilePosition(oFile, dOffset)
case (sType) of
#short: sMethod = #readUnsignedShort -- handler within BinaryIO
#long: sMethod = #readUnsignedLong -- handler within BinaryIO
end case
dWidth = call(sMethod, oFile)
dHeight = call(sMethod, oFile)
return [ #width: dWidth, #height: dHeight ]
end
If there are any questions about this document or how to use this, please feel free to contact me.
Copyright © 2001 Kendall Anderson | Invisible Threads