Page 2 of 2

Re: ColorMatrix filter

Posted: Fri Aug 09, 2013 9:58 am
by c4s
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"?

Re: ColorMatrix filter

Posted: Fri Aug 09, 2013 10:42 am
by wilbert
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"?
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.

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()
You could create a similar filter using PureBasic code only as a fallback but it would be much slower.
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 :(

Re: ColorMatrix filter

Posted: Fri Aug 09, 2013 11:12 am
by wilbert
Just for once a fallback and some comparisons.

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
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.

Re: ColorMatrix filter

Posted: Fri Aug 09, 2013 11:13 am
by c4s
@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...

Re: ColorMatrix filter

Posted: Fri Aug 09, 2013 10:42 pm
by BasicallyPure
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.

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
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.

Re: ColorMatrix filter

Posted: Sat Aug 10, 2013 7:29 am
by wilbert
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.
Thanks for pointing out the bug in the code. I corrected it.
The black and white filter is just one I found on the internet as it is :wink: