dib8bpp.c

来自「一个类似windows」· C语言 代码 · 共 824 行 · 第 1/2 页

C
824
字号
      PrevSourceAhead = (PIXEL *)((BYTE *)Source + SourceSurf->lDelta);
    } /* if */

    if (! FinalCopy8(Target, ScanLine, ClipSpans, ClipSpansCount, &SpanIndex, DestY, DestRect))
      {
        /* No more spans, everything else is clipped away, we're done */
        ExFreePool(ClipSpans);
        ExFreePool(ScanLine);
        ExFreePool(ScanLineAhead);
        return TRUE;
      }
    DestY++;
    Target = (PIXEL *)((BYTE *)Target + DestSurf->lDelta);
    Source += IntPart;
    E += FractPart;
    if (E >= DestRect->bottom - DestRect->top) {
      E -= DestRect->bottom - DestRect->top;
      Source = (PIXEL *)((BYTE *)Source + SourceSurf->lDelta);
    } /* if */
  } /* while */

  if (skip > 0 && Source != PrevSource)
    ScaleLineAvg8(ScanLine, Source, SourceRect->right - SourceRect->left, DestRect->right - DestRect->left);
  while (skip-- > 0) {
    if (! FinalCopy8(Target, ScanLine, ClipSpans, ClipSpansCount, &SpanIndex, DestY, DestRect))
      {
        /* No more spans, everything else is clipped away, we're done */
        ExFreePool(ClipSpans);
        ExFreePool(ScanLine);
        ExFreePool(ScanLineAhead);
        return TRUE;
      }
    DestY++;
    Target = (PIXEL *)((BYTE *)Target + DestSurf->lDelta);
  } /* while */

  ExFreePool(ClipSpans);
  ExFreePool(ScanLine);
  ExFreePool(ScanLineAhead);

  return TRUE;
}

