dibobj.c

来自「ReactOS是一些高手根据Windows XP的内核编写出的类XP。内核实现机」· C语言 代码 · 共 1,268 行 · 第 1/3 页

C
1,268
字号
/*
 * $Id: dibobj.c 28434 2007-08-20 19:50:07Z cfinck $
 *
 * ReactOS W32 Subsystem
 * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 ReactOS Team
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 */

#include <w32k.h>

#define NDEBUG
#include <debug.h>

UINT STDCALL
NtGdiSetDIBColorTable(HDC hDC, UINT StartIndex, UINT Entries, CONST RGBQUAD *Colors)
{
   PDC dc;
   PBITMAPOBJ BitmapObj;
   PPALGDI PalGDI;
   UINT Index;

   if (!(dc = DC_LockDc(hDC))) return 0;
   if (dc->IsIC)
   {
      DC_UnlockDc(dc);
      return 0;
   }

   BitmapObj = BITMAPOBJ_LockBitmap(dc->w.hBitmap);
   if (BitmapObj == NULL)
   {
      DC_UnlockDc(dc);
      SetLastWin32Error(ERROR_INVALID_PARAMETER);
      return 0;
   }

   if (BitmapObj->dib == NULL)
   {
      BITMAPOBJ_UnlockBitmap(BitmapObj);
      DC_UnlockDc(dc);
      SetLastWin32Error(ERROR_INVALID_PARAMETER);
      return 0;
   }

   if (BitmapObj->dib->dsBmih.biBitCount <= 8 &&
       StartIndex < (1 << BitmapObj->dib->dsBmih.biBitCount))
   {
      if (StartIndex + Entries > (1 << BitmapObj->dib->dsBmih.biBitCount))
         Entries = (1 << BitmapObj->dib->dsBmih.biBitCount) - StartIndex;

      PalGDI = PALETTE_LockPalette(BitmapObj->hDIBPalette);
      _SEH_TRY
      {
         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;
         }
      }
      _SEH_HANDLE
      {
         Entries = 0;
      }
      _SEH_END
      PALETTE_UnlockPalette(PalGDI);
   }
   else
      Entries = 0;

   BITMAPOBJ_UnlockBitmap(BitmapObj);
   DC_UnlockDc(dc);

   return Entries;
}

UINT STDCALL
NtGdiGetDIBColorTable(HDC hDC, UINT StartIndex, UINT Entries, RGBQUAD *Colors)
{
   PDC dc;
   PBITMAPOBJ BitmapObj;
   PPALGDI PalGDI;
   UINT Index;

   if (!(dc = DC_LockDc(hDC))) return 0;
   if (dc->IsIC)
   {
      DC_UnlockDc(dc);
      return 0;
   }

   BitmapObj = BITMAPOBJ_LockBitmap(dc->w.hBitmap);
   if (BitmapObj == NULL)
   {
      DC_UnlockDc(dc);
      SetLastWin32Error(ERROR_INVALID_PARAMETER);
      return 0;
   }

   if (BitmapObj->dib == NULL)
   {
      BITMAPOBJ_UnlockBitmap(BitmapObj);
      DC_UnlockDc(dc);
      SetLastWin32Error(ERROR_INVALID_PARAMETER);
      return 0;
   }

   if (BitmapObj->dib->dsBmih.biBitCount <= 8 &&
       StartIndex < (1 << BitmapObj->dib->dsBmih.biBitCount))
   {
      if (StartIndex + Entries > (1 << BitmapObj->dib->dsBmih.biBitCount))
         Entries = (1 << BitmapObj->dib->dsBmih.biBitCount) - StartIndex;

      PalGDI = PALETTE_LockPalette(BitmapObj->hDIBPalette);
      _SEH_TRY
      {
         for (Index = StartIndex;
              Index < StartIndex + Entries && Index < PalGDI->NumColors;
              Index++)
         {
            Colors[Index - StartIndex].rgbRed = PalGDI->IndexedColors[Index].peRed;
            Colors[Index - StartIndex].rgbGreen = PalGDI->IndexedColors[Index].peGreen;
            Colors[Index - StartIndex].rgbBlue = PalGDI->IndexedColors[Index].peBlue;
         }
      }
      _SEH_HANDLE
      {
         Entries = 0;
      }
      _SEH_END
      PALETTE_UnlockPalette(PalGDI);
   }
   else
      Entries = 0;

   BITMAPOBJ_UnlockBitmap(BitmapObj);
   DC_UnlockDc(dc);

   return Entries;
}

