Mike McCormack : comctl32: Remove Nx1 assumptions in ImageList_Read.

Alexandre Julliard julliard at wine.codeweavers.com
Wed Nov 8 06:42:54 CST 2006


Module: wine
Branch: master
Commit: e74b0ee9102470d1b866e94c54527b34806cf876
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=e74b0ee9102470d1b866e94c54527b34806cf876

Author: Mike McCormack <mike at codeweavers.com>
Date:   Wed Nov  8 15:01:04 2006 +0900

comctl32: Remove Nx1 assumptions in ImageList_Read.

---

 dlls/comctl32/imagelist.c |  172 ++++++++++++++++++---------------------------
 1 files changed, 68 insertions(+), 104 deletions(-)

diff --git a/dlls/comctl32/imagelist.c b/dlls/comctl32/imagelist.c
index 843654a..1cc886e 100644
--- a/dlls/comctl32/imagelist.c
+++ b/dlls/comctl32/imagelist.c
@@ -1884,97 +1884,80 @@ static int may_use_dibsection(HDC hdc) {
 #endif
 
 /* helper for ImageList_Read, see comments below */
-static HBITMAP _read_bitmap(LPSTREAM pstm,int ilcFlag,int cx,int cy) {
-    HDC                        xdc = 0, hBitmapDC =0;
+static BOOL _read_bitmap(HIMAGELIST himl, HDC hdcIml, LPSTREAM pstm, int ilcFlag)
+{
+    HDC                 xdc = 0;
     BITMAPFILEHEADER	bmfh;
     BITMAPINFOHEADER	bmih;
     int			bitsperpixel,palspace,longsperline,width,height;
-    LPBITMAPINFOHEADER	bmihc = NULL;
-    int			result = 0;
-    HBITMAP            hbitmap = 0, hDIB = 0;
+    LPBITMAPINFO       bmi = NULL;
+    int                result = FALSE;
+    HBITMAP            hDIB = 0;
     LPBYTE             bits = NULL;
+    int i, j, nheight, nRows, nCols;
+    POINT pt;
+    int cy = himl->cy;
+
+    if (!SUCCEEDED(IStream_Read ( pstm, &bmfh, sizeof(bmfh), NULL)))
+        return result;
+
+    if (bmfh.bfType != (('M'<<8)|'B'))
+        return result;
 
-    if (!SUCCEEDED(IStream_Read ( pstm, &bmfh, sizeof(bmfh), NULL))	||
-    	(bmfh.bfType != (('M'<<8)|'B'))					||
-    	!SUCCEEDED(IStream_Read ( pstm, &bmih, sizeof(bmih), NULL))	||
-    	(bmih.biSize != sizeof(bmih))
-    )
+    if (!SUCCEEDED(IStream_Read ( pstm, &bmih, sizeof(bmih), NULL)))
+        return result;
+
+    if ((bmih.biSize != sizeof(bmih)))
 	return 0;
 
     bitsperpixel = bmih.biPlanes * bmih.biBitCount;
     if (bitsperpixel<=8)
-    	palspace = (1<<bitsperpixel)*sizeof(RGBQUAD);
+        palspace = (1<<bitsperpixel)*sizeof(RGBQUAD);
     else
-    	palspace = 0;
+        palspace = 0;
     width = bmih.biWidth;
     height = bmih.biHeight;
-    bmihc = (LPBITMAPINFOHEADER)LocalAlloc(LMEM_ZEROINIT,sizeof(bmih)+palspace);
-    if (!bmihc) goto ret1;
-    memcpy(bmihc,&bmih,sizeof(bmih));
-    longsperline	= ((width*bitsperpixel+31)&~0x1f)>>5;
-    bmihc->biSizeImage	= (longsperline*height)<<2;
+    bmi = Alloc(sizeof(bmih)+palspace);
+    if (!bmi)
+        return result;
+
+    memcpy(bmi, &bmih, sizeof(bmih));
+    longsperline = ((width*bitsperpixel+31)&~0x1f)>>5;
+    bmi->bmiHeader.biSizeImage = (longsperline*height)<<2;
 
     /* read the palette right after the end of the bitmapinfoheader */
-    if (palspace)
-	if (!SUCCEEDED(IStream_Read ( pstm, bmihc+1, palspace, NULL)))
-	    goto ret1;
+    if (palspace && !SUCCEEDED(IStream_Read(pstm, bmi->bmiColors, palspace, NULL)))
+	goto error;
 
     xdc = GetDC(0);
-#if 0 /* Magic for NxM -> 1x(N*M) not implemented for DIB Sections */
-    if ((bitsperpixel>1) &&
-	((ilcFlag!=ILC_COLORDDB) && (!ilcFlag || may_use_dibsection(xdc)))
-     ) {
-	hbitmap = CreateDIBSection(xdc,(BITMAPINFO*)bmihc,0,(LPVOID*)&bits,0,0);
-	if (!hbitmap)
-	    goto ret1;
-	if (!SUCCEEDED(IStream_Read( pstm, bits, bmihc->biSizeImage, NULL)))
-	    goto ret1;
-	result = 1;
-    } else
-#endif
-    {
-       int i,nwidth,nheight,nRows;
-
-	nwidth	= width*(height/cy);
-	nheight	= cy;
-        nRows   = (height/cy);
 
-	if (bitsperpixel==1)
-	    hbitmap = CreateBitmap(nwidth,nheight,1,1,NULL);
-	else
-	    hbitmap = CreateCompatibleBitmap(xdc,nwidth,nheight);
-
-       hDIB = CreateDIBSection(xdc,(BITMAPINFO*)bmihc,0,(LPVOID*)&bits,0,0);
-       if (!hDIB)
-           goto ret1;
-       if (!SUCCEEDED(IStream_Read( pstm, bits, bmihc->biSizeImage, NULL)))
-           goto ret1;
-
-        hBitmapDC = CreateCompatibleDC(0);
-        SelectObject(hBitmapDC, hbitmap);
-
-	/* Copy the NxM bitmap into a 1x(N*M) bitmap we need, linewise */
-	/* Do not forget that windows bitmaps are bottom->top */
-        TRACE("nRows=%d\n", nRows);
-        for (i=0; i < nRows; i++){
-            StretchDIBits(hBitmapDC, width*i, 0, width, cy, 0, cy*(nRows-1-i), width, cy, bits,
-                (BITMAPINFO*)bmihc, DIB_RGB_COLORS, SRCCOPY);
+    nheight = cy;
+    nRows = height/cy;
+    nCols = width/himl->cx;
+
+    hDIB = CreateDIBSection(xdc, bmi, 0, (LPVOID*) &bits, 0, 0);
+    if (!hDIB)
+        goto error;
+    if (!SUCCEEDED(IStream_Read(pstm, bits, bmi->bmiHeader.biSizeImage, NULL)))
+        goto error;
+
+    /* Copy the NxM bitmap into a 1x(N*M) bitmap we need, linewise */
+    /* Do not forget that windows bitmaps are bottom->top */
+    for (i=0; i < nRows; i++) {
+        for (j=0; j < nCols; j++) {
+            imagelist_point_from_index(himl, i*nCols + j, &pt);
+            StretchDIBits(hdcIml, pt.x, pt.y, himl->cx, cy,
+                      j*himl->cx, (nRows - 1 - i)*himl->cy, himl->cx, cy, bits,
+                      bmi, DIB_RGB_COLORS, SRCCOPY);
         }
-        
-	result = 1;
     }
-ret1:
+
+    result = TRUE;
+error:
     if (xdc)	ReleaseDC(0,xdc);
-    if (bmihc)	LocalFree((HLOCAL)bmihc);
+    Free(bmi);
     if (hDIB)   DeleteObject(hDIB);
-    if (hBitmapDC)   DeleteDC(hBitmapDC);
-    if (!result) {
-	if (hbitmap) {
-	    DeleteObject(hbitmap);
-	    hbitmap = 0;
-	}
-    }
-    return hbitmap;
+    return result;
 }
 
 /*************************************************************************
@@ -1990,11 +1973,11 @@ ret1:
  *     Failure: NULL
  *
  * The format is like this:
- * 	ILHEAD 			ilheadstruct;
+ *	ILHEAD			ilheadstruct;
  *
  * for the color image part:
- * 	BITMAPFILEHEADER	bmfh;
- * 	BITMAPINFOHEADER	bmih;
+ *	BITMAPFILEHEADER	bmfh;
+ *	BITMAPINFOHEADER	bmih;
  * only if it has a palette:
  *	RGBQUAD		rgbs[nr_of_paletted_colors];
  *
@@ -2018,51 +2001,32 @@ HIMAGELIST WINAPI ImageList_Read (LPSTRE
     HBITMAP	hbmColor=0,hbmMask=0;
     int		i;
 
+    TRACE("%p\n", pstm);
+
     if (!SUCCEEDED(IStream_Read (pstm, &ilHead, sizeof(ILHEAD), NULL)))
-    	return NULL;
+	return NULL;
     if (ilHead.usMagic != (('L' << 8) | 'I'))
 	return NULL;
     if (ilHead.usVersion != 0x101) /* probably version? */
 	return NULL;
 
-#if 0
-    FIXME("	ilHead.cCurImage = %d\n",ilHead.cCurImage);
-    FIXME("	ilHead.cMaxImage = %d\n",ilHead.cMaxImage);
-    FIXME("	ilHead.cGrow = %d\n",ilHead.cGrow);
-    FIXME("	ilHead.cx = %d\n",ilHead.cx);
-    FIXME("	ilHead.cy = %d\n",ilHead.cy);
-    FIXME("	ilHead.flags = %x\n",ilHead.flags);
-    FIXME("	ilHead.ovls[0] = %d\n",ilHead.ovls[0]);
-    FIXME("	ilHead.ovls[1] = %d\n",ilHead.ovls[1]);
-    FIXME("	ilHead.ovls[2] = %d\n",ilHead.ovls[2]);
-    FIXME("	ilHead.ovls[3] = %d\n",ilHead.ovls[3]);
-#endif
-
-    hbmColor = _read_bitmap(pstm,ilHead.flags & ~ILC_MASK,ilHead.cx,ilHead.cy);
-    if (!hbmColor) {
+    himl = ImageList_Create(ilHead.cx, ilHead.cy, ilHead.flags, ilHead.cCurImage, ilHead.cMaxImage);
+    if (!himl) {
+	DeleteObject(hbmColor);
+	DeleteObject(hbmMask);
+	return NULL;
+    }
+    if (!_read_bitmap(himl, himl->hdcImage, pstm, ilHead.flags & ~ILC_MASK)) {
 	WARN("failed to read bitmap from stream\n");
 	return NULL;
     }
     if (ilHead.flags & ILC_MASK) {
-	hbmMask = _read_bitmap(pstm,0,ilHead.cx,ilHead.cy);
-	if (!hbmMask) {
+	if (!_read_bitmap(himl, himl->hdcMask, pstm, 0)) {
 	    DeleteObject(hbmColor);
 	    return NULL;
 	}
     }
 
-    himl = ImageList_Create (
-		    ilHead.cx,
-		    ilHead.cy,
-		    ilHead.flags,
-		    1,		/* initial */
-		    ilHead.cGrow
-    );
-    if (!himl) {
-	DeleteObject(hbmColor);
-	DeleteObject(hbmMask);
-	return NULL;
-    }
     SelectObject(himl->hdcImage, hbmColor);
     DeleteObject(himl->hbmImage);
     himl->hbmImage = hbmColor;
@@ -2076,7 +2040,7 @@ #endif
 
     ImageList_SetBkColor(himl,ilHead.bkcolor);
     for (i=0;i<4;i++)
-    	ImageList_SetOverlayImage(himl,ilHead.ovls[i],i+1);
+	ImageList_SetOverlayImage(himl,ilHead.ovls[i],i+1);
     return himl;
 }
 




More information about the wine-cvs mailing list