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

📄 dib16bpp.c

📁 这是一个开放源代码的与WINNT/WIN2K/WIN2003兼容的操作系统
💻 C
📖 第 1 页 / 共 3 页
字号:
                     BitsPerFormat(BltInfo->SourceSurface->iBitmapFormat));
            return FALSE;
    }

    return TRUE;
}

/* Optimize for bitBlt */
BOOLEAN
DIB_16BPP_ColorFill(SURFOBJ* DestSurface, RECTL* DestRect, ULONG color)
{
    ULONG DestY;

#if defined(_M_IX86) && !defined(_MSC_VER)
    /* This is about 10% faster than the generic C code below */ 
    ULONG delta = DestSurface->lDelta;
    ULONG width = (DestRect->right - DestRect->left) ;
    PULONG pos =  (PULONG) ((PBYTE)DestSurface->pvScan0 + DestRect->top * delta + (DestRect->left<<1));
    color = (color&0xffff);  /* If the color value is "abcd", put "abcdabcd" into color */
    color += (color<<16);

    for (DestY = DestRect->top; DestY< DestRect->bottom; DestY++)
    {
        __asm__ __volatile__ (
        "  cld\n"
        "  mov  %1,%%ebx\n" 
        "  mov  %2,%%edi\n" 
        "  test $0x03, %%edi\n" /* Align to fullword boundary */
        "  jz   .FL1\n"
        "  stosw\n"
        "  dec  %%ebx\n"
        "  jz   .FL2\n"
        ".FL1:\n"
        "  mov  %%ebx,%%ecx\n"     /* Setup count of fullwords to fill */
        "  shr  $1,%%ecx\n"
        "  rep stosl\n"         /* The actual fill */
        "  test $0x01, %%ebx\n"    /* One left to do at the right side? */
        "  jz   .FL2\n"
        "  stosw\n"
        ".FL2:\n"
        :
        : "a" (color), "r" (width), "m" (pos)
        : "%ecx", "%ebx", "%edi");
        pos =(PULONG)((ULONG_PTR)pos + delta);	 
    }
#else /* _M_IX86 */

    for (DestY = DestRect->top; DestY< DestRect->bottom; DestY++)
    {
        DIB_16BPP_HLine (DestSurface, DestRect->left, DestRect->right, DestY, color);
    }
#endif
    return TRUE;
}
/*
=======================================
 Stretching functions goes below
 Some parts of code are based on an
 article "Bresenhame image scaling"
 Dr. Dobb Journal, May 2002
=======================================
*/

typedef unsigned short PIXEL;

/* 16-bit HiColor (565 format) */
__inline PIXEL average16(PIXEL a, PIXEL b)
{
// This one doesn't work
/*
    if (a == b)
    {
        return a;
    }
    else
    {
        unsigned short mask = ~ (((a | b) & 0x0410) << 1);
        return ((a & mask) + (b & mask)) >> 1;
    }*/ /* if */

// This one should be correct, but it's too long
/*
    unsigned char r1, g1, b1, r2, g2, b2, rr, gr, br;
    unsigned short res;

    r1 = (a & 0xF800) >> 11;
    g1 = (a & 0x7E0) >> 5;
    b1 = (a & 0x1F);

    r2 = (b & 0xF800) >> 11;
    g2 = (b & 0x7E0) >> 5;
    b2 = (b & 0x1F);

    rr = (r1+r2) / 2;
    gr = (g1+g2) / 2;
    br = (b1+b2) / 2;

    res = (rr << 11) + (gr << 5) + br;

    return res;
*/
  return a; // FIXME: Depend on SetStretchMode
}

