1 Attachment(s)
[RESOLVED] SAGA_RLE1 decoder
NOTICE:
See the last post for the most up to date inormation. Anyway since I am nearly done, I am marking this thread as resolved.
Using the tools found at https://github.com/adventurebrew/sagaeunt to unpack Ite.rsc (Inherit the Earth: Quest for The Orb resource file) I extracted the individual resources. (See res.zip).
Wanting to convert the image resources to a more standardized format I attempted to write a SAGA_RLE1 (https://wiki.scummvm.org/index.php?t...iles/SAGA_RLE1) decompressor. Checking each file using the header description
(https://wiki.scummvm.org/index.php?t...nterface_Image I found several likely candidate resources for background images by checking whether the first two bytes would convert to a width of 320 pixels and the second two to a minum of 136. I attempted to write code to interpret SAGA_RLE1 encoding:
Code:
'This procedure attempts to read a resource as an image and convert it to a *.png file.
Private Sub ConvertToPNG(InFile As String, OutFile As String)
Dim Backtrack As New Integer
Dim Bit As New Integer
Dim BitfieldBytes() As Byte = {}
Dim Data As New Byte
Dim Data1 As New Byte
Dim Data2 As New Byte
Dim DataBytes() As Byte = {}
Dim Decoded As New List(Of Byte)
Dim ImageO As Bitmap = Nothing
Dim ImageSize As Size = Nothing
Dim MarkByte As New Byte
Dim Palette As New List(Of Color)
Dim Pixel As New Integer
Dim RunAddend As New Integer
Dim RunCount As New Integer
Using ResData As New BinaryReader(New MemoryStream(File.ReadAllBytes(InFile)))
ImageSize = New Size(ResData.ReadInt16, ResData.ReadInt16)
ResData.BaseStream.Seek(&H4%, SeekOrigin.Current)
For PaletteEntry As Integer = 0 To 255
Palette.Add(Color.FromArgb(&HFF%, ResData.ReadByte(), ResData.ReadByte(), ResData.ReadByte()))
Next PaletteEntry
While ResData.BaseStream.Position < ResData.BaseStream.Length
MarkByte = ResData.ReadByte()
Select Case MarkByte And &HC0%
Case &HC0%
RunCount = MarkByte And &H3F%
Decoded.AddRange(ResData.ReadBytes(RunCount))
Case &H80%
RunCount = (MarkByte And &H3F%) + &H3%
Data = ResData.ReadByte()
Decoded.AddRange(Enumerable.Repeat(Data, RunCount))
Case &H40%
RunCount = ((MarkByte >> &H3%) And &H7%) + &H3%
Backtrack = ResData.ReadByte()
DataBytes = Decoded.GetRange((Decoded.Count - &H1%) - Backtrack, RunCount).ToArray()
Decoded.AddRange(DataBytes)
Case &H0%
Select Case MarkByte And &H30%
Case &H30%
RunCount = (MarkByte And &HF%) + &H1%
Data1 = ResData.ReadByte()
Data2 = ResData.ReadByte()
BitfieldBytes = ResData.ReadBytes(RunCount)
For Each ByteO As Integer In BitfieldBytes
For BitIndex As Integer = &H0% To &H7%
Decoded.Add(If(((ByteO >> BitIndex) And &H1%) = &H0%, Data1, Data2))
Next BitIndex
Next ByteO
Case &H20%
RunCount = ToInt32(MarkByte And &HF%) << &H8%
RunAddend = ResData.ReadByte()
RunCount += RunAddend
Decoded.AddRange(ResData.ReadBytes(RunCount))
Case &H10%
Backtrack = (ToInt32(MarkByte And &HF%) << &H8%)
RunAddend = ResData.ReadByte()
Backtrack += RunAddend
RunCount = ResData.ReadByte()
DataBytes = Decoded.GetRange((Decoded.Count - &H1%) - Backtrack, RunCount).ToArray()
Decoded.AddRange(DataBytes)
End Select
End Select
End While
End Using
ImageO = New Bitmap(ImageSize.Width, ImageSize.Height)
Pixel = 0
For y As Integer = 0 To ImageSize.Height - 1
For x As Integer = 0 To ImageSize.Width - 1
ImageO.SetPixel(x, y, Palette(Decoded(Pixel)))
Pixel += 1
Next x
Next y
ImageO.Save($"{OutFile}.png")
End Sub
However it doesn't appear to work on any file I try. While I am going to take another look at it soon perhaps someone here will find an obvious error that has been overlooked. Any kind of feedback would be appreciated. :-)
EDIT
For some reason I am unable to upload example resources.
EDIT 2:
Probably because those resources are binary files. I guess a Google Drive link will have to do: https://drive.google.com/file/d/1CfT...ew?usp=sharing
EDIT 3:
Anyone wishing to do a virusscan on the files: https://www.virustotal.com/gui/home/upload
EDIT 4:
Thanks to a kind user on another forum (I had linked to this post there) I fixed the backtracking (markbyte & 0xC0 = 0x40) code. Still doesn't produce proper images but definitely improved.