Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- Imports System.IO
- Imports System.Drawing
- Module Module1
- Sub Main()
- Console.WriteLine(vbTab & "GVD2PNG v1.2 - TizzyT")
- If My.Application.CommandLineArgs.Count = 0 Then Console.ReadKey()
- For Each arg As String In My.Application.CommandLineArgs
- Try
- Dim File As String = System.IO.Path.GetFileNameWithoutExtension(arg)
- Dim path As String = System.IO.Path.GetDirectoryName(arg).Trim("\")
- Dim CrntGVD As New GVD(arg)
- CrntGVD.SavePNGs(path & "\" & File)
- Catch ex As Exception
- Console.WriteLine("Failed to process " & vbCrLf & arg & vbCrLf & ex.Message)
- Console.ReadKey()
- End Try
- Next
- End Sub
- End Module
- Public Class GVD
- ' Static magic
- Private Shared ReadOnly GVEW0100JPEG0100() As Byte = _
- New Byte() {71, 86, 69, 87, 48, 49, 48, 48, 74, 80, 69, 71, 48, 49, 48, 48}
- Private GVD_Width As Integer
- Private GVD_Height As Integer
- ' Static BLK_
- Private Shared ReadOnly BLK_() As Byte = New Byte() {66, 76, 75, 95}
- Private DataBaseCount As Integer
- ' Static value 1
- Private Shared ReadOnly Static1() As Byte = New Byte() {0, 0, 0, 1, 0, 0, 0, 0}
- Private DataBase As New List(Of Entries)
- Private LengthOfEntries As Integer
- Private GVDreader As FileStream
- ' Structure for Each GVD image Entry
- Private Structure Entries
- Dim PosX As Integer
- Dim PosY As Integer
- Dim Level As Integer
- Dim ImageLength As Integer
- Dim PadLength As Integer
- Dim Width As Integer
- Dim Height As Integer
- Dim Image As Bitmap
- Public Sub New(ByVal OldEntry As Entries, ByVal Image As Bitmap)
- PosX = OldEntry.PosX
- PosY = OldEntry.PosY
- Level = OldEntry.Level
- ImageLength = OldEntry.ImageLength
- PadLength = OldEntry.PadLength
- Width = OldEntry.Width
- Height = OldEntry.Height
- Me.Image = Image
- End Sub
- End Structure
- ' Contructor
- Public Sub New(ByVal SrcGVD As String)
- If IO.File.Exists(SrcGVD) Then 'Checks to see if file actually exists
- GVDreader = New FileStream(SrcGVD, FileMode.Open, FileAccess.Read)
- Dim Magic(15) As Byte
- GVDreader.Read(Magic, 0, 16)
- 'Checks for expected Magic
- If Magic.SequenceEqual(GVEW0100JPEG0100) Then
- 'Gets GVD header info
- If ProcessHeader() Then
- GVDreader.Seek(16, SeekOrigin.Current)
- ' Process and populate Entries into Entries List
- For i = 1 To DataBaseCount
- ProcessEntry(i)
- Next
- ' Check for second occurence of BLK bytes
- Dim BLKcheck(3) As Byte
- GVDreader.Read(BLKcheck, 0, 4)
- If BLKcheck.SequenceEqual(BLK_) Then
- ' Skip Length of embedded images and static value
- GVDreader.Seek(12, SeekOrigin.Current)
- ' Redo all processed Entries by adding their respective image (fix this)
- For i = 0 To DataBase.Count - 1
- Dim Data(DataBase(i).ImageLength - 1) As Byte
- GVDreader.Read(Data, 0, DataBase(i).ImageLength)
- Using meh As New MemoryStream(Data)
- Dim sup As New Bitmap(meh)
- DataBase(i) = New Entries(DataBase(i), sup)
- meh.Close()
- meh.Dispose()
- End Using
- 'Skip the length of the image pad to beginning of next image
- GVDreader.Seek(DataBase(i).PadLength, SeekOrigin.Current)
- Next
- Else
- Throw New Exception("Expect BLK_ not found")
- End If
- Erase BLKcheck
- Else
- Throw New Exception("Unknow error trying to read GVD Header" & vbCrLf & _
- "Possible BLK bytes not present where expected")
- End If
- Else
- Throw New Exception("Invalid GVD file (Magic mismatch)")
- End If
- Else
- Throw New Exception("GVD file at location doesn't exist")
- End If
- End Sub
- ' Used to verify and grab information from GVD
- Private Function ProcessHeader() As Boolean
- Try
- ' Get GVD width
- Dim Width(3) As Byte
- GVDreader.Read(Width, 0, 4)
- Array.Reverse(Width)
- GVD_Width = BitConverter.ToInt32(Width, 0)
- Erase Width
- ' Get GVD height
- Dim Height(3) As Byte
- GVDreader.Read(Height, 0, 4)
- Array.Reverse(Height)
- GVD_Height = BitConverter.ToInt32(Height, 0)
- Erase Height
- ' Check for expected BLK bytes
- Dim BLKcheck(3) As Byte
- GVDreader.Read(BLKcheck, 0, 4)
- ' Check if expected BLK bytes are present
- If Not BLKcheck.SequenceEqual(BLK_) Then Return False
- Erase BLKcheck
- ' Get number of DataBase Entries
- Dim DBcount(3) As Byte
- GVDreader.Read(DBcount, 0, 4)
- Array.Reverse(DBcount)
- DataBaseCount = (BitConverter.ToInt32(DBcount, 0) - 8) / 32
- Erase DBcount
- Catch ex As Exception
- Return False ' Something went wrong
- End Try
- Return True
- End Function
- ' Used to read from file and process an Entry
- Private Sub ProcessEntry(ByVal Entry As Integer)
- Dim Temp As New Entries ' Working Entry
- ' Get Horizontal Position
- Dim PosX(3) As Byte
- GVDreader.Read(PosX, 0, 4)
- Array.Reverse(PosX)
- Temp.PosX = BitConverter.ToInt32(PosX, 0)
- Erase PosX
- ' Get Vertical Posoition
- Dim PosY(3) As Byte
- GVDreader.Read(PosY, 0, 4)
- Array.Reverse(PosY)
- Temp.PosY = BitConverter.ToInt32(PosY, 0)
- Erase PosY
- ' Get Layer Level
- Dim LvL(3) As Byte
- GVDreader.Read(LvL, 0, 4)
- Array.Reverse(LvL)
- Temp.Level = BitConverter.ToInt32(LvL, 0)
- Erase LvL
- ' Get length of image (in bytes)
- Dim ImgLen(3) As Byte
- GVDreader.Read(ImgLen, 0, 4)
- Array.Reverse(ImgLen)
- Temp.ImageLength = BitConverter.ToInt32(ImgLen, 0)
- Erase ImgLen
- ' Get length of padding (in bytes)
- Dim PadLen(3) As Byte
- GVDreader.Read(PadLen, 0, 4)
- Array.Reverse(PadLen)
- Temp.PadLength = BitConverter.ToInt32(PadLen, 0)
- Erase PadLen
- ' Skip "Not Used" (4 bytes)
- GVDreader.Seek(4, SeekOrigin.Current)
- ' Get Width of image
- Dim Width(3) As Byte
- GVDreader.Read(Width, 0, 4)
- Array.Reverse(Width)
- Temp.Width = BitConverter.ToInt32(Width, 0)
- Erase Width
- ' Get height of image
- Dim Height(3) As Byte
- GVDreader.Read(Height, 0, 4)
- Array.Reverse(Height)
- Temp.Height = BitConverter.ToInt32(Height, 0)
- Erase Height
- ' Add working Entry to Entries List
- DataBase.Add(Temp)
- End Sub
- ' Returns byte array as a bitmap
- Private Function Bytes2Bitmap(ByVal ArrayData() As Byte) As Bitmap
- Dim bm As Bitmap
- Using ms As New MemoryStream(ArrayData)
- bm = New Bitmap(ms)
- ms.Close()
- ms.Dispose()
- End Using
- Return bm
- End Function
- ' Saves the PNGs for each layer
- Public Sub SavePNGs(ByVal Location As String)
- Dim LayerRes() As Size = CalcRes(GVD_Width, GVD_Height)
- Dim Layers(LayerRes.Length - 1) As EditableBitmap
- For i = 0 To Layers.Length - 1
- Layers(i) = New EditableBitmap(LayerRes(i).Width, LayerRes(i).Height)
- Next
- For Each GVD As Entries In DataBase
- Layers(GVD.Level).Draw(GVD.Image, GVD.PosX * 256, GVD.PosY * 256, GVD.Width, GVD.Height)
- Next
- For i = 0 To Layers.Length - 1
- Layers(i).Save(Location & "_Layer" & i & ".png", Imaging.ImageFormat.Png)
- Next
- End Sub
- ' Calculate the multiple resolutions for the GVD
- Private Function CalcRes(ByVal X As Integer, ByVal Y As Integer) As Size()
- Dim Res(CalcLevel(X, Y)) As Size
- For i = 0 To Res.Length - 1
- Res(i) = New Size(X, Y)
- X = Math.Round(X / 2)
- Y = Math.Round(Y / 2)
- Next
- Return Res
- End Function
- ' Given a resolution return how many levels are needed
- Private Function CalcLevel(ByVal X As Integer, Y As Integer) As Integer
- CalcLevel = 0
- While X > 256 OrElse Y > 256
- X = Math.Round(X / 2)
- Y = Math.Round(Y / 2)
- CalcLevel += 1
- End While
- End Function
- ' Bitmap class with embedded graphics object for editing
- Public Class EditableBitmap
- Private BM As Bitmap
- Private G As Graphics
- Sub New(ByVal ResX As Integer, ByVal ResY As Integer)
- BM = New Bitmap(ResX, ResY)
- G = Graphics.FromImage(BM)
- End Sub
- Public Sub Draw(ByVal Image As Bitmap, _
- ByVal PosX As Integer, _
- ByVal PosY As Integer, _
- ByVal SizeX As Integer, _
- ByVal SizeY As Integer)
- G.DrawImage(Image, PosX, PosY, SizeX, SizeY)
- End Sub
- Public Sub Save(ByVal Location As String, ByVal Format As Imaging.ImageFormat)
- BM.Save(Location, Format)
- End Sub
- End Class
- End Class
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement