Author Topic: (ASM) Calculating the Inverse colour of a 24-bit colour  (Read 8822 times)

0 Members and 1 Guest are viewing this topic.

Theo Gottwald

• Hero Member
• Posts: 1060
• User-Rate: +30/-4
• Gender:
(ASM) Calculating the Inverse colour of a 24-bit colour
« 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 BYREFSUB 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],ecxEND 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  ECX4023D1 8B5D08                 MOV EBX, DWORD PTR [EBP+08]4023D4 890B                   MOV DWORD PTR [EBX], ECX4023D6 8D65F4                 LEA ESP, DWORD PTR [EBP-0C]4023D9 5F                     POP EDI4023DA 5E                     POP ESI4023DB 5B                     POP EBX4023DC 5D                     POP EBP4023DD 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],alEND SUB         `
« Last Edit: June 06, 2007, 02:59:00 PM by Theo Gottwald »

Charles Pegge

• Global Moderator
• Hero Member
• Posts: 883
• User-Rate: +33/-1
Re: (ASM) Calculating the Inverse colour of a 24-bit colour
« Reply #1 on: June 06, 2007, 09:01:35 PM »
Here is a trick for preserving the alpha channel while inverting the r g b.

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`
« Last Edit: June 07, 2007, 12:01:18 AM by Charles Pegge »

Theo Gottwald

• Hero Member
• Posts: 1060
• User-Rate: +30/-4
• Gender:
Re: (ASM) Calculating the Inverse colour of a 24-bit colour
« Reply #2 on: June 06, 2007, 10:28:54 PM »
@Charles,
Can you provide the complete Subroutine, then people can just copy and paste it?

Charles Pegge

• Global Moderator
• Hero Member
• Posts: 883
• User-Rate: +33/-1
Re: (ASM) Calculating the Inverse colour of a 24-bit colour
« Reply #3 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.
« Last Edit: June 07, 2007, 12:40:18 AM by Charles Pegge »

Theo Gottwald

• Hero Member
• Posts: 1060
• User-Rate: +30/-4
• Gender:
Re: (ASM) Calculating the Inverse colour of a 24-bit colour
« Reply #4 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],alEND SUB`
« Last Edit: June 08, 2007, 08:46:10 AM by Theo Gottwald »

Charles Pegge

• Global Moderator
• Hero Member
• Posts: 883
• User-Rate: +33/-1
Re: (ASM) Calculating the Inverse colour of a 24-bit colour
« Reply #5 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 codenextpixel:  ! xor [edx], &h00ffffff  ! add edx, 4  ! dec ecx  ! jg nextpixelxit:END SUB`
« Last Edit: June 08, 2007, 10:26:05 AM by Charles Pegge »