#AutoIt3Wrapper_UseX64=n                          ; 32Bit-Modus!
#Region ;************ Includes ************
#include-once
#include <GDIPlus.au3>
#include <Memory.au3>
#EndRegion ;************ Includes ************
#Region ASM-Code
#cs _CountUniqueColors                            ;
	Use32                                         ; 32Bit Modus!
	mov esi,dword[esp+4]                          ; Pixelstruct-Pointer holen
	mov ecx,dword[esp+8]                          ; Anzahl der Pixel holen (Pixelcounter)
	mov edi,dword[esp+12]                         ; Colorstruct-Pointer holen
	xor eax,eax                                   ; eax als Farbzaehler (auf null setzen)
	@pixel_count:                                 ; Anfang der Schleife fuer alle Pixel
	mov ebx,[esi]                                 ; Farbwert aus Pixelstruct holen
	and ebx,0xffffff                              ; Alphachannel eliminieren
	cmp byte[edi+ebx],0                           ; Wert aus der Colorstruct = 0?
	jnz @next                                     ; wenn nicht 0, dann wurde die Farbe bereits gezaehlt, weiter -> @next
	inc eax                                       ; den Farbzaehler um eins erhoehen
	mov byte[edi+ebx],1                           ; den Wert in der Colorstruct auf 1 setzen
	@next:
	add esi,4                                     ; den Pixelstruct-Pointer um 4 erhoehen (naechstes DWORD)
	dec ecx                                       ; Pixelcounter um eins verringern
	jnz @pixel_count                              ; wenn Pixelcount nocht nicht 0, dann Schleife wiederholen
	ret                                           ; eax (Farbzaehler) wird zurueckgegeben
#ce
#EndRegion ASM-Code
; $__IGUC_g_bCode entspricht dem obigen ASM-Code im Binaerformat
Global Const $__IGUC_g_bCode = '0x8B7424048B4C24088B7C240C31C08B1E81E3FFFFFF00803C1F00750540C6041F0183C6044975E7C3'
; Die Speichergroesse fuer den ASM-Code berechnen
Global Const $__IGUC_g_iMemSize = StringLen($__IGUC_g_bCode) / 2 - 1
; Achtung! Hier unbedingt virtuellen Speicher mit "_MemVirtualAlloc" anfordern, weil sonst
; (bei eingeschalteter Datenausfuehrungsverhinderung = DEP) AutoIt mit einer Fehlermeldung beendet wird.
Global Const $__IGUC_g_pMem = _MemVirtualAlloc(0, $__IGUC_g_iMemSize, $MEM_COMMIT, $PAGE_EXECUTE_READWRITE)
If $__IGUC_g_pMem = 0 Then Exit MsgBox(16, 'Error!', "Can't allocate virtual memory!")
; Struktur fuer den ASM-Code im virtuellen Speicher erstellen
Global $__IGUC_g_tCodeBuffer = DllStructCreate('byte[' & $__IGUC_g_iMemSize & ']', $__IGUC_g_pMem)
; den ASM-Code in den Speicher schreiben (wird unten bei DllCallAddress aufgerufen)
DllStructSetData($__IGUC_g_tCodeBuffer, 1, $__IGUC_g_bCode)
OnAutoItExitRegister('__IGUC_Exit')
_GDIPlus_Startup()
Func __IGUC_Exit()
	_MemVirtualFree($__IGUC_g_pMem, $__IGUC_g_iMemSize, $MEM_DECOMMIT)
	$__IGUC_g_tCodeBuffer = 0
	_GDIPlus_Shutdown()
EndFunc   ;==>__IGUC_Exit
Func _GDIPlus_ImageGetUniqueColors(ByRef $hImage)
	Local $aDim, $tBitmapData, $tPixel, $pPixel, $tColors, $pColors, $aRet, $iError = 0
	$aDim =  _GDIPlus_ImageGetDimension($hImage)
	$tBitmapData = _GDIPlus_BitmapLockBits($hImage, 0, 0, $aDim[0], $aDim[1], $GDIP_ILMREAD, $GDIP_PXF32PARGB)
	If @error Then Return SetError(@error, 0, -1)
	$tPixel = DllStructCreate('dword[' & $tBitmapData.Width * $tBitmapData.Height & '];', $tBitmapData.Scan0) ; Pixelstruct (dword = 32 Bit pro Pixel)
	If @error Then Return SetError(10 + @error, 0, -1)
	$pPixel = DllStructGetPtr($tPixel)
	$tColors = DllStructCreate('byte[' & 0xffffff + 1 & '];') ; Colorstruct (1 Byte pro Farbwert)
	If @error Then Return SetError(20 + @error, 0, -1)
	$pColors = DllStructGetPtr($tColors)
	$aRet = DllCallAddress('uint:cdecl', DllStructGetPtr($__IGUC_g_tCodeBuffer), 'ptr', $pPixel, 'dword', $tBitmapData.Width * $tBitmapData.Height, 'ptr', $pColors)
	$iError = 30 + @error
	_GDIPlus_BitmapUnlockBits($hImage, $tBitmapData)
	$tColors = 0
	$tPixel = 0
	$tBitmapData = 0
	Return SetError($iError, 0, (IsArray($aRet) ? $aRet[0] : -1))
EndFunc   ;==>_GDIPlus_ImageGetUniqueColors