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

📄 dibobj.c

📁 这是一个开放源代码的与WINNT/WIN2K/WIN2003兼容的操作系统
💻 C
📖 第 1 页 / 共 3 页
字号:
         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;
                  break;
            }
            Info->bmiHeader.biSizeImage = BitmapObj->SurfObj.cjBits;
            Info->bmiHeader.biXPelsPerMeter = 0; /* FIXME */
            Info->bmiHeader.biYPelsPerMeter = 0; /* FIXME */
            Info->bmiHeader.biClrUsed =
            Info->bmiHeader.biClrImportant = 1 << Info->bmiHeader.biBitCount; /* FIXME */
            Result = BitmapObj->SurfObj.sizlBitmap.cy;
         }
      }
   }
   else
   {
      if (StartScan > BitmapObj->SurfObj.sizlBitmap.cy)
      {
         Result = 0;
      }
      else
      {
         ScanLines = min(ScanLines, BitmapObj->SurfObj.sizlBitmap.cy - StartScan);
         DestSize.cx = BitmapObj->SurfObj.sizlBitmap.cx;
         DestSize.cy = ScanLines;

	 DestBitmap = NULL;
	 if (Info->bmiHeader.biSize == sizeof(BITMAPINFOHEADER))
	 {
            DestBitmap = EngCreateBitmap(DestSize,
		                         /* DIB_GetDIBWidthBytes(DestSize.cx, Info->bmiHeader.biBitCount), */
		                         DestSize.cx * (Info->bmiHeader.biBitCount >> 3), /* HACK */
                                         BitmapFormat(Info->bmiHeader.biBitCount, Info->bmiHeader.biCompression),
                                         0 < Info->bmiHeader.biHeight ? 0 : BMF_TOPDOWN,
                                         Bits);
	 }

	 if (Info->bmiHeader.biSize == sizeof(BITMAPCOREHEADER))
	 {
	    BITMAPCOREHEADER* coreheader = (BITMAPCOREHEADER*) Info;

	    DestBitmap = EngCreateBitmap(DestSize,
		                         DIB_GetDIBWidthBytes(DestSize.cx, coreheader->bcBitCount),
                                         BitmapFormat(coreheader->bcBitCount, BI_RGB),
                                         0 < coreheader->bcHeight ? 0 : BMF_TOPDOWN,
                                         Bits);
	 }

         if(DestBitmap == NULL)
         {
            BITMAPOBJ_UnlockBitmap(BitmapObj);
            return 0;
         }

         DestSurfObj = EngLockSurface((HSURF)DestBitmap);

         SourcePalette = PALETTE_LockPalette(hSourcePalette);
         /* FIXME - SourcePalette can be NULL!!! Don't assert here! */
         ASSERT(SourcePalette);
         SourcePaletteType = SourcePalette->Mode;
         PALETTE_UnlockPalette(SourcePalette);

         DestPalette = PALETTE_LockPalette(hDestPalette);
         /* FIXME - DestPalette can be NULL!!!! Don't assert here!!! */
         ASSERT(DestPalette);
         DestPaletteType = DestPalette->Mode;

         /* Copy palette. */
         /* FIXME: This is largely incomplete. */
         if (Info->bmiHeader.biBitCount <= 8)
         {
            if (Usage == DIB_RGB_COLORS)
            {
               for (Index = 0;
                    Index < (1 << Info->bmiHeader.biBitCount) &&
                    Index < DestPalette->NumColors;
                    Index++)
               {
                  Info->bmiColors[Index].rgbRed =
                     DestPalette->IndexedColors[Index].peRed;
                  Info->bmiColors[Index].rgbGreen =
                     DestPalette->IndexedColors[Index].peGreen;
                  Info->bmiColors[Index].rgbBlue =
                     DestPalette->IndexedColors[Index].peBlue;
               }
            }
            if (Usage == DIB_PAL_COLORS)
            {
               DPRINT1("GetDIBits with DIB_PAL_COLORS isn't implemented yet.");
            }
         }

         PALETTE_UnlockPalette(DestPalette);

         XlateObj = IntEngCreateXlate(
            DestPaletteType, SourcePaletteType, hDestPalette, hSourcePalette);

         SourcePoint.x = 0;
         SourcePoint.y = BitmapObj->SurfObj.sizlBitmap.cy -
                         (StartScan + ScanLines);

         /* Determine destination rectangle */
         DestRect.top = 0;
         DestRect.left = 0;
         DestRect.right = DestSize.cx;
         DestRect.bottom = DestSize.cy;

         if (EngCopyBits(DestSurfObj, &BitmapObj->SurfObj,
                         NULL, XlateObj, &DestRect, &SourcePoint))
         {
            Result = ScanLines;
         }

         EngDeleteXlate(XlateObj);
         EngUnlockSurface(DestSurfObj);
      }
   }

   BITMAPOBJ_UnlockBitmap(BitmapObj);

   return Result;
}

