Skip to content

Commit 0e84ca8

Browse files
committed
Get indexed png writer somewhat working - output is spaghetti but at least it's a valid file now
1 parent 5d562f5 commit 0e84ca8

File tree

3 files changed

+93
-20
lines changed

3 files changed

+93
-20
lines changed

types/FileIO.bmx

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
Import BRL.PNGLoader
21
Import "IndexedImageWriter.bmx"
32

43
'//// FILE IO ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

types/IndexedImageWriter.bmx

Lines changed: 67 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,30 @@
1-
Import BRL.Bank
1+
Import "Utility.bmx"
2+
Import "UtilityPNG.bmx"
23

34
'//// INDEXED IMAGE WRITER //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
45

6+
Struct RGBColor
7+
Field m_R:Byte
8+
Field m_G:Byte
9+
Field m_B:Byte
10+
EndStruct
11+
12+
'////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
13+
514
Type IndexedImageWriter
615
Field m_PalR:Byte[256]
716
Field m_PalG:Byte[256]
817
Field m_PalB:Byte[256]
918

10-
Field m_CRCTable:Int[256]
19+
Field m_Palette:RGBColor[256]
20+
21+
'Field m_CRCTable:Int[256]
1122

1223
'////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1324

1425
Method New()
1526
LoadDefaultPalette()
16-
27+
Rem
1728
'Initialize CRC table
1829
For Local i:Int = 0 To 255
1930
Local value:Int = i
@@ -26,18 +37,19 @@ Type IndexedImageWriter
2637
Next
2738
m_CRCTable[i] = value
2839
Next
40+
EndRem
2941
EndMethod
3042

3143
'////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
32-
44+
Rem
3345
Method GenerateCRC32FromBank:Int(bank:TBank)
3446
Local crcResult:Int = $FFFFFFFF
3547
For Local i:Int = 0 Until BankSize(bank)
3648
crcResult = (crcResult Shr 8) ~ m_CRCTable[PeekByte(bank, i) ~ (crcResult & $FF)]
3749
Next
3850
Return ~crcResult '~ for bitwise complement
3951
EndMethod
40-
52+
EndRem
4153
'////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4254

4355
Method LoadDefaultPalette()
@@ -50,6 +62,10 @@ Type IndexedImageWriter
5062
m_PalR[index] = ReadByte(paletteStream)
5163
m_PalG[index] = ReadByte(paletteStream)
5264
m_PalB[index] = ReadByte(paletteStream)
65+
66+
m_Palette[index].m_R = m_PalR[index]
67+
m_Palette[index].m_G = m_PalG[index]
68+
m_Palette[index].m_B = m_PalB[index]
5369
Next
5470
CloseStream(paletteStream)
5571
EndMethod
@@ -147,7 +163,7 @@ Type IndexedImageWriter
147163
EndMethod
148164

