ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

bitmaps.c
Go to the documentation of this file.
00001 /*
00002  * COPYRIGHT:        GNU GPL, See COPYING in the top level directory
00003  * PROJECT:          ReactOS kernel
00004  * PURPOSE:          Bitmap functions
00005  * FILE:             subsys/win32k/objects/bitmaps.c
00006  * PROGRAMER:        Timo Kreuzer <timo.kreuzer@reactos.org>
00007  */
00008 
00009 #include <win32k.h>
00010 
00011 #define NDEBUG
00012 #include <debug.h>
00013 
00014 void
00015 NTAPI
00016 UnsafeSetBitmapBits(
00017     PSURFACE psurf,
00018     IN ULONG cjBits,
00019     IN PVOID pvBits)
00020 {
00021     PUCHAR pjDst, pjSrc;
00022     LONG lDeltaDst, lDeltaSrc;
00023     ULONG nWidth, nHeight, cBitsPixel;
00024 
00025     nWidth = psurf->SurfObj.sizlBitmap.cx;
00026     nHeight = psurf->SurfObj.sizlBitmap.cy;
00027     cBitsPixel = BitsPerFormat(psurf->SurfObj.iBitmapFormat);
00028 
00029     /* Get pointers */
00030     pjDst = psurf->SurfObj.pvScan0;
00031     pjSrc = pvBits;
00032     lDeltaDst = psurf->SurfObj.lDelta;
00033     lDeltaSrc = WIDTH_BYTES_ALIGN16(nWidth, cBitsPixel);
00034 
00035     while (nHeight--)
00036     {
00037         /* Copy one line */
00038         memcpy(pjDst, pjSrc, lDeltaSrc);
00039         pjSrc += lDeltaSrc;
00040         pjDst += lDeltaDst;
00041     }
00042 
00043 }
00044 
00045 HBITMAP
00046 NTAPI
00047 GreCreateBitmapEx(
00048     _In_ ULONG nWidth,
00049     _In_ ULONG nHeight,
00050     _In_ ULONG cjWidthBytes,
00051     _In_ ULONG iFormat,
00052     _In_ USHORT fjBitmap,
00053     _In_ ULONG cjSizeImage,
00054     _In_opt_ PVOID pvBits,
00055     _In_ FLONG flags)
00056 {
00057     PSURFACE psurf;
00058     HBITMAP hbmp;
00059     PVOID pvCompressedBits = NULL;
00060 
00061     /* Verify format */
00062     if (iFormat < BMF_1BPP || iFormat > BMF_PNG) return NULL;
00063 
00064     /* The infamous RLE hack */
00065     if ((iFormat == BMF_4RLE) || (iFormat == BMF_8RLE))
00066     {
00067         pvCompressedBits = pvBits;
00068         pvBits = NULL;
00069         iFormat = (iFormat == BMF_4RLE) ? BMF_4BPP : BMF_8BPP;
00070     }
00071 
00072     /* Allocate a surface */
00073     psurf = SURFACE_AllocSurface(STYPE_BITMAP,
00074                                  nWidth,
00075                                  nHeight,
00076                                  iFormat,
00077                                  fjBitmap,
00078                                  cjWidthBytes,
00079                                  pvBits);
00080     if (!psurf)
00081     {
00082         DPRINT1("SURFACE_AllocSurface failed.\n");
00083         return NULL;
00084     }
00085 
00086     /* The infamous RLE hack */
00087     if (pvCompressedBits)
00088     {
00089         SIZEL sizl;
00090         LONG lDelta;
00091 
00092         sizl.cx = nWidth;
00093         sizl.cy = nHeight;
00094         lDelta = WIDTH_BYTES_ALIGN32(nWidth, gajBitsPerFormat[iFormat]);
00095 
00096         pvBits = psurf->SurfObj.pvBits;
00097         DecompressBitmap(sizl, pvCompressedBits, pvBits, lDelta, iFormat);
00098     }
00099 
00100     /* Get the handle for the bitmap */
00101     hbmp = (HBITMAP)psurf->SurfObj.hsurf;
00102 
00103     /* Mark as API bitmap */
00104     psurf->flags |= (flags | API_BITMAP);
00105 
00106     /* Unlock the surface and return */
00107     SURFACE_UnlockSurface(psurf);
00108     return hbmp;
00109 }
00110 
00111 /* Creates a DDB surface,
00112  * as in CreateCompatibleBitmap or CreateBitmap.
00113  * Note that each scanline must be 32bit aligned!
00114  */
00115 HBITMAP
00116 NTAPI
00117 GreCreateBitmap(
00118     _In_ ULONG nWidth,
00119     _In_ ULONG nHeight,
00120     _In_ ULONG cPlanes,
00121     _In_ ULONG cBitsPixel,
00122     _In_opt_ PVOID pvBits)
00123 {
00124     /* Call the extended function */
00125     return GreCreateBitmapEx(nWidth,
00126                              nHeight,
00127                              0, /* Auto width */
00128                              BitmapFormat(cBitsPixel * cPlanes, BI_RGB),
00129                              0, /* No bitmap flags */
00130                              0, /* Auto size */
00131                              pvBits,
00132                              DDB_SURFACE /* DDB */);
00133 }
00134 
00135 HBITMAP
00136 APIENTRY
00137 NtGdiCreateBitmap(
00138     IN INT nWidth,
00139     IN INT nHeight,
00140     IN UINT cPlanes,
00141     IN UINT cBitsPixel,
00142     IN OPTIONAL LPBYTE pUnsafeBits)
00143 {
00144     HBITMAP hbmp;
00145     ULONG cRealBpp, cjWidthBytes, iFormat, fjBitmap;
00146     ULONGLONG cjSize;
00147     PSURFACE psurf;
00148 
00149     /* Calculate bitmap format and real bits per pixel. */
00150     iFormat = BitmapFormat(cBitsPixel * cPlanes, BI_RGB);
00151     cRealBpp = gajBitsPerFormat[iFormat];
00152 
00153     /* Calculate width and image size in bytes */
00154     cjWidthBytes = WIDTH_BYTES_ALIGN16(nWidth, cRealBpp);
00155     cjSize = (ULONGLONG)cjWidthBytes * nHeight;
00156 
00157     /* Check parameters (possible overflow of cjSize!) */
00158     if ((iFormat == 0) || (nWidth <= 0) || (nWidth >= 0x8000000) || (nHeight <= 0) ||
00159         (cBitsPixel > 32) || (cPlanes > 32) || (cjSize >= 0x100000000ULL))
00160     {
00161         DPRINT1("Invalid bitmap format! Width=%d, Height=%d, Bpp=%d, Planes=%d\n",
00162                 nWidth, nHeight, cBitsPixel, cPlanes);
00163         EngSetLastError(ERROR_INVALID_PARAMETER);
00164         return NULL;
00165     }
00166 
00167     /* Allocations larger than PAGE_SIZE go into user mem */
00168     fjBitmap = (cjSize > PAGE_SIZE) ? BMF_USERMEM : 0;
00169 
00170     /* Allocate the surface (but don't set the bits) */
00171     psurf = SURFACE_AllocSurface(STYPE_BITMAP,
00172                                  nWidth,
00173                                  nHeight,
00174                                  iFormat,
00175                                  fjBitmap,
00176                                  0,
00177                                  NULL);
00178     if (!psurf)
00179     {
00180         DPRINT1("SURFACE_AllocSurface failed.\n");
00181         return NULL;
00182     }
00183 
00184     /* Mark as API and DDB bitmap */
00185     psurf->flags |= (API_BITMAP | DDB_SURFACE);
00186 
00187     /* Check if we have bits to set */
00188     if (pUnsafeBits)
00189     {
00190         /* Protect with SEH and copy the bits */
00191         _SEH2_TRY
00192         {
00193             ProbeForRead(pUnsafeBits, (SIZE_T)cjSize, 1);
00194             UnsafeSetBitmapBits(psurf, 0, pUnsafeBits);
00195         }
00196         _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
00197         {
00198             GDIOBJ_vDeleteObject(&psurf->BaseObject);
00199             _SEH2_YIELD(return NULL;)
00200         }
00201         _SEH2_END
00202     }
00203     else
00204     {
00205         /* Zero the bits */
00206         RtlZeroMemory(psurf->SurfObj.pvBits, psurf->SurfObj.cjBits);
00207     }
00208 
00209     /* Get the handle for the bitmap */
00210     hbmp = (HBITMAP)psurf->SurfObj.hsurf;
00211 
00212     /* Unlock the surface */
00213     SURFACE_UnlockSurface(psurf);
00214 
00215     return hbmp;
00216 }
00217 
00218 
00219 HBITMAP FASTCALL
00220 IntCreateCompatibleBitmap(
00221     PDC Dc,
00222     INT Width,
00223     INT Height)
00224 {
00225     HBITMAP Bmp = NULL;
00226 
00227     /* MS doc says if width or height is 0, return 1-by-1 pixel, monochrome bitmap */
00228     if (0 == Width || 0 == Height)
00229     {
00230         return NtGdiGetStockObject(DEFAULT_BITMAP);
00231     }
00232 
00233     if (Dc->dctype != DC_TYPE_MEMORY)
00234     {
00235         PSURFACE psurf;
00236 
00237         Bmp = GreCreateBitmap(abs(Width),
00238                               abs(Height),
00239                               1,
00240                               Dc->ppdev->gdiinfo.cBitsPixel,
00241                               NULL);
00242         psurf = SURFACE_ShareLockSurface(Bmp);
00243         ASSERT(psurf);
00244         /* Set palette */
00245         psurf->ppal = PALETTE_ShareLockPalette(Dc->ppdev->devinfo.hpalDefault);
00246         /* Set flags */
00247         psurf->flags = API_BITMAP;
00248         psurf->hdc = NULL; // FIXME:
00249         SURFACE_ShareUnlockSurface(psurf);
00250     }
00251     else
00252     {
00253         DIBSECTION dibs;
00254         INT Count;
00255         PSURFACE psurf = Dc->dclevel.pSurface;
00256         Count = BITMAP_GetObject(psurf, sizeof(dibs), &dibs);
00257 
00258         if (Count == sizeof(BITMAP))
00259         {
00260             PSURFACE psurfBmp;
00261 
00262             Bmp = GreCreateBitmap(abs(Width),
00263                           abs(Height),
00264                           1,
00265                           dibs.dsBm.bmBitsPixel,
00266                           NULL);
00267             psurfBmp = SURFACE_ShareLockSurface(Bmp);
00268             ASSERT(psurfBmp);
00269             /* Assign palette */
00270             psurfBmp->ppal = psurf->ppal;
00271             GDIOBJ_vReferenceObjectByPointer((POBJ)psurf->ppal);
00272             /* Set flags */
00273             psurfBmp->flags = API_BITMAP;
00274             psurfBmp->hdc = NULL; // FIXME:
00275             SURFACE_ShareUnlockSurface(psurfBmp);
00276         }
00277         else if (Count == sizeof(DIBSECTION))
00278         {
00279             /* A DIB section is selected in the DC */
00280             BYTE buf[sizeof(BITMAPINFOHEADER) + 256*sizeof(RGBQUAD)] = {0};
00281             PVOID Bits;
00282             BITMAPINFO* bi = (BITMAPINFO*)buf;
00283 
00284             bi->bmiHeader.biSize          = sizeof(bi->bmiHeader);
00285             bi->bmiHeader.biWidth         = Width;
00286             bi->bmiHeader.biHeight        = Height;
00287             bi->bmiHeader.biPlanes        = dibs.dsBmih.biPlanes;
00288             bi->bmiHeader.biBitCount      = dibs.dsBmih.biBitCount;
00289             bi->bmiHeader.biCompression   = dibs.dsBmih.biCompression;
00290             bi->bmiHeader.biSizeImage     = 0;
00291             bi->bmiHeader.biXPelsPerMeter = dibs.dsBmih.biXPelsPerMeter;
00292             bi->bmiHeader.biYPelsPerMeter = dibs.dsBmih.biYPelsPerMeter;
00293             bi->bmiHeader.biClrUsed       = dibs.dsBmih.biClrUsed;
00294             bi->bmiHeader.biClrImportant  = dibs.dsBmih.biClrImportant;
00295 
00296             if (bi->bmiHeader.biCompression == BI_BITFIELDS)
00297             {
00298                 /* Copy the color masks */
00299                 RtlCopyMemory(bi->bmiColors, dibs.dsBitfields, 3*sizeof(RGBQUAD));
00300             }
00301             else if (bi->bmiHeader.biBitCount <= 8)
00302             {
00303                 /* Copy the color table */
00304                 UINT Index;
00305                 PPALETTE PalGDI;
00306 
00307                 if (!psurf->ppal)
00308                 {
00309                     EngSetLastError(ERROR_INVALID_HANDLE);
00310                     return 0;
00311                 }
00312 
00313                 PalGDI = psurf->ppal;
00314 
00315                 for (Index = 0;
00316                         Index < 256 && Index < PalGDI->NumColors;
00317                         Index++)
00318                 {
00319                     bi->bmiColors[Index].rgbRed   = PalGDI->IndexedColors[Index].peRed;
00320                     bi->bmiColors[Index].rgbGreen = PalGDI->IndexedColors[Index].peGreen;
00321                     bi->bmiColors[Index].rgbBlue  = PalGDI->IndexedColors[Index].peBlue;
00322                     bi->bmiColors[Index].rgbReserved = 0;
00323                 }
00324             }
00325 
00326             Bmp = DIB_CreateDIBSection(Dc,
00327                                        bi,
00328                                        DIB_RGB_COLORS,
00329                                        &Bits,
00330                                        NULL,
00331                                        0,
00332                                        0);
00333             return Bmp;
00334         }
00335     }
00336     return Bmp;
00337 }
00338 
00339 HBITMAP APIENTRY
00340 NtGdiCreateCompatibleBitmap(
00341     HDC hDC,
00342     INT Width,
00343     INT Height)
00344 {
00345     HBITMAP Bmp;
00346     PDC Dc;
00347 
00348     /* Check parameters */
00349     if ((Width <= 0) || (Height <= 0) || ((Width * Height) > 0x3FFFFFFF))
00350     {
00351         EngSetLastError(ERROR_INVALID_PARAMETER);
00352         return NULL;
00353     }
00354 
00355     if (!hDC)
00356         return GreCreateBitmap(Width, Height, 1, 1, 0);
00357 
00358     Dc = DC_LockDc(hDC);
00359 
00360     DPRINT("NtGdiCreateCompatibleBitmap(%04x,%d,%d, bpp:%d) = \n",
00361            hDC, Width, Height, Dc->ppdev->gdiinfo.cBitsPixel);
00362 
00363     if (NULL == Dc)
00364     {
00365         EngSetLastError(ERROR_INVALID_HANDLE);
00366         return NULL;
00367     }
00368 
00369     Bmp = IntCreateCompatibleBitmap(Dc, Width, Height);
00370 
00371     DPRINT("\t\t%04x\n", Bmp);
00372     DC_UnlockDc(Dc);
00373     return Bmp;
00374 }
00375 
00376 BOOL
00377 APIENTRY
00378 NtGdiGetBitmapDimension(
00379     HBITMAP hBitmap,
00380     LPSIZE psizDim)
00381 {
00382     PSURFACE psurfBmp;
00383     BOOL bResult = TRUE;
00384 
00385     if (hBitmap == NULL)
00386         return FALSE;
00387 
00388     /* Lock the bitmap */
00389     psurfBmp = SURFACE_ShareLockSurface(hBitmap);
00390     if (psurfBmp == NULL)
00391     {
00392         EngSetLastError(ERROR_INVALID_HANDLE);
00393         return FALSE;
00394     }
00395 
00396     /* Use SEH to copy the data to the caller */
00397     _SEH2_TRY
00398     {
00399         ProbeForWrite(psizDim, sizeof(SIZE), 1);
00400         *psizDim = psurfBmp->sizlDim;
00401     }
00402     _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
00403     {
00404         bResult = FALSE;
00405     }
00406     _SEH2_END
00407 
00408     /* Unlock the bitmap */
00409     SURFACE_ShareUnlockSurface(psurfBmp);
00410 
00411     return bResult;
00412 }
00413 
00414 
00415 VOID
00416 FASTCALL
00417 UnsafeGetBitmapBits(
00418     PSURFACE psurf,
00419     DWORD Bytes,
00420     OUT PBYTE pvBits)
00421 {
00422     PUCHAR pjDst, pjSrc;
00423     LONG lDeltaDst, lDeltaSrc;
00424     ULONG nWidth, nHeight, cBitsPixel;
00425 
00426     nWidth = psurf->SurfObj.sizlBitmap.cx;
00427     nHeight = psurf->SurfObj.sizlBitmap.cy;
00428     cBitsPixel = BitsPerFormat(psurf->SurfObj.iBitmapFormat);
00429 
00430     /* Get pointers */
00431     pjSrc = psurf->SurfObj.pvScan0;
00432     pjDst = pvBits;
00433     lDeltaSrc = psurf->SurfObj.lDelta;
00434     lDeltaDst = WIDTH_BYTES_ALIGN16(nWidth, cBitsPixel);
00435 
00436     while (nHeight--)
00437     {
00438         /* Copy one line */
00439         RtlCopyMemory(pjDst, pjSrc, lDeltaDst);
00440         pjSrc += lDeltaSrc;
00441         pjDst += lDeltaDst;
00442     }
00443 }
00444 
00445 LONG
00446 APIENTRY
00447 NtGdiGetBitmapBits(
00448     HBITMAP hBitmap,
00449     ULONG cjBuffer,
00450     OUT OPTIONAL PBYTE pUnsafeBits)
00451 {
00452     PSURFACE psurf;
00453     ULONG cjSize;
00454     LONG ret;
00455 
00456     /* Check parameters */
00457     if (pUnsafeBits != NULL && cjBuffer == 0)
00458     {
00459         return 0;
00460     }
00461 
00462     /* Lock the bitmap */
00463     psurf = SURFACE_ShareLockSurface(hBitmap);
00464     if (!psurf)
00465     {
00466         EngSetLastError(ERROR_INVALID_HANDLE);
00467         return 0;
00468     }
00469 
00470     /* Calculate the size of the bitmap in bytes */
00471     cjSize = WIDTH_BYTES_ALIGN16(psurf->SurfObj.sizlBitmap.cx,
00472                 BitsPerFormat(psurf->SurfObj.iBitmapFormat)) *
00473                 abs(psurf->SurfObj.sizlBitmap.cy);
00474 
00475     /* If the bits vector is null, the function should return the read size */
00476     if (pUnsafeBits == NULL)
00477     {
00478         SURFACE_ShareUnlockSurface(psurf);
00479         return cjSize;
00480     }
00481 
00482     /* Don't copy more bytes than the buffer has */
00483     cjBuffer = min(cjBuffer, cjSize);
00484 
00485     // FIXME: Use MmSecureVirtualMemory
00486     _SEH2_TRY
00487     {
00488         ProbeForWrite(pUnsafeBits, cjBuffer, 1);
00489         UnsafeGetBitmapBits(psurf, cjBuffer, pUnsafeBits);
00490         ret = cjBuffer;
00491     }
00492     _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
00493     {
00494         ret = 0;
00495     }
00496     _SEH2_END
00497 
00498     SURFACE_ShareUnlockSurface(psurf);
00499 
00500     return ret;
00501 }
00502 
00503 
00504 LONG APIENTRY
00505 NtGdiSetBitmapBits(
00506     HBITMAP hBitmap,
00507     DWORD Bytes,
00508     IN PBYTE pUnsafeBits)
00509 {
00510     LONG ret;
00511     PSURFACE psurf;
00512 
00513     if (pUnsafeBits == NULL || Bytes == 0)
00514     {
00515         return 0;
00516     }
00517 
00518     psurf = SURFACE_ShareLockSurface(hBitmap);
00519     if (psurf == NULL)
00520     {
00521         EngSetLastError(ERROR_INVALID_HANDLE);
00522         return 0;
00523     }
00524 
00525     _SEH2_TRY
00526     {
00527         ProbeForRead(pUnsafeBits, Bytes, 1);
00528         UnsafeSetBitmapBits(psurf, Bytes, pUnsafeBits);
00529         ret = 1;
00530     }
00531     _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
00532     {
00533         ret = 0;
00534     }
00535     _SEH2_END
00536 
00537     SURFACE_ShareUnlockSurface(psurf);
00538 
00539     return ret;
00540 }
00541 
00542 BOOL APIENTRY
00543 NtGdiSetBitmapDimension(
00544     HBITMAP hBitmap,
00545     INT Width,
00546     INT Height,
00547     LPSIZE Size)
00548 {
00549     PSURFACE psurf;
00550     BOOL Ret = TRUE;
00551 
00552     if (hBitmap == NULL)
00553         return FALSE;
00554 
00555     psurf = SURFACE_ShareLockSurface(hBitmap);
00556     if (psurf == NULL)
00557     {
00558         EngSetLastError(ERROR_INVALID_HANDLE);
00559         return FALSE;
00560     }
00561 
00562     if (Size)
00563     {
00564         _SEH2_TRY
00565         {
00566             ProbeForWrite(Size, sizeof(SIZE), 1);
00567             *Size = psurf->sizlDim;
00568         }
00569         _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
00570         {
00571             Ret = FALSE;
00572         }
00573         _SEH2_END
00574     }
00575 
00576     /* The dimension is changed even if writing the old value failed */
00577     psurf->sizlDim.cx = Width;
00578     psurf->sizlDim.cy = Height;
00579 
00580     SURFACE_ShareUnlockSurface(psurf);
00581 
00582     return Ret;
00583 }
00584 
00585 /*  Internal Functions  */
00586 
00587 HBITMAP
00588 FASTCALL
00589 BITMAP_CopyBitmap(HBITMAP hBitmap)
00590 {
00591     HBITMAP hbmNew;
00592     SURFACE *psurfSrc, *psurfNew;
00593 
00594     /* Fail, if no source bitmap is given */
00595     if (hBitmap == NULL) return 0;
00596 
00597     /* Lock the source bitmap */
00598     psurfSrc = SURFACE_ShareLockSurface(hBitmap);
00599     if (psurfSrc == NULL)
00600     {
00601         return 0;
00602     }
00603 
00604     /* Allocate a new bitmap with the same dimensions as the source bmp */
00605     hbmNew = GreCreateBitmapEx(psurfSrc->SurfObj.sizlBitmap.cx,
00606                                psurfSrc->SurfObj.sizlBitmap.cy,
00607                                abs(psurfSrc->SurfObj.lDelta),
00608                                psurfSrc->SurfObj.iBitmapFormat,
00609                                psurfSrc->SurfObj.fjBitmap & BMF_TOPDOWN,
00610                                psurfSrc->SurfObj.cjBits,
00611                                NULL,
00612                                psurfSrc->flags);
00613 
00614     if (hbmNew)
00615     {
00616         /* Lock the new bitmap */
00617         psurfNew = SURFACE_ShareLockSurface(hbmNew);
00618         if (psurfNew)
00619         {
00620             /* Copy the bitmap bits to the new bitmap buffer */
00621             RtlCopyMemory(psurfNew->SurfObj.pvBits,
00622                           psurfSrc->SurfObj.pvBits,
00623                           psurfNew->SurfObj.cjBits);
00624 
00625             /* Dereference the new bitmaps palette, we will use a different */
00626             GDIOBJ_vDereferenceObject(&psurfNew->ppal->BaseObject);
00627 
00628             /* Reference the palette of the source bitmap and use it */
00629             GDIOBJ_vReferenceObjectByPointer(&psurfSrc->ppal->BaseObject);
00630             psurfNew->ppal = psurfSrc->ppal;
00631 
00632             /* Unlock the new surface */
00633             SURFACE_ShareUnlockSurface(psurfNew);
00634         }
00635         else
00636         {
00637             /* Failed to lock the bitmap, shouldn't happen */
00638             GreDeleteObject(hbmNew);
00639             hbmNew = NULL;
00640         }
00641     }
00642 
00643     /* Unlock the source bitmap and return the handle of the new bitmap */
00644     SURFACE_ShareUnlockSurface(psurfSrc);
00645     return hbmNew;
00646 }
00647 
00648 INT APIENTRY
00649 BITMAP_GetObject(SURFACE *psurf, INT Count, LPVOID buffer)
00650 {
00651     PBITMAP pBitmap;
00652 
00653     if (!buffer) return sizeof(BITMAP);
00654     if ((UINT)Count < sizeof(BITMAP)) return 0;
00655 
00656     /* Always fill a basic BITMAP structure */
00657     pBitmap = buffer;
00658     pBitmap->bmType = 0;
00659     pBitmap->bmWidth = psurf->SurfObj.sizlBitmap.cx;
00660     pBitmap->bmHeight = psurf->SurfObj.sizlBitmap.cy;
00661     pBitmap->bmPlanes = 1;
00662     pBitmap->bmBitsPixel = BitsPerFormat(psurf->SurfObj.iBitmapFormat);
00663     pBitmap->bmWidthBytes = WIDTH_BYTES_ALIGN16(pBitmap->bmWidth, pBitmap->bmBitsPixel);
00664 
00665     /* Check for DIB section */
00666     if (psurf->hSecure)
00667     {
00668         /* Set bmBits in this case */
00669         pBitmap->bmBits = psurf->SurfObj.pvBits;
00670         /* DIBs data are 32 bits aligned */
00671         pBitmap->bmWidthBytes = WIDTH_BYTES_ALIGN32(pBitmap->bmWidth, pBitmap->bmBitsPixel);
00672 
00673         if (Count >= sizeof(DIBSECTION))
00674         {
00675             /* Fill rest of DIBSECTION */
00676             PDIBSECTION pds = buffer;
00677 
00678             pds->dsBmih.biSize = sizeof(BITMAPINFOHEADER);
00679             pds->dsBmih.biWidth = pds->dsBm.bmWidth;
00680             pds->dsBmih.biHeight = pds->dsBm.bmHeight;
00681             pds->dsBmih.biPlanes = pds->dsBm.bmPlanes;
00682             pds->dsBmih.biBitCount = pds->dsBm.bmBitsPixel;
00683 
00684             switch (psurf->SurfObj.iBitmapFormat)
00685             {
00686                 case BMF_1BPP:
00687                 case BMF_4BPP:
00688                 case BMF_8BPP:
00689                    pds->dsBmih.biCompression = BI_RGB;
00690                    break;
00691 
00692                 case BMF_16BPP:
00693                     if (psurf->ppal->flFlags & PAL_RGB16_555)
00694                         pds->dsBmih.biCompression = BI_RGB;
00695                     else
00696                         pds->dsBmih.biCompression = BI_BITFIELDS;
00697                     break;
00698 
00699                 case BMF_24BPP:
00700                 case BMF_32BPP:
00701                     /* 24/32bpp BI_RGB is actually BGR format */
00702                     if (psurf->ppal->flFlags & PAL_BGR)
00703                         pds->dsBmih.biCompression = BI_RGB;
00704                     else
00705                         pds->dsBmih.biCompression = BI_BITFIELDS;
00706                     break;
00707 
00708                 case BMF_4RLE:
00709                    pds->dsBmih.biCompression = BI_RLE4;
00710                    break;
00711                 case BMF_8RLE:
00712                    pds->dsBmih.biCompression = BI_RLE8;
00713                    break;
00714                 case BMF_JPEG:
00715                    pds->dsBmih.biCompression = BI_JPEG;
00716                    break;
00717                 case BMF_PNG:
00718                    pds->dsBmih.biCompression = BI_PNG;
00719                    break;
00720                 default:
00721                     ASSERT(FALSE); /* This shouldn't happen */
00722             }
00723 
00724             pds->dsBmih.biSizeImage = psurf->SurfObj.cjBits;
00725             pds->dsBmih.biXPelsPerMeter = 0;
00726             pds->dsBmih.biYPelsPerMeter = 0;
00727             pds->dsBmih.biClrUsed = psurf->ppal->NumColors;
00728             pds->dsBmih.biClrImportant = psurf->biClrImportant;
00729             pds->dsBitfields[0] = psurf->ppal->RedMask;
00730             pds->dsBitfields[1] = psurf->ppal->GreenMask;
00731             pds->dsBitfields[2] = psurf->ppal->BlueMask;
00732             pds->dshSection = psurf->hDIBSection;
00733             pds->dsOffset = psurf->dwOffset;
00734 
00735             return sizeof(DIBSECTION);
00736         }
00737     }
00738     else
00739     {
00740         /* Not set according to wine test, confirmed in win2k */
00741         pBitmap->bmBits = NULL;
00742     }
00743 
00744     return sizeof(BITMAP);
00745 }
00746 
00747 /*
00748  * @implemented
00749  */
00750 HDC
00751 APIENTRY
00752 NtGdiGetDCforBitmap(
00753     IN HBITMAP hsurf)
00754 {
00755     HDC hdc = NULL;
00756     PSURFACE psurf = SURFACE_ShareLockSurface(hsurf);
00757     if (psurf)
00758     {
00759         hdc = psurf->hdc;
00760         SURFACE_ShareUnlockSurface(psurf);
00761     }
00762     return hdc;
00763 }
00764 
00765 
00766 /* EOF */

Generated on Sun May 27 2012 04:38:24 for ReactOS by doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.