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

📄 bitmap-comm.c

📁 在ADS环境下MiniGUI的源码
💻 C
📖 第 1 页 / 共 2 页
字号:
    if (w_h < 1)
        return;

    pdc = dc_HDC2PDC (hdc);
    bpp = GAL_BytesPerPixel (pdc->gc);

    size = w_h * bpp;
#ifdef HAVE_ALLOCA
    if (!(bitmap = alloca (size)))
#else
    if (!(bitmap = malloc (size)))
#endif
        return;
    vbuff = bitmap;

    switch (bpp) {
        case 1:
            for (i = 0; i < size; i += 2) {
                *vbuff = (BYTE)(pdc->pencolor);
                vbuff++;
                *vbuff = (BYTE)(pdc->brushcolor);
                vbuff++;
            }
            break;
        case 2:
            for (i = 0; i < size; i += 4) {
                *(Uint16 *) vbuff = (Uint16)(pdc->pencolor);
                vbuff += 2;
                *(Uint16 *) vbuff = (Uint16)(pdc->brushcolor);
                vbuff += 2;
            }
            break;
        case 3:
            for (i = 0; i < size; i += 6) {
                *(Uint16 *) vbuff = (Uint16)(pdc->pencolor);
                *(vbuff + 2) = (BYTE)(pdc->pencolor >> 16);
                vbuff += 3;
                *(Uint16 *) vbuff = (Uint16)(pdc->brushcolor);
                *(vbuff + 2) = (BYTE)(pdc->brushcolor >> 16);
                vbuff += 3;
            }
            break;
        case 4:
            for (i = 0; i < size; i += 8) {
                *(Uint32 *) vbuff = (Uint32)(pdc->pencolor);
                vbuff += 4;
                *(Uint32 *) vbuff = (Uint32)(pdc->brushcolor);
                vbuff += 4;
            }
            break;
    }

    PutSavedBoxOnDC (hdc, x, y, H_V ? w_h : 1, H_V ? 1 : w_h, bitmap);
#ifndef HAVE_ALLOCA
    free (bitmap);
#endif
}

/* 
 * This function performs a fast box scaling.
 * This is a DDA-based algorithm; Iteration over target bitmap.
 *
 * This function comes from SVGALib, Copyright 1993 Harm Hanemaayer
 */

/* We use the 32-bit to 64-bit multiply and 64-bit to 32-bit divide of the
 * 386 (which gcc doesn't know well enough) to efficiently perform integer
 * scaling without having to worry about overflows.
 */

#if defined(__GNUC__) && defined(i386)

static inline int muldiv64(int m1, int m2, int d)
{
    /* int32 * int32 -> int64 / int32 -> int32 */
    int result;
    int dummy;
    __asm__ __volatile__ (
               "imull %%edx\n\t"
               "idivl %4\n\t"
  :               "=a"(result), "=d"(dummy)        /* out */
  :               "0"(m1), "1"(m2), "g"(d)                /* in */
               /***rjr***:               "ax", "dx"***/        /* mod */
        );
    return result;
}

#else

static inline int muldiv64 (int m1, int m2, int d)
{
    long long int mul = (long long int) m1 * m2;

    return (int) (mul / d);
}

#endif

/* Init a bitmap as a normal bitmap  */
BOOL GUIAPI InitBitmap (HDC hdc, Uint32 w, Uint32 h, Uint32 pitch, BYTE* bits, PBITMAP bmp)
{
    int depth = GetGDCapability (hdc, GDCAP_DEPTH);
    int bpp = GetGDCapability (hdc, GDCAP_BPP);

    if (w == 0 || h == 0)
        return FALSE;

    if (bits && pitch) {
        if (bpp * w > pitch)
            return FALSE;

        bmp->bmBits = bits;
        bmp->bmPitch = pitch;
    }
    else if (!bits) {
        bmpComputePitch (depth, w, &bmp->bmPitch, TRUE);

        if (!(bmp->bmBits = malloc (bmp->bmPitch * h)))
            return FALSE;
    }
    else /* bits is not zero, but pitch is zero */
        return FALSE;

    bmp->bmType = BMP_TYPE_NORMAL;
    bmp->bmWidth = w;
    bmp->bmHeight = h;
    bmp->bmBitsPerPixel = depth;
    bmp->bmBytesPerPixel = bpp;

    return TRUE;
}