149165
'////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
150-
166+
Rem
151167
Method WriteIndexedPNGFromPixmap:Int(sourcePixmap:TPixmap, filename:String)
152168
If filename = Null Then
153169
Return False
@@ -176,15 +192,13 @@ Type IndexedImageWriter
176192
177193
WriteInt(outputStream, pngWidth) 'Image Width (4 bytes)
178194
WriteInt(outputStream, pngHeight) 'Image Height (4 bytes)
179-
WriteByte(outputStream, 4) 'Bit Depth (1 byte) - BYTES per pixel not BITS per pixel
195+
WriteByte(outputStream, 8) 'Bit Depth (1 byte)
180196
WriteByte(outputStream, 3) 'Color Type (1 byte) - 3 for indexed color
181197
WriteByte(outputStream, 0) 'Compression Method (1 byte)
182198
WriteByte(outputStream, 0) 'Filter Method (1 byte)
183199
WriteByte(outputStream, 0) 'Interlace Method (1 byte) - 0 for no interlace
184200
185-
Rem
186-
Figure out how to generate correct CRC
187-
EndRem
201+
'Figure out how to generate correct CRC
188202
WriteInt(outputStream, 0) 'CRC-32 checksum (4 bytes)
189203
190204
'PLTE chunk (color table)
@@ -197,9 +211,7 @@ Type IndexedImageWriter
197211
WriteByte(outputStream, m_PalR[index]) 'Red (1 byte)
198212
Next
199213
200-
Rem
201-
Figure out how to generate correct CRC
202-
EndRem
214+
'Figure out how to generate correct CRC
203215
WriteInt(outputStream, 0) 'CRC-32 checksum (4 bytes)
204216
205217
'IDAT chunk (pixel array)
@@ -216,22 +228,58 @@ Type IndexedImageWriter
216228
Next
217229
Next
218230
219-
Rem
220-
Figure out how to generate correct CRC
221-
EndRem
231+
'Figure out how to generate correct CRC
222232
WriteInt(outputStream, 0) 'CRC-32 checksum (4 bytes)
223233
224234
'IEND chunk (EOF)
225235
WriteInt(outputStream, 0) 'Chunk Length (4 bytes) - 0 for IEND
226236
WriteInt(outputStream, 1229278788) 'Chunk Type (4 bytes) - 1229278788 (decimal) or 49 45 4E 44 (hex) or IEND (ascii)
227237
228-
Rem
229-
Figure out how to generate correct CRC
230-
EndRem
238+
'Figure out how to generate correct CRC
231239
WriteInt(outputStream, 0) 'CRC-32 checksum (4 bytes)
232240
233241
CloseStream(outputStream)
234242
Return True
235243
EndIf
236244
EndMethod
245+
EndRem
246+
'////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
247+
248+
Method WriteIndexedPNGFromPixmap:Int(sourcePixmap:TPixmap, filename:String, compression:Int = 5)
249+
Local outputStream:TStream = WriteStream(filename)
250+
251+
Try
252+
Local pngPtr:Byte Ptr = png_create_write_struct("1.6.37", Null, Null, Null)
253+
Local pngInfoPtr:Byte Ptr = png_create_info_struct(pngPtr)
254+
255+
png_set_write_fn(pngPtr, outputStream, UtilityPNG.PNGWrite, UtilityPNG.PNGFlush)
256+
257+
png_set_compression_level(pngPtr, Utility.Clamp(compression, 0, 9))
258+
png_set_IHDR(pngPtr, pngInfoPtr, sourcePixmap.Width, sourcePixmap.Height, 8, PNG_COLOR_TYPE_PALETTE, PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT)
259+
260+
Local palettePtr:Byte Ptr = m_Palette
261+
png_set_PLTE(pngPtr, pngInfoPtr, palettePtr, 256);
262+
263+
'sourcePixmap = sourcePixmap.Convert(PF_I8)
264+
For Local pixelY:Int = 0 Until sourcePixmap.Height
265+
For Local pixelX:Int = 0 Until sourcePixmap.Width
266+
WritePixel(sourcePixmap, pixelX, pixelY, ConvertColorToClosestIndex(ReadPixel(sourcePixmap, pixelX, pixelY)))
267+
Next
268+
Next
269+
270+
Local rows:Byte Ptr[sourcePixmap.Height]
271+
For Local i = 0 Until sourcePixmap.Height
272+
rows[i] = sourcePixmap.PixelPtr(0, i)
273+
Next
274+
png_set_rows(pngPtr, pngInfoPtr, rows)
275+
276+
png_write_png(pngPtr, pngInfoPtr, 0, Null)
277+
png_destroy_write_struct(Varptr pngPtr, Varptr pngInfoPtr, Null)
278+
279+
CloseStream(outputStream)
280+
Return True
281+
Catch error:String
282+
If error <> "PNG ERROR" Throw error
283+
EndTry
284+
EndMethod
237285
EndType

types/UtilityPNG.bmx

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
Import PUB.LibPNG
2+
3+
'//// PNG UTILITY FUNCTIONS /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4+
5+
Type UtilityPNG
6+
7+
'////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8+
9+
Function PNGWrite(pngPtr:Byte Ptr, buf:Byte Ptr, size:Int)
10+
Local outputStream:TStream = TStream(png_get_io_ptr(pngPtr))
11+
Return outputStream.WriteBytes(buf, size)
12+
EndFunction
13+
14+
'////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
15+
16+
Function PNGFlush(pngPtr:Byte Ptr)
17+
Local outputStream:TStream = TStream(png_get_io_ptr(pngPtr))
18+
FlushStream(outputStream)
19+
EndFunction
20+
EndType
21+
22+
'////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
23+
24+
Extern
25+
Function png_set_PLTE(png_ptr:Byte Ptr, info_ptr:Byte Ptr, palette:Byte Ptr, num_palette:Int) = "bmx_png_set_PLTE"
26+
EndExtern

0 commit comments

Comments
 (0)