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

📄 dibobj.c

📁 winNT技术操作系统,国外开放的原代码和LIUX一样
💻 C
📖 第 1 页 / 共 3 页
字号:
                  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),
                                          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;

   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 (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);

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

   return SrcHeight;
}

LONG STDCALL NtGdiGetBitmapBits(HBITMAP  hBitmap,
                        ULONG  Count,
                        OUT OPTIONAL PBYTE Bits)
{
  PBITMAPOBJ  bmp;
  LONG  height, ret;

  bmp = BITMAPOBJ_LockBitmap (hBitmap);
  if (!bmp)
  {
    return 0;
  }

  /* If the bits vector is null, the function should return the read size */
  if (Bits == NULL)
  {
    ret = bmp->SurfObj.cjBits;
    BITMAPOBJ_UnlockBitmap (bmp);
    return ret;
  }

  if (Count < 0)
  {
    DPRINT ("(%ld): Negative number of bytes passed???\n", Count);
    Count = -Count;
  }

  /* Only get entire lines */
  height = Count / abs(bmp->SurfObj.lDelta);
  if (height > bmp->SurfObj.sizlBitmap.cy)
  {
    height = bmp->SurfObj.sizlBitmap.cy;
  }
  Count = height * abs(bmp->SurfObj.lDelta);
  if (Count == 0)
  {
    DPRINT("Less then one entire line requested\n");
    BITMAPOBJ_UnlockBitmap (bmp);
    return  0;
  }

  DPRINT("(%08x, %ld, %p) %dx%d %d colors fetched height: %ld\n",
         hBitmap, Count, Bits, bmp->SurfObj.sizlBitmap.cx,
         bmp->SurfObj.sizlBitmap.cy,
         1 << BitsPerFormat(bmp->SurfObj.iBitmapFormat), height );
#if 0
  /* FIXME: Call DDI CopyBits here if available  */
  if(bmp->DDBitmap)
  {
    DPRINT("Calling device specific BitmapBits\n");
    if(bmp->DDBitmap->funcs->pBitmapBits)
    {
      ret = bmp->DDBitmap->funcs->pBitmapBits(hbitmap, bits, count,
                                              DDB_GET);
    }
    else
    {
      ERR_(bitmap)("BitmapBits == NULL??\n");
      ret = 0;
    }
  }
  else
#endif
  {
    memcpy(Bits, bmp->SurfObj.pvBits, Count);
    ret = Count;
  }

  BITMAPOBJ_UnlockBitmap (bmp);

  return  ret;
}

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;

⌨️ 快捷键说明

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