Opacity not initialized in SyncImage

Post any defects you find in the released or beta versions of the ImageMagick software here. Include the ImageMagick version, OS, and any command-line required to reproduce the problem. Got a patch for a bug? Post it here.
Post Reply
rsayle
Posts: 1
Joined: 2013-10-10T06:10:47-07:00
Authentication code: 6789

Opacity not initialized in SyncImage

Post by rsayle »

Please forgive me if this is a misunderstanding on my part, but I believe I've found
an obscure bug that affects the toolkit v6.8.6-9 which is fixed/resolved by the patch
below. My concern is that I'm not 100% sure of what the intended semantics and
invariants guaranteed by "image->matte" are supposed to be, so this might easily
be user error on my part.

The sequence of events is that if I read an 8-bit pseudo-color BMP image using
BlobToImage, the opacity/alpha channel of the resulting image is not initialized.
Indeed, if this call is made after reading a JPEG or similar file using the same
interface, I believe the internal pixel caching results in random junk values in
the PixelPacket::opacity field lead to strange results.

The source of the issue appears to be the logic in image.c:SyncImage where if
image->matte is false, then the opacity is unmodified. On the Linux boxes, but
not the Windows machines, that I've tested the PixelPacket data returned by
GetCacheViewAuthenticPixels above the affected code can and do contain random
values. My question is whether the pixel opacity is supposed to be initialized by
ImageMagic's readers, or whether the caller is expected to test the value of
image->matte to determine which bits are valid (and therefore not call
ExportImagePixels with "BGRA" as an argument for example).

Please let me know if the proposed fix below is the correct solution to my problem.
It certainly resolves the problem I'm seeing, but I'm unsure what is intended.

Code: Select all

*** image.c.orig        2013-10-10 14:01:05.000000000 +0100
--- image.c     2013-10-10 13:44:13.000000000 +0100
***************
*** 3457,3463 ****
        index=PushColormapIndex(image,(size_t) GetPixelIndex(indexes+x),
          &range_exception);
        if (image->matte == MagickFalse)
!         SetPixelRgb(q,image->colormap+(ssize_t) index)
        else
          SetPixelRGBO(q,image->colormap+(ssize_t) index);
        q++;
--- 3457,3466 ----
        index=PushColormapIndex(image,(size_t) GetPixelIndex(indexes+x),
          &range_exception);
        if (image->matte == MagickFalse)
!         {
!           SetPixelRgb(q,image->colormap+(ssize_t) index);
!           SetPixelOpacity(q,(Quantum)0);
!         }
        else
          SetPixelRGBO(q,image->colormap+(ssize_t) index);
        q++;
Please let me know if you need a test case. As mentioned above reproduceability is
an issue. But I can certainly provide the source code and test files that trigger this
behaviour on my local machine. Fingers-crossed the explanation above is sufficient.

Many thanks in advance,

Roger
--
Roger Sayle, Ph.D.
CEO and founder
NextMove Software Limited
Registered in England No. 07588305
Registered Office: Innovation Centre (Unit 23), Cambridge Science Park, Cambridge CB4 0EY
User avatar
magick
Site Admin
Posts: 11064
Joined: 2003-05-31T11:32:55-07:00

Re: Opacity not initialized in SyncImage

Post by magick »

ImageMagick by design does not initialize unused channels in an image. As you mentioned, unused channels can have random data (unless its memory mapped, then its 0). To initialize the alpha channel, use -alpha from the command line or SetImageAlphaChannel() with the MagickCore API.
Post Reply