Commit e74b0ee9 authored by Mike McCormack's avatar Mike McCormack Committed by Alexandre Julliard

comctl32: Remove Nx1 assumptions in ImageList_Read.

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