Ever since DarkMode I’ve had the 2 functions below to make pictures darker or lighter. There is one (!) instance where the function makes a very strange NOE.
The debugger shows me that MakeDarkerInner gives a picture back. But when making a new picture out of pp I can see that both pictures in pp are nil.
Xojo 2020r2.1, tested on Mojave and BS. The same code works fine in 2019r3.
Does anyone have an idea what I’m doing wrong?
Protected Function MakeDarker(original as Picture, amount as double) as Picture
Dim n As Integer=original.ImageCount
If n=0 Then
Return MakeDarkerInner(original, amount)
Else
Dim pp() As Picture
n=n-1
for i as integer=0 to n
pp.Add MakeDarkerInner(original.ImageAt(i), amount)
Next
Return new Picture(original.Width, original.Height, pp)
End If
End Function
Private Function MakeDarkerInner(OriginalPicture as Picture, theAmount as Double) as Picture
'change the value (lighter or darker) for the Original Picture
Dim OriginalHeight As Integer = OriginalPicture.height
Dim OriginalWidth As Integer = OriginalPicture.width
Dim OriginalRGBS As RGBSurface = OriginalPicture.RGBSurface
dim ResultPicture as new Picture(OriginalPicture.Width, OriginalPicture.Height, 32)
dim ResultRGBS as RGBSurface = ResultPicture.RGBSurface
for currentX as Integer = 0 to OriginalWidth
for currentY as Integer = 0 to OriginalHeight
dim theColor as Color = OriginalRGBS.Pixel(currentX, currentY)
ResultRGBS.Pixel(currentX, CurrentY) = HSV(theColor.Hue, theColor.Saturation, theColor.Value * theAmount)
next
next
ResultPicture.ApplyMask OriginalPicture.CopyMask
End Function
Jeff is right, you have a bad OBOE (off by one error).
you should always iterate Y first, and then X on the inner loop - this takes advantage of the fact that X pixels are next to each other in memory. Depending on picture size, this can provide a good speedup
#pragma DisableBackgroundTasks // always good for tight loops
Here is corrected code:
#pragma DisableBackgroundTasks // this will give you a 2x-10x speedup
for currentY as Integer = 0 to OriginalHeight-1
for currentX as Integer = 0 to OriginalWidth-1
dim theColor as Color = OriginalRGBS.Pixel(currentX, currentY)
ResultRGBS.Pixel(currentX, CurrentY) = HSV(theColor.Hue, theColor.Saturation, theColor.Value * theAmount, theColor.Alpha)
next
next
I suspect what’s happening is that with some picture sizes, the OBOE is causing a silent internal fault, but with some picture sizes it’s OK?
I’ve never used PIctures with multiple images so I don’t know, but I suspect Sam’s comment about not mixing the old style New Picture(w,h,32) and new style New Picture(w,h) constructors could be relevant. Did you make that change?