Theo's Forum

IT-Consultant: Charles Pegge => Assembler => Assembly Programming => Topic started by: Theo Gottwald on June 06, 2007, 02:46:05 PM

Title: (ASM) Calculating the Inverse colour of a 24-bit colour
Post by: Theo Gottwald on June 06, 2007, 02:46:05 PM
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.

Code: [Select]
' 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.

Code: [Select]
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.

Code: [Select]
' 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
         
Title: Re: (ASM) Calculating the Inverse colour of a 24-bit colour
Post by: Charles Pegge on June 06, 2007, 09:01:35 PM
Here is a trick for preserving the alpha channel while inverting the r g b.
instead of NOT ecx

Code: [Select]
!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:
Code: [Select]

!mov cl, [eax]
!mov ch,[eax+2]
!mov [eax+2],cl
!mov [eax],ch

Title: Re: (ASM) Calculating the Inverse colour of a 24-bit colour
Post by: Theo Gottwald on June 06, 2007, 10:28:54 PM
@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?
Title: Re: (ASM) Calculating the Inverse colour of a 24-bit colour
Post by: Charles Pegge on June 07, 2007, 12:28:18 AM
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.
Title: Re: (ASM) Calculating the Inverse colour of a 24-bit colour
Post by: Theo Gottwald on June 08, 2007, 08:43:15 AM
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 :-).

Code: [Select]
' 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
Title: Re: (ASM) Calculating the Inverse colour of a 24-bit colour
Post by: Charles Pegge on June 08, 2007, 09:58:08 AM
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.

Code: [Select]
' 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