//NOTE: If you change something here, please do the same in other dibXXbpp.c files!
BOOLEAN DIB_8BPP_StretchBlt(SURFOBJ *DestSurf, SURFOBJ *SourceSurf,
                            RECTL* DestRect, RECTL *SourceRect,
                            POINTL* MaskOrigin, POINTL BrushOrigin,
                            CLIPOBJ *ClipRegion, XLATEOBJ *ColorTranslation,
                            ULONG Mode)
{
   LONG SrcSizeY;
   LONG SrcSizeX;
   LONG DesSizeY;
   LONG DesSizeX;      
   LONG sx;
   LONG sy;
   LONG DesX;
   LONG DesY;
   LONG color;

  DPRINT("DIB_8BPP_StretchBlt: Source BPP: %u, srcRect: (%d,%d)-(%d,%d), dstRect: (%d,%d)-(%d,%d)\n",
     BitsPerFormat(SourceSurf->iBitmapFormat), SourceRect->left, SourceRect->top, SourceRect->right, SourceRect->bottom,
     DestRect->left, DestRect->top, DestRect->right, DestRect->bottom);

    SrcSizeY = SourceRect->bottom - SourceRect->top;
    SrcSizeX = SourceRect->right - SourceRect->left;
  
    DesSizeY = DestRect->bottom - DestRect->top;
    DesSizeX = DestRect->right - DestRect->left;

    switch(SourceSurf->iBitmapFormat)
    {     
      case BMF_1BPP:
	  /* FIXME :  MaskOrigin, BrushOrigin, ClipRegion, Mode ? */
      /* This is a reference implementation, it hasn't been optimized for speed */
                      
       for (DesY=DestRect->top; DesY<DestRect->bottom; DesY++)
       {			 
           sy = (((DesY - DestRect->top) * SrcSizeY) / DesSizeY) + SourceRect->top;
                     
            for (DesX=DestRect->left; DesX<DestRect->right; DesX++)
            {			
                  sx = (((DesX - DestRect->left) * SrcSizeX) / DesSizeX) + SourceRect->left;
                   		
                  if(DIB_1BPP_GetPixel(SourceSurf, sx, sy) == 0)
				  {
					DIB_8BPP_PutPixel(DestSurf, DesX, DesY, XLATEOBJ_iXlate(ColorTranslation, 0));
                  } 
				  else 
				  {
                    DIB_8BPP_PutPixel(DestSurf, DesX, DesY, XLATEOBJ_iXlate(ColorTranslation, 1));
                  }
            }
       }		

	  break;

      case BMF_4BPP:		
      /* FIXME :  MaskOrigin, BrushOrigin, ClipRegion, Mode ? */
      /* This is a reference implementation, it hasn't been optimized for speed */
                      
       for (DesY=DestRect->top; DesY<DestRect->bottom; DesY++)
       {			 
           sy = (((DesY - DestRect->top) * SrcSizeY) / DesSizeY) + SourceRect->top;
                     
            for (DesX=DestRect->left; DesX<DestRect->right; DesX++)
            {			
                 sx = (((DesX - DestRect->left) * SrcSizeX) / DesSizeX) + SourceRect->left;  		
                 color = DIB_4BPP_GetPixel(SourceSurf, sx, sy);
                 DIB_8BPP_PutPixel(DestSurf, DesX, DesY, XLATEOBJ_iXlate(ColorTranslation, color));
            }
       }	  	   
      break;

      case BMF_8BPP:
        return ScaleRectAvg8(DestSurf, SourceSurf, DestRect, SourceRect, MaskOrigin, BrushOrigin,
                             ClipRegion, ColorTranslation, Mode);
      break;

      case BMF_16BPP:		
      /* FIXME :  MaskOrigin, BrushOrigin, ClipRegion, Mode ? */
      /* This is a reference implementation, it hasn't been optimized for speed */
                      
       for (DesY=DestRect->top; DesY<DestRect->bottom; DesY++)
       {			 
           sy = (((DesY - DestRect->top) * SrcSizeY) / DesSizeY) + SourceRect->top;
                     
            for (DesX=DestRect->left; DesX<DestRect->right; DesX++)
            {			
                 sx = (((DesX - DestRect->left) * SrcSizeX) / DesSizeX) + SourceRect->left;  		
                 color = DIB_16BPP_GetPixel(SourceSurf, sx, sy);
                 DIB_8BPP_PutPixel(DestSurf, DesX, DesY, XLATEOBJ_iXlate(ColorTranslation, color));
            }
       }	  	   
	  break;

      case BMF_24BPP:
      /* FIXME :  MaskOrigin, BrushOrigin, ClipRegion, Mode ? */
      /* This is a reference implementation, it hasn't been optimized for speed */
                      
       for (DesY=DestRect->top; DesY<DestRect->bottom; DesY++)
       {			 
           sy = (((DesY - DestRect->top) * SrcSizeY) / DesSizeY) + SourceRect->top;
                     
            for (DesX=DestRect->left; DesX<DestRect->right; DesX++)
            {			
                 sx = (((DesX - DestRect->left) * SrcSizeX) / DesSizeX) + SourceRect->left;  		
                 color = DIB_24BPP_GetPixel(SourceSurf, sx, sy);
                 DIB_8BPP_PutPixel(DestSurf, DesX, DesY, XLATEOBJ_iXlate(ColorTranslation, color));
            }
       }	  	   		
	  break;

      case BMF_32BPP:
      /* FIXME :  MaskOrigin, BrushOrigin, ClipRegion, Mode ? */
      /* This is a reference implementation, it hasn't been optimized for speed */
                      
       for (DesY=DestRect->top; DesY<DestRect->bottom; DesY++)
       {			 
           sy = (((DesY - DestRect->top) * SrcSizeY) / DesSizeY) + SourceRect->top;
                     
            for (DesX=DestRect->left; DesX<DestRect->right; DesX++)
            {			
                 sx = (((DesX - DestRect->left) * SrcSizeX) / DesSizeX) + SourceRect->left;  		
                 color = DIB_32BPP_GetPixel(SourceSurf, sx, sy);
                 DIB_8BPP_PutPixel(DestSurf, DesX, DesY, XLATEOBJ_iXlate(ColorTranslation, color));
            }
       }	  	   		
	  break;



      default:
         DPRINT1("DIB_8BPP_StretchBlt: Unhandled Source BPP: %u\n", BitsPerFormat(SourceSurf->iBitmapFormat));
      return FALSE;
    }

  return TRUE;
}