INT STDCALL NtGdiStretchDIBits(HDC  hDC,
                       INT  XDest,
                       INT  YDest,
                       INT  DestWidth,
                       INT  DestHeight,
                       INT  XSrc,
                       INT  YSrc,
                       INT  SrcWidth,
                       INT  SrcHeight,
                       CONST VOID  *Bits,
                       CONST BITMAPINFO  *BitsInfo,
                       UINT  Usage,
                       DWORD  ROP)
{
   HBITMAP hBitmap, hOldBitmap;
   HDC hdcMem;
   HPALETTE hPal = NULL;

   if (!Bits || !BitsInfo)
   {
      SetLastWin32Error(ERROR_INVALID_PARAMETER);
      return 0;
   }

   hdcMem = NtGdiCreateCompatibleDC(hDC);
   hBitmap = NtGdiCreateCompatibleBitmap(hDC, BitsInfo->bmiHeader.biWidth,
                                         BitsInfo->bmiHeader.biHeight);
   hOldBitmap = NtGdiSelectObject(hdcMem, hBitmap);

   if(Usage == DIB_PAL_COLORS)
   {
      hPal = NtGdiGetCurrentObject(hDC, OBJ_PAL);
      hPal = NtUserSelectPalette(hdcMem, hPal, FALSE);
   }

   if (BitsInfo->bmiHeader.biCompression == BI_RLE4 ||
       BitsInfo->bmiHeader.biCompression == BI_RLE8)
   {
      /* copy existing bitmap from destination dc */
      if (SrcWidth == DestWidth && SrcHeight == DestHeight)
         NtGdiBitBlt(hdcMem, XSrc, abs(BitsInfo->bmiHeader.biHeight) - SrcHeight - YSrc,
                     SrcWidth, SrcHeight, hDC, XDest, YDest, ROP, 0, 0);
      else
         NtGdiStretchBlt(hdcMem, XSrc, abs(BitsInfo->bmiHeader.biHeight) - SrcHeight - YSrc,
                         SrcWidth, SrcHeight, hDC, XDest, YDest, DestWidth, DestHeight,
                         ROP, 0);
   }

   NtGdiSetDIBits(hdcMem, hBitmap, 0, BitsInfo->bmiHeader.biHeight, Bits,
                  BitsInfo, Usage);

   /* Origin for DIBitmap may be bottom left (positive biHeight) or top
      left (negative biHeight) */
   if (SrcWidth == DestWidth && SrcHeight == DestHeight)
      NtGdiBitBlt(hDC, XDest, YDest, DestWidth, DestHeight,
                  hdcMem, XSrc, abs(BitsInfo->bmiHeader.biHeight) - SrcHeight - YSrc,
                  ROP, 0, 0);
   else
      NtGdiStretchBlt(hDC, XDest, YDest, DestWidth, DestHeight,
                      hdcMem, XSrc, abs(BitsInfo->bmiHeader.biHeight) - SrcHeight - YSrc,
                      SrcWidth, SrcHeight, ROP, 0);

   if(hPal)
      NtUserSelectPalette(hdcMem, hPal, FALSE);

   NtGdiSelectObject(hdcMem, hOldBitmap);
   NtGdiDeleteObjectApp(hdcMem);
   NtGdiDeleteObject(hBitmap);

   return SrcHeight;
}


HBITMAP FASTCALL
IntCreateDIBitmap(PDC Dc, const BITMAPINFOHEADER *header,
                  DWORD init, LPCVOID bits, const BITMAPINFO *data,
                  UINT coloruse)
{
  HBITMAP handle;
 
  LONG width;
  LONG height;
  WORD planes; 
  WORD bpp;
  LONG compr;
  LONG dibsize;        
  BOOL fColor;
  SIZEL size;


  if (DIB_GetBitmapInfo( header, &width, &height, &planes, &bpp, &compr, &dibsize ) == -1) return 0;  

    
  // Check if we should create a monochrome or color bitmap. We create a monochrome bitmap only if it has exactly 2
  // colors, which are black followed by white, nothing else. In all other cases, we create a color bitmap.

  if (bpp != 1) fColor = TRUE;
  else if ((coloruse != DIB_RGB_COLORS) ||
           (init != CBM_INIT) || !data) fColor = FALSE;
  else
  {
    if (data->bmiHeader.biSize == sizeof(BITMAPINFOHEADER))
    {
      const RGBQUAD *rgb = data->bmiColors;
      DWORD col = RGB( rgb->rgbRed, rgb->rgbGreen, rgb->rgbBlue );

      // Check if the first color of the colormap is black
      if ((col == RGB(0, 0, 0)))
      {
        rgb++;
        col = RGB( rgb->rgbRed, rgb->rgbGreen, rgb->rgbBlue );

        // If the second color is white, create a monochrome bitmap
        fColor =  (col != RGB(0xff,0xff,0xff));
      }
    else fColor = TRUE;
  }
  else if (data->bmiHeader.biSize == sizeof(BITMAPCOREHEADER))
  {
    RGBTRIPLE *rgb = ((BITMAPCOREINFO *)data)->bmciColors;
     DWORD col = RGB( rgb->rgbtRed, rgb->rgbtGreen, rgb->rgbtBlue);

    if ((col == RGB(0,0,0)))
    {
      rgb++;
      col = RGB( rgb->rgbtRed, rgb->rgbtGreen, rgb->rgbtBlue );
      fColor = (col != RGB(0xff,0xff,0xff));
    }
    else fColor = TRUE;
  }
  else
  {
      DPRINT("(%ld): wrong size for data\n", data->bmiHeader.biSize );
      return 0;
    }
  }

  // Now create the bitmap
  if (fColor)
  {
    handle = IntCreateCompatibleBitmap(Dc, width, height);
  }
  else
  {
    size.cx = width;
    size.cy = abs(height);

    handle = IntCreateBitmap(size, DIB_GetDIBWidthBytes(width, 1), BMF_1BPP,
                             (height < 0 ? BMF_TOPDOWN : 0) | BMF_NOZEROINIT,
                             NULL);
  }

  if (height < 0)
    height = -height;

  if (NULL != handle && CBM_INIT == init)
  {
    IntSetDIBits(Dc, handle, 0, height, bits, data, coloruse);
  }

  return handle;
}