//NOTE: If you change something here, please do the same in other dibXXbpp.c files!
void ScaleLineAvg16(PIXEL *Target, PIXEL *Source, int SrcWidth, int TgtWidth)
{
    int NumPixels = TgtWidth;
    int IntPart = SrcWidth / TgtWidth;
    int FractPart = SrcWidth % TgtWidth;
    int Mid = TgtWidth >> 1;
    int E = 0;
    int skip;
    PIXEL p;

    skip = (TgtWidth < SrcWidth) ? 0 : (TgtWidth / (2*SrcWidth) + 1);
    NumPixels -= skip;

    while (NumPixels-- > 0)
    {
        p = *Source;
        if (E >= Mid)
        {
            p = average16(p, *(Source+1));
        }
        *Target++ = p;
        Source += IntPart;
        E += FractPart;
        if (E >= TgtWidth)
        {
            E -= TgtWidth;
            Source++;
        }
    }
    while (skip-- > 0)
    {
        *Target++ = *Source;
    }
}

static BOOLEAN
FinalCopy16(PIXEL *Target, PIXEL *Source, PSPAN ClipSpans, UINT ClipSpansCount, UINT *SpanIndex,
            UINT DestY, RECTL *DestRect)
{
    LONG Left, Right;

    while ( ClipSpans[*SpanIndex].Y < DestY ||
            (ClipSpans[*SpanIndex].Y == DestY && 
            ClipSpans[*SpanIndex].X + ClipSpans[*SpanIndex].Width < DestRect->left))
    {
        (*SpanIndex)++;
        if (ClipSpansCount <= *SpanIndex)
        {
            /* No more spans, everything else is clipped away, we're done */
            return FALSE;
        }
    }
    while (ClipSpans[*SpanIndex].Y == DestY)
    {
        if (ClipSpans[*SpanIndex].X < DestRect->right)
        {
            Left = max(ClipSpans[*SpanIndex].X, DestRect->left);

            Right = min(ClipSpans[*SpanIndex].X + ClipSpans[*SpanIndex].Width,
                    DestRect->right);

            memcpy(Target + Left - DestRect->left, Source + Left - DestRect->left,
                 (Right - Left) * sizeof(PIXEL));
        }

        (*SpanIndex)++;

        if (ClipSpansCount <= *SpanIndex)
        {
          /* No more spans, everything else is clipped away, we're done */
          return FALSE;
        }
    }

  return TRUE;
}

