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