Alpha channel blending with PHP's imagecopymerge()

The current implementation of imagecopymerge() produces unexpected results when merging two true colour images especially as imagecopy() produces results more inline with what I would expect.

By way of an example, consider the following code....

<?php
$bg   = imagecreatefrompng('tux.png');
$over = imagecreatefrompng('ff-logo-sm.png');
imagealphablending($bg, true);
imagesavealpha($bg, true);
imagecopy($bg, $over, 276, 300, 0, 0, 123, 119);
imagepng($bg, 'tux-fox-imagecopy.png');
?>

Using imagecopy the resulting image is....

As can be seen, the resulting image retains the alpha channel levels of both source and destination images.

Now with imagecopymerge...

<?php
$bg  = imagecreatefrompng('tux.png');
$over = imagecreatefrompng('ff-logo-sm.png');
imagealphablending($bg, true);
imagesavealpha($bg, true);
imagecopymerge($bg, $over, 276, 300, 0, 0, 123, 119, 100);
imagepng($bg, 'tux-fox-imagecopymerge-100-without-patch.png');
?>

The resulting image is...

Destination image retains alpha channel information while the alpha channel of the source image is ignored.

Applying a 50% reduction in opacity....

<?php
$bg  = imagecreatefrompng('tux.png');
$over = imagecreatefrompng('ff-logo-sm.png');
imagealphablending($bg, true);
imagesavealpha($bg, true);
imagecopymerge($bg, $over, 276, 300, 0, 0, 123, 119, 50);
imagepng($bg, 'tux-fox-imagecopymerge-50-without-patch.png');
?>

The resulting image is...

Possible Solution

With my patch (applied to ext/gd/libgd/gd.c), the results are more inline with what I would expect imagecopymerge to return ( the patch file can be found here.

<?php
$bg  = imagecreatefrompng('tux.png');
$over = imagecreatefrompng('ff-logo-sm.png');
imagealphablending($bg, true);
imagesavealpha($bg, true);
imagecopymerge($bg, $over, 276, 300, 0, 0, 123, 119, 100);
imagepng($bg, 'tux-fox-imagecopymerge-100-with-patch.png');
?>

Gives us....

And with 50% opacity reduction...

<?php
$bg  = imagecreatefrompng('tux.png');
$over = imagecreatefrompng('ff-logo-sm.png');
imagealphablending($bg, true);
imagesavealpha($bg, true);
imagecopymerge($bg, $over, 276, 300, 0, 0, 123, 119, 50);
imagepng($bg, 'tux-fox-imagecopymerge-50-with-patch.png');
?>

Gives us....