// Converts a DIB to a device-dependent bitmap
static INT FASTCALL
IntSetDIBits(
	PDC   DC,
	HBITMAP  hBitmap,
	UINT  StartScan,
	UINT  ScanLines,
	CONST VOID  *Bits,
	CONST BITMAPINFO  *bmi,
	UINT  ColorUse)
{
  BITMAPOBJ  *bitmap;
  HBITMAP     SourceBitmap;
  INT         result = 0;
  BOOL        copyBitsResult;
  SURFOBJ    *DestSurf, *SourceSurf;
  SIZEL       SourceSize;
  POINTL      ZeroPoint;
  RECTL       DestRect;
  XLATEOBJ   *XlateObj;
  PPALGDI     hDCPalette;
  //RGBQUAD    *lpRGB;
  HPALETTE    DDB_Palette, DIB_Palette;
  ULONG       DDB_Palette_Type, DIB_Palette_Type;
  INT         DIBWidth;

  // Check parameters
  if (!(bitmap = BITMAPOBJ_LockBitmap(hBitmap)))
  {
    return 0;
  }

  // Get RGB values
  //if (ColorUse == DIB_PAL_COLORS)
  //  lpRGB = DIB_MapPaletteColors(hDC, bmi);
  //else
  //  lpRGB = &bmi->bmiColors;

  DestSurf = &bitmap->SurfObj;

  // Create source surface
  SourceSize.cx = bmi->bmiHeader.biWidth;
  SourceSize.cy = ScanLines;

  // Determine width of DIB
  DIBWidth = DIB_GetDIBWidthBytes(SourceSize.cx, bmi->bmiHeader.biBitCount);

  SourceBitmap = EngCreateBitmap(SourceSize,
                                 DIBWidth,
                                 BitmapFormat(bmi->bmiHeader.biBitCount, bmi->bmiHeader.biCompression),
                                 bmi->bmiHeader.biHeight < 0 ? BMF_TOPDOWN : 0,
                                 (PVOID) Bits);
  if (0 == SourceBitmap)
  {
      BITMAPOBJ_UnlockBitmap(bitmap);
      SetLastWin32Error(ERROR_NO_SYSTEM_RESOURCES);
      return 0;
  }

  SourceSurf = EngLockSurface((HSURF)SourceBitmap);
  if (NULL == SourceSurf)
  {
      EngDeleteSurface((HSURF)SourceBitmap);
      BITMAPOBJ_UnlockBitmap(bitmap);
      SetLastWin32Error(ERROR_NO_SYSTEM_RESOURCES);
      return 0;
  }

  // Destination palette obtained from the hDC
  hDCPalette = PALETTE_LockPalette(DC->DevInfo->hpalDefault);
  if (NULL == hDCPalette)
    {
      EngUnlockSurface(SourceSurf);
      EngDeleteSurface((HSURF)SourceBitmap);
      BITMAPOBJ_UnlockBitmap(bitmap);
      SetLastWin32Error(ERROR_INVALID_HANDLE);
      return 0;
    }
  DDB_Palette_Type = hDCPalette->Mode;
  DDB_Palette = DC->DevInfo->hpalDefault;
  PALETTE_UnlockPalette(hDCPalette);

  // Source palette obtained from the BITMAPINFO
  DIB_Palette = BuildDIBPalette ( (PBITMAPINFO)bmi, (PINT)&DIB_Palette_Type );
  if (NULL == DIB_Palette)
    {
      EngUnlockSurface(SourceSurf);
      EngDeleteSurface((HSURF)SourceBitmap);
      BITMAPOBJ_UnlockBitmap(bitmap);
      SetLastWin32Error(ERROR_NO_SYSTEM_RESOURCES);
      return 0;
    }

  // Determine XLATEOBJ for color translation
  XlateObj = IntEngCreateXlate(DDB_Palette_Type, DIB_Palette_Type, DDB_Palette, DIB_Palette);
  if (NULL == XlateObj)
    {
      PALETTE_FreePalette(DIB_Palette);
      EngUnlockSurface(SourceSurf);
      EngDeleteSurface((HSURF)SourceBitmap);
      BITMAPOBJ_UnlockBitmap(bitmap);
      SetLastWin32Error(ERROR_NO_SYSTEM_RESOURCES);
      return 0;
    }

  // Zero point
  ZeroPoint.x = 0;
  ZeroPoint.y = 0;

  // Determine destination rectangle
  DestRect.left	= 0;
  DestRect.top	= abs(bmi->bmiHeader.biHeight) - StartScan - ScanLines;
  DestRect.right	= SourceSize.cx;
  DestRect.bottom	= DestRect.top + ScanLines;

  copyBitsResult = EngCopyBits(DestSurf, SourceSurf, NULL, XlateObj, &DestRect, &ZeroPoint);

  // If it succeeded, return number of scanlines copies
  if(copyBitsResult == TRUE)
  {
    result = SourceSize.cy - 1;
  }

  // Clean up
  EngDeleteXlate(XlateObj);
  PALETTE_FreePalette(DIB_Palette);
  EngUnlockSurface(SourceSurf);
  EngDeleteSurface((HSURF)SourceBitmap);

//  if (ColorUse == DIB_PAL_COLORS)
//    WinFree((LPSTR)lpRGB);

  BITMAPOBJ_UnlockBitmap(bitmap);

  return result;
}