// The CreateDIBitmap function creates a device-dependent bitmap (DDB) from a DIB and, optionally, sets the bitmap bits
// The DDB that is created will be whatever bit depth your reference DC is
HBITMAP STDCALL NtGdiCreateDIBitmap(HDC hDc, const BITMAPINFOHEADER *Header,
                                    DWORD Init, LPCVOID Bits, const BITMAPINFO *Data,
                                    UINT ColorUse)
{
  PDC Dc;
  HBITMAP Bmp;
  
  if (Header == NULL)
  {
	  return NULL;
  }

  if (Header->biSize == 0)
  {
	  return NULL;
  }

  if (NULL == hDc)
  {     
	   BITMAPINFOHEADER *change_Header = (BITMAPINFOHEADER *)Header;
       hDc =  IntGdiCreateDC(NULL, NULL, NULL, NULL,FALSE);
       if (hDc == NULL)
       {         
          SetLastWin32Error(ERROR_INVALID_HANDLE);
          return NULL;
       }
      Dc = DC_LockDc(hDc);
      if (Dc == NULL)
      {  
          NtGdiDeleteObjectApp(hDc);          
          SetLastWin32Error(ERROR_INVALID_HANDLE);
          return NULL;
      }
      
	  change_Header->biBitCount = 1;
	  change_Header->biPlanes = 1;

      Bmp = IntCreateDIBitmap(Dc, Header, Init, Bits, Data, ColorUse);                      
      DC_UnlockDc(Dc);
      NtGdiDeleteObjectApp(hDc);  
    }
    else
    {
       Dc = DC_LockDc(hDc);
       if (Dc == NULL)
       {                    
          SetLastWin32Error(ERROR_INVALID_HANDLE);
          return NULL;
       }
       Bmp = IntCreateDIBitmap(Dc, Header, Init, Bits, Data, ColorUse);
       DC_UnlockDc(Dc);
    }

  

  return Bmp;
}

HBITMAP STDCALL NtGdiCreateDIBSection(HDC hDC,
                              IN OPTIONAL HANDLE hSection,
                              IN DWORD dwOffset,
                              IN LPBITMAPINFO bmi,
                              DWORD  Usage,
                              IN UINT cjHeader,
                              IN FLONG fl,
                              IN ULONG_PTR dwColorSpace,
                              PVOID *Bits)
{
  HBITMAP hbitmap = 0;
  DC *dc;
  BOOL bDesktopDC = FALSE;

  // If the reference hdc is null, take the desktop dc
  if (hDC == 0)
  {
    hDC = NtGdiCreateCompatibleDC(0);
    bDesktopDC = TRUE;
  }

  if ((dc = DC_LockDc(hDC)))
  {
    hbitmap = DIB_CreateDIBSection ( dc, (BITMAPINFO*)bmi, Usage, Bits,
      hSection, dwOffset, 0);
    DC_UnlockDc(dc);
  }
  else
  {
    SetLastWin32Error(ERROR_INVALID_HANDLE);
  }

  if (bDesktopDC)
    NtGdiDeleteObjectApp(hDC);

  return hbitmap;
}

HBITMAP STDCALL
DIB_CreateDIBSection(
  PDC dc, BITMAPINFO *bmi, UINT usage,
  LPVOID *bits, HANDLE section,
  DWORD offset, DWORD ovr_pitch)
{
  HBITMAP res = 0;
  BITMAPOBJ *bmp = NULL;
  DIBSECTION *dib = NULL;

  // Fill BITMAP32 structure with DIB data
  BITMAPINFOHEADER *bi = &bmi->bmiHeader;
  INT effHeight;
  ULONG totalSize;
  UINT Entries = 0;
  BITMAP bm;
  SIZEL Size;

⌨️ 快捷键说明

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