//NOTE: If you change something here, please do the same in other dibXXbpp.c files!
BOOLEAN ScaleRectAvg16(SURFOBJ *DestSurf, SURFOBJ *SourceSurf,
                       RECTL* DestRect, RECTL *SourceRect,
                       POINTL* MaskOrigin, POINTL BrushOrigin,
                       CLIPOBJ *ClipRegion, XLATEOBJ *ColorTranslation,
                       ULONG Mode)
{
    int NumPixels = DestRect->bottom - DestRect->top;

    int IntPart = (((SourceRect->bottom - SourceRect->top) /
                  (DestRect->bottom - DestRect->top)) * SourceSurf->lDelta) >> 1;

    int FractPart = (SourceRect->bottom - SourceRect->top) % 
                    (DestRect->bottom - DestRect->top);

    int Mid = (DestRect->bottom - DestRect->top) >> 1;
    int E = 0;
    int skip;
    PIXEL *ScanLine, *ScanLineAhead;
    PIXEL *PrevSource = NULL;
    PIXEL *PrevSourceAhead = NULL;

    PIXEL *Target = (PIXEL *) ((PBYTE)DestSurf->pvScan0 + (DestRect->top *
                    DestSurf->lDelta) + 2 * DestRect->left);

    PIXEL *Source = (PIXEL *) ((PBYTE)SourceSurf->pvScan0 + (SourceRect->top *
                    SourceSurf->lDelta) + 2 * SourceRect->left);

    PSPAN ClipSpans;
    UINT ClipSpansCount;
    UINT SpanIndex;
    LONG DestY;

    if (! ClipobjToSpans(&ClipSpans, &ClipSpansCount, ClipRegion, DestRect))
    {
        return FALSE;
    }
    if (0 == ClipSpansCount)
    {
        /* No clip spans == empty clipping region, everything clipped away */
        ASSERT(NULL == ClipSpans);
        return TRUE;
    }
    skip = (DestRect->bottom - DestRect->top < SourceRect->bottom - SourceRect->top)
            ? 0 : ((DestRect->bottom - DestRect->top) /
                  (2 * (SourceRect->bottom - SourceRect->top)) + 1);

    NumPixels -= skip;

    ScanLine = (PIXEL*)ExAllocatePool(PagedPool, (DestRect->right - DestRect->left) *
                sizeof(PIXEL));

    ScanLineAhead = (PIXEL *)ExAllocatePool(PagedPool, (DestRect->right - 
                    DestRect->left) * sizeof(PIXEL));

    DestY = DestRect->top;
    SpanIndex = 0;
    while (NumPixels-- > 0)
    {
        if (Source != PrevSource)
        {
            if (Source == PrevSourceAhead)
            {
                /* the next scan line has already been scaled and stored in
                 * ScanLineAhead; swap the buffers that ScanLine and ScanLineAhead
                 * point to
                 */
                PIXEL *tmp = ScanLine;
                ScanLine = ScanLineAhead;
                ScanLineAhead = tmp;
            }
            else
            {
                ScaleLineAvg16(ScanLine, Source, SourceRect->right - SourceRect->left,
                DestRect->right - DestRect->left);
            }
            PrevSource = Source;
        }

        if (E >= Mid && PrevSourceAhead != (PIXEL *)((BYTE *)Source +
            SourceSurf->lDelta))
        {
            int x;

            ScaleLineAvg16(ScanLineAhead, (PIXEL *)((BYTE *)Source + 
                           SourceSurf->lDelta), SourceRect->right - 
                           SourceRect->left, DestRect->right - DestRect->left);

            for (x = 0; x < DestRect->right - DestRect->left; x++)
            {
                ScanLine[x] = average16(ScanLine[x], ScanLineAhead[x]);
            }

            PrevSourceAhead = (PIXEL *)((BYTE *)Source + SourceSurf->lDelta);
        }

        if (! FinalCopy16(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);
        }
    } /* while */

    if (skip > 0 && Source != PrevSource)
    {
        ScaleLineAvg16(ScanLine, Source, SourceRect->right - SourceRect->left,
                       DestRect->right - DestRect->left);
    }

    while (skip-- > 0)
    {
        if (! FinalCopy16(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);
    }

    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_16BPP_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 = 0;
   LONG sy = 0;
   LONG DesX;
   LONG DesY;
   PULONG DestBits;
   LONG DifflDelta;

   LONG SrcZoomXHight;
   LONG SrcZoomXLow;
   LONG SrcZoomYHight;
   LONG SrcZoomYLow;

   LONG sy_dec = 0;
   LONG sy_max;

   LONG sx_dec = 0;
   LONG sx_max;

  DPRINT("DIB_16BPP_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);

    /* Calc the Zoom height of Source */
    SrcSizeY = SourceRect->bottom - SourceRect->top;

    /* Calc the Zoom Width of Source */
    SrcSizeX = SourceRect->right - SourceRect->left;
  
    /* Calc the Zoom height of Destions */
    DesSizeY = DestRect->bottom - DestRect->top;

    /* Calc the Zoom width of Destions */
    DesSizeX = DestRect->right - DestRect->left;

    /* Calc the zoom factor of soruce height */
    SrcZoomYHight = SrcSizeY / DesSizeY;
    SrcZoomYLow = SrcSizeY - (SrcZoomYHight * DesSizeY);

    /* Calc the zoom factor of soruce width */
    SrcZoomXHight = SrcSizeX / DesSizeX;
    SrcZoomXLow = SrcSizeX - (SrcZoomXHight * DesSizeX);

    sx_max = DesSizeX;
    sy_max = DesSizeY;
    sy = SourceRect->top;

    DestBits = (PULONG)((PBYTE)DestSurf->pvScan0 + (DestRect->left << 1) +
                               DestRect->top * DestSurf->lDelta);

    DifflDelta = DestSurf->lDelta -  (DesSizeX << 1);

    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=0; DesY<DesSizeY; DesY++)
       {
            sx = SourceRect->left;

⌨️ 快捷键说明

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