// Converts a DIB to a device-dependent bitmap
INT STDCALL
NtGdiSetDIBits(
	HDC  hDC,
	HBITMAP  hBitmap,
	UINT  StartScan,
	UINT  ScanLines,
	CONST VOID  *Bits,
	CONST BITMAPINFO  *bmi,
	UINT  ColorUse)
{
  PDC Dc;
  INT Ret;

  Dc = DC_LockDc(hDC);
  if (NULL == Dc)
    {
      SetLastWin32Error(ERROR_INVALID_HANDLE);
      return 0;
    }
  if (Dc->IsIC)
    {
      DC_UnlockDc(Dc);
      return 0;
    }

  Ret = IntSetDIBits(Dc, hBitmap, StartScan, ScanLines, Bits, bmi, ColorUse);

  DC_UnlockDc(Dc);

  return Ret;
}

W32KAPI
INT
APIENTRY
NtGdiSetDIBitsToDeviceInternal(
    IN HDC hDC,
    IN INT XDest,
    IN INT YDest,
    IN DWORD Width,
    IN DWORD Height,
    IN INT XSrc,
    IN INT YSrc,
    IN DWORD StartScan,
    IN DWORD ScanLines,
    IN LPBYTE Bits,
    IN LPBITMAPINFO bmi,
    IN DWORD ColorUse,
    IN UINT cjMaxBits,
    IN UINT cjMaxInfo,
    IN BOOL bTransformCoordinates,
    IN OPTIONAL HANDLE hcmXform
)
{
  UNIMPLEMENTED;
  return 0;
}

/* Converts a device-dependent bitmap to a DIB */
INT STDCALL
NtGdiGetDIBits(HDC hDC,
               HBITMAP hBitmap,
               UINT StartScan,
               UINT ScanLines,
               LPVOID Bits,
               LPBITMAPINFO Info,
               UINT Usage)
{
   BITMAPOBJ *BitmapObj;
   SURFOBJ *DestSurfObj;
   XLATEOBJ *XlateObj;
   HBITMAP DestBitmap;
   SIZEL DestSize;
   HPALETTE hSourcePalette;
   HPALETTE hDestPalette;
   PPALGDI SourcePalette;
   PPALGDI DestPalette;
   ULONG SourcePaletteType;
   ULONG DestPaletteType;
   PDC Dc;
   POINTL SourcePoint;
   RECTL DestRect;
   ULONG Result = 0;
   ULONG Index;

   /* Get handle for the palette in DC. */
   Dc = DC_LockDc(hDC);
   if (Dc == NULL)
   {
      SetLastWin32Error(ERROR_INVALID_HANDLE);
      return 0;
   }
   if (Dc->IsIC)
   {
      DC_UnlockDc(Dc);
      return 0;
   }
   hSourcePalette = Dc->w.hPalette;
   /* FIXME: This is incorrect. hDestPalette should be something other. */
   hDestPalette = Dc->DevInfo->hpalDefault;
   DC_UnlockDc(Dc);

   /* Get pointer to the source bitmap object. */
   BitmapObj = BITMAPOBJ_LockBitmap(hBitmap);
   if (BitmapObj == NULL)
   {
      SetLastWin32Error(ERROR_INVALID_HANDLE);
      return 0;
   }

   if (Bits == NULL)
   {
      if (Info->bmiHeader.biSize == sizeof(BITMAPCOREHEADER))
      {
	  BITMAPCOREHEADER* coreheader = (BITMAPCOREHEADER*) Info;
          coreheader->bcWidth =BitmapObj->SurfObj.sizlBitmap.cx;
          coreheader->bcPlanes = 1;
          coreheader->bcBitCount =  BitsPerFormat(BitmapObj->SurfObj.iBitmapFormat);

	  coreheader->bcHeight = BitmapObj->SurfObj.sizlBitmap.cy;
	  if (BitmapObj->SurfObj.lDelta > 0)
	  coreheader->bcHeight = -coreheader->bcHeight;

	  Result = BitmapObj->SurfObj.sizlBitmap.cy;
      }

      if (Info->bmiHeader.biSize == sizeof(BITMAPINFOHEADER))
      {
         Info->bmiHeader.biWidth = BitmapObj->SurfObj.sizlBitmap.cx;

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?