Skip to content

Commit d9b1bb0

Browse files
author
MaximDude
committed
BMP file writer actually fully functional but incredibly slow
Sped up indexing by ignoring magenta (255,0,255) Generated file still has messed up thumbnail and doesn't open correctly in Photoshop, appears to be working fine in Paint, probably something bad in header or DIB
1 parent 9d2f887 commit d9b1bb0

File tree

1 file changed

+42
-44
lines changed

1 file changed

+42
-44
lines changed

cccp-bender-main.bmx

Lines changed: 42 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,9 @@ Type TBitmapIndex
2525
Global palR:Byte[256]
2626
Global palG:Byte[256]
2727
Global palB:Byte[256]
28+
29+
'Data Streams
30+
Global dataStream:TStream
2831

2932
'Load color table file
3033
Function FLoadPalette(paletteFile:String)
@@ -42,11 +45,11 @@ Type TBitmapIndex
4245

4346
'Indexed Bitmap File Writer
4447
Function FPixmapToIndexedBitmap(image:TPixmap,filename:String)
45-
'Variables
48+
'Variables
49+
Local paletteIndex:Int
4650
Local bmpWidth:Int, bmpWidthM4:Int
4751
Local bmpHeight:Int
4852
Local bmpSizeTotal:Int, bmpSizeTotalM4:Int
49-
Local paletteIndex:Int = 0
5053

5154
'Dimensions calc
5255
bmpWidth = PixmapWidth(image)
@@ -58,24 +61,19 @@ Type TBitmapIndex
5861
bmpSizeTotalM4 = ((bmpSizeTotal + 3) / 4) * 4
5962

6063
'Begin writing BMP file manually
61-
Local dataStream:TStream = WriteFile(filename)
64+
dataStream = WriteFile(filename)
6265

6366
'------ Bitmap File Header
64-
'Header file data is stored in little-endian format (least-significant byte first)
67+
'Data is stored in little-endian format (least-significant byte first)
6568
dataStream = LittleEndianStream(dataStream)
6669

6770
WriteShort(dataStream,19778) 'File ID (2 bytes (short)) - 19778 (deci) or 42 4D (hex) or BM (ascii) for bitmap
6871
WriteInt(dataStream,bmpSizeTotalM4) 'File Size (4 bytes (signed int))
6972
WriteShort(dataStream,0) 'Reserved (2 bytes)
7073
WriteShort(dataStream,0) 'Reserved (2 bytes)
7174
WriteInt(dataStream,54) 'Pixel Array Offset (4 bytes) - pixel array starts at 54th byte
72-
'Print("wrote header")
73-
74-
'CloseStream(headerStream)
7575

7676
'------ DIB Header (File Info)
77-
'dataStream = BigEndianStream(dataStream)
78-
7977
WriteInt(dataStream,40) 'DIB Header Size (4 bytes) - 40 bytes
8078
WriteInt(dataStream,bmpWidth) 'Bitmap Width (4 bytes)
8179
WriteInt(dataStream,bmpHeight) 'Bitmap Height (4 bytes)
@@ -87,59 +85,60 @@ Type TBitmapIndex
8785
WriteInt(dataStream,2835) 'Vertical resolution of the image (4 bytes) - Pixels Per Metre (2835 PPM equals 72.009 DPI/PPI)
8886
WriteInt(dataStream,256) 'Number of colors in the color palette (4 bytes)
8987
WriteInt(dataStream,0) 'Number of important colors (4 bytes) - 0 when every color is important
90-
'Print("wrote dib")
9188

9289
'------ Color Table
9390
For paletteIndex = 0 To 255
94-
WriteByte(dataStream,PalB[paletteIndex]) 'Blue (4 bytes) - offset 54
95-
WriteByte(dataStream,PalG[paletteIndex]) 'Green (4 bytes) - offset 58
96-
WriteByte(dataStream,PalR[paletteIndex]) 'Red (4 bytes) - offset 62
91+
WriteByte(dataStream,palB[paletteIndex]) 'Blue (4 bytes) - offset 54
92+
WriteByte(dataStream,palG[paletteIndex]) 'Green (4 bytes) - offset 58
93+
WriteByte(dataStream,palR[paletteIndex]) 'Red (4 bytes) - offset 62
9794
WriteByte(dataStream,0) 'Alpha (4 bytes) - offset 66
98-
If paletteIndex = 255 Then
99-
'Print("wrote color table")
100-
EndIf
10195
Next
10296

