⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dibobj.c

📁 winNT技术操作系统,国外开放的原代码和LIUX一样
💻 C
📖 第 1 页 / 共 3 页
字号:
/*
 * $Id: dibobj.c 24578 2006-10-20 13:19:13Z weiden $
 *
 * 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;
}

INT STDCALL
NtGdiSetDIBitsToDevice(
	HDC  hDC,
	INT  XDest,
	INT  YDest,
	DWORD  Width,
	DWORD  Height,
	INT  XSrc,
	INT  YSrc,
	UINT  StartScan,
	UINT  ScanLines,
	CONST VOID  *Bits,
	CONST BITMAPINFO  *bmi,
	UINT  ColorUse)
{
  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;
         Info->bmiHeader.biHeight = BitmapObj->SurfObj.sizlBitmap.cy;
         /* Report negtive height for top-down bitmaps. */
         if (BitmapObj->SurfObj.lDelta > 0)
            Info->bmiHeader.biHeight = -Info->bmiHeader.biHeight;
         Info->bmiHeader.biPlanes = 1;
         Info->bmiHeader.biBitCount = BitsPerFormat(BitmapObj->SurfObj.iBitmapFormat);
         if (Info->bmiHeader.biSize == sizeof(BITMAPINFOHEADER))
         {
            switch (BitmapObj->SurfObj.iBitmapFormat)
            {
               case BMF_1BPP: case BMF_4BPP: case BMF_8BPP:
               case BMF_16BPP: case BMF_24BPP: case BMF_32BPP:
                  Info->bmiHeader.biCompression = BI_RGB;
                  break;
               case BMF_4RLE:
                  Info->bmiHeader.biCompression = BI_RLE4;
                  break;
               case BMF_8RLE:
                  Info->bmiHeader.biCompression = BI_RLE8;
                  break;
               case BMF_JPEG:
                  Info->bmiHeader.biCompression = BI_JPEG;
                  break;
               case BMF_PNG:
                  Info->bmiHeader.biCompression = BI_PNG;

⌨️ 快捷键说明

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