Skip to content

Instantly share code, notes, and snippets.

@jkrumbiegel
Created January 29, 2024 07:59
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jkrumbiegel/89f1fa6d97e77667faa8feb1d003b224 to your computer and use it in GitHub Desktop.
Save jkrumbiegel/89f1fa6d97e77667faa8feb1d003b224 to your computer and use it in GitHub Desktop.
detect physical size png
function detect_png_physical_size(io::IO)
png_signature = "\x89PNG\r\n\x1a\n"
seekstart(io)
if String([read(io, UInt8) for _ in 1:length(png_signature)]) != png_signature
throw(ArgumentError("Not a png file"))
end
function read_chunk_length()
return ntoh(read(io, UInt32))
end
function read_chunk_type()
return String([read(io, UInt8) for _ in 1:4])
end
try
while true
chunk_length = read_chunk_length()
chunk_type = read_chunk_type()
if chunk_type == "pHYs"
x_px_per_unit = Int(ntoh(read(io, UInt32)))
y_px_per_unit = Int(ntoh(read(io, UInt32)))
units_are_meters = read(io, Bool)
return (; x_px_per_unit, y_px_per_unit, units_are_meters)
elseif chunk_type == "IDAT"
return nothing # pHYs always comes before IDAT if it exists
end
# Skip the chunk data
skip(io, chunk_length)
# Skip CRC
skip(io, 4)
end
catch e
if e isa EOFError
return nothing
else
rethrow(e)
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment