mirror of
https://github.com/reactos/reactos.git
synced 2025-02-22 16:36:33 +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
|
||||
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
|
||||
UserLoadImage(PCWSTR pwszName)
|
||||
{
|
||||
NTSTATUS Status;
|
||||
NTSTATUS Status = STATUS_SUCCESS;
|
||||
HANDLE hFile, hSection;
|
||||
BITMAPFILEHEADER *pbmfh;
|
||||
LPBITMAPINFO pbmi;
|
||||
ULONG cjInfoSize;
|
||||
PVOID pvBits;
|
||||
HBITMAP hbmp = 0;
|
||||
BITMAPV5INFO bmiLocal;
|
||||
|
||||
DPRINT("Enter UserLoadImage(%ls)\n", pwszName);
|
||||
|
||||
|
@ -194,40 +192,58 @@ UserLoadImage(PCWSTR pwszName)
|
|||
/* Get a pointer to the BITMAPINFO */
|
||||
pbmi = (LPBITMAPINFO)(pbmfh + 1);
|
||||
|
||||
/* Create a normalized local BITMAPINFO */
|
||||
_SEH2_TRY
|
||||
{
|
||||
Status = ProbeAndConvertToBitmapV5Info(&bmiLocal,
|
||||
pbmi,
|
||||
DIB_RGB_COLORS,
|
||||
0);
|
||||
}
|
||||
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
|
||||
{
|
||||
Status = _SEH2_GetExceptionCode();
|
||||
}
|
||||
_SEH2_END
|
||||
_SEH2_TRY
|
||||
{
|
||||
ProbeForRead(&pbmfh->bfSize, sizeof(DWORD), 1);
|
||||
ProbeForRead(pbmfh, pbmfh->bfSize, 1);
|
||||
}
|
||||
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
|
||||
{
|
||||
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 +
|
||||
bmiLocal.bmiHeader.bV5ClrUsed * sizeof(RGBQUAD);
|
||||
pvBits = (PVOID)((PCHAR)pbmi + cjInfoSize);
|
||||
/* Could be BITMAPCOREINFO */
|
||||
BITMAPINFO* pConvertedInfo;
|
||||
|
||||
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
|
||||
hbmp = NtGdiCreateDIBitmapInternal(NULL,
|
||||
bmiLocal.bmiHeader.bV5Width,
|
||||
bmiLocal.bmiHeader.bV5Height,
|
||||
pConvertedInfo->bmiHeader.biWidth,
|
||||
pConvertedInfo->bmiHeader.biHeight,
|
||||
CBM_INIT,
|
||||
pvBits,
|
||||
pbmi,
|
||||
DIB_RGB_COLORS,
|
||||
bmiLocal.bmiHeader.bV5Size,
|
||||
bmiLocal.bmiHeader.bV5SizeImage,
|
||||
pConvertedInfo->bmiHeader.biSize,
|
||||
pConvertedInfo->bmiHeader.biSizeImage,
|
||||
0,
|
||||
0);
|
||||
}
|
||||
|
||||
DIB_FreeConvertedBitmapInfo(pConvertedInfo, pbmi);
|
||||
}
|
||||
else
|
||||
{
|
||||
DPRINT1("Unknown file type!\n");
|
||||
}
|
||||
|
||||
leave:
|
||||
/* Unmap our section, we don't need it anymore */
|
||||
ZwUnmapViewOfSection(NtCurrentProcess(), pbmfh);
|
||||
|
||||
|
|
|
@ -674,18 +674,12 @@ NtGdiGetDIBitsInternal(
|
|||
/* We need a BITMAPINFO to create a DIB, but we have to fill
|
||||
* the BITMAPCOREINFO we're provided */
|
||||
pbmci = (BITMAPCOREINFO*)Info;
|
||||
Info = ExAllocatePoolWithTag(PagedPool, sizeof(BITMAPINFOHEADER) + 256 * sizeof(RGBQUAD), TAG_DIB);
|
||||
Info = DIB_ConvertBitmapInfo((BITMAPINFO*)pbmci, Usage);
|
||||
if(Info == NULL)
|
||||
{
|
||||
DPRINT1("Error, could not allocate another BITMAPINFO!\n");
|
||||
DPRINT1("Error, could not convert the BITMAPCOREINFO!\n");
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -1050,7 +1044,7 @@ done:
|
|||
|
||||
if(pDC) DC_UnlockDc(pDC);
|
||||
if(psurf) SURFACE_UnlockSurface(psurf);
|
||||
if(pbmci) ExFreePoolWithTag(Info, TAG_DIB);
|
||||
if(pbmci) DIB_FreeConvertedBitmapInfo(Info, (BITMAPINFO*)pbmci);
|
||||
|
||||
return ScanLines;
|
||||
}
|
||||
|
@ -2077,4 +2071,82 @@ ProbeAndConvertToBitmapV5Info(
|
|||
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 */
|
||||
|
|
Loading…
Reference in a new issue