Added code to display some info about the IHDR, pHYs, and tEXt chunks.
This commit is contained in:
parent
9d69cb51bd
commit
4ad99d6769
@ -24,10 +24,13 @@
|
||||
|
||||
If Not FileIO.FileSystem.FileExists(filename) Then
|
||||
Console.WriteLine("File {0} not found!", filename)
|
||||
Exit Sub
|
||||
End If
|
||||
Dim fs As New IO.FileStream(filename, IO.FileMode.Open, IO.FileAccess.Read, IO.FileShare.Read)
|
||||
Dim fi As New IO.FileInfo(filename)
|
||||
|
||||
Dim sizedigits As Integer = Math.Ceiling(Math.Log10(fs.Length))
|
||||
|
||||
While Not fs.Position = fs.Length
|
||||
Dim startposition As Long = fs.Position
|
||||
FindHeader(fs)
|
||||
@ -59,40 +62,54 @@
|
||||
End If
|
||||
|
||||
|
||||
Dim buf() As Byte
|
||||
Dim lenbuf(3), nameanddatabuf(), databuf(), crcbuf(3) As Byte
|
||||
Dim len As Integer
|
||||
|
||||
Dim chunklength As UInt32
|
||||
Dim chunktype As String = String.Empty
|
||||
|
||||
While chunktype <> "IEND" AndAlso fs.Position <> fs.Length
|
||||
ReDim buf(3)
|
||||
len = fs.Read(buf, 0, 4)
|
||||
Console.ForegroundColor = ConsoleColor.White
|
||||
|
||||
'read chunk length
|
||||
len = fs.Read(lenbuf, 0, 4)
|
||||
If len <> 4 Then
|
||||
Console.WriteLine("Incomplete chunk length header")
|
||||
Exit While
|
||||
End If
|
||||
|
||||
'big endian
|
||||
chunklength = &H1000000L * buf(0) + &H10000L * buf(1) + &H100L * buf(2) + buf(3)
|
||||
Console.Write("{0,10}:", chunklength)
|
||||
'read and print chunk length and offset in the file
|
||||
chunklength = BigEndianUInt32(lenbuf)
|
||||
Console.Write("{0," & sizedigits & "} @ {1,-" & sizedigits & "}:", chunklength, fs.Position - 4)
|
||||
|
||||
ReDim buf(chunklength + 3)
|
||||
len = fs.Read(buf, 0, chunklength + 4)
|
||||
'read in the chunk data and type
|
||||
ReDim nameanddatabuf(chunklength + 3)
|
||||
ReDim databuf(chunklength - 1)
|
||||
len = fs.Read(nameanddatabuf, 0, chunklength + 4)
|
||||
|
||||
'rewind and read only the chunk data
|
||||
fs.Seek(-chunklength, IO.SeekOrigin.Current)
|
||||
fs.Read(databuf, 0, chunklength)
|
||||
|
||||
'check for incomplete reads
|
||||
If len <> chunklength + 4 Then
|
||||
Console.WriteLine("Incomplete chunk data")
|
||||
Exit While
|
||||
End If
|
||||
chunktype = System.Text.Encoding.ASCII.GetString(buf, 0, 4)
|
||||
Console.Write(chunktype & " ")
|
||||
Dim datachecksum As UInt32 = Crc32.ComputeChecksum(buf)
|
||||
|
||||
ReDim buf(3)
|
||||
len = fs.Read(buf, 0, 4)
|
||||
'get chunk type as string
|
||||
chunktype = System.Text.Encoding.ASCII.GetString(nameanddatabuf, 0, 4)
|
||||
Console.Write(chunktype & " ")
|
||||
|
||||
'compute checksum of the chunk
|
||||
Dim datachecksum As UInt32 = Crc32.ComputeChecksum(nameanddatabuf)
|
||||
|
||||
'read reported checksum and compare it to the file
|
||||
len = fs.Read(crcbuf, 0, 4)
|
||||
If len <> 4 Then
|
||||
Console.WriteLine("Incomplete CRC data")
|
||||
End If
|
||||
Dim chunkchecksum As UInt32 = &H1000000L * buf(0) + &H10000L * buf(1) + &H100L * buf(2) + buf(3)
|
||||
Dim chunkchecksum As UInt32 = BigEndianUInt32(crcbuf)
|
||||
If chunkchecksum = datachecksum Then
|
||||
Console.Write("ok")
|
||||
Else
|
||||
@ -100,6 +117,10 @@
|
||||
End If
|
||||
Console.WriteLine()
|
||||
|
||||
'print info for some chunks
|
||||
Console.ForegroundColor = ConsoleColor.Gray
|
||||
PrintChunkInfo(chunktype, databuf)
|
||||
|
||||
End While
|
||||
|
||||
If extract Then
|
||||
@ -110,6 +131,10 @@
|
||||
End While
|
||||
|
||||
fs.Close()
|
||||
|
||||
#If CONFIG = "Debug" Then
|
||||
Console.ReadKey()
|
||||
#End If
|
||||
End Sub
|
||||
|
||||
Public Sub FindHeader(fs As IO.FileStream)
|
||||
@ -128,6 +153,10 @@
|
||||
End While
|
||||
End Sub
|
||||
|
||||
Private Function BigEndianUInt32(ByRef buf As Byte(), Optional offset As Integer = 0) As UInt32
|
||||
Return &H1000000L * buf(0 + offset) + &H10000L * buf(1 + offset) + &H100L * buf(2 + offset) + buf(3 + offset)
|
||||
End Function
|
||||
|
||||
Public Sub CopyPart(srcfile As String, destfile As String, offset As Long, bytes As Long)
|
||||
Dim srcfs As New IO.FileStream(srcfile, IO.FileMode.Open, IO.FileAccess.Read, IO.FileShare.Read)
|
||||
Dim destfs As New IO.FileStream(destfile, IO.FileMode.Create, IO.FileAccess.Write, IO.FileShare.Read)
|
||||
@ -139,6 +168,110 @@
|
||||
destfs.Close()
|
||||
End Sub
|
||||
|
||||
Private Sub PrintChunkInfo(chunktype As String, ByRef data As Byte())
|
||||
Select Case chunktype
|
||||
Case "IHDR"
|
||||
'image width
|
||||
Console.WriteLine("width: {0} px", BigEndianUInt32(data, 0))
|
||||
|
||||
'image height
|
||||
Console.WriteLine("height: {0} px", BigEndianUInt32(data, 4))
|
||||
|
||||
'bit depth
|
||||
Dim bitdepth As Byte = data(8)
|
||||
If {1, 2, 4, 8, 16}.Contains(bitdepth) Then
|
||||
Console.WriteLine("bit depth: {0} bits/sample", bitdepth)
|
||||
Else
|
||||
Console.WriteLine("bit depth: {0} bits/sample INVALID", bitdepth)
|
||||
End If
|
||||
|
||||
'color types
|
||||
Dim colortype As Byte = data(9)
|
||||
Dim colortypename As String
|
||||
Select Case colortype
|
||||
Case 0
|
||||
colortypename = "greyscale"
|
||||
If Not {1, 2, 4, 8, 16}.Contains(bitdepth) Then
|
||||
colortypename &= ", INVALID BIT DEPTH"
|
||||
End If
|
||||
Case 2
|
||||
colortypename = "truecolor"
|
||||
If Not {8, 16}.Contains(bitdepth) Then
|
||||
colortypename &= ", INVALID BIT DEPTH"
|
||||
End If
|
||||
Case 3
|
||||
colortypename = "indexed"
|
||||
If Not {1, 2, 4, 8}.Contains(bitdepth) Then
|
||||
colortypename &= ", INVALID BIT DEPTH"
|
||||
End If
|
||||
Case 4
|
||||
colortypename = "greyscale with alpha"
|
||||
If Not {8, 16}.Contains(bitdepth) Then
|
||||
colortypename &= ", INVALID BIT DEPTH"
|
||||
End If
|
||||
Case 6
|
||||
colortypename = "truecolor with alpha"
|
||||
If Not {8, 16}.Contains(bitdepth) Then
|
||||
colortypename &= ", INVALID BIT DEPTH"
|
||||
End If
|
||||
Case Else
|
||||
colortypename = "UNKNOWN"
|
||||
End Select
|
||||
Console.WriteLine("color type: {0} ({1})", colortype, colortypename)
|
||||
|
||||
'compression method
|
||||
If data(10) = 0 Then
|
||||
Console.WriteLine("compression method: 0 (deflate)")
|
||||
Else
|
||||
Console.WriteLine("compression method: {0} (UNKNOWN)", data(10))
|
||||
End If
|
||||
|
||||
'filter method
|
||||
If data(11) = 0 Then
|
||||
Console.WriteLine("filter method: 0 (adaptive)")
|
||||
Else
|
||||
Console.WriteLine("filter method: {0} (UNKNOWN)", data(11))
|
||||
End If
|
||||
|
||||
'interlace method
|
||||
If data(12) = 0 Then
|
||||
Console.WriteLine("interlace method: 0 (no interlace)")
|
||||
ElseIf data(12) = 1 Then
|
||||
Console.WriteLine("interlace method: 1 (Adam7)")
|
||||
Else
|
||||
Console.WriteLine("interlace method: {0} (UNKNOWN)", data(12))
|
||||
End If
|
||||
|
||||
'end IHDR
|
||||
|
||||
Case "pHYs"
|
||||
Dim unitsaremetres As Boolean = (data(8) = 1)
|
||||
If unitsaremetres Then
|
||||
Console.WriteLine("pixels per unit, x: {0} px ({1:g} ppi)", BigEndianUInt32(data, 0), BigEndianUInt32(data, 0) * 0.0254)
|
||||
Console.WriteLine("pixels per unit, y: {0} px ({1:g} ppi)", BigEndianUInt32(data, 4), BigEndianUInt32(data, 0) * 0.0254)
|
||||
Else
|
||||
Console.WriteLine("pixels per unit, x: {0} px", BigEndianUInt32(data, 0))
|
||||
Console.WriteLine("pixels per unit, y: {0} px", BigEndianUInt32(data, 4))
|
||||
End If
|
||||
If data(8) = 0 Then
|
||||
Console.WriteLine("units: 0 (unknown)")
|
||||
ElseIf data(8) = 1 Then
|
||||
Console.WriteLine("units: 1 (metre)")
|
||||
Else
|
||||
Console.WriteLine("units: {0} (UNKNOWN)", data(8))
|
||||
End If
|
||||
|
||||
Case "tEXt"
|
||||
Dim keywordlength As Integer = Array.FindIndex(data, Function(x) x = &H0) - 1
|
||||
Dim keyword(keywordlength - 1) As Byte
|
||||
Dim textstring(data.Length - keywordlength - 1 - 1) As Byte
|
||||
Array.Copy(data, 0, keyword, 0, keywordlength)
|
||||
Array.Copy(data, keywordlength + 1, textstring, 0, data.Length - keywordlength - 1)
|
||||
Console.WriteLine("keyword: {0}", System.Text.Encoding.GetEncoding("ISO-8859-1").GetString(keyword))
|
||||
Console.WriteLine("value: {0}", System.Text.Encoding.GetEncoding("ISO-8859-1").GetString(textstring))
|
||||
End Select
|
||||
End Sub
|
||||
|
||||
Public Class Crc32
|
||||
Shared table As UInteger()
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user