mirror of
https://github.com/reactos/reactos.git
synced 2025-02-23 00:45:24 +00:00
[WIN32K]
- rewrite UserLoadImage so that it uses information from the BITMAPFILEHEADER and probes the right buffer. svn path=/branches/reactos-yarotows/; revision=48364
This commit is contained in:
parent
fa93ac8293
commit
b011aff53b
3 changed files with 125 additions and 34 deletions
|
@ -18,3 +18,6 @@ DIB_MapPaletteColors(PDC dc, CONST BITMAPINFO* lpbmi);
|
||||||
|
|
||||||
HPALETTE FASTCALL
|
HPALETTE FASTCALL
|
||||||
BuildDIBPalette (CONST BITMAPINFO *bmi, PINT paletteType);
|
BuildDIBPalette (CONST BITMAPINFO *bmi, PINT paletteType);
|
||||||
|
|
||||||
|
BITMAPINFO* FASTCALL DIB_ConvertBitmapInfo(CONST BITMAPINFO* bmi, DWORD Usage);
|
||||||
|
VOID FASTCALL DIB_FreeConvertedBitmapInfo(BITMAPINFO* converted, BITMAPINFO* orig);
|
|
@ -157,14 +157,12 @@ HBITMAP
|
||||||
NTAPI
|
NTAPI
|
||||||
UserLoadImage(PCWSTR pwszName)
|
UserLoadImage(PCWSTR pwszName)
|
||||||
{
|
{
|
||||||
NTSTATUS Status;
|
NTSTATUS Status = STATUS_SUCCESS;
|
||||||
HANDLE hFile, hSection;
|
HANDLE hFile, hSection;
|
||||||
BITMAPFILEHEADER *pbmfh;
|
BITMAPFILEHEADER *pbmfh;
|
||||||
LPBITMAPINFO pbmi;
|
LPBITMAPINFO pbmi;
|
||||||
ULONG cjInfoSize;
|
|
||||||
PVOID pvBits;
|
PVOID pvBits;
|
||||||
HBITMAP hbmp = 0;
|
HBITMAP hbmp = 0;
|
||||||
BITMAPV5INFO bmiLocal;
|
|
||||||
|
|
||||||
DPRINT("Enter UserLoadImage(%ls)\n", pwszName);
|
DPRINT("Enter UserLoadImage(%ls)\n", pwszName);
|
||||||
|
|
||||||
|
@ -194,40 +192,58 @@ UserLoadImage(PCWSTR pwszName)
|
||||||
/* Get a pointer to the BITMAPINFO */
|
/* Get a pointer to the BITMAPINFO */
|
||||||
pbmi = (LPBITMAPINFO)(pbmfh + 1);
|
pbmi = (LPBITMAPINFO)(pbmfh + 1);
|
||||||
|
|
||||||
/* Create a normalized local BITMAPINFO */
|
_SEH2_TRY
|
||||||
_SEH2_TRY
|
{
|
||||||
{
|
ProbeForRead(&pbmfh->bfSize, sizeof(DWORD), 1);
|
||||||
Status = ProbeAndConvertToBitmapV5Info(&bmiLocal,
|
ProbeForRead(pbmfh, pbmfh->bfSize, 1);
|
||||||
pbmi,
|
}
|
||||||
DIB_RGB_COLORS,
|
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
|
||||||
0);
|
{
|
||||||
}
|
Status = _SEH2_GetExceptionCode();
|
||||||
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
|
}
|
||||||
{
|
_SEH2_END
|
||||||
Status = _SEH2_GetExceptionCode();
|
|
||||||
}
|
|
||||||
_SEH2_END
|
|
||||||
|
|
||||||
if (NT_SUCCESS(Status))
|
if(!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
DPRINT1("Bad File?\n");
|
||||||
|
goto leave;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pbmfh->bfType == 0x4D42 /* 'BM' */)
|
||||||
{
|
{
|
||||||
cjInfoSize = bmiLocal.bmiHeader.bV5Size +
|
/* Could be BITMAPCOREINFO */
|
||||||
bmiLocal.bmiHeader.bV5ClrUsed * sizeof(RGBQUAD);
|
BITMAPINFO* pConvertedInfo;
|
||||||
pvBits = (PVOID)((PCHAR)pbmi + cjInfoSize);
|
|
||||||
|
pvBits = (PVOID)((PCHAR)pbmi + pbmfh->bfOffBits);
|
||||||
|
|
||||||
|
pConvertedInfo = DIB_ConvertBitmapInfo(pbmi, DIB_RGB_COLORS);
|
||||||
|
if(!pConvertedInfo)
|
||||||
|
{
|
||||||
|
DPRINT1("Unable to convert the bitmap Info\n");
|
||||||
|
goto leave;
|
||||||
|
}
|
||||||
|
|
||||||
// FIXME: use Gre... so that the BITMAPINFO doesn't get probed
|
// FIXME: use Gre... so that the BITMAPINFO doesn't get probed
|
||||||
hbmp = NtGdiCreateDIBitmapInternal(NULL,
|
hbmp = NtGdiCreateDIBitmapInternal(NULL,
|
||||||
bmiLocal.bmiHeader.bV5Width,
|
pConvertedInfo->bmiHeader.biWidth,
|
||||||
bmiLocal.bmiHeader.bV5Height,
|
pConvertedInfo->bmiHeader.biHeight,
|
||||||
CBM_INIT,
|
CBM_INIT,
|
||||||
pvBits,
|
pvBits,
|
||||||
pbmi,
|
pbmi,
|
||||||
DIB_RGB_COLORS,
|
DIB_RGB_COLORS,
|
||||||
bmiLocal.bmiHeader.bV5Size,
|
pConvertedInfo->bmiHeader.biSize,
|
||||||
bmiLocal.bmiHeader.bV5SizeImage,
|
pConvertedInfo->bmiHeader.biSizeImage,
|
||||||
0,
|
0,
|
||||||
0);
|
0);
|
||||||
}
|
|
||||||
|
|
||||||
|
DIB_FreeConvertedBitmapInfo(pConvertedInfo, pbmi);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
DPRINT1("Unknown file type!\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
leave:
|
||||||
/* Unmap our section, we don't need it anymore */
|
/* Unmap our section, we don't need it anymore */
|
||||||
ZwUnmapViewOfSection(NtCurrentProcess(), pbmfh);
|
ZwUnmapViewOfSection(NtCurrentProcess(), pbmfh);
|
||||||
|
|
||||||
|
|
|
@ -674,18 +674,12 @@ NtGdiGetDIBitsInternal(
|
||||||
/* We need a BITMAPINFO to create a DIB, but we have to fill
|
/* We need a BITMAPINFO to create a DIB, but we have to fill
|
||||||
* the BITMAPCOREINFO we're provided */
|
* the BITMAPCOREINFO we're provided */
|
||||||
pbmci = (BITMAPCOREINFO*)Info;
|
pbmci = (BITMAPCOREINFO*)Info;
|
||||||
Info = ExAllocatePoolWithTag(PagedPool, sizeof(BITMAPINFOHEADER) + 256 * sizeof(RGBQUAD), TAG_DIB);
|
Info = DIB_ConvertBitmapInfo((BITMAPINFO*)pbmci, Usage);
|
||||||
if(Info == NULL)
|
if(Info == NULL)
|
||||||
{
|
{
|
||||||
DPRINT1("Error, could not allocate another BITMAPINFO!\n");
|
DPRINT1("Error, could not convert the BITMAPCOREINFO!\n");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
RtlZeroMemory(Info, sizeof(BITMAPINFOHEADER) + 256 * sizeof(RGBQUAD));
|
|
||||||
Info->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
|
|
||||||
Info->bmiHeader.biBitCount = pbmci->bmciHeader.bcBitCount;
|
|
||||||
Info->bmiHeader.biPlanes = pbmci->bmciHeader.bcPlanes;
|
|
||||||
Info->bmiHeader.biWidth = pbmci->bmciHeader.bcWidth;
|
|
||||||
Info->bmiHeader.biHeight = pbmci->bmciHeader.bcHeight;
|
|
||||||
rgbQuads = Info->bmiColors;
|
rgbQuads = Info->bmiColors;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1050,7 +1044,7 @@ done:
|
||||||
|
|
||||||
if(pDC) DC_UnlockDc(pDC);
|
if(pDC) DC_UnlockDc(pDC);
|
||||||
if(psurf) SURFACE_UnlockSurface(psurf);
|
if(psurf) SURFACE_UnlockSurface(psurf);
|
||||||
if(pbmci) ExFreePoolWithTag(Info, TAG_DIB);
|
if(pbmci) DIB_FreeConvertedBitmapInfo(Info, (BITMAPINFO*)pbmci);
|
||||||
|
|
||||||
return ScanLines;
|
return ScanLines;
|
||||||
}
|
}
|
||||||
|
@ -2077,4 +2071,82 @@ ProbeAndConvertToBitmapV5Info(
|
||||||
return STATUS_SUCCESS;
|
return STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Converts a BITMAPCOREINFO to a BITMAPINFO structure,
|
||||||
|
* or does nothing if it's already a BITMAPINFO (or V4 or V5) */
|
||||||
|
BITMAPINFO*
|
||||||
|
FASTCALL
|
||||||
|
DIB_ConvertBitmapInfo (CONST BITMAPINFO* pbmi, DWORD Usage)
|
||||||
|
{
|
||||||
|
CONST BITMAPCOREINFO* pbmci = (BITMAPCOREINFO*)pbmi;
|
||||||
|
BITMAPINFO* pNewBmi ;
|
||||||
|
UINT numColors = 0, ColorsSize = 0;
|
||||||
|
|
||||||
|
if(pbmi->bmiHeader.biSize >= sizeof(BITMAPINFOHEADER)) return (BITMAPINFO*)pbmi;
|
||||||
|
if(pbmi->bmiHeader.biSize != sizeof(BITMAPCOREHEADER)) return NULL;
|
||||||
|
|
||||||
|
if(pbmci->bmciHeader.bcBitCount <= 8)
|
||||||
|
{
|
||||||
|
numColors = 1 << pbmci->bmciHeader.bcBitCount;
|
||||||
|
if(Usage == DIB_PAL_COLORS)
|
||||||
|
{
|
||||||
|
ColorsSize = numColors * sizeof(WORD);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ColorsSize = numColors * sizeof(RGBQUAD);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (Usage == DIB_PAL_COLORS)
|
||||||
|
{
|
||||||
|
/* Invalid at high Res */
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
pNewBmi = ExAllocatePoolWithTag(PagedPool, sizeof(BITMAPINFOHEADER) + ColorsSize, TAG_DIB);
|
||||||
|
if(!pNewBmi) return NULL;
|
||||||
|
|
||||||
|
RtlZeroMemory(pNewBmi, sizeof(BITMAPINFOHEADER) + ColorsSize);
|
||||||
|
|
||||||
|
pNewBmi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
|
||||||
|
pNewBmi->bmiHeader.biBitCount = pbmci->bmciHeader.bcBitCount;
|
||||||
|
pNewBmi->bmiHeader.biWidth = pbmci->bmciHeader.bcWidth;
|
||||||
|
pNewBmi->bmiHeader.biHeight = pbmci->bmciHeader.bcHeight;
|
||||||
|
pNewBmi->bmiHeader.biPlanes = pbmci->bmciHeader.bcPlanes;
|
||||||
|
pNewBmi->bmiHeader.biCompression = BI_RGB ;
|
||||||
|
pNewBmi->bmiHeader.biSizeImage = DIB_GetDIBImageBytes(pNewBmi->bmiHeader.biWidth,
|
||||||
|
pNewBmi->bmiHeader.biHeight,
|
||||||
|
pNewBmi->bmiHeader.biBitCount);
|
||||||
|
|
||||||
|
if(Usage == DIB_PAL_COLORS)
|
||||||
|
{
|
||||||
|
RtlCopyMemory(pNewBmi->bmiColors, pbmci->bmciColors, ColorsSize);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
UINT i;
|
||||||
|
for(i=0; i<numColors; i++)
|
||||||
|
{
|
||||||
|
pNewBmi->bmiColors[i].rgbRed = pbmci->bmciColors[i].rgbtRed;
|
||||||
|
pNewBmi->bmiColors[i].rgbGreen = pbmci->bmciColors[i].rgbtGreen;
|
||||||
|
pNewBmi->bmiColors[i].rgbBlue = pbmci->bmciColors[i].rgbtBlue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return pNewBmi ;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Frees a BITMAPINFO created with DIB_ConvertBitmapInfo */
|
||||||
|
VOID
|
||||||
|
FASTCALL
|
||||||
|
DIB_FreeConvertedBitmapInfo(BITMAPINFO* converted, BITMAPINFO* orig)
|
||||||
|
{
|
||||||
|
if(converted != orig)
|
||||||
|
ExFreePoolWithTag(converted, TAG_DIB);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* EOF */
|
/* EOF */
|
||||||
|
|
Loading…
Reference in a new issue