iblis gave me the code to check (scan the pic) the most used color and the number of times it is used in the pic

is there any methode to do the same but to class each color with numbers of times and have the 2,3,4,.. most used colors....

something like coulref(coulnum,usedtime)
Posted on 2002-11-04 08:37:59 by Thor0Asgard
Maybe something like this will work:
COLORCOUNT STRUCT

sum dd ?
color dd ?
COLORCOUNT ENDS


ColorCounts COLORCOUNT 256 dup (?)


CountColors PROC USES esi, pBuffer:DWORD, iLength:DWORD

; Initialize Array
xor eax, eax
mov ecx, 255
mov edx, OFFSET ColorCounts
ASSUME edx:PTR COLORCOUNT
_0: mov [edx+ecx*8].sum, eax
mov [edx+ecx*8].color, ecx
dec ecx
jns _0

; Count bytes
mov ecx, iLength
mov esi, pBuffer
dec ecx
js _x
_4: movzx eax, BYTE PTR [esi+ecx]
sub ecx, 1
inc DWORD PTR [edx+eax*8].sum
jnc _4

; Bubble Sort Array
ITEM EQU <edx+ecx*8>
NEXT EQU <edx+ecx*8+8>
mov esi, 254
_5: mov ecx, esi
_6: mov eax, [ITEM].sum
cmp eax, [NEXT].sum
jge _7
xchg eax, [NEXT].sum
mov [ITEM].sum, eax
mov eax, [ITEM].color
xchg eax, [NEXT].color
mov [ITEM].color, eax
_7: dec ecx
jns _6
add edx, 8
dec esi
jns _5
ASSUME edx:NOTHING
_x: ret

CountColors ENDP
I've just whipped it up during my break here at work - hasn't been assembled or tested - let me know how it does? :) Also, this has been coded to get the job done - optimization will come later. My initial thoughts on your code above was this is the problem you wanted to solve rather than the single greater color problem - this is really a common thing to do for many tasks.
Posted on 2002-11-04 10:29:41 by bitRAKE
Sorry, haven't had time to follow the thread.. but, why sort?

It could be done like this:

Declare a 256 entries table of e.g. dwords, initialize it to all zeros. Call it Counts.

loop:
if (len<=0) then exit

Get a pixel.. use it as index to the Counts table.

Increment the corresponding table element.

Check if (once incremented) it's > than MaxCount.. if yes then set MaxCount to it, and MaxCountIndex to the index.

decrement len
goto loop



Sorry if I wrote something obvious that has already been written in the thread.. gotta run now.

Take care,
Maverick
Posted on 2002-11-04 10:52:13 by Maverick
Maverick, we have crossed that bridge. Now we are trying for the 1st greatest color, the 2nd greatest color, 3rd, 4th, etc... It can be done without sorting, but it would mean multiple scans of the array and flagging previous retrieved values. IMHO, much more can be done with the sorted array of color counts. Additionally, I am not fully aware of where Thor0Asgard is heading with this project.
Posted on 2002-11-04 11:16:56 by bitRAKE
iblis,
you don't need to use manipulations with esp in your proc.
Posted on 2002-11-04 14:05:53 by The Svin
1st thanks all for your help
and sorry for my bad english
i'll try to explain what i whant to do.

1) i scan a 256 bitmap to find which color is the most used and the number of ocurences
2) with specific layer i map( do not know if map is the wright term) some data (a file or some text or everything else
into my pic by changing the code of the color by one non used in the pic after set the rgb as the ones of my 'color ref'.

so i modify the pic but it's visualy the same one and with an hex editor it's not simple to see that it's a special pic 'cause the're no attachement and the format is thr real one.

that's the interrest of my prog. after i can use some encryption but it's a fine start for me.

assuming each byte is split into 8 bytes (1 or 0) and do something like this
if it's 0 use orginal color code else use one of the nonused one

and with the layer made before retreive the data.

for example i'e got a pic 'called it image4.bmp'
the color 0 is the most used and it is use 49110 times so i can store 6138 bytes into with the 1st non use color but if i can have the 2nd most use color maybe i can optimize the space into the pic


thanks to help me...
Posted on 2002-11-04 14:06:31 by Thor0Asgard
Hi bitRAKE :)
Maverick, we have crossed that bridge. Now we are trying for the 1st greatest color, the 2nd greatest color, 3rd, 4th, etc... It can be done without sorting, but it would mean multiple scans of the array and flagging previous retrieved values. IMHO, much more can be done with the sorted array of color counts. Additionally, I am not fully aware of where Thor0Asgard is heading with this project.

I see.. sorry for my post then, I was in a hurry and couldn't read carefully all the posts. :(

I'm making myself tired now trying to implement some sort of strong typing in C++ for simple int derived types. I hate that language at times.
Posted on 2002-11-04 15:18:03 by Maverick

iblis,
you don't need to use manipulations with esp in your proc.



Why? What's so bad about using esp if you do it right? I want to know these things. ;)

