📄 bitmap-comm.c
字号:
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 + -