_In_ ULONG iUsage)
{
PPALETTE ppal;
- ULONG i, cColors;
+ ULONG i, cBitsPixel, cColors;
+
+ if (pbmi->bmiHeader.biSize < sizeof(BITMAPINFOHEADER))
+ {
+ PBITMAPCOREINFO pbci = (PBITMAPCOREINFO)pbmi;
+ cBitsPixel = pbci->bmciHeader.bcBitCount;
+ }
+ else
+ {
+ cBitsPixel = pbmi->bmiHeader.biBitCount;
+ }
/* Check if the colors are indexed */
- if (pbmi->bmiHeader.biBitCount <= 8)
+ if (cBitsPixel <= 8)
{
/* We create a "full" palette */
- cColors = 1 << pbmi->bmiHeader.biBitCount;
+ cColors = 1 << cBitsPixel;
/* Allocate the palette */
ppal = PALETTE_AllocPalette(PAL_INDEXED,
0);
/* Check if the BITMAPINFO specifies how many colors to use */
- if (pbmi->bmiHeader.biClrUsed != 0)
+ if ((pbmi->bmiHeader.biSize >= sizeof(BITMAPINFOHEADER)) &&
+ (pbmi->bmiHeader.biClrUsed != 0))
{
/* This is how many colors we can actually process */
cColors = min(cColors, pbmi->bmiHeader.biClrUsed);
/* Loop all color indices in the DIB */
for (i = 0; i < cColors; i++)
{
- /* Get the RGB value from the DC palette, indexed by the DIB
- color table value */
- crColor = PALETTE_ulGetRGBColorFromIndex(ppalDC, pwColors[i]);
+ /* Get the palette index and handle wraparound when exceeding
+ the number of colors in the DC palette */
+ WORD wIndex = pwColors[i] % ppalDC->NumColors;
+
+ /* USe the RGB value from the DC palette */
+ crColor = PALETTE_ulGetRGBColorFromIndex(ppalDC, wIndex);
PALETTE_vSetRGBColorForIndex(ppal, i, crColor);
}
}
// FIXME: this one is undocumented
// ASSERT(FALSE);
// }
- else // if (iUsage == DIB_RGB_COLORS)
+ else if (pbmi->bmiHeader.biSize >= sizeof(BITMAPINFOHEADER))
{
/* The colors are an array of RGBQUAD values */
RGBQUAD *prgb = (RGBQUAD*)((PCHAR)pbmi + pbmi->bmiHeader.biSize);
RGBQUAD rgb = prgb[i];
COLORREF crColor = RGB(rgb.rgbRed, rgb.rgbGreen, rgb.rgbBlue);
+ /* Set the RGB value in the palette */
+ PALETTE_vSetRGBColorForIndex(ppal, i, crColor);
+ }
+ }
+ else
+ {
+ /* The colors are an array of RGBTRIPLE values */
+ RGBTRIPLE *prgb = (RGBTRIPLE*)((PCHAR)pbmi + pbmi->bmiHeader.biSize);
+
+ /* Loop all color indices in the DIB */
+ for (i = 0; i < cColors; i++)
+ {
+ /* Get the color value and translate it to a COLORREF */
+ RGBTRIPLE rgb = prgb[i];
+ COLORREF crColor = RGB(rgb.rgbtRed, rgb.rgbtGreen, rgb.rgbtBlue);
+
/* Set the RGB value in the palette */
PALETTE_vSetRGBColorForIndex(ppal, i, crColor);
}
ULONG flRedMask, flGreenMask, flBlueMask;
/* Check if the DIB contains bitfield values */
- if (pbmi->bmiHeader.biCompression == BI_BITFIELDS)
+ if ((pbmi->bmiHeader.biSize >= sizeof(BITMAPINFOHEADER)) &&
+ (pbmi->bmiHeader.biCompression == BI_BITFIELDS))
{
/* Check if we have a v4/v5 header */
if (pbmi->bmiHeader.biSize >= sizeof(BITMAPV4HEADER))
{
/* Check what bit depth we have. Note: optimization flags are
calculated in PALETTE_AllocPalette() */
- if (pbmi->bmiHeader.biBitCount == 16)
+ if (cBitsPixel == 16)
{
/* This is an RGB 555 palette */
flRedMask = 0x7C00;
return ppal;
}
-
-UINT
-APIENTRY
-IntSetDIBColorTable(
- HDC hDC,
- UINT StartIndex,
- UINT Entries,
- CONST RGBQUAD *Colors)
-{
- PDC dc;
- PSURFACE psurf;
- PPALETTE PalGDI;
- UINT Index;
- ULONG biBitCount;
-
- if (!(dc = DC_LockDc(hDC))) return 0;
- if (dc->dctype == DC_TYPE_INFO)
- {
- DC_UnlockDc(dc);
- return 0;
- }
-
- psurf = dc->dclevel.pSurface;
- if (psurf == NULL)
- {
- DC_UnlockDc(dc);
- EngSetLastError(ERROR_INVALID_PARAMETER);
- return 0;
- }
-
- if (psurf->hSecure == NULL)
- {
- DC_UnlockDc(dc);
- EngSetLastError(ERROR_INVALID_PARAMETER);
- return 0;
- }
-
- biBitCount = BitsPerFormat(psurf->SurfObj.iBitmapFormat);
- if ((biBitCount <= 8) && (StartIndex < (1UL << biBitCount)))
- {
- if (StartIndex + Entries > (1UL << biBitCount))
- Entries = (1 << biBitCount) - StartIndex;
-
- if (psurf->ppal == NULL)
- {
- DC_UnlockDc(dc);
- EngSetLastError(ERROR_INVALID_HANDLE);
- return 0;
- }
-
- PalGDI = psurf->ppal;
-
- for (Index = StartIndex;
- Index < StartIndex + Entries && Index < PalGDI->NumColors;
- Index++)
- {
- PalGDI->IndexedColors[Index].peRed = Colors[Index - StartIndex].rgbRed;
- PalGDI->IndexedColors[Index].peGreen = Colors[Index - StartIndex].rgbGreen;
- PalGDI->IndexedColors[Index].peBlue = Colors[Index - StartIndex].rgbBlue;
- }
- }
- else
- Entries = 0;
-
- /* Mark the brushes invalid */
- dc->pdcattr->ulDirty_ |= DIRTY_FILL|DIRTY_LINE|DIRTY_BACKGROUND|DIRTY_TEXT;
-
- DC_UnlockDc(dc);
-
- return Entries;
-}
-
-UINT
-APIENTRY
-IntGetDIBColorTable(
- HDC hDC,
- UINT StartIndex,
- UINT Entries,
- RGBQUAD *Colors)
-{
- PDC dc;
- PSURFACE psurf;
- PPALETTE ppal;
- UINT Index, Count = 0;
-
- if (!(dc = DC_LockDc(hDC))) return 0;
- if (dc->dctype == DC_TYPE_INFO)
- {
- DC_UnlockDc(dc);
- return 0;
- }
-
- psurf = dc->dclevel.pSurface;
- if (psurf == NULL)
- {
- DC_UnlockDc(dc);
- EngSetLastError(ERROR_INVALID_PARAMETER);
- return 0;
- }
-
- if (psurf->hSecure == NULL)
- {
- DC_UnlockDc(dc);
- EngSetLastError(ERROR_INVALID_PARAMETER);
- return 0;
- }
-
- ppal = psurf->ppal;
- ASSERT(ppal);
-
- if (ppal->flFlags & PAL_INDEXED)
- {
-
- for (Index = StartIndex;
- Index < StartIndex + Entries && Index < ppal->NumColors;
- Index++)
- {
- Colors[Index - StartIndex].rgbRed = ppal->IndexedColors[Index].peRed;
- Colors[Index - StartIndex].rgbGreen = ppal->IndexedColors[Index].peGreen;
- Colors[Index - StartIndex].rgbBlue = ppal->IndexedColors[Index].peBlue;
- Colors[Index - StartIndex].rgbReserved = 0;
- Count++;
- }
- }
-
- DC_UnlockDc(dc);
-
- return Count;
-}
-
// Converts a DIB to a device-dependent bitmap
static INT
FASTCALL
EXLATEOBJ exlo;
PPALETTE ppalDIB = 0;
+ if (!bmi) return 0;
+
SourceBitmap = GreCreateBitmapEx(bmi->bmiHeader.biWidth,
ScanLines,
0,
return result;
}
+static
+HBITMAP
+IntGdiCreateMaskFromRLE(
+ DWORD Width,
+ DWORD Height,
+ ULONG Compression,
+ const BYTE* Bits,
+ DWORD BitsSize)
+{
+ HBITMAP Mask;
+ DWORD x, y;
+ SURFOBJ* SurfObj;
+ UINT i = 0;
+ BYTE Data, NumPixels, ToSkip;
+
+ ASSERT((Compression == BI_RLE8) || (Compression == BI_RLE4));
+
+ /* Create the bitmap */
+ Mask = GreCreateBitmapEx(Width, Height, 0, BMF_1BPP, 0, 0, NULL, 0);
+ if (!Mask)
+ return NULL;
+
+ SurfObj = EngLockSurface((HSURF)Mask);
+ if (!SurfObj)
+ {
+ GreDeleteObject(Mask);
+ return NULL;
+ }
+ ASSERT(SurfObj->pvBits != NULL);
+
+ x = y = 0;
+
+ while (i < BitsSize)
+ {
+ NumPixels = Bits[i];
+ Data = Bits[i + 1];
+ i += 2;
+
+ if (NumPixels != 0)
+ {
+ if ((x + NumPixels) > Width)
+ NumPixels = Width - x;
+
+ if (NumPixels == 0)
+ continue;
+
+ DIB_1BPP_HLine(SurfObj, x, x + NumPixels, y, 1);
+ x += NumPixels;
+ continue;
+ }
+
+ if (Data < 3)
+ {
+ switch (Data)
+ {
+ case 0:
+ /* End of line */
+ y++;
+ if (y == Height)
+ goto done;
+ x = 0;
+ break;
+ case 1:
+ /* End of file */
+ goto done;
+ case 2:
+ /* Jump */
+ if (i >= (BitsSize - 1))
+ goto done;
+ x += Bits[i];
+ if (x > Width)
+ x = Width;
+ y += Bits[i + 1];
+ if (y >= Height)
+ goto done;
+ i += 2;
+ break;
+ }
+ /* Done for this run */
+ continue;
+ }
+
+ /* Embedded data into the RLE */
+ NumPixels = Data;
+ if (Compression == BI_RLE8)
+ ToSkip = NumPixels;
+ else
+ ToSkip = (NumPixels / 2) + (NumPixels & 1);
+
+ if ((i + ToSkip) > BitsSize)
+ goto done;
+ ToSkip = (ToSkip + 1) & ~1;
+
+ if ((x + NumPixels) > Width)
+ NumPixels = Width - x;
+
+ if (NumPixels != 0)
+ {
+ DIB_1BPP_HLine(SurfObj, x, x + NumPixels, y, 1);
+ x += NumPixels;
+ }
+ i += ToSkip;
+ }
+
+done:
+ EngUnlockSurface(SurfObj);
+ return Mask;
+}
+
W32KAPI
INT
APIENTRY
INT ret = 0;
NTSTATUS Status = STATUS_SUCCESS;
PDC pDC;
- HBITMAP hSourceBitmap = NULL;
- SURFOBJ *pDestSurf, *pSourceSurf = NULL;
+ HBITMAP hSourceBitmap = NULL, hMaskBitmap = NULL;
+ SURFOBJ *pDestSurf, *pSourceSurf = NULL, *pMaskSurf = NULL;
SURFACE *pSurf;
RECTL rcDest;
POINTL ptSource;
goto Exit2;
}
+ ScanLines = min(ScanLines, abs(bmi->bmiHeader.biHeight) - StartScan);
+
pDC = DC_LockDc(hDC);
if (!pDC)
{
EngSetLastError(ERROR_INVALID_HANDLE);
goto Exit2;
}
+
if (pDC->dctype == DC_TYPE_INFO)
{
DC_UnlockDc(pDC);
- goto Exit2;
+ goto Exit;
}
- pSurf = pDC->dclevel.pSurface;
-
- pDestSurf = pSurf ? &pSurf->SurfObj : NULL;
-
- ScanLines = min(ScanLines, abs(bmi->bmiHeader.biHeight) - StartScan);
-
rcDest.left = XDest;
rcDest.top = YDest;
if (bTransformCoordinates)
goto Exit;
}
- ASSERT(pSurf->ppal);
+ /* HACK: If this is a RLE bitmap, only the relevant pixels must be set. */
+ if ((bmi->bmiHeader.biCompression == BI_RLE8) || (bmi->bmiHeader.biCompression == BI_RLE4))
+ {
+ hMaskBitmap = IntGdiCreateMaskFromRLE(bmi->bmiHeader.biWidth,
+ ScanLines,
+ bmi->bmiHeader.biCompression,
+ Bits,
+ cjMaxBits);
+ if (!hMaskBitmap)
+ {
+ EngSetLastError(ERROR_NO_SYSTEM_RESOURCES);
+ Status = STATUS_NO_MEMORY;
+ goto Exit;
+ }
+ pMaskSurf = EngLockSurface((HSURF)hMaskBitmap);
+ if (!pMaskSurf)
+ {
+ Status = STATUS_UNSUCCESSFUL;
+ goto Exit;
+ }
+ }
/* Create a palette for the DIB */
ppalDIB = CreateDIBPalette(bmi, pDC, ColorUse);
goto Exit;
}
+ /* This is actually a blit */
+ DC_vPrepareDCsForBlit(pDC, &rcDest, NULL, NULL);
+ pSurf = pDC->dclevel.pSurface;
+ if (!pSurf)
+ {
+ DC_vFinishBlit(pDC, NULL);
+ ret = ScanLines;
+ goto Exit;
+ }
+
+ ASSERT(pSurf->ppal);
+
/* Initialize EXLATEOBJ */
EXLATEOBJ_vInitialize(&exlo,
ppalDIB,
pDC->pdcattr->crBackgroundClr,
pDC->pdcattr->crForegroundClr);
+ pDestSurf = &pSurf->SurfObj;
+
/* Copy the bits */
DPRINT("BitsToDev with dstsurf=(%d|%d) (%d|%d), src=(%d|%d) w=%d h=%d\n",
rcDest.left, rcDest.top, rcDest.right, rcDest.bottom,
ptSource.x, ptSource.y, SourceSize.cx, SourceSize.cy);
Status = IntEngBitBlt(pDestSurf,
pSourceSurf,
- NULL,
- pDC->rosdc.CombinedClip,
+ pMaskSurf,
+ &pDC->co.ClipObj,
&exlo.xlo,
&rcDest,
&ptSource,
+ pMaskSurf ? &ptSource : NULL,
NULL,
NULL,
- NULL,
- ROP4_FROM_INDEX(R3_OPINDEX_SRCCOPY));
+ pMaskSurf ? ROP4_MASK : ROP4_FROM_INDEX(R3_OPINDEX_SRCCOPY));
/* Cleanup EXLATEOBJ */
EXLATEOBJ_vCleanup(&exlo);
+ /* We're done */
+ DC_vFinishBlit(pDC, NULL);
+
Exit:
if (NT_SUCCESS(Status))
{
if (pSourceSurf) EngUnlockSurface(pSourceSurf);
if (hSourceBitmap) EngDeleteSurface((HSURF)hSourceBitmap);
+ if (pMaskSurf) EngUnlockSurface(pMaskSurf);
+ if (hMaskBitmap) EngDeleteSurface((HSURF)hMaskBitmap);
DC_UnlockDc(pDC);
Exit2:
- ExFreePool(pbmiSafe);
+ ExFreePoolWithTag(pbmiSafe, 'pmTG');
return ret;
}
/* Converts a device-dependent bitmap to a DIB */
INT
APIENTRY
-NtGdiGetDIBitsInternal(
+GreGetDIBitsInternal(
HDC hDC,
HBITMAP hBitmap,
UINT StartScan,
DWORD compr, size ;
USHORT i;
int bitmap_type;
- RGBTRIPLE* rgbTriples;
RGBQUAD* rgbQuads;
VOID* colorPtr;
- NTSTATUS Status = STATUS_SUCCESS;
DPRINT("Entered NtGdiGetDIBitsInternal()\n");
if ((Usage && Usage != DIB_PAL_COLORS) || !Info || !hBitmap)
return 0;
- _SEH2_TRY
- {
- /* Probe for read and write */
- ProbeForRead(Info, MaxInfo, 1);
- ProbeForWrite(Info, MaxInfo, 1);
- if (Bits) ProbeForWrite(Bits, MaxBits, 1);
- }
- _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
- {
- Status = _SEH2_GetExceptionCode();
- }
- _SEH2_END
-
- if (!NT_SUCCESS(Status))
- {
- return 0;
- }
-
colorPtr = (LPBYTE)Info + Info->bmiHeader.biSize;
- rgbTriples = colorPtr;
rgbQuads = colorPtr;
bitmap_type = DIB_GetBitmapInfo(&Info->bmiHeader,
switch(bpp)
{
case 0: /* Only info */
- if(pbmci)
- {
- pbmci->bmciHeader.bcWidth = (WORD)psurf->SurfObj.sizlBitmap.cx;
- pbmci->bmciHeader.bcHeight = (WORD)((psurf->SurfObj.fjBitmap & BMF_TOPDOWN) ?
- -psurf->SurfObj.sizlBitmap.cy :
- psurf->SurfObj.sizlBitmap.cy);
- pbmci->bmciHeader.bcPlanes = 1;
- pbmci->bmciHeader.bcBitCount = BitsPerFormat(psurf->SurfObj.iBitmapFormat);
- }
Info->bmiHeader.biWidth = psurf->SurfObj.sizlBitmap.cx;
Info->bmiHeader.biHeight = (psurf->SurfObj.fjBitmap & BMF_TOPDOWN) ?
-psurf->SurfObj.sizlBitmap.cy :
if(Usage == DIB_RGB_COLORS)
{
ULONG colors = min(psurf->ppal->NumColors, 256);
-
- if(pbmci)
- {
- for(i = 0; i < colors; i++)
- {
- rgbTriples[i].rgbtRed = psurf->ppal->IndexedColors[i].peRed;
- rgbTriples[i].rgbtGreen = psurf->ppal->IndexedColors[i].peGreen;
- rgbTriples[i].rgbtBlue = psurf->ppal->IndexedColors[i].peBlue;
- }
- }
if(colors != 256) Info->bmiHeader.biClrUsed = colors;
for(i = 0; i < colors; i++)
{
rgbQuads[i].rgbRed = psurf->ppal->IndexedColors[i].peRed;
rgbQuads[i].rgbGreen = psurf->ppal->IndexedColors[i].peGreen;
rgbQuads[i].rgbBlue = psurf->ppal->IndexedColors[i].peBlue;
+ rgbQuads[i].rgbReserved = 0;
}
}
else
{
for(i = 0; i < 256; i++)
- {
- if(pbmci) ((WORD*)rgbTriples)[i] = i;
((WORD*)rgbQuads)[i] = i;
- }
}
}
else
{
for(i = 0; i < 256; i++)
{
- if(pbmci) ((WORD*)rgbTriples)[i] = i;
((WORD*)rgbQuads)[i] = i;
}
}
}
for (i = 0; i < pDcPal->NumColors; i++)
{
- if (pbmci)
- {
- rgbTriples[i].rgbtRed = pDcPal->IndexedColors[i].peRed;
- rgbTriples[i].rgbtGreen = pDcPal->IndexedColors[i].peGreen;
- rgbTriples[i].rgbtBlue = pDcPal->IndexedColors[i].peBlue;
- }
-
rgbQuads[i].rgbRed = pDcPal->IndexedColors[i].peRed;
rgbQuads[i].rgbGreen = pDcPal->IndexedColors[i].peGreen;
rgbQuads[i].rgbBlue = pDcPal->IndexedColors[i].peBlue;
switch (bpp)
{
case 1:
- if (pbmci)
- {
- rgbTriples[0].rgbtRed = rgbTriples[0].rgbtGreen =
- rgbTriples[0].rgbtBlue = 0;
- rgbTriples[1].rgbtRed = rgbTriples[1].rgbtGreen =
- rgbTriples[1].rgbtBlue = 0xff;
- }
- rgbQuads[0].rgbRed = rgbQuads[0].rgbGreen =
- rgbQuads[0].rgbBlue = 0;
+ rgbQuads[0].rgbRed = rgbQuads[0].rgbGreen = rgbQuads[0].rgbBlue = 0;
rgbQuads[0].rgbReserved = 0;
- rgbQuads[1].rgbRed = rgbQuads[1].rgbGreen =
- rgbQuads[1].rgbBlue = 0xff;
+ rgbQuads[1].rgbRed = rgbQuads[1].rgbGreen = rgbQuads[1].rgbBlue = 0xff;
rgbQuads[1].rgbReserved = 0;
break;
case 4:
- if (pbmci)
- RtlCopyMemory(rgbTriples, EGAColorsTriples, sizeof(EGAColorsTriples));
RtlCopyMemory(rgbQuads, EGAColorsQuads, sizeof(EGAColorsQuads));
-
break;
case 8:
{
INT r, g, b;
RGBQUAD *color;
- if (pbmci)
- {
- RGBTRIPLE *colorTriple;
-
- RtlCopyMemory(rgbTriples, DefLogPaletteTriples,
- 10 * sizeof(RGBTRIPLE));
- RtlCopyMemory(rgbTriples + 246, DefLogPaletteTriples + 10,
- 10 * sizeof(RGBTRIPLE));
- colorTriple = rgbTriples + 10;
- for(r = 0; r <= 5; r++) /* FIXME */
- {
- for(g = 0; g <= 5; g++)
- {
- for(b = 0; b <= 5; b++)
- {
- colorTriple->rgbtRed = (r * 0xff) / 5;
- colorTriple->rgbtGreen = (g * 0xff) / 5;
- colorTriple->rgbtBlue = (b * 0xff) / 5;
- color++;
- }
- }
- }
- }
memcpy(rgbQuads, DefLogPaletteQuads,
10 * sizeof(RGBQUAD));
memcpy(rgbQuads + 246, DefLogPaletteQuads + 10,
psurfDest = SURFACE_ShareLockSurface(hBmpDest);
- rcDest.left = 0;
- rcDest.top = 0;
- rcDest.bottom = ScanLines;
- rcDest.right = psurf->SurfObj.sizlBitmap.cx;
+ RECTL_vSetRect(&rcDest, 0, 0, psurf->SurfObj.sizlBitmap.cx, ScanLines);
srcPoint.x = 0;
ScanLines = 0;
else
{
- Status = STATUS_SUCCESS;
- _SEH2_TRY
- {
- RtlCopyMemory(Bits, pDIBits, DIB_GetDIBImageBytes (width, ScanLines, bpp));
- }
- _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
- {
- Status = _SEH2_GetExceptionCode();
- }
- _SEH2_END
-
- if(!NT_SUCCESS(Status))
- {
- DPRINT1("Unable to copy bits to the user provided pointer\n");
- ScanLines = 0;
- }
+ RtlCopyMemory(Bits, pDIBits, DIB_GetDIBImageBytes (width, ScanLines, bpp));
}
GreDeleteObject(hBmpDest);
if(pDC) DC_UnlockDc(pDC);
if(psurf) SURFACE_ShareUnlockSurface(psurf);
- if(pbmci) DIB_FreeConvertedBitmapInfo(Info, (BITMAPINFO*)pbmci);
+ if(pbmci) DIB_FreeConvertedBitmapInfo(Info, (BITMAPINFO*)pbmci, Usage);
return ScanLines;
}
+INT
+APIENTRY
+NtGdiGetDIBitsInternal(
+ _In_ HDC hdc,
+ _In_ HBITMAP hbm,
+ _In_ UINT iStartScan,
+ _In_ UINT cScans,
+ _Out_opt_ LPBYTE pjBits,
+ _Inout_ LPBITMAPINFO pbmiUser,
+ _In_ UINT iUsage,
+ _In_ UINT cjMaxBits,
+ _In_ UINT cjMaxInfo)
+{
+ PBITMAPINFO pbmi;
+ HANDLE hSecure = NULL;
+ INT iResult = 0;
+ UINT cjAlloc;
+
+ /* Check for bad iUsage */
+ if (iUsage > 2) return 0;
+
+ /* Check if the size of the bitmap info is large enough */
+ if (cjMaxInfo < sizeof(BITMAPCOREHEADER))
+ {
+ return 0;
+ }
+
+ /* Use maximum size */
+ cjMaxInfo = min(cjMaxInfo, sizeof(BITMAPV5HEADER) + 256 * sizeof(RGBQUAD));
+
+ // HACK: the underlying code sucks and doesn't care for the size, so we
+ // give it the maximum ever needed
+ cjAlloc = sizeof(BITMAPV5HEADER) + 256 * sizeof(RGBQUAD);
+
+ /* Allocate a buffer the bitmapinfo */
+ pbmi = ExAllocatePoolWithTag(PagedPool, cjAlloc, 'imBG');
+ if (!pbmi)
+ {
+ /* Fail */
+ return 0;
+ }
+
+ /* Use SEH */
+ _SEH2_TRY
+ {
+ /* Probe and copy the BITMAPINFO */
+ ProbeForRead(pbmiUser, cjMaxInfo, 1);
+ RtlCopyMemory(pbmi, pbmiUser, cjMaxInfo);
+ }
+ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+ {
+ _SEH2_YIELD(goto cleanup;)
+ }
+ _SEH2_END;
+
+ /* Check if the header size is large enough */
+ if ((pbmi->bmiHeader.biSize < sizeof(BITMAPCOREHEADER)) ||
+ (pbmi->bmiHeader.biSize > cjMaxInfo))
+ {
+ goto cleanup;
+ }
+
+ /* Check if the caller provided bitmap bits */
+ if (pjBits)
+ {
+ /* Secure the user mode memory */
+ hSecure = EngSecureMem(pjBits, cjMaxBits);
+ if (!hSecure)
+ {
+ goto cleanup;
+ }
+ }
+
+ /* Now call the internal function */
+ iResult = GreGetDIBitsInternal(hdc,
+ hbm,
+ iStartScan,
+ cScans,
+ pjBits,
+ pbmi,
+ iUsage,
+ cjMaxBits,
+ cjMaxInfo);
+
+ /* Check for success */
+ if (iResult)
+ {
+ /* Use SEH to copy back to user mode */
+ _SEH2_TRY
+ {
+ /* Copy the data back */
+ ProbeForWrite(pbmiUser, cjMaxInfo, 1);
+ RtlCopyMemory(pbmiUser, pbmi, cjMaxInfo);
+ }
+ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+ {
+ /* Ignore */
+ }
+ _SEH2_END;
+ }
+
+cleanup:
+ if (hSecure) EngUnsecureMem(hSecure);
+ ExFreePoolWithTag(pbmi, 'imBG');
+
+ return iResult;
+}
+
+
#define ROP_TO_ROP4(Rop) ((Rop) >> 16)
W32KAPI
return 0;
}
+ /* Check for info / mem DC without surface */
+ if (!pdc->dclevel.pSurface)
+ {
+ DC_UnlockDc(pdc);
+ // CHECKME
+ return TRUE;
+ }
+
/* Transform dest size */
sizel.cx = cxDst;
sizel.cy = cyDst;
hcmXform);
}
- pvBits = ExAllocatePoolWithTag(PagedPool, cjMaxBits, 'pmeT');
- if (!pvBits)
+ if (pjInit && (cjMaxBits > 0))
{
- return 0;
- }
+ pvBits = ExAllocatePoolWithTag(PagedPool, cjMaxBits, 'pmeT');
+ if (!pvBits)
+ {
+ return 0;
+ }
- _SEH2_TRY
- {
- ProbeForRead(pjInit, cjMaxBits, 1);
- RtlCopyMemory(pvBits, pjInit, cjMaxBits);
+ _SEH2_TRY
+ {
+ ProbeForRead(pjInit, cjMaxBits, 1);
+ RtlCopyMemory(pvBits, pjInit, cjMaxBits);
+ }
+ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+ {
+ ExFreePoolWithTag(pvBits, 'pmeT');
+ _SEH2_YIELD(return 0);
+ }
+ _SEH2_END
}
- _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+ else
{
- _SEH2_YIELD(return 0);
+ pvBits = NULL;
}
- _SEH2_END
/* FIXME: Locking twice is cheesy, coord tranlation in UM will fix it */
if (!(pdc = DC_LockDc(hdc)))
goto cleanup;
}
- psurfDst = pdc->dclevel.pSurface;
- if (!psurfDst)
- {
- // CHECKME
- bResult = TRUE;
- goto cleanup;
- }
-
/* Calculate source and destination rect */
rcSrc.left = xSrc;
rcSrc.top = ySrc;
goto cleanup;
}
+ /* Prepare DC for blit */
+ DC_vPrepareDCsForBlit(pdc, &rcDst, NULL, NULL);
+
+ psurfDst = pdc->dclevel.pSurface;
+
/* Initialize XLATEOBJ */
EXLATEOBJ_vInitialize(&exlo,
ppalDIB,
pdc->pdcattr->crBackgroundClr,
pdc->pdcattr->crForegroundClr);
- /* Prepare DC for blit */
- DC_vPrepareDCsForBlit(pdc, rcDst, NULL, rcSrc);
-
/* Perform the stretch operation */
bResult = IntEngStretchBlt(&psurfDst->SurfObj,
&psurfTmp->SurfObj,
NULL,
- pdc->rosdc.CombinedClip,
+ &pdc->co.ClipObj,
&exlo.xlo,
+ &pdc->dclevel.ca,
&rcDst,
&rcSrc,
NULL,
if (psurfTmp) SURFACE_ShareUnlockSurface(psurfTmp);
if (hbmTmp) GreDeleteObject(hbmTmp);
if (pdc) DC_UnlockDc(pdc);
- ExFreePoolWithTag(pvBits, 'pmeT');
+ if (pvBits) ExFreePoolWithTag(pvBits, 'pmeT');
return bResult;
}
if(pjInit && (fInit == CBM_INIT))
{
+ if (cjMaxBits == 0) return NULL;
safeBits = ExAllocatePoolWithTag(PagedPool, cjMaxBits, TAG_DIB);
if(!safeBits)
{
HBITMAP res = 0;
SURFACE *bmp = NULL;
void *mapBits = NULL;
- PPALETTE ppalDIB;
+ PPALETTE ppalDIB = NULL;
// Fill BITMAP32 structure with DIB data
CONST BITMAPINFOHEADER *bi = &bmi->bmiHeader;
//SIZEL Size;
HANDLE hSecure;
- DPRINT("format (%ld,%ld), planes %d, bpp %d, size %ld, colors %ld (%s)\n",
+ DPRINT("format (%ld,%ld), planes %u, bpp %u, size %lu, colors %lu (%s)\n",
bi->biWidth, bi->biHeight, bi->biPlanes, bi->biBitCount,
bi->biSizeImage, bi->biClrUsed, usage == DIB_PAL_COLORS? "PAL" : "RGB");
/* Create a palette for the DIB */
ppalDIB = CreateDIBPalette(bmi, dc, usage);
- if (ppalDIB)
- {
- if (bmp->ppal) PALETTE_ShareUnlockPalette(bmp->ppal);
- bmp->ppal = ppalDIB;
- }
// Clean up in case of errors
cleanup:
- if (!res || !bmp || !bm.bmBits)
+ if (!res || !bmp || !bm.bmBits || !ppalDIB)
{
- DPRINT("Got an error res=%08x, bmp=%p, bm.bmBits=%p\n", res, bmp, bm.bmBits);
+ DPRINT("Got an error res=%p, bmp=%p, bm.bmBits=%p\n", res, bmp, bm.bmBits);
if (bm.bmBits)
{
// MmUnsecureVirtualMemory(hSecure); // FIXME: Implement this!
}
if (bmp)
+ {
+ SURFACE_ShareUnlockSurface(bmp);
bmp = NULL;
+ }
if (res)
{
GreDeleteObject(res);
res = 0;
}
+
+ if(ppalDIB)
+ {
+ PALETTE_ShareUnlockPalette(ppalDIB);
+ }
}
if (bmp)
{
+ /* If we're here, everything went fine */
+ SURFACE_vSetPalette(bmp, ppalDIB);
+ PALETTE_ShareUnlockPalette(ppalDIB);
SURFACE_ShareUnlockSurface(bmp);
}
*size = header->biSizeImage;
return 1;
}
- DPRINT1("(%d): unknown/wrong size for header\n", header->biSize );
+ DPRINT1("(%u): unknown/wrong size for header\n", header->biSize );
return -1;
}
/* Frees a BITMAPINFO created with DIB_ConvertBitmapInfo */
VOID
FASTCALL
-DIB_FreeConvertedBitmapInfo(BITMAPINFO* converted, BITMAPINFO* orig)
+DIB_FreeConvertedBitmapInfo(BITMAPINFO* converted, BITMAPINFO* orig, DWORD usage)
{
- if(converted != orig)
+ BITMAPCOREINFO* pbmci;
+ if(converted == orig)
+ return;
+
+ if(usage == -1)
+ {
+ /* Caller don't want any conversion */
ExFreePoolWithTag(converted, TAG_DIB);
+ return;
+ }
+
+ /* Perform inverse conversion */
+ pbmci = (BITMAPCOREINFO*)orig;
+
+ ASSERT(pbmci->bmciHeader.bcSize == sizeof(BITMAPCOREHEADER));
+ pbmci->bmciHeader.bcBitCount = converted->bmiHeader.biBitCount;
+ pbmci->bmciHeader.bcWidth = converted->bmiHeader.biWidth;
+ pbmci->bmciHeader.bcHeight = converted->bmiHeader.biHeight;
+ pbmci->bmciHeader.bcPlanes = converted->bmiHeader.biPlanes;
+
+ if(pbmci->bmciHeader.bcBitCount <= 8)
+ {
+ UINT numColors = converted->bmiHeader.biClrUsed;
+ if(!numColors) numColors = 1 << pbmci->bmciHeader.bcBitCount;
+ if(usage == DIB_PAL_COLORS)
+ {
+ RtlZeroMemory(pbmci->bmciColors, (1 << pbmci->bmciHeader.bcBitCount) * sizeof(WORD));
+ RtlCopyMemory(pbmci->bmciColors, converted->bmiColors, numColors * sizeof(WORD));
+ }
+ else
+ {
+ UINT i;
+ RtlZeroMemory(pbmci->bmciColors, (1 << pbmci->bmciHeader.bcBitCount) * sizeof(RGBTRIPLE));
+ for(i=0; i<numColors; i++)
+ {
+ pbmci->bmciColors[i].rgbtRed = converted->bmiColors[i].rgbRed;
+ pbmci->bmciColors[i].rgbtGreen = converted->bmiColors[i].rgbGreen;
+ pbmci->bmciColors[i].rgbtBlue = converted->bmiColors[i].rgbBlue;
+ }
+ }
+ }
+ /* Now free it, it's not needed anymore */
+ ExFreePoolWithTag(converted, TAG_DIB);
}
/* EOF */