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.
Posted on 2004-08-12 06:11:27 by donkey
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.
Posted on 2004-08-12 09:34:18 by djinn

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
Posted on 2004-08-12 18:07:30 by Relvinian