BOOLEAN
DIB_8BPP_TransparentBlt(SURFOBJ *DestSurf, SURFOBJ *SourceSurf,
                        RECTL*  DestRect,  POINTL  *SourcePoint,
                        XLATEOBJ *ColorTranslation, ULONG iTransColor)
{
  ULONG RoundedRight, X, Y, SourceX, SourceY, Source, wd, Dest;
  ULONG *DestBits;

  RoundedRight = DestRect->right - ((DestRect->right - DestRect->left) & 0x3);
  SourceY = SourcePoint->y;
  DestBits = (ULONG*)((PBYTE)DestSurf->pvScan0 + DestRect->left +
                      (DestRect->top * DestSurf->lDelta));
  wd = DestSurf->lDelta - (DestRect->right - DestRect->left);

  for(Y = DestRect->top; Y < DestRect->bottom; Y++)
  {
    DestBits = (ULONG*)((PBYTE)DestSurf->pvScan0 + DestRect->left +
                        (Y * DestSurf->lDelta));
    SourceX = SourcePoint->x;
    for (X = DestRect->left; X < RoundedRight; X += 4, DestBits++)
    {
      Dest = *DestBits;

      Source = DIB_GetSourceIndex(SourceSurf, SourceX++, SourceY);
      if(Source != iTransColor)
      {
        Dest &= 0xFFFFFF00;
        Dest |= (XLATEOBJ_iXlate(ColorTranslation, Source) & 0xFF);
      }

      Source = DIB_GetSourceIndex(SourceSurf, SourceX++, SourceY);
      if(Source != iTransColor)
      {
        Dest &= 0xFFFF00FF;
        Dest |= ((XLATEOBJ_iXlate(ColorTranslation, Source) << 8) & 0xFF00);
      }

      Source = DIB_GetSourceIndex(SourceSurf, SourceX++, SourceY);
      if(Source != iTransColor)
      {
        Dest &= 0xFF00FFFF;
        Dest |= ((XLATEOBJ_iXlate(ColorTranslation, Source) << 16) & 0xFF0000);
      }

      Source = DIB_GetSourceIndex(SourceSurf, SourceX++, SourceY);
      if(Source != iTransColor)
      {
        Dest &= 0x00FFFFFF;
        Dest |= ((XLATEOBJ_iXlate(ColorTranslation, Source) << 24) & 0xFF000000);
      }

      *DestBits = Dest;
    }

    if(X < DestRect->right)
    {
      for (; X < DestRect->right; X++)
      {
        Source = DIB_GetSourceIndex(SourceSurf, SourceX++, SourceY);
        if(Source != iTransColor)
        {
          *((BYTE*)DestBits) = (BYTE)(XLATEOBJ_iXlate(ColorTranslation, Source) & 0xFF);
        }
        DestBits = (PULONG)((ULONG_PTR)DestBits + 1);
      }
    }
    SourceY++;
  }

  return TRUE;
}

typedef union {
   ULONG ul;
   struct {
      UCHAR red;
      UCHAR green;
      UCHAR blue;
      UCHAR alpha;
   } col;
} NICEPIXEL32;

typedef union {
   USHORT us;
   struct {
      USHORT red:5,
             green:6,
             blue:5;
   } col;
} NICEPIXEL16;

static __inline UCHAR
Clamp8(ULONG val)
{
   return (val > 255) ? 255 : val;
}

