Skip to content

Commit 5d562f5

Browse files
committed
Add indexed png writer - doesn't work, CRCs generated from banks/streams/everything are wrong (code removed)
1 parent 169f57f commit 5d562f5

File tree

1 file changed

+100
-1
lines changed

1 file changed

+100
-1
lines changed

types/IndexedImageWriter.bmx

Lines changed: 100 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,41 @@
1+
Import BRL.Bank
2+
13
'//// INDEXED IMAGE WRITER //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
24

35
Type IndexedImageWriter
46
Field m_PalR:Byte[256]
57
Field m_PalG:Byte[256]
68
Field m_PalB:Byte[256]
79

10+
Field m_CRCTable:Int[256]
11+
812
'////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
913

1014
Method New()
1115
LoadDefaultPalette()
16+
17+
'Initialize CRC table
18+
For Local i:Int = 0 To 255
19+
Local value:Int = i
20+
For Local j:Int = 0 To 7
21+
If (value & $1) Then
22+
value = (value Shr 1) ~ $EDB88320 '~ for XOR
23+
Else
24+
value = (value Shr 1)
25+
EndIf
26+
Next
27+
m_CRCTable[i] = value
28+
Next
29+
EndMethod
30+
31+
'////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
32+
33+
Method GenerateCRC32FromBank:Int(bank:TBank)
34+
Local crcResult:Int = $FFFFFFFF
35+
For Local i:Int = 0 Until BankSize(bank)
36+
crcResult = (crcResult Shr 8) ~ m_CRCTable[PeekByte(bank, i) ~ (crcResult & $FF)]
37+
Next
38+
Return ~crcResult '~ for bitwise complement
1239
EndMethod
1340

1441
'////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
@@ -126,10 +153,82 @@ Type IndexedImageWriter
126153
Return False
127154
Else
128155
Local pngWidth:Int = sourcePixmap.Width
156+
Local pngWidthM4:Int = ((pngWidth + 3) / 4) * 4 'pngWidth adjusted to be divisible by 4. Written file is spaghetti if not adjusted!
129157
Local pngHeight:Int = sourcePixmap.Height
158+
Local pngSizeTotal:Int = pngWidthM4 * pngHeight 'dimensions (with adjusted width)
159+
Local pngSizeTotalM4:Int = ((pngSizeTotal + 3) / 4) * 4 'bmpSizeTotal adjusted to be divisible by 4. Written file is spaghetti if not adjusted!
130160

131161
'Begin writing PNG file manually
132-
Local outputStream:TStream = BigEndianStream(WriteFile(filename)) 'PNG file data is stored in network byte order (big-endian, most-significant byte first)
162+
Local outputStream:TStream = BigEndianStream(WriteFile(filename)) 'PNG file data is stored in network byte order (big-endian)
163+
164+
'PNG file header
165+
WriteByte(outputStream, 137) 'Has the high bit set to detect transmission systems that do not support 8-bit data and to reduce the chance that a text file is mistakenly interpreted as a PNG, or vice versa. 89 (hex) (1 byte)
166+
WriteByte(outputStream, 80) 'File ID (in ASCII, the letters PNG). 50 4E 47 (hex) (3 bytes)
167+
WriteByte(outputStream, 78)
168+
WriteByte(outputStream, 71)
169+
WriteShort(outputStream, 3338) 'A DOS-style line ending (CRLF) to detect DOS-Unix line ending conversion of the data. 0D 0A (hex) (2 bytes)
170+
WriteByte(outputStream, 26) 'A byte that stops display of the file under DOS when the command type has been used—the end-of-file character. 1A (hex) (1 byte)
171+
WriteByte(outputStream, 10) 'A Unix-style line ending (LF) to detect Unix-DOS line ending conversion. 0A (hex) (1 byte)
172+
173+
'IHDR chunk (file properties)
174+
WriteInt(outputStream, 13) 'Chunk Length (4 bytes) - 13 bytes for IHDR
175+
WriteInt(outputStream, 1229472850) 'Chunk Type (4 bytes) - 1229472850 (decimal) or 49 48 44 52 (hex) or IHDR (ascii)
176+
177+
WriteInt(outputStream, pngWidth) 'Image Width (4 bytes)
178+
WriteInt(outputStream, pngHeight) 'Image Height (4 bytes)
179+
WriteByte(outputStream, 4) 'Bit Depth (1 byte) - BYTES per pixel not BITS per pixel
180+
WriteByte(outputStream, 3) 'Color Type (1 byte) - 3 for indexed color
181+
WriteByte(outputStream, 0) 'Compression Method (1 byte)
182+
WriteByte(outputStream, 0) 'Filter Method (1 byte)
183+
WriteByte(outputStream, 0) 'Interlace Method (1 byte) - 0 for no interlace
184+
185+
Rem
186+
Figure out how to generate correct CRC
187+
EndRem
188+
WriteInt(outputStream, 0) 'CRC-32 checksum (4 bytes)
189+
190+
'PLTE chunk (color table)
191+
WriteInt(outputStream, 768) 'Chunk Length (4 bytes) - 4 bytes (ARGB) times the amount of colors in the palette = 1024 bytes
192+
WriteInt(outputStream, 1347179589) 'Chunk Type (4 bytes) - 1347179589 (decimal) or 50 4C 54 45 (hex) or PLTE (ascii)
193+
194+
For Local index:Int = 0 To 255
195+
WriteByte(outputStream, m_PalB[index]) 'Blue (1 byte)
196+
WriteByte(outputStream, m_PalG[index]) 'Green (1 byte)
197+
WriteByte(outputStream, m_PalR[index]) 'Red (1 byte)
198+
Next
199+
200+
Rem
201+
Figure out how to generate correct CRC
202+
EndRem
203+
WriteInt(outputStream, 0) 'CRC-32 checksum (4 bytes)
204+
205+
'IDAT chunk (pixel array)
206+
WriteInt(outputStream, pngSizeTotal) 'Chunk Length (4 bytes) - width times height of the image + padding
207+
WriteInt(outputStream, 1229209940) 'Chunk Type (4 bytes) - 1229209940 (decimal) or 49 44 41 54 (hex) or IDAT (ascii)
208+
209+
For Local pixelY:Int = pngHeight - 1 To 0 Step -1
210+
For Local pixelX:Int = 0 Until pngWidth
211+
If pixelX < pngWidth Then
212+
WriteByte(outputStream, ConvertColorToClosestIndex(ReadPixel(sourcePixmap, pixelX, pixelY)))
213+
'Else
214+
' WriteByte(outputStream, 0) 'Line padding
215+
EndIf
216+
Next
217+
Next
218+
219+
Rem
220+
Figure out how to generate correct CRC
221+
EndRem
222+
WriteInt(outputStream, 0) 'CRC-32 checksum (4 bytes)
223+
224+
'IEND chunk (EOF)
225+
WriteInt(outputStream, 0) 'Chunk Length (4 bytes) - 0 for IEND
226+
WriteInt(outputStream, 1229278788) 'Chunk Type (4 bytes) - 1229278788 (decimal) or 49 45 4E 44 (hex) or IEND (ascii)
227+
228+
Rem
229+
Figure out how to generate correct CRC
230+
EndRem
231+
WriteInt(outputStream, 0) 'CRC-32 checksum (4 bytes)
133232

134233
CloseStream(outputStream)
135234
Return True

0 commit comments

Comments
 (0)