Discussion:
When does IShellItemImageFactory return a premultiplied image?
(too old to reply)
Timo Kunze
2010-03-27 22:16:43 UTC
Permalink
Hi,

my application uses IShellItemImageFactory to retrieve thumbnails on
Windows 7. The app draws them using the AlphaBlend function.
Some thumbnails don't look like in Windows Explorer, which seems to be
caused by IShellItemImageFactory sometimes returning an image with
pre-multiplied alpha and sometimes an image that is not pre-multiplied.
For example the recycler's thumbnail looks right without any
post-processing, so it already is pre-multiplied. A filesystem folder's
thumbnail must be pre-multiplied before drawing, otherwise the shadow,
that it casts to the right, will be missing.

Is there a way to make IShellItemImageFactory always return a
pre-multiplied image? Or is there a (performant) way to decide whether
post-processing is necessary?

Thanks
Timo
--
www.TimoSoft-Software.de - Unicode controls for VB6
"Those who sacrifice freedom for safety deserve neither."
"Demokratie ist per Definition unsicher. Ihr Schutz entsteht aus der
Überzeugung, dass die demokratischen Kräfte überwiegen und sich – auf
demokratischem Wege – durchsetzen."
Jim Barry
2010-03-29 10:29:06 UTC
Permalink
Post by Timo Kunze
my application uses IShellItemImageFactory to retrieve thumbnails on
Windows 7. The app draws them using the AlphaBlend function.
Some thumbnails don't look like in Windows Explorer, which seems to be
caused by IShellItemImageFactory sometimes returning an image with
pre-multiplied alpha and sometimes an image that is not pre-multiplied.
For example the recycler's thumbnail looks right without any
post-processing, so it already is pre-multiplied. A filesystem folder's
thumbnail must be pre-multiplied before drawing, otherwise the shadow,
that it casts to the right, will be missing.
Is there a way to make IShellItemImageFactory always return a
pre-multiplied image? Or is there a (performant) way to decide whether
post-processing is necessary?
Deja vu...

http://groups.google.co.uk/group/microsoft.public.platformsdk.shell/msg/555c8cc4dbc7d966

The problem also exists in Vista and I did try quite hard to get
Microsoft to fix it. As usual, my comments were thoroughly ignored and
the bug is still there in Windows 7.

- Jim
Timo Kunze
2010-03-29 17:55:29 UTC
Permalink
Post by Jim Barry
http://groups.google.co.uk/group/microsoft.public.platformsdk.shell/msg/555c8cc4dbc7d966
The problem also exists in Vista and I did try quite hard to get
Microsoft to fix it. As usual, my comments were thoroughly ignored and
the bug is still there in Windows 7.
"But I suppose you can determine with some confidence whether the pixel
values are premultiplied simply by testing whether R, G, or B is greater
than A for any pixel."

I'll try that.

Many thanks, Jim
Timo
--
www.TimoSoft-Software.de - Unicode controls for VB6
"Those who sacrifice freedom for safety deserve neither."
"Demokratie ist per Definition unsicher. Ihr Schutz entsteht aus der
Überzeugung, dass die demokratischen Kräfte überwiegen und sich – auf
demokratischem Wege – durchsetzen."
Timo Kunze
2010-04-10 17:40:01 UTC
Permalink
Hi Jim,

this seems to work. Thanks again.

Timo
--
www.TimoSoft-Software.de - Unicode controls for VB6
"Those who sacrifice freedom for safety deserve neither."
"Demokratie ist per Definition unsicher. Ihr Schutz entsteht aus der
Überzeugung, dass die demokratischen Kräfte überwiegen und sich – auf
demokratischem Wege – durchsetzen."
Timo Kunze
2010-05-01 15:59:54 UTC
Permalink
Hello Jim,

I must correct myself. Detection of pre-multiplied images doesn't really
work. Here's the code I use for detection:

BOOL IsPremultiplied(LPRGBQUAD pBits, int numberOfPixels)
{
BOOL premultiplied = FALSE;

for(int i = 0; i < numberOfPixels && !premultiplied; i++) {
premultiplied = (pBits[i].rgbReserved > 0) && (pBits[i].rgbBlue <=
pBits[i].rgbReserved || pBits[i].rgbGreen <= pBits[i].rgbReserved ||
pBits[i].rgbRed <= pBits[i].rgbReserved);
}
return premultiplied;
}

It works for e.g. the icon of the Windows 7 "Home net group" (or
whatever it is called in English) desktop icon and for the recycler's
icon. But it fails (returns TRUE instead of FALSE) for *.theme files. Do
you have another suggestion?

Best regards
Timo
--
www.TimoSoft-Software.de - Unicode controls for VB6
"Those who sacrifice freedom for safety deserve neither."
"Demokratie ist per Definition unsicher. Ihr Schutz entsteht aus der
Überzeugung, dass die demokratischen Kräfte überwiegen und sich – auf
demokratischem Wege – durchsetzen."
Jim Barry
2010-05-17 11:55:31 UTC
Permalink
Post by Timo Kunze
Hello Jim,
I must correct myself. Detection of pre-multiplied images doesn't really
BOOL IsPremultiplied(LPRGBQUAD pBits, int numberOfPixels)
{
BOOL premultiplied = FALSE;
for(int i = 0; i < numberOfPixels && !premultiplied; i++) {
premultiplied = (pBits[i].rgbReserved > 0) && (pBits[i].rgbBlue <=
pBits[i].rgbReserved || pBits[i].rgbGreen <= pBits[i].rgbReserved ||
pBits[i].rgbRed <= pBits[i].rgbReserved);
}
return premultiplied;
}
Hi Timo,

Your detection code is incorrect. My point was that for valid
premultiplied image data, the RGB values of each pixel are always less
than or equal to its alpha value. Therefore, if any pixel has an RGB
value greater than its alpha value then you can be pretty sure that the
image data is not premultiplied. However, finding a single pixel where
RGB are all less than or equal to alpha doesn't prove anything.

It's technically possible for a non-premultiplied image to have RGB <= A
for all pixels, of course, though it seems fairly unlikely except for
the case where alpha is 255 for all pixels, and then the RGB values are
unaffected by premultiplication anyway.

Try this:

BOOL IsPremultiplied(LPRGBQUAD pBits, int numberOfPixels)
{
for (int i = 0; i < numberOfPixels; ++i)
{
if (pBits[i].rgbBlue > pBits[i].rgbReserved ||
pBits[i].rgbGreen > pBits[i].rgbReserved ||
pBits[i].rgbRed > pBits[i].rgbReserved)
{
return false;
}
}
return true;
}

- Jim
Timo Kunze
2010-05-17 17:05:24 UTC
Permalink
Hello Jim,

I can't express how much I thank you. I've been working on thumbnail
support, including dynamic resizing and adorners like sprockets for
videos, for more than a year now (with smaller and larger gaps) and this
was the last thing missing.
If you send me a mail with your contact data, I'll donate you something.

Best regards
Timo
--
www.TimoSoft-Software.de - Unicode controls for VB6
"Those who sacrifice freedom for safety deserve neither."
"Demokratie ist per Definition unsicher. Ihr Schutz entsteht aus der
Überzeugung, dass die demokratischen Kräfte überwiegen und sich – auf
demokratischem Wege – durchsetzen."
Jim Barry
2010-06-10 09:56:25 UTC
Permalink
Post by Timo Kunze
I can't express how much I thank you. I've been working on thumbnail
support, including dynamic resizing and adorners like sprockets for
videos, for more than a year now (with smaller and larger gaps) and this
was the last thing missing.
If you send me a mail with your contact data, I'll donate you something.
Hi Timo, please excuse the late reply. I haven't been checking this
group much lately, as it's on death row and execution is imminent :(

Anyway, glad to help out - there's no charge :)

- Jim

Loading...