10397
'------ Pixel Array
10498
Local px:Int, py:Int
105-
Local R:Int, G:Int, B:Int, ARGB:Long
106-
Local bestDistance:Int, bestIndex:Int, distance:Int
107-
Local RDIFF:Int, GDIFF:Int, BDIFF:Int
108-
99+
Local pixelData:Long
100+
Local bestIndex:Int = 0
101+
Local magenta:Int = 16711935
109102
For py = bmpHeight -1 To 0 Step -1
110103
For px = 0 To bmpWidthM4 -1
111-
If px < bmpWidth 'if a valid pixel on canvas
112-
bestDistance = 17000000
113-
bestIndex = 0
114-
distance = 0
115-
116-
For paletteIndex = 0 To 255 ' Check all color indexes for best match by pythagora
117-
ARGB = ReadPixel(image,px,py)
118-
R = (ARGB & $00FF0000) Shr 16
119-
G = (ARGB & $FF00) Shr 8
120-
B = (ARGB & $FF)
121-
RDIFF = Abs(R - palR[paletteIndex])
122-
GDIFF = Abs(G - palG[paletteIndex])
123-
BDIFF = Abs(B - palB[paletteIndex])
124-
distance = (RDIFF^2 + GDIFF^2 + BDIFF^2)
125-
If distance <= bestDistance Then
126-
bestIndex = paletteIndex
127-
bestDistance = distance
128-
EndIf
129-
'Print("working" + paletteIndex)
130-
Next
104+
'if a valid pixel on canvas
105+
If px < bmpWidth
106+
'Read pixel data
107+
pixelData = ReadPixel(image,px,py)
108+
'skip diffing magenta
109+
If pixelData = 16711935 Then
110+
WriteByte(dataStream,1)
111+
Else
112+
'Check all color indexes for best match by pythagora
113+
Local R:Int, G:Int, B:Int
114+
Local RDIFF:Int, GDIFF:Int, BDIFF:Int
115+
Local bestDistance:Int = 17000000
116+
Local distance:Int = 0
117+
For paletteIndex = 0 To 255
118+
R = (pixelData & $00FF0000) Shr 16
119+
G = (pixelData & $FF00) Shr 8
120+
B = (pixelData & $FF)
121+
RDIFF = Abs(R - palR[paletteIndex])
122+
GDIFF = Abs(G - palG[paletteIndex])
123+
BDIFF = Abs(B - palB[paletteIndex])
124+
distance = (RDIFF^2 + GDIFF^2 + BDIFF^2)
125+
If distance <= bestDistance Then
126+
bestIndex = paletteIndex
127+
bestDistance = distance
128+
EndIf
129+
Next
130+
EndIf
131131
WriteByte(dataStream,bestIndex)
132132
Else
133-
WriteByte(dataStream,0) ' line padding
133+
WriteByte(dataStream,0) 'line padding
134134
EndIf
135135
Next
136136
Next
137-
For paletteIndex = 1 To bmpSizeTotalM4 - bmpSizeTotal ' eof padding
137+
For paletteIndex = 1 To bmpSizeTotalM4 - bmpSizeTotal 'eof padding
138138
WriteByte(dataStream,0)
139139
Next
140140

141141
CloseStream(dataStream)
142-
'Print ("stream closed")
143142
EndFunction
144143

145144
EndType
@@ -384,7 +383,6 @@ Type TAppOutput
384383
SetRotation(0)
385384
'Output copy for saving
386385
TAppFileIO.tempOutputImage = GrabPixmap(0,96,768,384)
387-
'ConvertPixmap(TAppFileIO.tempOutputImage,PF_BGR888)
388386
Flip(1)
389387
If TAppFileIO.prepForSave
390388
TAppFileIO.FPrepForSave()

0 commit comments

Comments
 (0)