Re: NeuQuant (SSE2)
Posted: Tue Jan 31, 2017 8:03 am
Can anyone spot what I'm doing wrong here? If the code runs with the current commenting, quality is good but the colors are wrong. Switch the commenting in the inxSearch loop and the colors become right but the quality goes way down. Here's the code, it'll download the sample image one time:
This code works fine with the luis port of Dekker's algorithm but this implementation is so much faster I'd like to get it working with 8bit output.
Code: Select all
IncludeFile "NeuQuant.pbi"
Macro GetPixel32BitImage (x, y)
PeekL(bitsptr_in + sz_colorbits_in + ((x) << 2) - ((y) + 1) * wb_in)
EndMacro
Macro SetPixel8BitImage (x, y, col)
PokeB(bitsptr_out + (h*wb_out) + (x) - ((y) + 1) * wb_out, col)
EndMacro
Procedure ImageTo8bit(image_number)
If ImageDepth(image_number)<>32
this = CreateImage(#PB_Any, ImageWidth(image_number), ImageHeight(image_number), 32)
StartDrawing(ImageOutput(this))
DrawImage(ImageID(image_number), 0, 0)
StopDrawing()
FreeImage(image_number)
image_number = this
hImageIn = ImageID(this)
Else
hImageIn = ImageID(image_number)
EndIf
*palette = AllocateMemory(256*SizeOf(RGBQUAD))
NeuQuant::InitNet()
NeuQuant::Learn(image_number)
NeuQuant::UnbiasNet(*palette)
NeuQuant::InxBuild()
GetObject_(hImageIn,SizeOf(BITMAP),bmp32.BITMAP)
With bmp32
w = \bmWidth
h = \bmHeight
bitsptr_in = \bmBits
sz_colorbits_in = \bmWidthBytes * bmp32\bmHeight
wb_in = \bmWidthBytes
EndWith
With bmi8.BITMAPINFO
\bmiHeader\biSize = SizeOf(BITMAPINFOHEADER)
\bmiHeader\biWidth = w
\bmiHeader\biHeight = h
\bmiHeader\biPlanes = 1
\bmiHeader\biBitCount = 8
EndWith
hdcDest = CreateCompatibleDC_(0)
hImageOut = CreateDIBSection_(hdcDest, @bmi8, #DIB_PAL_COLORS, @ppvbits, 0, 0)
SelectObject_(hdcDest, hImageOut)
GdiFlush_()
SetDIBColorTable_(hdcDest,0,256,*palette)
DeleteDC_(hdcDest)
GetObject_(hImageOut, SizeOf(BITMAP), @bmp8.BITMAP)
With bmp8
wb_out = \bmWidthBytes
bitsptr_out = \bmBits
EndWith
StartDrawing(ImageOutput(image_number))
max_x = w - 1
max_y = h - 1
For y = 0 To max_y
For x = 0 To max_x
index.a = NeuQuant::InxSearch(NeuQuant::PointOrdDith(x, y)) ; comment this line out if uncommenting the next 2
;thiscolor = GetPixel32BitImage(x, y)
;index.a = NeuQuant::InxSearch(thiscolor)
SetPixel8BitImage(x, y, index)
Next
Next
StopDrawing()
FreeMemory(*palette)
ProcedureReturn hImageOut
EndProcedure
;////////////////////////////////////////////////////
; TEST CODE
;////////////////////////////////////////////////////
file$ = GetTemporaryDirectory()+"girl.jpg"
If FileSize(file$) = -1
InitNetwork()
If Not ReceiveHTTPFile("http://www.lloydsplace.com/girl.jpg", file$)
MessageRequester("oops!","Problem getting image... quitting")
EndIf
EndIf
UseJPEGImageDecoder()
image_number = LoadImage(#PB_Any, "girl.jpg")
w=ImageWidth(image_number)
h=ImageHeight(image_number)
result = ImageTo8bit(image_number)
; Let's take a look at the results...
OpenWindow(0,0,0,w,h,"")
ImageGadget(0,0,0,0,0,result)
Repeat:EventID = WaitWindowEvent():Until EventID = #PB_Event_CloseWindow