BOOLEAN
DIB_8BPP_AlphaBlend(SURFOBJ* Dest, SURFOBJ* Source, RECTL* DestRect,
                    RECTL* SourceRect, CLIPOBJ* ClipRegion,
                    XLATEOBJ* ColorTranslation, BLENDOBJ* BlendObj)
{
   INT Rows, Cols, SrcX, SrcY;
   register PUCHAR Dst;
   ULONG DstDelta;
   BLENDFUNCTION BlendFunc;
   register NICEPIXEL32 DstPixel;
   register NICEPIXEL32 SrcPixel;
   register NICEPIXEL16 SrcPixel16;
   UCHAR Alpha, SrcBpp;
   HPALETTE SrcPalette, DstPalette;
   XLATEOBJ *SrcTo32Xlate, *DstTo32Xlate, *DstFrom32Xlate;

   DPRINT("DIB_8BPP_AlphaBlend: srcRect: (%d,%d)-(%d,%d), dstRect: (%d,%d)-(%d,%d)\n",
          SourceRect->left, SourceRect->top, SourceRect->right, SourceRect->bottom,
          DestRect->left, DestRect->top, DestRect->right, DestRect->bottom);

   ASSERT(DestRect->bottom - DestRect->top == SourceRect->bottom - SourceRect->top &&
          DestRect->right - DestRect->left == SourceRect->right - SourceRect->left);

   BlendFunc = BlendObj->BlendFunction;
   if (BlendFunc.BlendOp != AC_SRC_OVER)
   {
      DPRINT1("BlendOp != AC_SRC_OVER\n");
      return FALSE;
   }
   if (BlendFunc.BlendFlags != 0)
   {
      DPRINT1("BlendFlags != 0\n");
      return FALSE;
   }
   if ((BlendFunc.AlphaFormat & ~AC_SRC_ALPHA) != 0)
   {
      DPRINT1("Unsupported AlphaFormat (0x%x)\n", BlendFunc.AlphaFormat);
      return FALSE;
   }
   if ((BlendFunc.AlphaFormat & AC_SRC_ALPHA) != 0 &&
       BitsPerFormat(Source->iBitmapFormat) != 32)
   {
      DPRINT1("Source bitmap must be 32bpp when AC_SRC_ALPHA is set\n");
      return FALSE;
   }

   SrcBpp = BitsPerFormat(Source->iBitmapFormat);
   SrcPalette = IntEngGetXlatePalette(ColorTranslation, XO_SRCPALETTE);
   if (SrcPalette != 0)
   {
      SrcTo32Xlate = IntEngCreateXlate(PAL_RGB, 0, NULL, SrcPalette);
      if (SrcTo32Xlate == NULL)
      {
         DPRINT1("IntEngCreateXlate failed\n");
         return FALSE;
      }
   }
   else
   {
      SrcTo32Xlate = NULL;
      ASSERT(SrcBpp >= 16);
   }

   DstPalette = IntEngGetXlatePalette(ColorTranslation, XO_DESTPALETTE);
   DstTo32Xlate = IntEngCreateXlate(PAL_RGB, 0, NULL, DstPalette);
   DstFrom32Xlate = IntEngCreateXlate(0, PAL_RGB, DstPalette, NULL);
   if (DstTo32Xlate == NULL || DstFrom32Xlate == NULL)
   {
      if (SrcTo32Xlate != NULL)
         EngDeleteXlate(SrcTo32Xlate);
      if (DstTo32Xlate != NULL)
         EngDeleteXlate(DstTo32Xlate);
      if (DstFrom32Xlate != NULL)
         EngDeleteXlate(DstFrom32Xlate);
      DPRINT1("IntEngCreateXlate failed\n");
      return FALSE;
   }

   Dst = (PUCHAR)((ULONG_PTR)Dest->pvScan0 + (DestRect->top * Dest->lDelta) +
                             DestRect->left);
   DstDelta = Dest->lDelta - (DestRect->right - DestRect->left);

   Rows = DestRect->bottom - DestRect->top;
   SrcY = SourceRect->top;
   while (--Rows >= 0)
   {
      Cols = DestRect->right - DestRect->left;
      SrcX = SourceRect->left;
      while (--Cols >= 0)
      {
         if (SrcTo32Xlate != NULL)
         {
            SrcPixel.ul = DIB_GetSource(Source, SrcX++, SrcY, SrcTo32Xlate);
         }
         else if (SrcBpp <= 16)
         {
            SrcPixel16.us = DIB_GetSource(Source, SrcX++, SrcY, ColorTranslation);
            SrcPixel.col.red = (SrcPixel16.col.red << 3) | (SrcPixel16.col.red >> 2);
            SrcPixel.col.green = (SrcPixel16.col.green << 2) | (SrcPixel16.col.green >> 4);
            SrcPixel.col.blue = (SrcPixel16.col.blue << 3) | (SrcPixel16.col.blue >> 2);
         }
         else
         {
            SrcPixel.ul = DIB_GetSourceIndex(Source, SrcX++, SrcY);
         }
         SrcPixel.col.red = SrcPixel.col.red * BlendFunc.SourceConstantAlpha / 255;
         SrcPixel.col.green = SrcPixel.col.green * BlendFunc.SourceConstantAlpha / 255;
         SrcPixel.col.blue = SrcPixel.col.blue * BlendFunc.SourceConstantAlpha / 255;
         SrcPixel.col.alpha = (SrcBpp == 32) ? (SrcPixel.col.alpha * BlendFunc.SourceConstantAlpha / 255) : BlendFunc.SourceConstantAlpha;

         Alpha = ((BlendFunc.AlphaFormat & AC_SRC_ALPHA) != 0) ?
                 SrcPixel.col.alpha : BlendFunc.SourceConstantAlpha;

         DstPixel.ul = XLATEOBJ_iXlate(DstTo32Xlate, *Dst);
         DstPixel.col.red = Clamp8(DstPixel.col.red * (255 - Alpha) / 255 + SrcPixel.col.red);
         DstPixel.col.green = Clamp8(DstPixel.col.green * (255 - Alpha) / 255 + SrcPixel.col.green);
         DstPixel.col.blue = Clamp8(DstPixel.col.blue * (255 - Alpha) / 255 + SrcPixel.col.blue);
         *Dst++ = XLATEOBJ_iXlate(DstFrom32Xlate, DstPixel.ul);
      }
      Dst = (PUCHAR)((ULONG_PTR)Dst + DstDelta);
      SrcY++;
   }

   if (SrcTo32Xlate != NULL)
      EngDeleteXlate(SrcTo32Xlate);
   if (DstTo32Xlate != NULL)
      EngDeleteXlate(DstTo32Xlate);
   if (DstFrom32Xlate != NULL)
      EngDeleteXlate(DstFrom32Xlate);

   return TRUE;
}

/* EOF */

⌨️ 快捷键说明

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