Slowdown when putting symbols into image data
William Prothero
prothero at earthednet.org
Tue Sep 9 12:40:39 EDT 2014
Folks:
Drawing symbols on an image, in my app, has gone up a factor of 10, from 2.25 seconds in version 6.6.2 to 24 seconds in version 7.0RC1. I’m on OSX, Mavericks. This is a significant slowdown. The slowdown occurs in the drawSymbol method. If I comment it out, so all the operations happen without actually drawing the symbol, the speed without drawing the symbol is 4.55 seconds in v7.0. I can tolerate the delay from 2.25 to 4.55 seconds, but the symbol drawing routine slowdown is quite significant and I’d like to see it speeded up.
My drawing code is derived from Colin’s SimplePaint program, modified for byte operations. The drawing code is below. First an array of the symbol image data is created, then when drawing all of the symbols, that array is accessed to put the image data into the binary of the image. I included the setSymbolArray handler (which is only called once), for clarity. The major slowdown is not in this method.
Can anybody, with a quick scan suggest how to optimize this, or perhaps its a problem with livecode. If it’s not obvious to anybody, I’ll see if I can narrow the problem to a specific line of script.
Thanks,
Bill
—This is the draw program. For each symbol, the correct element of the symbol array is loaded to the array: sBrushDataArray
on drawTheSymbol x,y
put round(x) into startX
put round(y) into startY
put round(sBrushWidth/4) into sXDelta
put round(sBrushHeight/2) into sYDelta
put the keys of sBrushDataArray into tBrushKeys
repeat for each line aKey in tBrushKeys
put sBrushDataArray[aKey] into tbrushBinaryData -- the current part of a row of binary data of brush
put length (tbrushBinaryData) into tLength -- the length of the binary data
put aKey div sBrushWidth into tBrushRow -- calculate the row of the brush the data comes from
-- get currentBrushRow for calculation of imagedata row to fit it into the image, sYDelta offsets the brush
put tBrushRow + startY - sYDelta into tImageCurrRow
put aKey mod sBrushWidth into tCurrBrushColumn -- the column of the brush the current data comes from
put tCurrBrushColumn + startX - sXDelta into tCurrImageColumn -- the column in the image to fit into the imageData; sXDelta offsets the brush
put tImageCurrRow * sMyWidth + tCurrImageColumn into tNewStart -- calculate the byte in xy coord of the image where to insert brushData
put byte 1 to tLength of tbrushBinaryData into byte tNewStart * 4 - 3 to tNewStart*4 - 3 + tLength -1 of imgdata -- insert brushimageData into image imageData
end repeat
end drawTheSymbol
—This method is called only once. The array is created with an element for each symbol that is to be plotted
--This puts image data into the quakeBrushForMag[#] array
on setSymbolArray currentbrush
put the imageData of image currentbrush into currentbrushdata
put the alphaData of image currentbrush into brushalpha
put the width of image currentBrush into sBrushWidth
put the height of image currentBrush into sBrushHeight
put round(sBrushWidth/2) into sXDelta -- to offset the brush so it is visible when using the finger
put sBrushHeight into sYDelta -- same as above
put 0 into sXDelta
put 0 into sYDelta
put "" into sBrushDataArray
--- build array of brush imagedata
repeat with y = 0 to sBrushHeight - 1
put byteToNum (byte ((y*sBrushWidth)+1) of brushalpha)
if byteToNum (byte ((y*sBrushWidth)+1) of brushalpha) > sAlphaCutOff then
put true into tAlphaOn
put "" into tCollect
put ((y*sBrushWidth ) + 1) into tStartDot
else
put false into tAlphaOn
put "" into tCollect
end if
repeat with x = 0 to sBrushWidth - 1
put ((x+(y*sBrushWidth))+1) into tDot
put (byteToNum(byte tDot of brushalpha) > sAlphaCutOff) into tNowAlphaOn
if tNowAlphaOn then
put byte tDot * 4 - 3 to tDot * 4 of currentbrushdata after tCollect -- above threshold-> collect
end if
-- test if state of alpha threshold changed
if tAlphaOn <> tNowAlphaOn then
if tAlphaOn then
-- state changed to alpha below threshold, write array
put tDot into tStopDot
put tCollect into sBrushDataArray[tStartDot]
put "" into tCollect -- clear tCollect since it is passed to the array
else
-- state changed to alpha above threshold
put tDot into tStartDot
end if
-- reset tAlphaOn to current state of alpha threshold since it changed
put tNowAlphaOn into tAlphaOn
-- end alpha state changed
end if
end repeat
if tCollect <> "" then put tCollect into sBrushDataArray[tStartDot]
put "" into tCollect
end repeat
--- end build array
end setSymbolArray
William A. Prothero
http://es.earthednet.org/
More information about the use-livecode
mailing list