You'd be better off getting the base pointer of the pixmap memory with PixmapPtr() and then using a pointer variable such as `writeto:Int Ptr` with casting such as If rgb<>0 writeto[0]=rgb, and handle the x and y locations incrementing by using your own counters.
If you jump into WritePixel for every pixel, it has to look up the pixmap, find the base pointer, add your x coordinate (which you have to also calculate before you can pass it), take your y coord (also needing constant calculation) and multiply it by the row bytes then add it to the total, THEN access the pixel at the memory address. Lots of work. Just keep your own pointer and increment it with each write, by 1 (since it's an int pointer, it actually adds 4 to the pointer). That should be a lot faster.
Here is a cut-and-paste of part of an alphablending routine ... the main part. You'll need to set up the variables. It might not be the fastest on the planet but I can confirm that it works.
Also to answer previous uncertaintly, yes pixmaps are entirely in main memory. When you grab a pixmap you are dumping the backbuffer to a pixmap in main memory, which goes over the graphics bus. Similarly when you draw a pixmap or convert it into an image, it goes over the bus from main memory to graphics memory.
This code just does one ROW of pixels, once set up. You'd need a for/next loop to do all rows.
Local MRowBytesLeft:Int 'Row byte counter
Local MSourcePointer4:Int Ptr=DataBankIntPtr+MSourceXYSkip 'For copying Int data from
Local MDestPointer4:Int Ptr=MDest.DataBankIntPtr+MDestXYSkip 'For copying Int data to
Local MSourceData:Int 'For storing source pixel data
Local MDestData:Int 'For storing destination pixel data
Local MFilterRed:Int=$FF000000 'To mask off Red data
Local MFilterGreen:Int=$00FF0000 'To mask off Green data
Local MFilterBlue:Int=$0000FF00 'To mask off Blue data
Local MFilterAlpha:Int=$000000FF 'To mask off Alpha
Local MDestRed:Int 'To compose Red
Local MDestGreen:Int 'To compose Green
Local MDestBlue:Int 'To compose Blue
Local MAlpha:Int 'To get source alpha
Local MSourceRatio:Float 'To calculate amount of source color
Local MDestRatio:Float 'To calculate amount of dest color
For Local MRow:Int=0 To MRows
MRowBytesLeft=MRowBytes 'Initialize
While MRowBytesLeft>2 'Loopcounter=3 or more (at least 4 bytes/1 pixel to go)
MSourceData=MSourcePointer4[0] 'Get source pixel data RGBA
MDestData=MDestPointer4[0] 'Get destination pixel data RGBA
MAlpha=MSourceData & MFilterAlpha 'Get source alpha
MSourceRatio=(1.0/256.0)*MAlpha 'Calculate amount of source color
MDestRatio=1.0-MSourceRatio 'Calculate amount of dest color
MDestRed=Int((((MDestData & MFilterRed) Shr 24) *MDestRatio) + (((MSourceData & MFilterRed) Shr 24) *MSourceRatio))
MDestGreen=Int((((MDestData & MFilterGreen) Shr 16) *MDestRatio) + (((MSourceData & MFilterGreen) Shr 16) *MSourceRatio))
MDestBlue=Int((((MDestData & MFilterBlue) Shr 8) *MDestRatio) + (((MSourceData & MFilterBlue) Shr 8) *MSourceRatio))
MDestPointer4[0]=(MDestData & MFilterAlpha) | (MDestRed Shl 24) | (MDestGreen Shl 16) | (MDestBlue Shl 8) 'AlphaBlend 1 pixel
MRowBytesLeft:-4 'Just done 4 bytes/1 pixel
MSourcePointer4:+1 'Jump past 1 pixel
MDestPointer4:+1 'Jump past 1 pixel
Wend
MSourcePointer4:+MSourceRowSkip 'Next row in source
MDestPointer4:+MDestRowSkip 'Next row in dest
Next