Alexandre Julliard : comctl32: Setup the alpha channel also when reading an imagelist from a stream.
Alexandre Julliard
julliard at winehq.org
Wed Nov 16 12:46:44 CST 2011
Module: wine
Branch: master
Commit: 73b9dc98eb9ab371f92d8c0a054c71f3d9b194ee
URL: http://source.winehq.org/git/wine.git/?a=commit;h=73b9dc98eb9ab371f92d8c0a054c71f3d9b194ee
Author: Alexandre Julliard <julliard at winehq.org>
Date: Tue Nov 15 22:11:15 2011 +0100
comctl32: Setup the alpha channel also when reading an imagelist from a stream.
---
dlls/comctl32/imagelist.c | 83 +++++++++++++++++++++++++++++++-------------
1 files changed, 58 insertions(+), 25 deletions(-)
diff --git a/dlls/comctl32/imagelist.c b/dlls/comctl32/imagelist.c
index 9d2b6f9..c32cb0b 100644
--- a/dlls/comctl32/imagelist.c
+++ b/dlls/comctl32/imagelist.c
@@ -2090,26 +2090,23 @@ ImageList_Merge (HIMAGELIST himl1, INT i1, HIMAGELIST himl2, INT i2,
/* helper for ImageList_Read, see comments below */
-static BOOL _read_bitmap(HDC hdcIml, LPSTREAM pstm)
+static void *read_bitmap(LPSTREAM pstm, BITMAPINFO *bmi)
{
BITMAPFILEHEADER bmfh;
int bitsperpixel, palspace;
- char bmi_buf[sizeof(BITMAPINFOHEADER) + sizeof(RGBQUAD) * 256];
- LPBITMAPINFO bmi = (LPBITMAPINFO)bmi_buf;
- int result = FALSE;
- LPBYTE bits = NULL;
+ void *bits;
if (FAILED(IStream_Read ( pstm, &bmfh, sizeof(bmfh), NULL)))
- return FALSE;
+ return NULL;
if (bmfh.bfType != (('M'<<8)|'B'))
- return FALSE;
+ return NULL;
if (FAILED(IStream_Read ( pstm, &bmi->bmiHeader, sizeof(bmi->bmiHeader), NULL)))
- return FALSE;
+ return NULL;
if ((bmi->bmiHeader.biSize != sizeof(bmi->bmiHeader)))
- return FALSE;
+ return NULL;
TRACE("width %u, height %u, planes %u, bpp %u\n",
bmi->bmiHeader.biWidth, bmi->bmiHeader.biHeight,
@@ -2125,23 +2122,17 @@ static BOOL _read_bitmap(HDC hdcIml, LPSTREAM pstm)
/* read the palette right after the end of the bitmapinfoheader */
if (palspace && FAILED(IStream_Read(pstm, bmi->bmiColors, palspace, NULL)))
- goto error;
+ return NULL;
bits = Alloc(bmi->bmiHeader.biSizeImage);
- if (!bits)
- goto error;
- if (FAILED(IStream_Read(pstm, bits, bmi->bmiHeader.biSizeImage, NULL)))
- goto error;
-
- if (!StretchDIBits(hdcIml, 0, 0, bmi->bmiHeader.biWidth, bmi->bmiHeader.biHeight,
- 0, 0, bmi->bmiHeader.biWidth, bmi->bmiHeader.biHeight,
- bits, bmi, DIB_RGB_COLORS, SRCCOPY))
- goto error;
- result = TRUE;
+ if (!bits) return NULL;
-error:
- Free(bits);
- return result;
+ if (FAILED(IStream_Read(pstm, bits, bmi->bmiHeader.biSizeImage, NULL)))
+ {
+ Free(bits);
+ return NULL;
+ }
+ return bits;
}
/*************************************************************************
@@ -2177,6 +2168,11 @@ error:
*/
HIMAGELIST WINAPI ImageList_Read (LPSTREAM pstm)
{
+ char image_buf[sizeof(BITMAPINFOHEADER) + sizeof(RGBQUAD) * 256];
+ char mask_buf[sizeof(BITMAPINFOHEADER) + sizeof(RGBQUAD) * 256];
+ BITMAPINFO *image_info = (BITMAPINFO *)image_buf;
+ BITMAPINFO *mask_info = (BITMAPINFO *)mask_buf;
+ void *image_bits, *mask_bits = NULL;
ILHEAD ilHead;
HIMAGELIST himl;
int i;
@@ -2197,19 +2193,56 @@ HIMAGELIST WINAPI ImageList_Read (LPSTREAM pstm)
if (!himl)
return NULL;
- if (!_read_bitmap(himl->hdcImage, pstm))
+ if (!(image_bits = read_bitmap(pstm, image_info)))
{
WARN("failed to read bitmap from stream\n");
return NULL;
}
if (ilHead.flags & ILC_MASK)
{
- if (!_read_bitmap(himl->hdcMask, pstm))
+ if (!(mask_bits = read_bitmap(pstm, mask_info)))
{
WARN("failed to read mask bitmap from stream\n");
return NULL;
}
}
+ else mask_info = NULL;
+
+ if (himl->has_alpha && image_info->bmiHeader.biBitCount == 32)
+ {
+ DWORD *ptr = image_bits;
+ BYTE *mask_ptr = mask_bits;
+ int stride = himl->cy * image_info->bmiHeader.biWidth;
+
+ if (image_info->bmiHeader.biHeight > 0) /* bottom-up */
+ {
+ ptr += (imagelist_height( ilHead.cCurImage ) - 1) * stride;
+ mask_ptr += (imagelist_height( ilHead.cCurImage ) - 1) * stride / 8;
+ stride = -stride;
+ image_info->bmiHeader.biHeight = himl->cy;
+ }
+ else image_info->bmiHeader.biHeight = -himl->cy;
+
+ for (i = 0; i < ilHead.cCurImage; i += TILE_COUNT)
+ {
+ add_dib_bits( himl, i, min( ilHead.cCurImage - i, TILE_COUNT ),
+ himl->cx, himl->cy, image_info, mask_info, ptr, mask_ptr );
+ ptr += stride;
+ mask_ptr += stride / 8;
+ }
+ }
+ else
+ {
+ StretchDIBits( himl->hdcImage, 0, 0, image_info->bmiHeader.biWidth, image_info->bmiHeader.biHeight,
+ 0, 0, image_info->bmiHeader.biWidth, image_info->bmiHeader.biHeight,
+ image_bits, image_info, DIB_RGB_COLORS, SRCCOPY);
+ if (mask_info)
+ StretchDIBits( himl->hdcMask, 0, 0, mask_info->bmiHeader.biWidth, mask_info->bmiHeader.biHeight,
+ 0, 0, mask_info->bmiHeader.biWidth, mask_info->bmiHeader.biHeight,
+ mask_bits, mask_info, DIB_RGB_COLORS, SRCCOPY);
+ }
+ Free( image_bits );
+ Free( mask_bits );
himl->cCurImage = ilHead.cCurImage;
himl->cMaxImage = ilHead.cMaxImage;
More information about the wine-cvs
mailing list