One of those many ASM Gems, you need - or not.
In this case, you see an example how to deal with ASM and BYREF Parameter.
' inverts the color BYREF
' May not work if the colour includes Alpha-channels, because the whole number is been inverted.
'
' invertiert variable mit farbwert (Komplemtärfarbe durch invertierung (NOT) Rückgabe BYREF
SUB X_HP(BYREF rgbColor AS LONG)
!mov eax,rgbColor ' eax hat 24-bit farbe
!mov ecx,[eax] ' get Value from BYREF
!not ecx ' Farbe invertieren
!mov ebx,rgbColor
!mov [ebx],ecx
END SUB
In DisASM things look like expected.
4023CA 8B4508 MOV EAX, DWORD PTR [EBP+08]
4023CD 8B08 MOV ECX, DWORD PTR [EAX]
4023CF F7D1 NOT ECX
4023D1 8B5D08 MOV EBX, DWORD PTR [EBP+08]
4023D4 890B MOV DWORD PTR [EBX], ECX
4023D6 8D65F4 LEA ESP, DWORD PTR [EBP-0C]
4023D9 5F POP EDI
4023DA 5E POP ESI
4023DB 5B POP EBX
4023DC 5D POP EBP
4023DD C20400 RET NEAR 0004
Here is another one, which returns the colours in RGB.
' returns INVERSE Colour from 24-bit in RGB Parts
'
SUB X_HN(BYVAL rgbColor AS LONG,BYREF Red AS BYTE,BYREF Green AS BYTE,BYREF Blue AS BYTE)
!mov eax,rgbColor ' eax hat 24-bit farbe
!not eax ' Farbe invertieren
!mov rgbColor,eax
!mov eax,rgbColor
!mov ebx,Red
!mov [ebx],al
!shr eax,8
!mov ebx,Green
!mov [ebx],al
!shr eax,8
!mov ebx,Blue
!mov [ebx],al
END SUB
Here is a trick for preserving the alpha channel while inverting the r g b.
instead of NOT ecx
!xor ecx &h00ffffff
And if you are preparing an image for display in Opengl, the R and B bytes need to be swapped so instead of MOVing the whole 32 bit word:
!mov cl, [eax]
!mov ch,[eax+2]
!mov [eax+2],cl
!mov [eax],ch
@Charles,
I have just added the code tags for better readability.
Can you provide the complete Subroutine, then people can just copy and paste it?
I was just offering suggestions rather than code, Theo :)
Currently I am without Microsoft or Powerbasic, working on a dedicated Linux box. Do you mind examples in Freebasic? I dont want to confuse anyone. There are a few differences, some subtle.
I don't Mind Freebasic, just have the wish, that you make a note in the title like this:
(FREEBASIC) titletext ....
then noone will be confused that it doesnt compile "as is" with PB.
While I can do that also :-).
' returns INVERSE Colour from 24-bit in RGB Parts, preserves Alpha-Channel
'
SUB X_HN(BYVAL rgbColor AS LONG,BYREF Red AS BYTE,BYREF Green AS BYTE,BYREF Blue AS BYTE)
!mov eax,rgbColor ' eax hat 24-bit farbe
!xor eax &h00ffffff
!mov rgbColor,eax
!mov eax,rgbColor
!mov ebx,Red
!mov [ebx],al
!shr eax,8
!mov ebx,Green
!mov [ebx],al
!shr eax,8
!mov ebx,Blue
!mov [ebx],al
END SUB
This does an entire image in one go.
Supposing your image is held in an array of LONG integers:
Pass the location of he start of the image and the number of pixels:
Example:
InvertImage(varptr(img(0)), 60000 )
PS: I have just optimised the routine by operating directly on the pixels without loading them into the eax register.
' Converts a 32 bit RGBA Image into its INVERSE Colour while preserving the Alpha-Channel
'
SUB InvertImage(BYVAL image AS LONG PTR, BYVAL size AS LONG)
! mov edx, image
! mov ecx,size
' safety checks
! cmp edx, 0
! jle xit
! cmp ecx, 0
! jle xit
' main code
nextpixel:
! xor [edx], &h00ffffff
! add edx, 4
! dec ecx
! jg nextpixel
xit:
END SUB