BOOL ScaleBitmap (BITMAP *dst, const BITMAP *src)
{
    BYTE *dp1 = src->bmBits;
    BYTE *dp2 = dst->bmBits;
    int xfactor;
    int yfactor;

    if (dst->bmWidth == 0 || dst->bmHeight == 0)
        return TRUE;

    if (dst->bmBytesPerPixel != src->bmBytesPerPixel)
        return FALSE;

    xfactor = muldiv64 (src->bmWidth, 65536, dst->bmWidth);         /* scaled by 65536 */
    yfactor = muldiv64 (src->bmHeight, 65536, dst->bmHeight);       /* scaled by 65536 */

    switch (dst->bmBytesPerPixel) {
    case 1:
        {
            int y, sy;
            sy = 0;
            for (y = 0; y < dst->bmHeight;) {
                int sx = 0;
                BYTE *dp2old = dp2;
                int x;
                x = 0;
#if 0
                while (x < dst->bmWidth - 8) {
                    *(dp2 + x) = *(dp1 + (sx >> 16));
                    sx += xfactor;
                    *(dp2 + x + 1) = *(dp1 + (sx >> 16));
                    sx += xfactor;
                    *(dp2 + x + 2) = *(dp1 + (sx >> 16));
                    sx += xfactor;
                    *(dp2 + x + 3) = *(dp1 + (sx >> 16));
                    sx += xfactor;
                    *(dp2 + x + 4) = *(dp1 + (sx >> 16));
                    sx += xfactor;
                    *(dp2 + x + 5) = *(dp1 + (sx >> 16));
                    sx += xfactor;
                    *(dp2 + x + 6) = *(dp1 + (sx >> 16));
                    sx += xfactor;
                    *(dp2 + x + 7) = *(dp1 + (sx >> 16));
                    sx += xfactor;
                    x += 8;
                }
#endif
                while (x < dst->bmWidth) {
                    *(dp2 + x) = *(dp1 + (sx >> 16));
                    sx += xfactor;
                    x++;
                }
                dp2 += dst->bmPitch;
                y++;
                while (y < dst->bmHeight) {
                    int l;
                    int syint = sy >> 16;
                    sy += yfactor;
                    if ((sy >> 16) != syint)
                        break;
                    /* Copy identical lines. */
                    l = dp2 - dp2old;
                    memcpy(dp2, dp2old, l);
                    dp2old = dp2;
                    dp2 += l;
                    y++;
                }
                dp1 = (BYTE *)src->bmBits + (sy >> 16) * src->bmPitch;
            }
        }
    break;
    case 2:
        {
            int y, sy;
            sy = 0;
            for (y = 0; y < dst->bmHeight;) {
                int sx = 0;
                BYTE *dp2old = dp2;
                int x;
                x = 0;
                /* This can be greatly optimized with loop */
                /* unrolling; omitted to save space. */
                while (x < dst->bmWidth) {
                    *(unsigned short *) (dp2 + x * 2) =
                        *(unsigned short *) (dp1 + (sx >> 16) * 2);
                    sx += xfactor;
                    x++;
                }
                dp2 += dst->bmPitch;
                y++;
                while (y < dst->bmHeight) {
                    int l;
                    int syint = sy >> 16;
                    sy += yfactor;
                    if ((sy >> 16) != syint)
                        break;
                    /* Copy identical lines. */
                    l = dp2 - dp2old;
                    memcpy(dp2, dp2old, l);
                    dp2old = dp2;
                    dp2 += l;
                    y++;
                }
                dp1 = (BYTE *)src->bmBits + (sy >> 16) * src->bmPitch;
            }
        }
    break;
    case 3:
        {
            int y, sy;
            sy = 0;
            for (y = 0; y < dst->bmHeight;) {
                int sx = 0;
                BYTE *dp2old = dp2;
                int x;
                x = 0;
                /* This can be greatly optimized with loop */
                /* unrolling; omitted to save space. */
                while (x < dst->bmWidth) {
                    *(unsigned short *) (dp2 + x * 3) =
                        *(unsigned short *) (dp1 + (sx >> 16) * 3);
                    *(unsigned char *) (dp2 + x * 3 + 2) =
                        *(unsigned char *) (dp1 + (sx >> 16) * 3 + 2);
                    sx += xfactor;
                    x++;
                }
                dp2 += dst->bmPitch;
                y++;
                while (y < dst->bmHeight) {
                    int l;
                    int syint = sy >> 16;
                    sy += yfactor;
                    if ((sy >> 16) != syint)
                        break;
                    /* Copy identical lines. */
                    l = dp2 - dp2old;
                    memcpy(dp2, dp2old, l);
                    dp2old = dp2;
                    dp2 += l;
                    y++;
                }
                dp1 = (BYTE *)src->bmBits + (sy >> 16) * src->bmPitch;
            }
        }
    break;
    case 4:
        {
            int y, sy;
            sy = 0;
            for (y = 0; y < dst->bmHeight;) {
                int sx = 0;
                BYTE *dp2old = dp2;
                int x;
                x = 0;
                /* This can be greatly optimized with loop */
                /* unrolling; omitted to save space. */
                while (x < dst->bmWidth) {
                    *(unsigned *) (dp2 + x * 4) =
                        *(unsigned *) (dp1 + (sx >> 16) * 4);
                    sx += xfactor;
                    x++;
                }
                dp2 += dst->bmPitch;
                y++;
                while (y < dst->bmHeight) {
                    int l;
                    int syint = sy >> 16;
                    sy += yfactor;
                    if ((sy >> 16) != syint)
                        break;
                    /* Copy identical lines. */
                    l = dp2 - dp2old;
                    memcpy(dp2, dp2old, l);
                    dp2old = dp2;
                    dp2 += l;
                    y++;
                }
                dp1 = (BYTE *)src->bmBits + (sy >> 16) * src->bmPitch;
            }
        }
    break;
    }

    return TRUE;
}

gal_pixel GUIAPI GetPixelInBitmap (const BITMAP* bmp, int x, int y)
{
    BYTE* dst;

    if (x < 0 || y < 0 || x >= bmp->bmWidth || y >= bmp->bmHeight)
        return 0;

    dst = (BYTE*)bmp->bmBits + y * bmp->bmPitch + x * bmp->bmBytesPerPixel;
    return _mem_get_pixel (dst, bmp->bmBytesPerPixel);
}

BOOL GUIAPI SetPixelInBitmap (const BITMAP* bmp, int x, int y, gal_pixel pixel)
{
    BYTE* dst;

    if (x < 0 || y < 0 || x >= bmp->bmWidth || y >= bmp->bmHeight)
        return FALSE;

    dst = (BYTE*)bmp->bmBits + y * bmp->bmPitch + x * bmp->bmBytesPerPixel;
    _mem_set_pixel (dst, bmp->bmBytesPerPixel, pixel);
    return TRUE;
}

⌨️ 快捷键说明

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