Looks really interesting!
A couple of ASM-newbie questions: Is this for Windows only? Is there a way to detect if SSE2 is available? And if it's not available, what would be a fallback solution that would still work with the provided "framework"?
ColorMatrix filter
Re: ColorMatrix filter
If any of you native English speakers have any suggestions for the above text, please let me know (via PM). Thanks!
Re: ColorMatrix filter
The code is cross platform. I tested it on OS X and Windows but I see no reason why it shouldn't work on Linux also.c4s wrote:Looks really interesting!
A couple of ASM-newbie questions: Is this for Windows only? Is there a way to detect if SSE2 is available? And if it's not available, what would be a fallback solution that would still work with the provided "framework"?
You can detect if SSE2 is supported
Code: Select all
Procedure HasSSE2()
!mov eax, 1
!cpuid
!xor eax, eax
!bt edx, 26
!rcl eax, 1
ProcedureReturn
EndProcedure
Debug HasSSE2()
It might not be good but personally I don't code fallbacks for SSE2. I just tell it requires SSE2.
My main OS is OS X and all Intel Macs have SSE2. Windows 8 also requires SSE2.
Intel introduced SSE2 in 2001, AMD followed in 2003.
SSE2 has a lot of advantages. For the few people that still use a 10 year old computer ... sorry

Windows (x64)
Raspberry Pi OS (Arm64)
Raspberry Pi OS (Arm64)
Re: ColorMatrix filter
Just for once a fallback and some comparisons.
Fallback for CM_Apply
Speed comparison of a 32 bit image with 3488 x 2616 pixels on OS X
Point / Plot without a filter : 336 ms
Point / Plot with CM_Apply (SSE2) : 486 ms
Point / Plot with CM_Apply fallback (No SSE2) : 1094 ms
CM_ApplyToImage (SSE2) : 40 ms
You see that the SSE2 routine optimized for 32 bit images working directly on the drawing buffer is over 25x faster compared to the fallback routine.
Fallback for CM_Apply
Code: Select all
Procedure.l CM_ApplyNoSSE2(Color.l, *Filter.CM_Filter)
Protected.f r, r0, g, g0, b, b0, a, a0
Protected *M.CM_Matrix = (*Filter + 15) & -16
r0 = Red(Color)
g0 = Green(Color)
b0 = Blue(Color)
a0 = Alpha(Color)
r = *M\m[0] * r0 + *M\m[4] * g0 + *M\m[8] * b0 + *M\m[12] * a0 + *M\m[16]
g = *M\m[1] * r0 + *M\m[5] * g0 + *M\m[9] * b0 + *M\m[13] * a0 + *M\m[17]
b = *M\m[2] * r0 + *M\m[6] * g0 + *M\m[10] * b0 + *M\m[14] * a0 + *M\m[18]
a = *M\m[3] * r0 + *M\m[7] * g0 + *M\m[11] * b0 + *M\m[15] * a0 + *M\m[19]
If r < 0 : r = 0 : EndIf
If g < 0 : g = 0 : EndIf
If b < 0 : b = 0 : EndIf
If a < 0 : a = 0 : EndIf
If r > 255 : r = 255 : EndIf
If g > 255 : g = 255 : EndIf
If b > 255 : b = 255 : EndIf
If a > 255 : a = 255 : EndIf
ProcedureReturn RGBA(r, g, b, a)
EndProcedure
Point / Plot without a filter : 336 ms
Point / Plot with CM_Apply (SSE2) : 486 ms
Point / Plot with CM_Apply fallback (No SSE2) : 1094 ms
CM_ApplyToImage (SSE2) : 40 ms
You see that the SSE2 routine optimized for 32 bit images working directly on the drawing buffer is over 25x faster compared to the fallback routine.
Last edited by wilbert on Fri Aug 09, 2013 11:40 am, edited 1 time in total.
Windows (x64)
Raspberry Pi OS (Arm64)
Raspberry Pi OS (Arm64)
Re: ColorMatrix filter
@wilbert
Thanks for your reply and the explanation (edit: and the code
).
The reason I'm asking for a fallback isn't really to support old computers but rather that I don't understand too much of ASM. I would appreciate a PB-only solution simply for the sake of understanding what's going on under the hood...
Thanks for your reply and the explanation (edit: and the code

The reason I'm asking for a fallback isn't really to support old computers but rather that I don't understand too much of ASM. I would appreciate a PB-only solution simply for the sake of understanding what's going on under the hood...
If any of you native English speakers have any suggestions for the above text, please let me know (via PM). Thanks!
- BasicallyPure
- Enthusiast
- Posts: 539
- Joined: Thu Mar 24, 2011 12:40 am
- Location: Iowa, USA
Re: ColorMatrix filter
I have updated the code for my demo program.
It seems to be working as intended now.
I still want to add the 'save as' option.
@Wilbert,
I found a problem with your CM_ApplyToImage() procedure.
What is the 'Black and White' filter exactly?
It is not really monochrome but seems to be a different form of gray scale.
BP.
edit:
Experimenting with the Black and White reveals that it is like a grayscale with very high contrast.
You can get something similar by using grayscale then adjusting contrast to maximum then adjusting
contrast to maximum again.
I find that decreasing brightness some before using Black and White gives better results.
It seems to be working as intended now.
I still want to add the 'save as' option.
@Wilbert,
I found a problem with your CM_ApplyToImage() procedure.
Code: Select all
Procedure CM_ApplyToImage(Image, *Filter.CM_Filter)
Protected.i w, x, y, max_x, max_y
Protected.i addr, pitch, byte_order
;If StartDrawing(ImageOutput(0)) ; <--- this is wrong
If StartDrawing(ImageOutput(Image)) ; <--- this is what it should be
w = OutputWidth()
max_y = OutputHeight() - 1
It is not really monochrome but seems to be a different form of gray scale.
BP.
edit:
Experimenting with the Black and White reveals that it is like a grayscale with very high contrast.
You can get something similar by using grayscale then adjusting contrast to maximum then adjusting
contrast to maximum again.
I find that decreasing brightness some before using Black and White gives better results.
BasicallyPure
Until you know everything you know nothing, all you have is what you believe.
Until you know everything you know nothing, all you have is what you believe.
Re: ColorMatrix filter
Thanks for pointing out the bug in the code. I corrected it.BasicallyPure wrote:What is the 'Black and White' filter exactly?
It is not really monochrome but seems to be a different form of gray scale.
The black and white filter is just one I found on the internet as it is

Windows (x64)
Raspberry Pi OS (Arm64)
Raspberry Pi OS (Arm64)