Keep in mind, I'm not an Anger Fog worshipping optimization guru, obsessed with squaring the circle, spending hours upon hours shaving off infinitesimal clock cycles from my code. I prefer code that's solid and workable over code that's excessively fast. I realize that this makes me a bad programmer and inferior to many people here, but I make no claims to being a good programmer, and I'm always willing to learn and I help out when I can.

Thor0Asgard needed help so I did my best. That's all I can do.
Posted on 2002-11-04 18:13:03 by iblis
you proc is 100% working and it's very fast

here's a dump of your table for one of my pic

because it has 2 non used color i'll can use the 2 most used colors for my algo

so there's 67505 pixels to use,18395 more with the 2nd color

it'll represent 8438 bytes so 2300 bytes more with the 2nd color

thanks again the your great help..


you're a strong coder
Posted on 2002-11-05 06:28:22 by Thor0Asgard
What's so bad about using esp if you do it right?

I mean you can use
mov ecx,
mov edi,
instead of
mov edi,
mov ecx,
it is 8 byte shorter.

Let say that value of esp at the start of your proc = x
Then return address = x
arg1 = x+4
arg2 = x+8
after pushing 4 reg with changes esp = x - 16 or x = esp+16
then now
arg1=esp+16+4=esp+20
arg2=esp+16+8=esp+24

Now you want to use some space in range from esp-1024 to esp(excluding)
At the end of stosd edi will have address = esp-1024+256*4=esp
and you even can you it as base pointer to arg instead of esp
Note that
mov edi,
mov ecx,
is 8 bytes more! then
mov ecx,
mov edi,

because shift offset value < 128 and byte will be use in opcode instead of dword as in your
version.
Posted on 2002-11-05 17:07:34 by The Svin
Doh! /smacks forehead.

Yup. I'm just so used to using esp to reference stack data. It didn't even occur to me.

Thanks. ;)
Posted on 2002-11-05 17:37:00 by iblis
Sorry I am late to this thread. I just registered yesterday. Here is my contribution to the problem. I use the first loop to count the colors and the second loop to select the highest count. Ratch

B EQU BYTE PTR
D EQU DWORD PTR
@ EQU OFFSET

LOCVAR1 STRUC ;structure for local variable
BINS DD 256 DUP (?)
LOCVAR1 ENDS

STKVAR1 STRUC ;structure for parameters
SRCPIC DD ?
COULNUM DD ?
MAXCOUNT DD ?
STKVAR1 ENDS

.DATA?
COULNUM DD ? ;color of max count
MAXCOUNT DD ? ;max count

.DATA
SRCPIC DB 8,8,8,4,5,0,0,5,6,7
DB 246 DUP (7)

.CODE
MAIN:
INVOKIT CHECKMAXCOUL,@ SRCPIC,@ COULNUM,@ MAXCOUNT ;call the subroutine

MOV EAX,
MOV ECX,

XOR EAX,EAX
; INVOKE ;return back to windows callback routine
INVOKE ExitProcess,EAX

;------------------------------------------------------------------------------
; Subroutine begins here
;------------------------------------------------------------------------------
CHECKMAXCOUL:
P1 EQU 3*4+4+ESP.STKVAR1 ;stack variables+return address+3 saved registers

PUSHIT EBX,ESI,EDI ;save the critical windows registers

MOV ESI, ;load the address

SUB ESP,LOCVAR1 ;make room for local variables

MOV ECX,256 ;load the counter
XOR EAX,EAX
MOV EDI,ESP ;ESP=address of BINS table
REP STOSD ;zero fill BINS table

MOV ECX,256/4 ;load the counter
;get a count of each of the 256 colors
.REPEAT
LODSD ;load next 4 bytes
MOVZX EDX,AL ;expand byte
INC D ;increment counter of bin
SHR EAX,8 ;shift to next byte
MOVZX EDX,AL ;expand byte
INC D ;increment counter of bin
SHR EAX,8 ;shift to next byte
MOVZX EDX,AL ;expand byte
INC D ;increment counter of bin
SHR EAX,8 ;shift to next byte
MOVZX EDX,AL ;expand byte
INC D ;increment counter of bin
DEC ECX
.UNTIL ZERO?
;find the highest count
MOV ESI,ESP ;ESP=adr of BINS
MOV ECX,256
XOR EDX,EDX ;comparison for MAXCOUNT starting at zero

.REPEAT
LODSD
.IF EAX > EDX ;check if higher number found in bin
LEA EBX, ;subtrace overshoot
MOV EDX,EAX ;new MAXCOUNT
SUB EBX,ESP ;new COULNUM
.ENDIF
DEC ECX
.UNTIL ZERO?

ADD ESP,LOCVAR1 ;recover local variable space

MOV ,EDX
MOV ,EBX

POPIT EDI,ESI,EBX ;restore critical windows registers
RET STKVAR1 ;return and recover the stack variable space
END MAIN
Posted on 2002-11-10 12:19:27 by Ratch