[Mono-winforms-list] [Mono-osx] DrawImage alpha blend broken in libgdiplus
Sebastien Pouliot
sebastien.pouliot at gmail.com
Thu Apr 16 09:08:36 EDT 2009
On Thu, 2009-04-16 at 15:38 +0300, Alex Shulgin wrote:
> Alex Shulgin wrote:
> > Sebastien Pouliot wrote:
> >> On Thu, 2009-04-09 at 18:22 +0300, Alex Shulgin wrote:
> >>>
> >>> I'm trying to run the tests in mcs/class/System.Drawing/Test under
> >>> MonoDevelop and I have 144 failing tests (out of 1377) to begin with...
> >>>
> >>> Is this normal situation or my system is severely broken?
> >>
> >> It's definitively not normal.
> >> It could be some path issues since some tests depends on external files
> >> (and MD compiled output could be at the "wrong" place).
> >>> I'm on x86 Ubuntu 8.10 with the following packages freshly built from
> >>> svn:
> >>>
> >>> libgdiplus
> >>> mono
> >>> mcs
> >>> gtk-sharp
> >>> mono-addins
> >>> monodevelop
> >>>
> >>> The number of failing tests doesn't change if I apply my patch to
> >>> libgdiplus, though.
> >>>
> >>> How do I proceed?
> >>
> >> You can try a "make run-test" at the prompt.
> >>
> >> If that works (or you can't make it work) then email a patch with the
> >> new test(s) and I'll try it on my box.
> >
> > Hi again,
> >
> > I've tried
> >
> > ~/src/mono/trunk/mcs/class/System.Drawing$ make run-test MCS=gmcs
> >
> > where gmcs is built & installed from trunk.
> >
> > This time I get only 6 failures (two related to XML serialization and
> > the rest in PrintingPermissionTest), so I've tried to apply my patch and
> > see what happens.
> >
> > The result was that some tests that save an image, then load it and
> > check pixel format failed (on png and .ico). The tests expect to get
> > Format32bppArgb, but they get Format32bppPArgb per my change.
> >
> > Thinking further about this situation, I've looked into pngcodec.c to
> > see how does it save the image if it's data is in PARGB format. It
> > turned out, that there's no special handling for this!
> >
> > There's a simple code to demonstrate what happens if you load an ARGB
> > PNG image, save it untouched, then load it again.
> >
> > using System;
> > using System.Drawing;
> >
> > namespace AlphaBlend
> > {
> > class MainClass
> > {
> > public static void Main(string[] args)
> > {
> > Bitmap pngmask = new Bitmap("gimpmask.png");
> > Console.WriteLine("orig: PixelFormat={0}, pixel at (4,4): {1}",
> > pngmask.PixelFormat, pngmask.GetPixel(4,4));
> >
> > pngmask.Save("savedmask.png");
> >
> > Bitmap loadedmask = new Bitmap("savedmask.png");
> > Console.WriteLine("load: PixelFormat={0}, pixel at (4,4): {1}",
> > loadedmask.PixelFormat,
> > loadedmask.GetPixel(4,4));
> > }
> > }
> > }
> >
> > On the attached test image this code gives:
> >
> > orig: PixelFormat=Format32bppArgb, pixel at (4,4): Color [A=51, R=49,
> > G=49, B=49]
> > load: PixelFormat=Format32bppArgb, pixel at (4,4): Color [A=51, R=9,
> > G=9, B=9]
> >
> > The RGB channels get premultiplied twice...
> >
> > To resolve this mess I propose the following:
> >
> > 1. Postpone premultiplication until actual use of cairo functions which
> > require it.
> >
> > 2. Add premultiplication code where it's currently missing (as in my
> > original patch + few similar places).
> >
> > 3. Add code to handle saving of PARGB bitmaps created by user like this:
> > new Bitmap(w, h, PixelFormat.Format32bppPArgb). Possibly just throw
> > NotImplementedException for now.
> >
> > This way we'll fix current problem with creating mask in memory and
> > alpha blending it on some background.
> >
> > We'll avoid post-multiplication otherwise needed before saving an ARGB
> > PNG image. Also, libgdiplus won't lie anymore that loaded image data is
> > in ARGB format while it's actually in PARGB. :)
> >
> > What do you think?
>
> Any comments?
Sounds correct but will requires a lot of testing. Please open a bug
report for this and copy/paste the email info into it (otherwise we'll
lose track of important data).
Thanks
Sebastien
More information about the Mono-winforms-list
mailing list