A while back, Runar Jordahl wrote an article on how to do alpha blending in Smalltalk. He found that it was fast enough for standard applications.
Just for fun, I thought I'd try to approach the problem a different way. Runar's implementation plays nice with Images, uses proper encapsulation and does the alpha blending in floating point numbers. I took the "D*** the torpedoes" approach and went for put raw speed. I broke all the encapsulation rules and did the operation as fast as I could using Integer arithmetic in Smalltalk. The result is over 6 times faster than Runar's optimized approach.
Using this technique, I can alpha blend two images of size 1128x680 within about 200mS on my system. Not bad for being pure Smalltalk code. With a primitive, I'm sure I can go much faster.
The following method for Depth32Image does the work. It assumes that the palette is ABGR.
alphaBlendWith: aDepth32Image
| otherBits bitsSize |
aDepth32Image width = self width
ifFalse: [^self error: 'Not the same size'].
aDepth32Image height = self height
ifFalse: [^self error: 'Not the same size'].
aDepth32Image bitsPerPixel = 32
ifFalse: [^self error: 'Wrong pixel depth'].
otherBits := aDepth32Image bits.
bitsSize := bits size.
1 to: bitsSize by: 4 do: [:i |
| j a ra |
a := otherBits at: i.
ra := 255 - a.
j := i + 1.
bits at: j put: (((bits at: j) * ra)
+ ((otherBits at: j) * a) bitShift: -8).
j := j + 1.
bits at: j put: (((bits at: j) * ra)
+ ((otherBits at: j) * a) bitShift: -8).
j := j + 1.
bits at: j put: (((bits at: j) * ra)
+ ((otherBits at: j) * a) bitShift: -8)]