BTW, just FYI the Griffon image is 1.75MB ~128,000 colors and the function requires 21MB of memory to count the colors :) But other larger images with less colors saw that drop off sharply. A 1024x768 image with around 11,000 colors only required 6MB.
hi donkey,
I could be way off base here, but try allocating/reallocating a heap 4k bigger than what you will actually use therefor not possible to access non-existing page.
I could be way off base here, but try allocating/reallocating a heap 4k bigger than what you will actually use therefor not possible to access non-existing page.
BTW, just FYI the Griffon image is 1.75MB ~128,000 colors and the function requires 21MB of memory to count the colors :) But other larger images with less colors saw that drop off sharply. A 1024x768 image with around 11,000 colors only required 6MB.
Yep, that is one major drawback with this algo that I posted. Even a bitmap all black will take 256k + 256 bytes to give a count of one. :(
I've been playing with it on my machine and have a ASM version that's some what hand tuned which works well from the source I posted. Here's my version.
TITLE ColorCount.asm
.486
.model flat
extern __imp__GetProcessHeap@0:near
extern __imp__HeapAlloc@12:near
extern __imp__HeapFree@12:near
.code
; ----------------------------------------------------------------------------
; prototype:
; int __stdcall CountColors(LPVOID pRawPixelData, int Width, int Height);
;
; Description:
; Returns the count of unique colors in a given image.
;
; Params:
; - A pointer to the raw pixel data in 32-bit format (ARGB) or (BGRA)
; - Width of image
; - Height of image
; ----------------------------------------------------------------------------
align 16
_CountColors@12 PROC NEAR
push ecx
push ebx
push ebp
push esi
push edi
call DWORD PTR __imp__GetProcessHeap@0
mov ebx, eax
mov esi, [esp+24]
push 262144
push 8
push eax
call dword ptr __imp__HeapAlloc@12
mov ecx, [esp+28]
imul ecx, [esp+32]
mov [esp+16], eax
lea ebp, [esi+ecx*4]
align 4
ExaminePixel:
movzx edx, WORD PTR [esi]
cmp DWORD PTR [eax+edx*4], 0
lea edi, [eax+edx*4]
jne SHORT NoSubAlloc
push 256
push 8
push ebx
call dword ptr __imp__HeapAlloc@12
mov [edi], eax
mov eax, [esp+16]
NoSubAlloc:
movzx ecx, BYTE PTR [esi+2]
mov edx, [edi]
add esi, 4
cmp esi, ebp
mov BYTE PTR [ecx+edx], 1
jb SHORT ExaminePixel
xor esi, esi
mov edi, eax
lea ebp, [eax+262144]
align 4
AddCounts:
mov ecx, [edi]
test ecx, ecx
je SHORT NotAllocated
mov eax, 255
align 4
CountSubArray:
cmp BYTE PTR [ecx+eax], 0
je SHORT @F
add esi, 1
@@:
sub eax, 1
jns short CountSubArray
push ecx
push 0
push ebx
call dword ptr __imp__HeapFree@12
NotAllocated:
add edi, 4
cmp edi, ebp
jb SHORT AddCounts
push [esp+16]
push 0
push ebx
call dword ptr __imp__HeapFree@12
mov eax, esi
pop edi
pop esi
pop ebp
pop ebx
pop ecx
ret 12
_CountColors@12 ENDP
END
Relvinian