/* * Return the full scan size for a bitmap. * * Based on Wine, Utils.c and Windows Graphics Prog pg 595, SDK amvideo.h. */ UINT FASTCALL DIB_BitmapMaxBitsSize( PBITMAPINFO Info, UINT ScanLines) { UINT Ret; if (!Info) return 0; if (Info->bmiHeader.biSize == sizeof(BITMAPCOREHEADER)) { PBITMAPCOREHEADER Core = (PBITMAPCOREHEADER) Info; Ret = WIDTH_BYTES_ALIGN32(Core->bcWidth * Core->bcPlanes, Core->bcBitCount) * ScanLines; } else /* assume BITMAPINFOHEADER */ { if ((Info->bmiHeader.biCompression == BI_RGB) || (Info->bmiHeader.biCompression == BI_BITFIELDS)) { Ret = WIDTH_BYTES_ALIGN32( Info->bmiHeader.biWidth * Info->bmiHeader.biPlanes, Info->bmiHeader.biBitCount) * ScanLines; } else { Ret = Info->bmiHeader.biSizeImage; } } return Ret; }
/* * @implemented */ int WINAPI GdiGetBitmapBitsSize( BITMAPINFO *lpbmi) { UINT Ret; if (!lpbmi) return 0; if (lpbmi->bmiHeader.biSize == sizeof(BITMAPCOREHEADER)) { PBITMAPCOREHEADER Core = (PBITMAPCOREHEADER) lpbmi; Ret = WIDTH_BYTES_ALIGN32(Core->bcWidth * Core->bcPlanes, Core->bcBitCount) * Core->bcHeight; } else /* assume BITMAPINFOHEADER */ { if (!(lpbmi->bmiHeader.biCompression) || (lpbmi->bmiHeader.biCompression == BI_BITFIELDS)) { Ret = WIDTH_BYTES_ALIGN32( lpbmi->bmiHeader.biWidth * lpbmi->bmiHeader.biPlanes, lpbmi->bmiHeader.biBitCount) * abs(lpbmi->bmiHeader.biHeight); } else { Ret = lpbmi->bmiHeader.biSizeImage; } } return Ret; }
/** * This function is not exported, because it makes no sense for * The driver to punt back to this function */ BOOL APIENTRY EngRealizeBrush( BRUSHOBJ *pbo, SURFOBJ *psoDst, SURFOBJ *psoPattern, SURFOBJ *psoMask, XLATEOBJ *pxlo, ULONG iHatch) { EBRUSHOBJ *pebo; HBITMAP hbmpRealize; SURFOBJ *psoRealize; PSURFACE psurfRealize; POINTL ptlSrc = {0, 0}; RECTL rclDest; ULONG lWidth; /* Calculate width in bytes of the realized brush */ lWidth = WIDTH_BYTES_ALIGN32(psoPattern->sizlBitmap.cx, BitsPerFormat(psoDst->iBitmapFormat)); /* Allocate a bitmap */ hbmpRealize = EngCreateBitmap(psoPattern->sizlBitmap, lWidth, psoDst->iBitmapFormat, BMF_NOZEROINIT, NULL); if (!hbmpRealize) { return FALSE; } /* Lock the bitmap */ psurfRealize = SURFACE_ShareLockSurface(hbmpRealize); /* Already delete the pattern bitmap (will be kept until dereferenced) */ EngDeleteSurface((HSURF)hbmpRealize); if (!psurfRealize) { return FALSE; } /* Copy the bits to the new format bitmap */ rclDest.left = rclDest.top = 0; rclDest.right = psoPattern->sizlBitmap.cx; rclDest.bottom = psoPattern->sizlBitmap.cy; psoRealize = &psurfRealize->SurfObj; EngCopyBits(psoRealize, psoPattern, NULL, pxlo, &rclDest, &ptlSrc); pebo = CONTAINING_RECORD(pbo, EBRUSHOBJ, BrushObject); pebo->pengbrush = (PVOID)psurfRealize; return TRUE; }
static void sw_MapRenderbuffer(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint x, GLuint y, GLuint w, GLuint h, GLbitfield mode, GLubyte **mapOut, GLint *rowStrideOut) { if(rb->ClassID == SW_FRONT_RENDERBUFFER_CLASS) { /* This is our front buffer */ struct sw_front_renderbuffer* srb = (struct sw_front_renderbuffer*)rb; struct sw_framebuffer* fb = CONTAINING_RECORD(srb, struct sw_framebuffer, frontbuffer); /* Set the stride */ *rowStrideOut = WIDTH_BYTES_ALIGN32(rb->Width, pixel_formats[fb->format_index].color_bits); /* Remember where we "mapped" */ srb->x = x; srb->y = y; srb->w = w; srb->h = h; /* Remember if we should write it later */ srb->write = !!(mode & GL_MAP_WRITE_BIT); /* Get the bits, if needed */ if(mode & GL_MAP_READ_BIT) { BitBlt(srb->hdcmem, srb->x, srb->y, srb->w, srb->h, IntGetCurrentDC(), srb->x, srb->y, SRCCOPY); } /* And return it */ *mapOut = (BYTE*)srb->swrast.Buffer + *rowStrideOut*y + x*pixel_formats[fb->format_index].color_bits/8; return; } if(rb->ClassID == SW_BACK_RENDERBUFFER_CLASS) { /* This is our front buffer */ struct swrast_renderbuffer* srb = (struct swrast_renderbuffer*)rb; const GLuint bpp = _mesa_get_format_bytes(rb->Format); /* Set the stride */ *rowStrideOut = srb->RowStride; *mapOut = (BYTE*)srb->Buffer + srb->RowStride*y + x*bpp; return; } /* Let mesa rasterizer take care of this */ _swrast_map_soft_renderbuffer(ctx, rb, x, y, w, h, mode, mapOut, rowStrideOut); }
/* Renderbuffer routines */ static GLboolean sw_bb_renderbuffer_storage(struct gl_context* ctx, struct gl_renderbuffer *rb, GLenum internalFormat, GLuint width, GLuint height) { struct swrast_renderbuffer *srb = swrast_renderbuffer(rb); struct sw_framebuffer* fb = CONTAINING_RECORD(srb, struct sw_framebuffer, backbuffer); UINT widthBytes = WIDTH_BYTES_ALIGN32(width, pixel_formats[fb->format_index].color_bits); srb->Base.Format = pixel_formats[fb->format_index].mesa; if(srb->Buffer) srb->Buffer = HeapReAlloc(GetProcessHeap(), 0, srb->Buffer, widthBytes*height); else srb->Buffer = HeapAlloc(GetProcessHeap(), 0, widthBytes*height); if(!srb->Buffer) { srb->Base.Format = MESA_FORMAT_NONE; return GL_FALSE; } srb->Base.Width = width; srb->Base.Height = height; srb->RowStride = widthBytes; return GL_TRUE; }
/* * @implemented */ ULONG APIENTRY EngSetPointerShape( _In_ SURFOBJ *pso, _In_opt_ SURFOBJ *psoMask, _In_opt_ SURFOBJ *psoColor, _In_opt_ XLATEOBJ *pxlo, _In_ LONG xHot, _In_ LONG yHot, _In_ LONG x, _In_ LONG y, _In_ RECTL *prcl, _In_ FLONG fl) { PDEVOBJ *ppdev; GDIPOINTER *pgp; LONG lDelta = 0; HBITMAP hbmSave = NULL, hbmColor = NULL, hbmMask = NULL; PSURFACE psurfSave = NULL, psurfColor = NULL, psurfMask = NULL; RECTL rectl; SIZEL sizel = {0, 0}; ASSERT(pso); ppdev = GDIDEV(pso); pgp = &ppdev->Pointer; /* Handle the case where we have no XLATEOBJ */ if (pxlo == NULL) pxlo = &gexloTrivial.xlo; /* Do we have any bitmap at all? */ if (psoColor || psoMask) { /* Get the size of the new pointer */ if (psoColor) { sizel.cx = psoColor->sizlBitmap.cx; sizel.cy = psoColor->sizlBitmap.cy; } else// if (psoMask) { sizel.cx = psoMask->sizlBitmap.cx; sizel.cy = psoMask->sizlBitmap.cy / 2; } rectl.left = 0; rectl.top = 0; rectl.right = sizel.cx; rectl.bottom = sizel.cy; /* Calculate lDelta for our surfaces. */ lDelta = WIDTH_BYTES_ALIGN32(sizel.cx, BitsPerFormat(pso->iBitmapFormat)); /* Create a bitmap for saving the pixels under the cursor. */ hbmSave = EngCreateBitmap(sizel, lDelta, pso->iBitmapFormat, BMF_TOPDOWN | BMF_NOZEROINIT, NULL); psurfSave = SURFACE_ShareLockSurface(hbmSave); if (!psurfSave) goto failure; } if (psoColor) { if (fl & SPS_ALPHA) { /* Always store the alpha cursor in RGB. */ EXLATEOBJ exloSrcRGB; PEXLATEOBJ pexlo; pexlo = CONTAINING_RECORD(pxlo, EXLATEOBJ, xlo); EXLATEOBJ_vInitialize(&exloSrcRGB, pexlo->ppalSrc, &gpalRGB, 0, 0, 0); hbmColor = EngCreateBitmap(psoColor->sizlBitmap, WIDTH_BYTES_ALIGN32(sizel.cx, 32), BMF_32BPP, BMF_TOPDOWN | BMF_NOZEROINIT, NULL); psurfColor = SURFACE_ShareLockSurface(hbmColor); if (!psurfColor) goto failure; /* Now copy the given bitmap. */ rectl.bottom = psoColor->sizlBitmap.cy; IntEngCopyBits(&psurfColor->SurfObj, psoColor, NULL, &exloSrcRGB.xlo, &rectl, (POINTL*)&rectl); EXLATEOBJ_vCleanup(&exloSrcRGB); } else { /* Color bitmap must have the same format as the dest surface */ if (psoColor->iBitmapFormat != pso->iBitmapFormat) { DPRINT1("Screen surface and cursor color bitmap format don't match!.\n"); goto failure; } /* Create a bitmap to copy the color bitmap to */ hbmColor = EngCreateBitmap(psoColor->sizlBitmap, lDelta, pso->iBitmapFormat, BMF_TOPDOWN | BMF_NOZEROINIT, NULL); psurfColor = SURFACE_ShareLockSurface(hbmColor); if (!psurfColor) goto failure; /* Now copy the given bitmap. */ rectl.bottom = psoColor->sizlBitmap.cy; IntEngCopyBits(&psurfColor->SurfObj, psoColor, NULL, pxlo, &rectl, (POINTL*)&rectl); } } /* Create a mask surface */ if (psoMask) { EXLATEOBJ exlo; PPALETTE ppal; lDelta = WIDTH_BYTES_ALIGN32(sizel.cx, BitsPerFormat(pso->iBitmapFormat)); /* Create a bitmap for the mask */ hbmMask = EngCreateBitmap(psoMask->sizlBitmap, lDelta, pso->iBitmapFormat, BMF_TOPDOWN | BMF_NOZEROINIT, NULL); psurfMask = SURFACE_ShareLockSurface(hbmMask); if (!psurfMask) goto failure; /* Initialize an EXLATEOBJ */ ppal = PALETTE_ShareLockPalette(ppdev->devinfo.hpalDefault); EXLATEOBJ_vInitialize(&exlo, gppalMono, ppal, 0, RGB(0xff,0xff,0xff), RGB(0,0,0)); /* Copy the mask bitmap */ rectl.bottom = psoMask->sizlBitmap.cy; IntEngCopyBits(&psurfMask->SurfObj, psoMask, NULL, &exlo.xlo, &rectl, (POINTL*)&rectl); /* Cleanup */ EXLATEOBJ_vCleanup(&exlo); if (ppal) PALETTE_ShareUnlockPalette(ppal); } /* Hide mouse pointer */ IntHideMousePointer(ppdev, pso); /* Free old color bitmap */ if (pgp->psurfColor) { EngDeleteSurface(pgp->psurfColor->BaseObject.hHmgr); SURFACE_ShareUnlockSurface(pgp->psurfColor); pgp->psurfColor = NULL; } /* Free old mask bitmap */ if (pgp->psurfMask) { EngDeleteSurface(pgp->psurfMask->BaseObject.hHmgr); SURFACE_ShareUnlockSurface(pgp->psurfMask); pgp->psurfMask = NULL; } /* Free old save bitmap */ if (pgp->psurfSave) { EngDeleteSurface(pgp->psurfSave->BaseObject.hHmgr); SURFACE_ShareUnlockSurface(pgp->psurfSave); pgp->psurfSave = NULL; } /* See if we are being asked to hide the pointer. */ if (psoMask == NULL && psoColor == NULL) { /* We're done */ return SPS_ACCEPT_NOEXCLUDE; } /* Now set the new cursor */ pgp->psurfColor = psurfColor; pgp->psurfMask = psurfMask; pgp->psurfSave = psurfSave; pgp->HotSpot.x = xHot; pgp->HotSpot.y = yHot; pgp->Size = sizel; pgp->flags = fl; if (x != -1) { ppdev->ptlPointer.x = x; ppdev->ptlPointer.y = y; IntShowMousePointer(ppdev, pso); if (prcl != NULL) { prcl->left = x - pgp->HotSpot.x; prcl->top = y - pgp->HotSpot.x; prcl->right = prcl->left + pgp->Size.cx; prcl->bottom = prcl->top + pgp->Size.cy; } } else if (prcl != NULL) { prcl->left = prcl->top = prcl->right = prcl->bottom = -1; } return SPS_ACCEPT_NOEXCLUDE; failure: /* Cleanup surfaces */ if (hbmMask) EngDeleteSurface((HSURF)hbmMask); if (psurfMask) SURFACE_ShareUnlockSurface(psurfMask); if (hbmColor) EngDeleteSurface((HSURF)hbmColor); if (psurfColor) SURFACE_ShareUnlockSurface(psurfColor); if (hbmSave) EngDeleteSurface((HSURF)hbmSave); if (psurfSave) SURFACE_ShareUnlockSurface(psurfSave); return SPS_ERROR; }
BOOL APIENTRY IntEngEnter(PINTENG_ENTER_LEAVE EnterLeave, SURFOBJ *psoDest, RECTL *DestRect, BOOL ReadOnly, POINTL *Translate, SURFOBJ **ppsoOutput) { LONG Exchange; SIZEL BitmapSize; POINTL SrcPoint; LONG Width; RECTL ClippedDestRect; /* Normalize */ if (DestRect->right < DestRect->left) { Exchange = DestRect->left; DestRect->left = DestRect->right; DestRect->right = Exchange; } if (DestRect->bottom < DestRect->top) { Exchange = DestRect->top; DestRect->top = DestRect->bottom; DestRect->bottom = Exchange; } if (NULL != psoDest && STYPE_BITMAP != psoDest->iType && (NULL == psoDest->pvScan0 || 0 == psoDest->lDelta)) { /* Driver needs to support DrvCopyBits, else we can't do anything */ SURFACE *psurfDest = CONTAINING_RECORD(psoDest, SURFACE, SurfObj); if (!(psurfDest->flags & HOOK_COPYBITS)) { return FALSE; } /* Allocate a temporary bitmap */ BitmapSize.cx = DestRect->right - DestRect->left; BitmapSize.cy = DestRect->bottom - DestRect->top; Width = WIDTH_BYTES_ALIGN32(BitmapSize.cx, BitsPerFormat(psoDest->iBitmapFormat)); EnterLeave->OutputBitmap = EngCreateBitmap(BitmapSize, Width, psoDest->iBitmapFormat, BMF_TOPDOWN | BMF_NOZEROINIT, NULL); if (!EnterLeave->OutputBitmap) { DPRINT1("EngCreateBitmap() failed\n"); return FALSE; } *ppsoOutput = EngLockSurface((HSURF)EnterLeave->OutputBitmap); if (*ppsoOutput == NULL) { EngDeleteSurface((HSURF)EnterLeave->OutputBitmap); return FALSE; } EnterLeave->DestRect.left = 0; EnterLeave->DestRect.top = 0; EnterLeave->DestRect.right = BitmapSize.cx; EnterLeave->DestRect.bottom = BitmapSize.cy; SrcPoint.x = DestRect->left; SrcPoint.y = DestRect->top; ClippedDestRect = EnterLeave->DestRect; if (SrcPoint.x < 0) { ClippedDestRect.left -= SrcPoint.x; SrcPoint.x = 0; } if (psoDest->sizlBitmap.cx < SrcPoint.x + ClippedDestRect.right - ClippedDestRect.left) { ClippedDestRect.right = ClippedDestRect.left + psoDest->sizlBitmap.cx - SrcPoint.x; } if (SrcPoint.y < 0) { ClippedDestRect.top -= SrcPoint.y; SrcPoint.y = 0; } if (psoDest->sizlBitmap.cy < SrcPoint.y + ClippedDestRect.bottom - ClippedDestRect.top) { ClippedDestRect.bottom = ClippedDestRect.top + psoDest->sizlBitmap.cy - SrcPoint.y; } EnterLeave->TrivialClipObj = EngCreateClip(); if (EnterLeave->TrivialClipObj == NULL) { EngUnlockSurface(*ppsoOutput); EngDeleteSurface((HSURF)EnterLeave->OutputBitmap); return FALSE; } EnterLeave->TrivialClipObj->iDComplexity = DC_TRIVIAL; if (ClippedDestRect.left < (*ppsoOutput)->sizlBitmap.cx && 0 <= ClippedDestRect.right && SrcPoint.x < psoDest->sizlBitmap.cx && ClippedDestRect.top <= (*ppsoOutput)->sizlBitmap.cy && 0 <= ClippedDestRect.bottom && SrcPoint.y < psoDest->sizlBitmap.cy && ! GDIDEVFUNCS(psoDest).CopyBits( *ppsoOutput, psoDest, EnterLeave->TrivialClipObj, NULL, &ClippedDestRect, &SrcPoint)) { EngDeleteClip(EnterLeave->TrivialClipObj); EngUnlockSurface(*ppsoOutput); EngDeleteSurface((HSURF)EnterLeave->OutputBitmap); return FALSE; } EnterLeave->DestRect.left = DestRect->left; EnterLeave->DestRect.top = DestRect->top; EnterLeave->DestRect.right = DestRect->right; EnterLeave->DestRect.bottom = DestRect->bottom; Translate->x = - DestRect->left; Translate->y = - DestRect->top; } else { Translate->x = 0; Translate->y = 0; *ppsoOutput = psoDest; } if (NULL != *ppsoOutput) { SURFACE* psurfOutput = CONTAINING_RECORD(*ppsoOutput, SURFACE, SurfObj); if (0 != (psurfOutput->flags & HOOK_SYNCHRONIZE)) { if (NULL != GDIDEVFUNCS(*ppsoOutput).SynchronizeSurface) { GDIDEVFUNCS(*ppsoOutput).SynchronizeSurface(*ppsoOutput, DestRect, 0); } else if (STYPE_BITMAP == (*ppsoOutput)->iType && NULL != GDIDEVFUNCS(*ppsoOutput).Synchronize) { GDIDEVFUNCS(*ppsoOutput).Synchronize((*ppsoOutput)->dhpdev, DestRect); } } } else return FALSE; EnterLeave->DestObj = psoDest; EnterLeave->OutputObj = *ppsoOutput; EnterLeave->ReadOnly = ReadOnly; return TRUE; }
HBITMAP NTAPI GreCreateBitmapEx( _In_ ULONG nWidth, _In_ ULONG nHeight, _In_ ULONG cjWidthBytes, _In_ ULONG iFormat, _In_ USHORT fjBitmap, _In_ ULONG cjSizeImage, _In_opt_ PVOID pvBits, _In_ FLONG flags) { PSURFACE psurf; HBITMAP hbmp; PVOID pvCompressedBits = NULL; /* Verify format */ if (iFormat < BMF_1BPP || iFormat > BMF_PNG) return NULL; /* The infamous RLE hack */ if ((iFormat == BMF_4RLE) || (iFormat == BMF_8RLE)) { pvCompressedBits = pvBits; pvBits = NULL; iFormat = (iFormat == BMF_4RLE) ? BMF_4BPP : BMF_8BPP; } /* Allocate a surface */ psurf = SURFACE_AllocSurface(STYPE_BITMAP, nWidth, nHeight, iFormat, fjBitmap, cjWidthBytes, pvBits); if (!psurf) { DPRINT1("SURFACE_AllocSurface failed.\n"); return NULL; } /* The infamous RLE hack */ if (pvCompressedBits) { SIZEL sizl; LONG lDelta; sizl.cx = nWidth; sizl.cy = nHeight; lDelta = WIDTH_BYTES_ALIGN32(nWidth, gajBitsPerFormat[iFormat]); pvBits = psurf->SurfObj.pvBits; DecompressBitmap(sizl, pvCompressedBits, pvBits, lDelta, iFormat); } /* Get the handle for the bitmap */ hbmp = (HBITMAP)psurf->SurfObj.hsurf; /* Mark as API bitmap */ psurf->flags |= (flags | API_BITMAP); /* Unlock the surface and return */ SURFACE_UnlockSurface(psurf); return hbmp; }
PSURFACE NTAPI SURFACE_AllocSurface( _In_ USHORT iType, _In_ ULONG cx, _In_ ULONG cy, _In_ ULONG iFormat, _In_ ULONG fjBitmap, _In_opt_ ULONG cjWidth, _In_opt_ ULONG cjBufSize, _In_opt_ PVOID pvBits) { ULONG cBitsPixel, cjBits, cjObject; PSURFACE psurf; SURFOBJ *pso; PVOID pvSection; NT_ASSERT(!pvBits || (iType == STYPE_BITMAP)); NT_ASSERT((iFormat <= BMF_32BPP) || (cjBufSize != 0)); NT_ASSERT((LONG)cy > 0); /* Verify format */ if ((iFormat < BMF_1BPP) || (iFormat > BMF_PNG)) { DPRINT1("Invalid bitmap format: %lu\n", iFormat); return NULL; } /* Get bits per pixel from the format */ cBitsPixel = gajBitsPerFormat[iFormat]; /* Are bits and a width in bytes given? */ if (pvBits && cjWidth) { /* Align the width (Windows compatibility, drivers expect that) */ cjWidth = WIDTH_BYTES_ALIGN32((cjWidth << 3) / cBitsPixel, cBitsPixel); } else { /* Calculate width from the bitmap width in pixels */ cjWidth = WIDTH_BYTES_ALIGN32(cx, cBitsPixel); } /* Is this an uncompressed format? */ if (iFormat <= BMF_32BPP) { /* Calculate the correct bitmap size in bytes */ if (!NT_SUCCESS(RtlULongMult(cjWidth, cy, &cjBits))) { DPRINT1("Overflow calculating size: cjWidth %lu, cy %lu\n", cjWidth, cy); return NULL; } /* Did we get a buffer and size? */ if ((pvBits != NULL) && (cjBufSize != 0)) { /* Make sure the buffer is large enough */ if (cjBufSize < cjBits) { DPRINT1("Buffer is too small, required: %lu, got %lu\n", cjBits, cjBufSize); return NULL; } } } else { /* Compressed format, use the provided size */ NT_ASSERT(cjBufSize != 0); cjBits = cjBufSize; } /* Check if we need an extra large object */ if ((iType == STYPE_BITMAP) && (pvBits == NULL) && !(fjBitmap & BMF_USERMEM) && !(fjBitmap & BMF_KMSECTION)) { /* Allocate an object large enough to hold the bits */ cjObject = sizeof(SURFACE) + cjBits; } else { /* Otherwise just allocate the SURFACE structure */ cjObject = sizeof(SURFACE); } /* Check for arithmetic overflow */ if (cjObject < sizeof(SURFACE)) { /* Fail! */ DPRINT1("Overflow calculating cjObject: cjBits %lu\n", cjBits); return NULL; } /* Allocate a SURFACE object */ psurf = (PSURFACE)GDIOBJ_AllocObjWithHandle(GDI_OBJECT_TYPE_BITMAP, cjObject); if (!psurf) { return NULL; } /* Initialize the basic fields */ pso = &psurf->SurfObj; pso->hsurf = psurf->BaseObject.hHmgr; pso->sizlBitmap.cx = cx; pso->sizlBitmap.cy = cy; pso->iBitmapFormat = iFormat; pso->iType = iType; pso->fjBitmap = (USHORT)fjBitmap; pso->iUniq = InterlockedIncrement(&giUniqueSurface); pso->cjBits = cjBits; /* Check if we need a bitmap buffer */ if (iType == STYPE_BITMAP) { /* Check if we got one or if we need to allocate one */ if (pvBits != NULL) { /* Use the caller provided buffer */ pso->pvBits = pvBits; } else if (fjBitmap & BMF_USERMEM) { /* User mode memory was requested */ pso->pvBits = EngAllocUserMem(cjBits, 0); /* Check for failure */ if (!pso->pvBits) { GDIOBJ_vDeleteObject(&psurf->BaseObject); return NULL; } } else if (fjBitmap & BMF_KMSECTION) { /* Use a kernel mode section */ pso->pvBits = EngAllocSectionMem(&pvSection, (fjBitmap & BMF_NOZEROINIT) ? 0 : FL_ZERO_MEMORY, cjBits, TAG_DIB); /* Check for failure */ if (!pso->pvBits) { GDIOBJ_vDeleteObject(&psurf->BaseObject); return NULL; } /* Free the section already, but keep the mapping */ EngFreeSectionMem(pvSection, NULL); } else { /* Buffer is after the object */ pso->pvBits = psurf + 1; /* Zero the buffer, except requested otherwise */ if (!(fjBitmap & BMF_NOZEROINIT)) { RtlZeroMemory(pso->pvBits, cjBits); } } /* Set pvScan0 and lDelta */ if (fjBitmap & BMF_TOPDOWN) { /* Topdown is the normal way */ pso->pvScan0 = pso->pvBits; pso->lDelta = cjWidth; } else { /* Inversed bitmap (bottom up) */ pso->pvScan0 = ((PCHAR)pso->pvBits + pso->cjBits - cjWidth); pso->lDelta = -(LONG)cjWidth; } } else { /* There are no bitmap bits */ pso->pvScan0 = pso->pvBits = NULL; pso->lDelta = 0; } /* Assign a default palette and increment its reference count */ SURFACE_vSetPalette(psurf, appalSurfaceDefault[iFormat]); return psurf; }