-FORCEINLINE
-DWORD
-GetBMIColor(CONST BITMAPINFO* pbmi, INT i)
-{
- DWORD dwRet = 0;
- INT size;
- if(pbmi->bmiHeader.biSize == sizeof(BITMAPCOREHEADER))
- {
- /* BITMAPCOREINFO holds RGBTRIPLE values */
- size = sizeof(RGBTRIPLE);
- }
- else
- {
- size = sizeof(RGBQUAD);
- }
- memcpy(&dwRet, (PBYTE)pbmi + pbmi->bmiHeader.biSize + i*size, size);
- return dwRet;
-}
-
-NTSTATUS
-FASTCALL
-ProbeAndConvertToBitmapV5Info(
- OUT PBITMAPV5INFO pbmiDst,
- IN CONST BITMAPINFO* pbmiUnsafe,
- IN DWORD dwColorUse,
- IN UINT MaxSize)
-{
- DWORD dwSize;
- ULONG ulWidthBytes;
- PBITMAPV5HEADER pbmhDst = &pbmiDst->bmiHeader;
-
- /* Get the size and probe */
- ProbeForRead(&pbmiUnsafe->bmiHeader.biSize, sizeof(DWORD), 1);
- dwSize = pbmiUnsafe->bmiHeader.biSize;
- /* At least dwSize bytes must be valids */
- ProbeForRead(pbmiUnsafe, max(dwSize, MaxSize), 1);
- if(!MaxSize)
- ProbeForRead(pbmiUnsafe, DIB_BitmapInfoSize(pbmiUnsafe, dwColorUse), 1);
-
- /* Check the size */
- // FIXME: are intermediate sizes allowed? As what are they interpreted?
- // make sure we don't use a too big dwSize later
- if (dwSize != sizeof(BITMAPCOREHEADER) &&
- dwSize != sizeof(BITMAPINFOHEADER) &&
- dwSize != sizeof(BITMAPV4HEADER) &&
- dwSize != sizeof(BITMAPV5HEADER))
- {
- return STATUS_INVALID_PARAMETER;
- }
-
- if (dwSize == sizeof(BITMAPCOREHEADER))
- {
- PBITMAPCOREHEADER pbch = (PBITMAPCOREHEADER)pbmiUnsafe;
-
- /* Manually copy the fields that are present */
- pbmhDst->bV5Width = pbch->bcWidth;
- pbmhDst->bV5Height = pbch->bcHeight;
- pbmhDst->bV5Planes = pbch->bcPlanes;
- pbmhDst->bV5BitCount = pbch->bcBitCount;
-
- /* Set some default values */
- pbmhDst->bV5Compression = BI_RGB;
- pbmhDst->bV5SizeImage = DIB_GetDIBImageBytes(pbch->bcWidth,
- pbch->bcHeight,
- pbch->bcPlanes*pbch->bcBitCount) ;
- pbmhDst->bV5XPelsPerMeter = 72;
- pbmhDst->bV5YPelsPerMeter = 72;
- pbmhDst->bV5ClrUsed = 0;
- pbmhDst->bV5ClrImportant = 0;
- }
- else
- {
- /* Copy valid fields */
- memcpy(pbmiDst, pbmiUnsafe, dwSize);
- if(!pbmhDst->bV5SizeImage)
- pbmhDst->bV5SizeImage = DIB_GetDIBImageBytes(pbmhDst->bV5Width,
- pbmhDst->bV5Height,
- pbmhDst->bV5Planes*pbmhDst->bV5BitCount) ;
-
- if(dwSize < sizeof(BITMAPV5HEADER))
- {
- /* Zero out the rest of the V5 header */
- memset((char*)pbmiDst + dwSize, 0, sizeof(BITMAPV5HEADER) - dwSize);
- }
- }
- pbmhDst->bV5Size = sizeof(BITMAPV5HEADER);
-
-
- if (dwSize < sizeof(BITMAPV4HEADER))
- {
- if (pbmhDst->bV5Compression == BI_BITFIELDS)
- {
- pbmhDst->bV5RedMask = GetBMIColor(pbmiUnsafe, 0);
- pbmhDst->bV5GreenMask = GetBMIColor(pbmiUnsafe, 1);
- pbmhDst->bV5BlueMask = GetBMIColor(pbmiUnsafe, 2);
- pbmhDst->bV5AlphaMask = 0;
- pbmhDst->bV5ClrUsed = 0;
- }
-
-// pbmhDst->bV5CSType;
-// pbmhDst->bV5Endpoints;
-// pbmhDst->bV5GammaRed;
-// pbmhDst->bV5GammaGreen;
-// pbmhDst->bV5GammaBlue;
- }
-
- if (dwSize < sizeof(BITMAPV5HEADER))
- {
-// pbmhDst->bV5Intent;
-// pbmhDst->bV5ProfileData;
-// pbmhDst->bV5ProfileSize;
-// pbmhDst->bV5Reserved;
- }
-
- ulWidthBytes = ((pbmhDst->bV5Width * pbmhDst->bV5Planes *
- pbmhDst->bV5BitCount + 31) & ~31) / 8;
-
- if (pbmhDst->bV5SizeImage == 0)
- pbmhDst->bV5SizeImage = abs(ulWidthBytes * pbmhDst->bV5Height);
-
- if (pbmhDst->bV5ClrUsed == 0)
- {
- switch(pbmhDst->bV5BitCount)
- {
- case 1:
- pbmhDst->bV5ClrUsed = 2;
- break;
- case 4:
- pbmhDst->bV5ClrUsed = 16;
- break;
- case 8:
- pbmhDst->bV5ClrUsed = 256;
- break;
- default:
- pbmhDst->bV5ClrUsed = 0;
- break;
- }
- }
-
- if (pbmhDst->bV5Planes != 1)
- {
- return STATUS_INVALID_PARAMETER;
- }
-
- if (pbmhDst->bV5BitCount != 0 && pbmhDst->bV5BitCount != 1 &&
- pbmhDst->bV5BitCount != 4 && pbmhDst->bV5BitCount != 8 &&
- pbmhDst->bV5BitCount != 16 && pbmhDst->bV5BitCount != 24 &&
- pbmhDst->bV5BitCount != 32)
- {
- DPRINT("Invalid bit count: %d\n", pbmhDst->bV5BitCount);
- return STATUS_INVALID_PARAMETER;
- }
-
- if ((pbmhDst->bV5BitCount == 0 &&
- pbmhDst->bV5Compression != BI_JPEG && pbmhDst->bV5Compression != BI_PNG))
- {
- DPRINT("Bit count 0 is invalid for compression %d.\n", pbmhDst->bV5Compression);
- return STATUS_INVALID_PARAMETER;
- }
-
- if (pbmhDst->bV5Compression == BI_BITFIELDS &&
- pbmhDst->bV5BitCount != 16 && pbmhDst->bV5BitCount != 32)
- {
- DPRINT("Bit count %d is invalid for compression BI_BITFIELDS.\n", pbmhDst->bV5BitCount);
- return STATUS_INVALID_PARAMETER;
- }
-
- /* Copy Colors */
- if(pbmhDst->bV5ClrUsed)
- {
- INT i;
- if(dwColorUse == DIB_PAL_COLORS)
- {
- RtlCopyMemory(pbmiDst->bmiColors,
- pbmiUnsafe->bmiColors,
- pbmhDst->bV5ClrUsed * sizeof(WORD));
- }
- else
- {
- for(i = 0; i < pbmhDst->bV5ClrUsed; i++)
- {
- ((DWORD*)pbmiDst->bmiColors)[i] = GetBMIColor(pbmiUnsafe, i);
- }
- }
- }
-
- return STATUS_SUCCESS;
-}
-