You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
2769 lines
77 KiB
2769 lines
77 KiB
/*++
|
|
|
|
Copyright (c) 1996-1999 Microsoft Corporation
|
|
|
|
Module Name
|
|
|
|
|
|
Abstract:
|
|
|
|
Lingyun Wang
|
|
|
|
Author:
|
|
|
|
|
|
Enviornment:
|
|
|
|
User Mode
|
|
|
|
Revision History:
|
|
|
|
--*/
|
|
|
|
#include "precomp.hxx"
|
|
#pragma hdrstop
|
|
|
|
extern PFNTRANSBLT gpfnTransparentBlt;
|
|
|
|
#if (_WIN32_WINNT == 0x400)
|
|
typedef struct _LOGPALETTE2
|
|
{
|
|
USHORT PalVersion;
|
|
USHORT PalNumEntries;
|
|
PALETTEENTRY palPalEntry[2];
|
|
} LOGPALETTE2;
|
|
|
|
typedef struct _LOGPALETTE16
|
|
{
|
|
USHORT PalVersion;
|
|
USHORT PalNumEntries;
|
|
PALETTEENTRY palPalEntry[16];
|
|
} LOGPALETTE16;
|
|
|
|
typedef struct _LOGPALETTE256
|
|
{
|
|
USHORT PalVersion;
|
|
USHORT PalNumEntries;
|
|
PALETTEENTRY palPalEntry[256];
|
|
} LOGPALETTE256;
|
|
|
|
/******************************Public*Routine******************************\
|
|
* StartPixel
|
|
* Give a scanline pointer and position of a pixel, return the byte address
|
|
* of where the pixel is at depending on the format
|
|
*
|
|
* History:
|
|
* 2-Dec-1996 -by- Lingyun Wang [lingyunw]
|
|
* Wrote it.
|
|
\**************************************************************************/
|
|
PBYTE StartPixel (
|
|
PBYTE pjBits,
|
|
ULONG xStart,
|
|
ULONG iBitmapFormat
|
|
)
|
|
{
|
|
PBYTE pjStart = pjBits;
|
|
//
|
|
// getting the starting pixel
|
|
//
|
|
switch (iBitmapFormat)
|
|
{
|
|
case 1:
|
|
pjStart = pjBits + (xStart >> 3);
|
|
break;
|
|
|
|
case 4:
|
|
pjStart = pjBits + (xStart >> 1);
|
|
break;
|
|
|
|
case 8:
|
|
pjStart = pjBits + xStart;
|
|
break;
|
|
|
|
case 16:
|
|
pjStart = pjBits + 2*xStart;
|
|
break;
|
|
|
|
case 24:
|
|
pjStart = pjBits + 3*xStart;
|
|
break;
|
|
|
|
case 32:
|
|
pjStart = pjBits+4*xStart;
|
|
break;
|
|
|
|
default:
|
|
WARNING ("Startpixel -- bad iFormatSrc\n");
|
|
}
|
|
|
|
return (pjStart);
|
|
}
|
|
|
|
|
|
/******************************Public*Routine******************************\
|
|
* vTransparentIdentityCopy4
|
|
*
|
|
* Doing a transparent copy on two same size 4BPP format DIBs
|
|
*
|
|
* Returns:
|
|
* VOID.
|
|
*
|
|
* History:
|
|
* 09-Dec-1996 -by- Lingyun Wang [lingyunw]
|
|
* Wrote it.
|
|
\**************************************************************************/
|
|
VOID vTransparentIdentityCopy4 (
|
|
PDIBINFO pDibInfoDst,
|
|
PDIBINFO pDibInfoSrc,
|
|
ULONG TransColor)
|
|
{
|
|
PBYTE pjDst = (PBYTE)pDibInfoDst->pvBase + pDibInfoDst->stride*pDibInfoDst->rclDIB.top
|
|
+ (pDibInfoDst->rclDIB.left >> 1);
|
|
PBYTE pjSrc = (PBYTE)pDibInfoSrc->pvBase + pDibInfoSrc->stride*pDibInfoSrc->rclDIB.top
|
|
+ (pDibInfoSrc->rclDIB.left >> 1);
|
|
LONG cx = pDibInfoDst->rclDIB.right - pDibInfoDst->rclDIB.left;
|
|
LONG cy = pDibInfoDst->rclDIB.bottom - pDibInfoDst->rclDIB.top;
|
|
|
|
PBYTE pjDstTemp;
|
|
PBYTE pjSrcTemp;
|
|
LONG cxTemp;
|
|
|
|
BYTE jSrc=0;
|
|
BYTE jDst=0;
|
|
LONG iSrc, iDst;
|
|
|
|
|
|
while(cy--)
|
|
{
|
|
cxTemp = cx;
|
|
|
|
iSrc = pDibInfoSrc->rclDIB.left;
|
|
iDst = pDibInfoDst->rclDIB.left;
|
|
|
|
pjSrcTemp = pjSrc;
|
|
pjDstTemp = pjDst;
|
|
|
|
while (cxTemp--)
|
|
{
|
|
if (iSrc & 0x00000001)
|
|
{
|
|
jSrc = *pjSrcTemp & 0x0F;
|
|
pjSrcTemp++;
|
|
}
|
|
else
|
|
{
|
|
jSrc = (*pjSrcTemp & 0xF0)>>4;
|
|
}
|
|
|
|
iSrc++;
|
|
|
|
if (iDst & 0x00000001)
|
|
{
|
|
if (jSrc != (BYTE)TransColor)
|
|
{
|
|
jDst |= jSrc & 0x0F;
|
|
}
|
|
else
|
|
{
|
|
jDst |= *pjDstTemp & 0x0F;
|
|
}
|
|
|
|
*pjDstTemp++ = jDst;
|
|
jDst = 0;
|
|
}
|
|
else
|
|
{
|
|
if (jSrc != (BYTE)TransColor)
|
|
{
|
|
jDst |= (jSrc << 4);
|
|
}
|
|
else
|
|
{
|
|
jDst |= *pjDstTemp & 0xF0;
|
|
}
|
|
}
|
|
|
|
iDst++;
|
|
}
|
|
pjDst += pDibInfoDst->stride;
|
|
pjSrc += pDibInfoSrc->stride;
|
|
}
|
|
}
|
|
|
|
/******************************Public*Routine******************************\
|
|
* vTransparentS4D1
|
|
*
|
|
* Doing a transparent copy from 4PP to 1BPP
|
|
*
|
|
* Returns:
|
|
* VOID.
|
|
*
|
|
* History:
|
|
* 09-Dec-1996 -by- Lingyun Wang [lingyunw]
|
|
* Wrote it.
|
|
\**************************************************************************/
|
|
VOID vTransparentS4D1 (
|
|
PDIBINFO pDibInfoDst,
|
|
PDIBINFO pDibInfoSrc,
|
|
ULONG TransColor)
|
|
{
|
|
PBYTE pjDst = (PBYTE)pDibInfoDst->pvBase + pDibInfoDst->stride*pDibInfoDst->rclDIB.top
|
|
+ (pDibInfoDst->rclDIB.left >> 3);
|
|
|
|
PBYTE pjSrc = (PBYTE)pDibInfoSrc->pvBase + pDibInfoSrc->stride*pDibInfoSrc->rclDIB.top
|
|
+ (pDibInfoSrc->rclDIB.left >> 1);
|
|
LONG cx = pDibInfoDst->rclDIB.right - pDibInfoDst->rclDIB.left;
|
|
LONG cy = pDibInfoDst->rclDIB.bottom - pDibInfoDst->rclDIB.top;
|
|
PBYTE pjDstTemp;
|
|
PBYTE pjSrcTemp;
|
|
BYTE jSrc, jDst;
|
|
LONG cxTemp;
|
|
BYTE rgbBlue, rgbGreen, rgbRed;
|
|
LONG iSrc, iDst;
|
|
LOGPALETTE2 logPal2;
|
|
HPALETTE hPal;
|
|
LONG i;
|
|
ULONG rgbColor;
|
|
BYTE xlate[16];
|
|
|
|
//
|
|
// build up our xlate table
|
|
//
|
|
logPal2.PalVersion = 0x300;
|
|
logPal2.PalNumEntries = 2;
|
|
|
|
for (i = 0; i < 2; i++)
|
|
{
|
|
logPal2.palPalEntry[i].peRed = pDibInfoDst->pbmi->bmiColors[i].rgbRed;
|
|
logPal2.palPalEntry[i].peGreen = pDibInfoDst->pbmi->bmiColors[i].rgbGreen;
|
|
logPal2.palPalEntry[i].peBlue = pDibInfoDst->pbmi->bmiColors[i].rgbBlue;
|
|
logPal2.palPalEntry[i].peFlags = 0;
|
|
}
|
|
|
|
hPal = CreatePalette ((LOGPALETTE *)&logPal2);
|
|
|
|
for (i = 0; i<16; i++)
|
|
{
|
|
rgbColor = RGB(pDibInfoSrc->pbmi->bmiColors[i].rgbRed, pDibInfoSrc->pbmi->bmiColors[i].rgbGreen,
|
|
pDibInfoSrc->pbmi->bmiColors[i].rgbBlue);
|
|
|
|
xlate[i] = (BYTE)GetNearestPaletteIndex(hPal, rgbColor);
|
|
}
|
|
|
|
if (hPal)
|
|
{
|
|
DeleteObject(hPal);
|
|
}
|
|
|
|
while(cy--)
|
|
{
|
|
cxTemp = cx;
|
|
|
|
iSrc = pDibInfoSrc->rclDIB.left;
|
|
iDst = pDibInfoDst->rclDIB.left & 0x07;
|
|
|
|
pjDstTemp = pjDst;
|
|
|
|
jDst = *pjDstTemp >> (8 - iDst);
|
|
|
|
pjSrcTemp = pjSrc;
|
|
|
|
while (cxTemp--)
|
|
{
|
|
if (iSrc & 0x00000001)
|
|
{
|
|
jSrc = *pjSrcTemp & 0x0F;
|
|
pjSrcTemp++;
|
|
}
|
|
else
|
|
{
|
|
jSrc = (*pjSrcTemp & 0xF0)>>4;
|
|
}
|
|
|
|
iSrc++;
|
|
|
|
//
|
|
// put one pixel in the dest
|
|
//
|
|
if (jSrc != TransColor)
|
|
{
|
|
jDst |= xlate[jSrc]; //0 OR 1
|
|
}
|
|
else
|
|
{
|
|
jDst |= 1-xlate[jSrc];
|
|
}
|
|
|
|
jDst = jDst << 1;
|
|
iDst++;
|
|
|
|
if (!(iDst & 0x07))
|
|
{
|
|
*(pjDstTemp++) = jDst;
|
|
jDst = 0;
|
|
}
|
|
}
|
|
|
|
if (iDst & 0x00000007)
|
|
{
|
|
// We need to build up the last pel correctly.
|
|
|
|
BYTE jMask = (BYTE) (0x000000FF >> (iDst & 0x00000007));
|
|
|
|
jDst = (BYTE) (jDst << (8 - (iDst & 0x00000007)));
|
|
|
|
*pjDstTemp = (BYTE) ((*pjDstTemp & jMask) | (jDst & ~jMask));
|
|
}
|
|
|
|
pjDst += pDibInfoDst->stride;
|
|
pjSrc += pDibInfoSrc->stride;
|
|
}
|
|
}
|
|
|
|
/******************************Public*Routine******************************\
|
|
* vTransparentS4D4
|
|
*
|
|
* Doing a transparent copy from 4PP to 4bpp non identity
|
|
*
|
|
* Returns:
|
|
* VOID.
|
|
*
|
|
* History:
|
|
* 09-Dec-1996 -by- Lingyun Wang [lingyunw]
|
|
* Wrote it.
|
|
\**************************************************************************/
|
|
VOID vTransparentS4D4 (
|
|
PDIBINFO pDibInfoDst,
|
|
PDIBINFO pDibInfoSrc,
|
|
ULONG TransColor)
|
|
{
|
|
PBYTE pjDst = (PBYTE)pDibInfoDst->pvBase + pDibInfoDst->stride*pDibInfoDst->rclDIB.top
|
|
+ (pDibInfoDst->rclDIB.left >> 1);
|
|
PBYTE pjSrc = (PBYTE)pDibInfoSrc->pvBase + pDibInfoSrc->stride*pDibInfoSrc->rclDIB.top
|
|
+ (pDibInfoSrc->rclDIB.left >> 1);
|
|
|
|
LONG cx = pDibInfoDst->rclDIB.right - pDibInfoDst->rclDIB.left;
|
|
LONG cy = pDibInfoDst->rclDIB.bottom - pDibInfoDst->rclDIB.top;
|
|
PBYTE pjDstTemp;
|
|
PBYTE pjSrcTemp;
|
|
BYTE jSrc, jDst;
|
|
BYTE rgbBlue, rgbGreen, rgbRed;
|
|
LONG iSrc, iDst;
|
|
LOGPALETTE16 logPal16;
|
|
HPALETTE hPal;
|
|
LONG i;
|
|
ULONG cxTemp;
|
|
ULONG rgbColor;
|
|
BYTE xlate[16];
|
|
|
|
//
|
|
// build up translate table
|
|
//
|
|
logPal16.PalVersion = 0x300;
|
|
logPal16.PalNumEntries = 16;
|
|
|
|
for (i = 0; i < 16; i++)
|
|
{
|
|
logPal16.palPalEntry[i].peRed = pDibInfoDst->pbmi->bmiColors[i].rgbRed;
|
|
logPal16.palPalEntry[i].peGreen = pDibInfoDst->pbmi->bmiColors[i].rgbGreen;
|
|
logPal16.palPalEntry[i].peBlue = pDibInfoDst->pbmi->bmiColors[i].rgbBlue;
|
|
logPal16.palPalEntry[i].peFlags = 0;
|
|
}
|
|
|
|
hPal = CreatePalette ((LOGPALETTE *)&logPal16);
|
|
|
|
for (i = 0; i<16; i++)
|
|
{
|
|
rgbColor = RGB(pDibInfoSrc->pbmi->bmiColors[i].rgbRed, pDibInfoSrc->pbmi->bmiColors[i].rgbGreen,
|
|
pDibInfoSrc->pbmi->bmiColors[i].rgbBlue);
|
|
|
|
xlate[i] = (BYTE)GetNearestPaletteIndex(hPal, rgbColor);
|
|
}
|
|
|
|
if (hPal)
|
|
{
|
|
DeleteObject(hPal);
|
|
}
|
|
|
|
while(cy--)
|
|
{
|
|
cxTemp = cx;
|
|
|
|
iSrc = pDibInfoSrc->rclDIB.left;
|
|
iDst = pDibInfoDst->rclDIB.left;
|
|
|
|
pjDstTemp = pjDst;
|
|
pjSrcTemp = pjSrc;
|
|
|
|
while (cxTemp--)
|
|
{
|
|
if (iSrc & 0x00000001)
|
|
{
|
|
jSrc = *pjSrcTemp & 0x0F;
|
|
pjSrcTemp++;
|
|
}
|
|
else
|
|
{
|
|
jSrc = (*pjSrcTemp & 0xF0)>>4;
|
|
}
|
|
|
|
iSrc++;
|
|
|
|
if (iDst & 0x00000001)
|
|
{
|
|
if (jSrc != (BYTE)TransColor)
|
|
{
|
|
jDst |= xlate[jSrc] & 0x0F;
|
|
}
|
|
else
|
|
{
|
|
jDst |= *pjDstTemp & 0x0F;
|
|
}
|
|
|
|
*pjDstTemp++ = jDst;
|
|
jDst = 0;
|
|
}
|
|
else
|
|
{
|
|
if (jSrc != (BYTE)TransColor)
|
|
{
|
|
jDst |= (xlate[jSrc] << 4);
|
|
}
|
|
else
|
|
{
|
|
jDst |= *pjDstTemp & 0xF0;
|
|
}
|
|
}
|
|
|
|
iDst++;
|
|
}
|
|
|
|
pjDst += pDibInfoDst->stride;
|
|
pjSrc += pDibInfoSrc->stride;
|
|
}
|
|
}
|
|
|
|
/******************************Public*Routine******************************\
|
|
* vTransparentS4D8
|
|
*
|
|
* Doing a transparent copy from 4PP to 8bpp
|
|
*
|
|
* Returns:
|
|
* VOID.
|
|
*
|
|
* History:
|
|
* 09-Dec-1996 -by- Lingyun Wang [lingyunw]
|
|
* Wrote it.
|
|
\**************************************************************************/
|
|
VOID vTransparentS4D8 (
|
|
PDIBINFO pDibInfoDst,
|
|
PDIBINFO pDibInfoSrc,
|
|
ULONG TransColor)
|
|
{
|
|
PBYTE pjDst = (PBYTE)pDibInfoDst->pvBase + pDibInfoDst->stride*pDibInfoDst->rclDIB.top;
|
|
+ pDibInfoDst->rclDIB.left;
|
|
PBYTE pjSrc = (PBYTE)pDibInfoSrc->pvBase + pDibInfoSrc->stride*pDibInfoSrc->rclDIB.top
|
|
+ (pDibInfoSrc->rclDIB.left >> 1);
|
|
LONG cx = pDibInfoDst->rclDIB.right - pDibInfoDst->rclDIB.left;
|
|
LONG cy = pDibInfoDst->rclDIB.bottom - pDibInfoDst->rclDIB.top;
|
|
PBYTE pjDstTemp;
|
|
PBYTE pjSrcTemp;
|
|
BYTE jSrc;
|
|
LONG cxTemp;
|
|
BYTE rgbBlue, rgbGreen, rgbRed;
|
|
LONG iSrc;
|
|
LOGPALETTE256 logPal256;
|
|
HPALETTE hPal;
|
|
LONG i;
|
|
ULONG rgbColor;
|
|
BYTE xlate[16];
|
|
|
|
logPal256.PalVersion = 0x300;
|
|
logPal256.PalNumEntries = 256;
|
|
|
|
for (i = 0; i < 256; i++)
|
|
{
|
|
logPal256.palPalEntry[i].peRed = pDibInfoDst->pbmi->bmiColors[i].rgbRed;
|
|
logPal256.palPalEntry[i].peGreen = pDibInfoDst->pbmi->bmiColors[i].rgbGreen;
|
|
logPal256.palPalEntry[i].peBlue = pDibInfoDst->pbmi->bmiColors[i].rgbBlue;
|
|
logPal256.palPalEntry[i].peFlags = 0;
|
|
}
|
|
|
|
hPal = CreatePalette ((LOGPALETTE *)&logPal256);
|
|
|
|
for (i = 0; i<16; i++)
|
|
{
|
|
rgbColor = RGB(pDibInfoSrc->pbmi->bmiColors[i].rgbRed, pDibInfoSrc->pbmi->bmiColors[i].rgbGreen,
|
|
pDibInfoSrc->pbmi->bmiColors[i].rgbBlue);
|
|
|
|
xlate[i] = (BYTE)GetNearestPaletteIndex(hPal, rgbColor);
|
|
|
|
//Dprintf("i=%x, rgbColor = 0x%08x, xlate[i] = %x", i, rgbColor, xlate[i]);
|
|
}
|
|
|
|
if (hPal)
|
|
{
|
|
DeleteObject(hPal);
|
|
}
|
|
|
|
while(cy--)
|
|
{
|
|
cxTemp = cx;
|
|
|
|
iSrc = pDibInfoSrc->rclDIB.left;
|
|
|
|
pjDstTemp = pjDst;
|
|
pjSrcTemp = pjSrc;
|
|
|
|
while (cxTemp--)
|
|
{
|
|
if (iSrc & 0x00000001)
|
|
{
|
|
jSrc = *pjSrcTemp & 0x0F;
|
|
pjSrcTemp++;
|
|
}
|
|
else
|
|
{
|
|
jSrc = (*pjSrcTemp & 0xF0)>>4;
|
|
}
|
|
|
|
iSrc++;
|
|
|
|
if (jSrc != (BYTE)TransColor)
|
|
{
|
|
*pjDstTemp = xlate[jSrc];
|
|
}
|
|
|
|
pjDstTemp++;
|
|
}
|
|
|
|
pjDst += pDibInfoDst->stride;
|
|
pjSrc += pDibInfoSrc->stride;
|
|
}
|
|
}
|
|
|
|
/******************************Public*Routine******************************\
|
|
* vTransparentS4D16
|
|
*
|
|
* Doing a transparent copy from 4BPP to 16BPP
|
|
*
|
|
* Returns:
|
|
* VOID.
|
|
*
|
|
* History:
|
|
* 09-Dec-1996 -by- Lingyun Wang [lingyunw]
|
|
* Wrote it.
|
|
\**************************************************************************/
|
|
VOID vTransparentS4D16 (
|
|
PDIBINFO pDibInfoDst,
|
|
PDIBINFO pDibInfoSrc,
|
|
ULONG TransColor)
|
|
{
|
|
PBYTE pjDst = (PBYTE)pDibInfoDst->pvBase + pDibInfoDst->stride*pDibInfoDst->rclDIB.top
|
|
+ pDibInfoDst->rclDIB.left*2;
|
|
PBYTE pjSrc = (PBYTE)pDibInfoSrc->pvBase + pDibInfoSrc->stride*pDibInfoSrc->rclDIB.top
|
|
+ (pDibInfoSrc->rclDIB.left >> 1);
|
|
|
|
LONG cx = pDibInfoDst->rclDIB.right - pDibInfoDst->rclDIB.left;
|
|
LONG cy = pDibInfoDst->rclDIB.bottom - pDibInfoDst->rclDIB.top;
|
|
PBYTE pjDstTemp;
|
|
PBYTE pjSrcTemp;
|
|
BYTE jSrc;
|
|
LONG cxTemp;
|
|
BYTE rgbBlue, rgbGreen, rgbRed;
|
|
LONG iSrc, iDst;
|
|
|
|
while(cy--)
|
|
{
|
|
cxTemp = cx;
|
|
|
|
iSrc = pDibInfoSrc->rclDIB.left;
|
|
iDst = pDibInfoDst->rclDIB.left;
|
|
|
|
pjDstTemp = pjDst;
|
|
pjSrcTemp = pjSrc;
|
|
|
|
while (cxTemp--)
|
|
{
|
|
if (iSrc & 0x00000001)
|
|
{
|
|
jSrc = *pjSrcTemp & 0x0F;
|
|
pjSrcTemp++;
|
|
}
|
|
else
|
|
{
|
|
jSrc = (*pjSrcTemp & 0xF0)>>4;
|
|
}
|
|
|
|
iSrc++;
|
|
|
|
if (jSrc != (BYTE)TransColor)
|
|
{
|
|
rgbBlue = pDibInfoSrc->pbmi->bmiColors[jSrc].rgbBlue;
|
|
rgbGreen = pDibInfoSrc->pbmi->bmiColors[jSrc].rgbGreen;
|
|
rgbRed = pDibInfoSrc->pbmi->bmiColors[jSrc].rgbRed;
|
|
|
|
//
|
|
// figure out 5-5-5 or 5-6-5
|
|
//
|
|
if (pDibInfoDst->pbmi->bmiHeader.biCompression == BI_BITFIELDS)
|
|
{
|
|
//5-5-5
|
|
if (*(DWORD *)&pDibInfoDst->pbmi->bmiColors[1] == 0x03E0)
|
|
{
|
|
*(PUSHORT)pjDstTemp = (USHORT)rgbBlue >> 3;
|
|
*(PUSHORT)pjDstTemp |= (USHORT)(rgbGreen >> 3) << 5;
|
|
*(PUSHORT)pjDstTemp |= (USHORT)(rgbRed >> 3) << 10;
|
|
}
|
|
// 5-6-5
|
|
else if (*(DWORD *)&pDibInfoDst->pbmi->bmiColors[1] == 0x07E0)
|
|
{
|
|
*(PUSHORT)pjDstTemp = (USHORT)rgbBlue >> 3;
|
|
*(PUSHORT)pjDstTemp |= (USHORT)(rgbGreen >> 2) << 5;
|
|
*(PUSHORT)pjDstTemp |= (USHORT)(rgbRed >> 3) << 11;
|
|
}
|
|
else
|
|
{
|
|
WARNING ("unsupported BITFIELDS\n");
|
|
}
|
|
}
|
|
else
|
|
{
|
|
*(PUSHORT)pjDstTemp = (USHORT)rgbBlue >> 3;
|
|
*(PUSHORT)pjDstTemp |= (USHORT)(rgbGreen >> 3) << 5;
|
|
*(PUSHORT)pjDstTemp |= (USHORT)(rgbRed >> 3) << 10;
|
|
}
|
|
}
|
|
|
|
pjDstTemp += 2;
|
|
}
|
|
|
|
pjDst += pDibInfoDst->stride;
|
|
pjSrc += pDibInfoSrc->stride;
|
|
}
|
|
}
|
|
|
|
/******************************Public*Routine******************************\
|
|
* vTransparentS4D24
|
|
*
|
|
* Doing a transparent copy from 4BPP to 24BPP
|
|
*
|
|
* Returns:
|
|
* VOID.
|
|
*
|
|
* History:
|
|
* 09-Dec-1996 -by- Lingyun Wang [lingyunw]
|
|
* Wrote it.
|
|
\**************************************************************************/
|
|
VOID vTransparentS4D24 (
|
|
PDIBINFO pDibInfoDst,
|
|
PDIBINFO pDibInfoSrc,
|
|
ULONG TransColor)
|
|
{
|
|
PBYTE pjDst = (PBYTE)pDibInfoDst->pvBase + pDibInfoDst->stride*pDibInfoDst->rclDIB.top
|
|
+ pDibInfoDst->rclDIB.left*3;
|
|
PBYTE pjSrc = (PBYTE)pDibInfoSrc->pvBase + pDibInfoSrc->stride*pDibInfoSrc->rclDIB.top
|
|
+ (pDibInfoSrc->rclDIB.left >> 1);
|
|
|
|
LONG cx = pDibInfoDst->rclDIB.right - pDibInfoDst->rclDIB.left;
|
|
LONG cy = pDibInfoDst->rclDIB.bottom - pDibInfoDst->rclDIB.top;
|
|
PBYTE pjDstTemp;
|
|
PBYTE pjSrcTemp;
|
|
LONG cxTemp;
|
|
BYTE jSrc;
|
|
LONG iSrc, iDst;
|
|
BYTE rgbBlue, rgbGreen, rgbRed;
|
|
|
|
while(cy--)
|
|
{
|
|
cxTemp = cx;
|
|
|
|
pjDstTemp = pjDst;
|
|
pjSrcTemp = pjSrc;
|
|
|
|
iSrc = pDibInfoSrc->rclDIB.left;
|
|
iDst = pDibInfoDst->rclDIB.left;
|
|
|
|
while (cxTemp--)
|
|
{
|
|
if (iSrc & 0x00000001)
|
|
{
|
|
jSrc = *pjSrcTemp & 0x0F;
|
|
pjSrcTemp++;
|
|
}
|
|
else
|
|
{
|
|
jSrc = (*pjSrcTemp & 0xF0)>>4;
|
|
}
|
|
|
|
iSrc++;
|
|
|
|
if (jSrc != (BYTE)TransColor)
|
|
{
|
|
rgbBlue = pDibInfoSrc->pbmi->bmiColors[jSrc].rgbBlue;
|
|
rgbGreen = pDibInfoSrc->pbmi->bmiColors[jSrc].rgbGreen;
|
|
rgbRed = pDibInfoSrc->pbmi->bmiColors[jSrc].rgbRed;
|
|
|
|
*(pjDstTemp++) = (BYTE) rgbBlue;
|
|
*(pjDstTemp++) = (BYTE) rgbGreen;
|
|
*(pjDstTemp++) = (BYTE) rgbRed;
|
|
}
|
|
else
|
|
{
|
|
pjDstTemp += 3;
|
|
}
|
|
}
|
|
|
|
pjDst += pDibInfoDst->stride;
|
|
pjSrc += pDibInfoSrc->stride;
|
|
}
|
|
}
|
|
|
|
/******************************Public*Routine******************************\
|
|
* vTransparentS4D32
|
|
*
|
|
* Doing a transparent copy from 4BPP to 32BPP
|
|
*
|
|
* Returns:
|
|
* VOID.
|
|
*
|
|
* History:
|
|
* 09-Dec-1996 -by- Lingyun Wang [lingyunw]
|
|
* Wrote it.
|
|
\**************************************************************************/
|
|
VOID vTransparentS4D32 (
|
|
PDIBINFO pDibInfoDst,
|
|
PDIBINFO pDibInfoSrc,
|
|
ULONG TransColor)
|
|
{
|
|
PBYTE pjDst = (PBYTE)pDibInfoDst->pvBase + pDibInfoDst->stride*pDibInfoDst->rclDIB.top
|
|
+ pDibInfoDst->rclDIB.left*4;
|
|
PBYTE pjSrc = (PBYTE)pDibInfoSrc->pvBase + pDibInfoSrc->stride*pDibInfoSrc->rclDIB.top
|
|
+ (pDibInfoSrc->rclDIB.left >> 1);
|
|
|
|
LONG cx = pDibInfoDst->rclDIB.right - pDibInfoDst->rclDIB.left;
|
|
LONG cy = pDibInfoDst->rclDIB.bottom - pDibInfoDst->rclDIB.top;
|
|
PBYTE pjDstTemp;
|
|
PBYTE pjSrcTemp;
|
|
LONG cxTemp;
|
|
BYTE jSrc;
|
|
LONG iSrc, iDst;
|
|
BYTE rgbBlue, rgbGreen, rgbRed;
|
|
|
|
while(cy--)
|
|
{
|
|
cxTemp = cx;
|
|
|
|
pjDstTemp = pjDst;
|
|
pjSrcTemp = pjSrc;
|
|
iSrc = pDibInfoSrc->rclDIB.left;
|
|
iDst = pDibInfoDst->rclDIB.left;
|
|
|
|
while (cxTemp--)
|
|
{
|
|
if (iSrc & 0x00000001)
|
|
{
|
|
jSrc = *pjSrcTemp & 0x0F;
|
|
pjSrcTemp++;
|
|
}
|
|
else
|
|
{
|
|
jSrc = (*pjSrcTemp & 0xF0)>>4;
|
|
}
|
|
|
|
iSrc++;
|
|
|
|
if (jSrc != (BYTE)TransColor)
|
|
{
|
|
rgbBlue = pDibInfoSrc->pbmi->bmiColors[jSrc].rgbBlue;
|
|
rgbGreen = pDibInfoSrc->pbmi->bmiColors[jSrc].rgbGreen;
|
|
rgbRed = pDibInfoSrc->pbmi->bmiColors[jSrc].rgbRed;
|
|
|
|
*(PULONG)pjDstTemp = (DWORD) (rgbBlue | (WORD)rgbGreen << 8 | (DWORD)rgbRed << 16);
|
|
}
|
|
pjDstTemp += 4;
|
|
}
|
|
|
|
pjDst += pDibInfoDst->stride;
|
|
pjSrc += pDibInfoSrc->stride;
|
|
}
|
|
}
|
|
|
|
/******************************Public*Routine******************************\
|
|
* vTransparentS8D16
|
|
*
|
|
* Doing a transparent copy from 8BPP to 16BPP
|
|
*
|
|
* Returns:
|
|
* VOID.
|
|
*
|
|
* History:
|
|
* 09-Dec-1996 -by- Lingyun Wang [lingyunw]
|
|
* Wrote it.
|
|
\**************************************************************************/
|
|
VOID vTransparentS8D16 (
|
|
PDIBINFO pDibInfoDst,
|
|
PDIBINFO pDibInfoSrc,
|
|
ULONG TransColor)
|
|
{
|
|
PBYTE pjDst = (PBYTE)pDibInfoDst->pvBase + pDibInfoDst->stride*pDibInfoDst->rclDIB.top
|
|
+ pDibInfoDst->rclDIB.left*2;
|
|
PBYTE pjSrc = (PBYTE)pDibInfoSrc->pvBase + pDibInfoSrc->stride*pDibInfoSrc->rclDIB.top
|
|
+ pDibInfoSrc->rclDIB.left;
|
|
|
|
LONG cx = pDibInfoDst->rclDIB.right - pDibInfoDst->rclDIB.left;
|
|
LONG cy = pDibInfoDst->rclDIB.bottom - pDibInfoDst->rclDIB.top;
|
|
PBYTE pjDstTemp;
|
|
PBYTE pjSrcTemp;
|
|
BYTE jSrc;
|
|
LONG cxTemp;
|
|
BYTE rgbBlue, rgbGreen, rgbRed;
|
|
|
|
while(cy--)
|
|
{
|
|
cxTemp = cx;
|
|
|
|
pjDstTemp = pjDst;
|
|
pjSrcTemp = pjSrc;
|
|
|
|
while (cxTemp--)
|
|
{
|
|
jSrc = *pjSrcTemp++;
|
|
|
|
//
|
|
// put one pixel in the dest
|
|
//
|
|
if (jSrc != (BYTE)TransColor)
|
|
{
|
|
rgbBlue = pDibInfoSrc->pbmi->bmiColors[jSrc].rgbBlue;
|
|
rgbGreen = pDibInfoSrc->pbmi->bmiColors[jSrc].rgbGreen;
|
|
rgbRed = pDibInfoSrc->pbmi->bmiColors[jSrc].rgbRed;
|
|
|
|
//
|
|
// figure out 5-5-5 or 5-6-5
|
|
//
|
|
if (pDibInfoDst->pbmi->bmiHeader.biCompression == BI_BITFIELDS)
|
|
{
|
|
//5-5-5
|
|
if (*(DWORD *)&pDibInfoDst->pbmi->bmiColors[1] == 0x03E0)
|
|
{
|
|
*(PUSHORT)pjDstTemp = (USHORT)rgbBlue >> 3;
|
|
*(PUSHORT)pjDstTemp |= (USHORT)(rgbGreen >> 3) << 5;
|
|
*(PUSHORT)pjDstTemp |= (USHORT)(rgbRed >> 3) << 10;
|
|
}
|
|
// 5-6-5
|
|
else if (*(DWORD *)&pDibInfoDst->pbmi->bmiColors[1] == 0x07E0)
|
|
{
|
|
*(PUSHORT)pjDstTemp = (USHORT)rgbBlue >> 3;
|
|
*(PUSHORT)pjDstTemp |= (USHORT)(rgbGreen >> 2) << 5;
|
|
*(PUSHORT)pjDstTemp |= (USHORT)(rgbRed >> 3) << 11;
|
|
}
|
|
else
|
|
{
|
|
WARNING ("unsupported BITFIELDS\n");
|
|
}
|
|
}
|
|
else
|
|
{
|
|
*(PUSHORT)pjDstTemp = (USHORT)rgbBlue >> 3;
|
|
*(PUSHORT)pjDstTemp |= (USHORT)(rgbGreen >> 3) << 5;
|
|
*(PUSHORT)pjDstTemp |= (USHORT)(rgbRed >> 3) << 10;
|
|
}
|
|
}
|
|
|
|
pjDstTemp += 2;
|
|
|
|
}
|
|
|
|
pjDst += pDibInfoDst->stride;
|
|
pjSrc += pDibInfoSrc->stride;
|
|
}
|
|
}
|
|
|
|
/******************************Public*Routine******************************\
|
|
* vTransparentS8D24
|
|
*
|
|
* Doing a transparent copy from 8BPP to 16BPP
|
|
*
|
|
* Returns:
|
|
* VOID.
|
|
*
|
|
* History:
|
|
* 09-Dec-1996 -by- Lingyun Wang [lingyunw]
|
|
* Wrote it.
|
|
\**************************************************************************/
|
|
VOID vTransparentS8D24 (
|
|
PDIBINFO pDibInfoDst,
|
|
PDIBINFO pDibInfoSrc,
|
|
ULONG TransColor)
|
|
{
|
|
PBYTE pjDst = (PBYTE)pDibInfoDst->pvBase + pDibInfoDst->stride*pDibInfoDst->rclDIB.top
|
|
+ pDibInfoDst->rclDIB.left*3;
|
|
PBYTE pjSrc = (PBYTE)pDibInfoSrc->pvBase + pDibInfoSrc->stride*pDibInfoSrc->rclDIB.top
|
|
+ pDibInfoSrc->rclDIB.left;
|
|
|
|
LONG cx = pDibInfoDst->rclDIB.right - pDibInfoDst->rclDIB.left;
|
|
LONG cy = pDibInfoDst->rclDIB.bottom - pDibInfoDst->rclDIB.top;
|
|
PBYTE pjDstTemp;
|
|
PBYTE pjSrcTemp;
|
|
BYTE jSrc;
|
|
LONG cxTemp;
|
|
BYTE rgbBlue, rgbGreen, rgbRed;
|
|
|
|
while(cy--)
|
|
{
|
|
cxTemp = cx;
|
|
|
|
pjDstTemp = pjDst;
|
|
pjSrcTemp = pjSrc;
|
|
|
|
while (cxTemp--)
|
|
{
|
|
jSrc = *pjSrcTemp++;
|
|
|
|
if (jSrc != (BYTE)TransColor)
|
|
{
|
|
rgbBlue = pDibInfoSrc->pbmi->bmiColors[jSrc].rgbBlue;
|
|
rgbGreen = pDibInfoSrc->pbmi->bmiColors[jSrc].rgbGreen;
|
|
rgbRed = pDibInfoSrc->pbmi->bmiColors[jSrc].rgbRed;
|
|
|
|
*(pjDstTemp++) = (BYTE) rgbBlue;
|
|
*(pjDstTemp++) = (BYTE) rgbGreen;
|
|
*(pjDstTemp++) = (BYTE) rgbRed;
|
|
}
|
|
else
|
|
{
|
|
pjDstTemp += 3;
|
|
}
|
|
}
|
|
|
|
pjDst += pDibInfoDst->stride;
|
|
pjSrc += pDibInfoSrc->stride;
|
|
}
|
|
}
|
|
|
|
/******************************Public*Routine******************************\
|
|
* vTransparentS8D32
|
|
*
|
|
* Doing a transparent copy from 8BPP to 32BPP
|
|
*
|
|
* Returns:
|
|
* VOID.
|
|
*
|
|
* History:
|
|
* 09-Dec-1996 -by- Lingyun Wang [lingyunw]
|
|
* Wrote it.
|
|
\**************************************************************************/
|
|
VOID vTransparentS8D32 (
|
|
PDIBINFO pDibInfoDst,
|
|
PDIBINFO pDibInfoSrc,
|
|
ULONG TransColor)
|
|
{
|
|
PBYTE pjDst = (PBYTE)pDibInfoDst->pvBase + pDibInfoDst->stride*pDibInfoDst->rclDIB.top
|
|
+ pDibInfoDst->rclDIB.left*4;
|
|
PBYTE pjSrc = (PBYTE)pDibInfoSrc->pvBase + pDibInfoSrc->stride*pDibInfoSrc->rclDIB.top
|
|
+ pDibInfoSrc->rclDIB.left;
|
|
LONG cx = pDibInfoDst->rclDIB.right - pDibInfoDst->rclDIB.left;
|
|
LONG cy = pDibInfoDst->rclDIB.bottom - pDibInfoDst->rclDIB.top;
|
|
PBYTE pjDstTemp;
|
|
PBYTE pjSrcTemp;
|
|
BYTE jSrc;
|
|
LONG cxTemp;
|
|
BYTE rgbBlue, rgbGreen, rgbRed;
|
|
|
|
while(cy--)
|
|
{
|
|
cxTemp = cx;
|
|
|
|
pjDstTemp = pjDst;
|
|
pjSrcTemp = pjSrc;
|
|
|
|
while (cxTemp--)
|
|
{
|
|
jSrc = *pjSrcTemp++;
|
|
|
|
if (jSrc != (BYTE)TransColor)
|
|
{
|
|
rgbBlue = pDibInfoSrc->pbmi->bmiColors[jSrc].rgbBlue;
|
|
rgbGreen = pDibInfoSrc->pbmi->bmiColors[jSrc].rgbGreen;
|
|
rgbRed = pDibInfoSrc->pbmi->bmiColors[jSrc].rgbRed;
|
|
|
|
*(PULONG)pjDstTemp = (DWORD) (rgbBlue | (WORD)rgbGreen << 8 | (DWORD)rgbRed << 16);
|
|
}
|
|
pjDstTemp += 4;
|
|
}
|
|
|
|
pjDst += pDibInfoDst->stride;
|
|
pjSrc += pDibInfoSrc->stride;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
/******************************Public*Routine******************************\
|
|
* vTransparentS8D1
|
|
*
|
|
* Doing a transparent copy from 8BPP to other 1,16,24,32bpp format DIBs
|
|
*
|
|
* Returns:
|
|
* VOID.
|
|
*
|
|
* History:
|
|
* 09-Dec-1996 -by- Lingyun Wang [lingyunw]
|
|
* Wrote it.
|
|
\**************************************************************************/
|
|
VOID vTransparentS8D1 (
|
|
PDIBINFO pDibInfoDst,
|
|
PDIBINFO pDibInfoSrc,
|
|
ULONG TransColor)
|
|
{
|
|
PBYTE pjDst = (PBYTE)pDibInfoDst->pvBase + pDibInfoDst->stride*pDibInfoDst->rclDIB.top;
|
|
|
|
pjDst = StartPixel (pjDst, pDibInfoDst->rclDIB.left, pDibInfoDst->pbmi->bmiHeader.biBitCount);
|
|
|
|
PBYTE pjSrc = (PBYTE)pDibInfoSrc->pvBase + pDibInfoSrc->stride*pDibInfoSrc->rclDIB.top
|
|
+ pDibInfoSrc->rclDIB.left;
|
|
|
|
LONG cx = pDibInfoDst->rclDIB.right - pDibInfoDst->rclDIB.left;
|
|
LONG cy = pDibInfoDst->rclDIB.bottom - pDibInfoDst->rclDIB.top;
|
|
PBYTE pjDstTemp;
|
|
PBYTE pjSrcTemp;
|
|
BYTE jSrc;
|
|
LONG cxTemp;
|
|
HDC hdc;
|
|
HBITMAP hbm;
|
|
ULONG ulWidthDst, ulHeightDst, ulWidthSrc, ulHeightSrc;
|
|
BYTE pByte[32];
|
|
INT i, j;
|
|
BYTE pByteSrc[256];
|
|
LONG iDst;
|
|
BYTE jDst;
|
|
|
|
//
|
|
// build the color translation table
|
|
//
|
|
hdc = CreateCompatibleDC (pDibInfoDst->hdc);
|
|
|
|
//
|
|
// save the original width/height
|
|
//
|
|
ulWidthDst = pDibInfoDst->pbmi->bmiHeader.biWidth;
|
|
ulHeightDst = pDibInfoDst->pbmi->bmiHeader.biHeight;
|
|
|
|
pDibInfoDst->pbmi->bmiHeader.biWidth = 256;
|
|
pDibInfoDst->pbmi->bmiHeader.biHeight = 1;
|
|
|
|
//
|
|
// Create a 256X1 DIB
|
|
//
|
|
hbm = CreateDIBSection(hdc, (PBITMAPINFO)pDibInfoDst->pbmi, DIB_RGB_COLORS, (PVOID *)&pByte, NULL, 0);
|
|
|
|
if (!hdc || !hbm)
|
|
{
|
|
//
|
|
// It's bad to fail and return here without a return value, but it's better
|
|
// than crashing later when accessing pByte. At some point it would be nice
|
|
// to change the vTansparentxxxx functions to return success/failure.
|
|
//
|
|
if (hdc)
|
|
{
|
|
DeleteDC(hdc);
|
|
}
|
|
|
|
if (hbm)
|
|
{
|
|
DeleteObject(hbm);
|
|
}
|
|
|
|
pDibInfoDst->pbmi->bmiHeader.biWidth = ulWidthDst;
|
|
pDibInfoDst->pbmi->bmiHeader.biHeight = ulHeightDst;
|
|
WARNING ("failed to create hdc or hbm\n");
|
|
return;
|
|
}
|
|
|
|
SelectObject (hdc, hbm);
|
|
|
|
for (i = 0; i < 256; i++)
|
|
{
|
|
pByteSrc[i] = (unsigned char)i;
|
|
}
|
|
|
|
ulWidthSrc = pDibInfoSrc->pbmi->bmiHeader.biWidth;
|
|
ulHeightSrc = pDibInfoSrc->pbmi->bmiHeader.biHeight;
|
|
|
|
pDibInfoSrc->pbmi->bmiHeader.biWidth = 256;
|
|
pDibInfoSrc->pbmi->bmiHeader.biHeight = 1;
|
|
|
|
SetDIBits(hdc, hbm, 0, 1, pByteSrc, (PBITMAPINFO)pDibInfoSrc->pbmi,pDibInfoSrc->iUsage);
|
|
|
|
//
|
|
// retore bitmap width/height
|
|
//
|
|
pDibInfoSrc->pbmi->bmiHeader.biWidth = ulWidthSrc;
|
|
pDibInfoSrc->pbmi->bmiHeader.biHeight = ulHeightSrc;
|
|
|
|
pDibInfoDst->pbmi->bmiHeader.biWidth = ulWidthDst;
|
|
pDibInfoDst->pbmi->bmiHeader.biHeight = ulHeightDst;
|
|
|
|
//
|
|
// now pByte contains all the 256 color mappings, just need to split them up
|
|
//
|
|
BYTE bTmp = 0;
|
|
|
|
while(cy--)
|
|
{
|
|
cxTemp = cx;
|
|
|
|
pjDstTemp = pjDst;
|
|
pjSrcTemp = pjSrc;
|
|
|
|
iDst = pDibInfoDst->rclDIB.left & 0x07;
|
|
|
|
jDst = *pjDstTemp >> (7 - iDst);
|
|
|
|
while (cxTemp--)
|
|
{
|
|
jSrc = *pjSrcTemp++;
|
|
|
|
//
|
|
// put one pixel in the dest
|
|
//
|
|
bTmp = pByte[jSrc >> 3];
|
|
bTmp >>= 7 - (jSrc & 0x07);
|
|
|
|
if (jSrc != TransColor)
|
|
{
|
|
jDst |= bTmp;
|
|
}
|
|
else
|
|
{
|
|
jDst |= 1-bTmp;
|
|
}
|
|
|
|
jDst <<= 1;
|
|
|
|
iDst++;
|
|
|
|
if (!(iDst & 0x07))
|
|
{
|
|
*(pjDstTemp++) = jDst;
|
|
jDst = 0;
|
|
}
|
|
}
|
|
pjDst += pDibInfoDst->stride;
|
|
pjSrc += pDibInfoSrc->stride;
|
|
}
|
|
|
|
DeleteDC(hdc);
|
|
DeleteObject(hbm);
|
|
}
|
|
|
|
/******************************Public*Routine******************************\
|
|
* vTransparentS8D4
|
|
*
|
|
* Doing a transparent copy from 8BPP to other 1,16,24,32bpp format DIBs
|
|
*
|
|
* Returns:
|
|
* VOID.
|
|
*
|
|
* History:
|
|
* 09-Dec-1996 -by- Lingyun Wang [lingyunw]
|
|
* Wrote it.
|
|
\**************************************************************************/
|
|
VOID vTransparentS8D4 (
|
|
PDIBINFO pDibInfoDst,
|
|
PDIBINFO pDibInfoSrc,
|
|
ULONG TransColor)
|
|
{
|
|
PBYTE pjDst = (PBYTE)pDibInfoDst->pvBase + pDibInfoDst->stride*pDibInfoDst->rclDIB.top;
|
|
|
|
pjDst = StartPixel (pjDst, pDibInfoDst->rclDIB.left, pDibInfoDst->pbmi->bmiHeader.biBitCount);
|
|
|
|
PBYTE pjSrc = (PBYTE)pDibInfoSrc->pvBase + pDibInfoSrc->stride*pDibInfoSrc->rclDIB.top
|
|
+ pDibInfoSrc->rclDIB.left;
|
|
|
|
LONG cx = pDibInfoDst->rclDIB.right - pDibInfoDst->rclDIB.left;
|
|
LONG cy = pDibInfoDst->rclDIB.bottom - pDibInfoDst->rclDIB.top;
|
|
PBYTE pjDstTemp;
|
|
PBYTE pjSrcTemp;
|
|
BYTE jSrc;
|
|
LONG cxTemp;
|
|
HDC hdc;
|
|
HBITMAP hbm;
|
|
ULONG ulWidthDst, ulHeightDst, ulWidthSrc, ulHeightSrc;
|
|
BYTE pByte[128];
|
|
INT i, j;
|
|
BYTE xlate[256];
|
|
BYTE pByteSrc[256];
|
|
LONG iDst;
|
|
|
|
//
|
|
// build the color translation table
|
|
//
|
|
hdc = CreateCompatibleDC (pDibInfoDst->hdc);
|
|
|
|
//
|
|
// save the original width/height
|
|
//
|
|
ulWidthDst = pDibInfoDst->pbmi->bmiHeader.biWidth;
|
|
ulHeightDst = pDibInfoDst->pbmi->bmiHeader.biHeight;
|
|
|
|
pDibInfoDst->pbmi->bmiHeader.biWidth = 256;
|
|
pDibInfoDst->pbmi->bmiHeader.biHeight = 1;
|
|
|
|
//
|
|
// Create a 256X1 DIB
|
|
//
|
|
hbm = CreateDIBSection(hdc, (PBITMAPINFO)pDibInfoDst->pbmi, DIB_RGB_COLORS, (PVOID *)&pByte, NULL, 0);
|
|
|
|
if (!hdc || !hbm)
|
|
{
|
|
//
|
|
// It's bad to fail and return here without a return value, but it's better
|
|
// than crashing later when accessing pByte. At some point it would be nice
|
|
// to change the vTansparentxxxx functions to return success/failure.
|
|
//
|
|
if (hdc)
|
|
{
|
|
DeleteDC(hdc);
|
|
}
|
|
|
|
if (hbm)
|
|
{
|
|
DeleteObject(hbm);
|
|
}
|
|
|
|
pDibInfoDst->pbmi->bmiHeader.biWidth = ulWidthDst;
|
|
pDibInfoDst->pbmi->bmiHeader.biHeight = ulHeightDst;
|
|
WARNING ("failed to create hdc or hbm\n");
|
|
return;
|
|
}
|
|
|
|
SelectObject (hdc, hbm);
|
|
|
|
for (i = 0; i < 256; i++)
|
|
{
|
|
pByteSrc[i] = (unsigned char)i;
|
|
}
|
|
|
|
ulWidthSrc = pDibInfoSrc->pbmi->bmiHeader.biWidth;
|
|
ulHeightSrc = pDibInfoSrc->pbmi->bmiHeader.biHeight;
|
|
|
|
pDibInfoSrc->pbmi->bmiHeader.biWidth = 256;
|
|
pDibInfoSrc->pbmi->bmiHeader.biHeight = 1;
|
|
|
|
SetDIBits(hdc, hbm, 0, 1, pByteSrc, (PBITMAPINFO)pDibInfoSrc->pbmi,DIB_RGB_COLORS);
|
|
|
|
//
|
|
// retore bitmap width/height
|
|
//
|
|
pDibInfoSrc->pbmi->bmiHeader.biWidth = ulWidthSrc;
|
|
pDibInfoSrc->pbmi->bmiHeader.biHeight = ulHeightSrc;
|
|
|
|
pDibInfoDst->pbmi->bmiHeader.biWidth = ulWidthDst;
|
|
pDibInfoDst->pbmi->bmiHeader.biHeight = ulHeightDst;
|
|
|
|
//
|
|
// now pByte contains all the 256 color mappings, just need to split them up
|
|
//
|
|
j = 0;
|
|
for (i = 0; i < 128; i++)
|
|
{
|
|
xlate[j] = (pByte[i] & 0xF0) >> 4;
|
|
xlate[j++] = pByte[i] & 0x0F;
|
|
}
|
|
|
|
BYTE jDst;
|
|
|
|
while(cy--)
|
|
{
|
|
cxTemp = cx;
|
|
|
|
iDst = pDibInfoDst->rclDIB.left;
|
|
|
|
pjDstTemp = pjDst;
|
|
pjSrcTemp = pjSrc;
|
|
|
|
while (cxTemp--)
|
|
{
|
|
jSrc = *pjSrcTemp++;
|
|
|
|
if (iDst & 0x00000001)
|
|
{
|
|
if (jSrc != (BYTE)TransColor)
|
|
{
|
|
jDst |= (xlate[jSrc] & 0x0F);
|
|
}
|
|
else
|
|
{
|
|
jDst |= (*pjDstTemp & 0x0F);
|
|
}
|
|
|
|
*pjDstTemp = jDst;
|
|
jDst = 0;
|
|
|
|
pjDstTemp++;
|
|
}
|
|
else
|
|
{
|
|
if (jSrc != (BYTE)TransColor)
|
|
{
|
|
jDst |= (xlate[jSrc] & 0x0F)<< 4;
|
|
}
|
|
else
|
|
{
|
|
jDst |= (*pjDstTemp & 0x0F) << 4;
|
|
}
|
|
}
|
|
|
|
iDst++;
|
|
}
|
|
|
|
pjDst += pDibInfoDst->stride;
|
|
pjSrc += pDibInfoSrc->stride;
|
|
}
|
|
|
|
DeleteDC(hdc);
|
|
DeleteObject(hbm);
|
|
}
|
|
|
|
|
|
/******************************Public*Routine******************************\
|
|
* vTransparentIdentityCopy8
|
|
*
|
|
* Doing a transparent copy on two same size 8BPP format DIBs
|
|
*
|
|
* Returns:
|
|
* VOID.
|
|
*
|
|
* History:
|
|
* 09-Dec-1996 -by- Lingyun Wang [lingyunw]
|
|
* Wrote it.
|
|
\**************************************************************************/
|
|
VOID vTransparentIdentityCopy8 (
|
|
PDIBINFO pDibInfoDst,
|
|
PDIBINFO pDibInfoSrc,
|
|
ULONG TransColor)
|
|
{
|
|
PBYTE pjDst = (PBYTE)pDibInfoDst->pvBase + pDibInfoDst->stride*pDibInfoDst->rclDIB.top
|
|
+ pDibInfoDst->rclDIB.left;
|
|
PBYTE pjSrc = (PBYTE)pDibInfoSrc->pvBase + pDibInfoSrc->stride*pDibInfoSrc->rclDIB.top
|
|
+ pDibInfoSrc->rclDIB.left;
|
|
LONG cx = pDibInfoSrc->rclDIB.right - pDibInfoSrc->rclDIB.left;
|
|
LONG cy = pDibInfoSrc->rclDIB.bottom - pDibInfoSrc->rclDIB.top;
|
|
PBYTE pjDstTemp;
|
|
PBYTE pjSrcTemp;
|
|
|
|
LONG cxTemp;
|
|
|
|
while(cy--)
|
|
{
|
|
cxTemp = cx;
|
|
|
|
pjDstTemp = pjDst;
|
|
pjSrcTemp = pjSrc;
|
|
|
|
while (cxTemp--)
|
|
{
|
|
if (*pjSrcTemp != (BYTE)TransColor)
|
|
{
|
|
*pjDstTemp = *pjSrcTemp;
|
|
}
|
|
pjDstTemp++;
|
|
pjSrcTemp++;
|
|
}
|
|
|
|
pjDst += pDibInfoDst->stride;
|
|
pjSrc += pDibInfoSrc->stride;
|
|
}
|
|
}
|
|
|
|
/******************************Public*Routine******************************\
|
|
* vTransparentS8D8
|
|
*
|
|
* Doing a transparent copy on two same size 8BPP format DIBs
|
|
*
|
|
* Returns:
|
|
* VOID.
|
|
*
|
|
* History:
|
|
* 09-Dec-1996 -by- Lingyun Wang [lingyunw]
|
|
* Wrote it.
|
|
\**************************************************************************/
|
|
VOID vTransparentS8D8 (
|
|
PDIBINFO pDibInfoDst,
|
|
PDIBINFO pDibInfoSrc,
|
|
ULONG TransColor)
|
|
{
|
|
PBYTE pjDst = (PBYTE)pDibInfoDst->pvBase + pDibInfoDst->stride*pDibInfoDst->rclDIB.top
|
|
+ pDibInfoDst->rclDIB.left;
|
|
PBYTE pjSrc = (PBYTE)pDibInfoSrc->pvBase + pDibInfoSrc->stride*pDibInfoSrc->rclDIB.top
|
|
+ pDibInfoSrc->rclDIB.left;
|
|
LONG cx = pDibInfoDst->rclDIB.right - pDibInfoDst->rclDIB.left;
|
|
LONG cy = pDibInfoDst->rclDIB.bottom - pDibInfoDst->rclDIB.top;
|
|
PBYTE pjDstTemp;
|
|
PBYTE pjSrcTemp;
|
|
LONG cxTemp;
|
|
HDC hdc;
|
|
HBITMAP hbm;
|
|
ULONG ulWidthDst, ulHeightDst, ulWidthSrc, ulHeightSrc;
|
|
INT i, j;
|
|
BYTE pByteSrc[256];
|
|
PBYTE pxlate;
|
|
LONG iDst;
|
|
|
|
//
|
|
// build the color translation table
|
|
//
|
|
hdc = CreateCompatibleDC (pDibInfoDst->hdc);
|
|
|
|
//
|
|
// save the original width/height
|
|
//
|
|
ulWidthDst = pDibInfoDst->pbmi->bmiHeader.biWidth;
|
|
ulHeightDst = pDibInfoDst->pbmi->bmiHeader.biHeight;
|
|
|
|
pDibInfoDst->pbmi->bmiHeader.biWidth = 256;
|
|
pDibInfoDst->pbmi->bmiHeader.biHeight = 1;
|
|
|
|
//
|
|
// Create a 256X1 DIB
|
|
//
|
|
hbm = CreateDIBSection(hdc, (PBITMAPINFO)pDibInfoDst->pbmi, DIB_RGB_COLORS, (PVOID *)&pxlate, NULL, 0);
|
|
|
|
if (!hdc || !hbm)
|
|
{
|
|
//
|
|
// It's bad to fail and return here without a return value, but it's better
|
|
// than crashing later when accessing pxlate. At some point it would be nice
|
|
// to change the vTansparentxxxx functions to return success/failure.
|
|
//
|
|
if (hdc)
|
|
{
|
|
DeleteDC(hdc);
|
|
}
|
|
|
|
if (hbm)
|
|
{
|
|
DeleteObject(hbm);
|
|
}
|
|
|
|
pDibInfoDst->pbmi->bmiHeader.biWidth = ulWidthDst;
|
|
pDibInfoDst->pbmi->bmiHeader.biHeight = ulHeightDst;
|
|
WARNING ("failed to create hdc or hbm\n");
|
|
return;
|
|
}
|
|
|
|
SelectObject (hdc, hbm);
|
|
|
|
for (i = 0; i < 256; i++)
|
|
{
|
|
pByteSrc[i] = (unsigned char)i;
|
|
}
|
|
|
|
ulWidthSrc = pDibInfoSrc->pbmi->bmiHeader.biWidth;
|
|
ulHeightSrc = pDibInfoSrc->pbmi->bmiHeader.biHeight;
|
|
|
|
pDibInfoSrc->pbmi->bmiHeader.biWidth = 256;
|
|
pDibInfoSrc->pbmi->bmiHeader.biHeight = 1;
|
|
|
|
SetDIBits(hdc, hbm, 0, 1, pByteSrc, (PBITMAPINFO)pDibInfoSrc->pbmi,DIB_RGB_COLORS);
|
|
|
|
//
|
|
// retore bitmap width/height
|
|
//
|
|
pDibInfoSrc->pbmi->bmiHeader.biWidth = ulWidthSrc;
|
|
pDibInfoSrc->pbmi->bmiHeader.biHeight = ulHeightSrc;
|
|
|
|
pDibInfoDst->pbmi->bmiHeader.biWidth = ulWidthDst;
|
|
pDibInfoDst->pbmi->bmiHeader.biHeight = ulHeightDst;
|
|
|
|
|
|
while(cy--)
|
|
{
|
|
cxTemp = cx;
|
|
|
|
pjDstTemp = pjDst;
|
|
pjSrcTemp = pjSrc;
|
|
|
|
while (cxTemp--)
|
|
{
|
|
if (*pjSrcTemp != (BYTE)TransColor)
|
|
{
|
|
*pjDstTemp = pxlate[*pjSrcTemp];
|
|
}
|
|
|
|
pjDstTemp++;
|
|
pjSrcTemp++;
|
|
}
|
|
|
|
pjDst += pDibInfoDst->stride;
|
|
pjSrc += pDibInfoSrc->stride;
|
|
}
|
|
|
|
DeleteObject(hbm);
|
|
DeleteDC(hdc);
|
|
}
|
|
|
|
|
|
|
|
#if 0
|
|
/******************************Public*Routine******************************\
|
|
* vTransparentIdentityCopy16
|
|
*
|
|
* Doing a transparent copy on two same size 16BPP format DIBs
|
|
*
|
|
* Returns:
|
|
* VOID.
|
|
*
|
|
* History:
|
|
* 09-Dec-1996 -by- Lingyun Wang [lingyunw]
|
|
* Wrote it.
|
|
\**************************************************************************/
|
|
VOID vTransparentIdentityCopy16 (
|
|
PDIBINFO pDibInfoDst,
|
|
PDIBINFO pDibInfoSrc,
|
|
ULONG TransColor)
|
|
{
|
|
PUSHORT pusDst = (PUSHORT)((PBYTE)pDibInfoDst->pvBase + pDibInfoDst->rclDIB.top*pDibInfoDst->stride)
|
|
+ pDibInfoDst->rclDIB.left;
|
|
PUSHORT pusSrc = (PUSHORT)((PBYTE)pDibInfoSrc->pvBase + pDibInfoSrc->rclDIB.top*pDibInfoDst->stride)
|
|
+ pDibInfoSrc->rclDIB.left;
|
|
LONG cx = pDibInfoDst->rclDIB.right - pDibInfoDst->rclDIB.left;
|
|
LONG cy = pDibInfoDst->rclDIB.bottom - pDibInfoDst->rclDIB.top;
|
|
PUSHORT pusDstTemp;
|
|
PUSHORT pusSrcTemp;
|
|
LONG cxTemp;
|
|
|
|
while(cy--)
|
|
{
|
|
cxTemp = cx;
|
|
|
|
pusDstTemp = pusDst;
|
|
pusSrcTemp = pusSrc;
|
|
|
|
while (cxTemp--)
|
|
{
|
|
if (*pusSrcTemp != (USHORT)TransColor)
|
|
{
|
|
*pusDstTemp = *pusSrcTemp;
|
|
}
|
|
|
|
pusDstTemp++;
|
|
pusSrcTemp++;
|
|
}
|
|
|
|
pusDst = (PUSHORT)((PBYTE)pusDst + pDibInfoDst->stride);
|
|
pusSrc = (PUSHORT)((PBYTE)pusSrc + pDibInfoSrc->stride);
|
|
}
|
|
}
|
|
|
|
/******************************Public*Routine******************************\
|
|
* vTransparentIdentityCopy24
|
|
*
|
|
* Doing a transparent copy on two same size 8BPP format DIBs
|
|
*
|
|
* Returns:
|
|
* VOID.
|
|
*
|
|
* History:
|
|
* 09-Dec-1996 -by- Lingyun Wang [lingyunw]
|
|
* Wrote it.
|
|
\**************************************************************************/
|
|
VOID vTransparentIdentityCopy24 (
|
|
PDIBINFO pDibInfoDst,
|
|
PDIBINFO pDibInfoSrc,
|
|
ULONG TransColor)
|
|
{
|
|
PBYTE pjDst = (PBYTE)pDibInfoDst->pvBase + pDibInfoDst->stride*pDibInfoDst->rclDIB.top
|
|
+ pDibInfoDst->rclDIB.left*3;
|
|
PBYTE pjSrc = (PBYTE)pDibInfoSrc->pvBase + pDibInfoSrc->stride*pDibInfoSrc->rclDIB.top
|
|
+ pDibInfoSrc->rclDIB.left*3;
|
|
LONG cx = pDibInfoDst->rclDIB.right - pDibInfoDst->rclDIB.left;
|
|
LONG cy = pDibInfoDst->rclDIB.bottom - pDibInfoDst->rclDIB.top;
|
|
PBYTE pjDstTemp;
|
|
PBYTE pjSrcTemp;
|
|
ULONG ulTemp;
|
|
LONG cxTemp;
|
|
|
|
while(cy--)
|
|
{
|
|
cxTemp = cx;
|
|
|
|
pjDstTemp = pjDst;
|
|
pjSrcTemp = pjSrc;
|
|
|
|
while (cxTemp--)
|
|
{
|
|
ulTemp = (ULONG) *(pjSrcTemp + 2);
|
|
ulTemp = ulTemp << 8;
|
|
ulTemp |= (ULONG) *(pjSrcTemp + 1);
|
|
ulTemp = ulTemp << 8;
|
|
ulTemp |= (ULONG) *pjSrcTemp;
|
|
|
|
if (ulTemp != TransColor)
|
|
{
|
|
*(pjDstTemp++) = (BYTE) ulTemp;
|
|
*(pjDstTemp++) = (BYTE) (ulTemp >> 8);
|
|
*(pjDstTemp++) = (BYTE) (ulTemp >> 16);
|
|
}
|
|
else
|
|
{
|
|
pjDstTemp += 3;
|
|
}
|
|
|
|
pjSrcTemp += 3;
|
|
}
|
|
|
|
pjDst += pDibInfoDst->stride;
|
|
pjSrc += pDibInfoSrc->stride;
|
|
}
|
|
}
|
|
#endif
|
|
|
|
/******************************Public*Routine******************************\
|
|
* vTransparentIdentityCopy32
|
|
*
|
|
* Doing a transparent copy on two same size 32BPP format DIBs
|
|
*
|
|
* Returns:
|
|
* VOID.
|
|
*
|
|
* History:
|
|
* 09-Dec-1996 -by- Lingyun Wang [lingyunw]
|
|
* Wrote it.
|
|
\**************************************************************************/
|
|
VOID vTransparentIdentityCopy32 (
|
|
PDIBINFO pDibInfoDst,
|
|
PDIBINFO pDibInfoSrc,
|
|
ULONG TransColor)
|
|
{
|
|
PULONG pulDst = (PULONG)((PBYTE)pDibInfoDst->pvBase + pDibInfoDst->stride*pDibInfoDst->rclDIB.top)
|
|
+ pDibInfoDst->rclDIB.left;
|
|
PULONG pulSrc = (PULONG)((PBYTE)pDibInfoSrc->pvBase + pDibInfoSrc->stride*pDibInfoSrc->rclDIB.top)
|
|
+ pDibInfoSrc->rclDIB.left;
|
|
LONG cx = pDibInfoDst->rclDIB.right - pDibInfoDst->rclDIB.left;
|
|
LONG cy = pDibInfoDst->rclDIB.bottom - pDibInfoDst->rclDIB.top;
|
|
PULONG pulDstTemp;
|
|
PULONG pulSrcTemp;
|
|
LONG cxTemp;
|
|
|
|
while(cy--)
|
|
{
|
|
cxTemp = cx;
|
|
|
|
pulDstTemp = pulDst;
|
|
pulSrcTemp = pulSrc;
|
|
|
|
while (cxTemp--)
|
|
{
|
|
// mask off highest byte -- workaround Memphis problem
|
|
if ((*pulSrcTemp & 0x00FFFFFF) != TransColor)
|
|
{
|
|
*pulDstTemp = *pulSrcTemp;
|
|
}
|
|
|
|
pulDstTemp++;
|
|
pulSrcTemp++;
|
|
}
|
|
|
|
pulDst = (PULONG)((PBYTE)pulDst + pDibInfoDst->stride);
|
|
pulSrc = (PULONG)((PBYTE)pulSrc + pDibInfoSrc->stride);
|
|
}
|
|
}
|
|
|
|
|
|
/******************************Public*Routine******************************\
|
|
* vTransparentS16D32
|
|
*
|
|
* Doing a transparent copy from 16BPP to 32BPP
|
|
*
|
|
* Returns:
|
|
* VOID.
|
|
*
|
|
* History:
|
|
* 22-Aug-1997 -by- Ori Gershony [orig]
|
|
* Wrote it.
|
|
\**************************************************************************/
|
|
VOID vTransparentS16D32 (
|
|
PDIBINFO pDibInfoDst,
|
|
PDIBINFO pDibInfoSrc,
|
|
ULONG TransColor)
|
|
{
|
|
PBYTE pjDst = (PBYTE)pDibInfoDst->pvBase + pDibInfoDst->stride*pDibInfoDst->rclDIB.top
|
|
+ pDibInfoDst->rclDIB.left*4;
|
|
PBYTE pjSrc = (PBYTE)pDibInfoSrc->pvBase + pDibInfoSrc->stride*pDibInfoSrc->rclDIB.top
|
|
+ pDibInfoSrc->rclDIB.left*2;
|
|
LONG cx = pDibInfoDst->rclDIB.right - pDibInfoDst->rclDIB.left;
|
|
LONG cy = pDibInfoDst->rclDIB.bottom - pDibInfoDst->rclDIB.top;
|
|
PBYTE pjDstTemp;
|
|
PUSHORT pjSrcTemp;
|
|
USHORT jSrc;
|
|
LONG cxTemp;
|
|
BYTE rgbBlue, rgbGreen, rgbRed;
|
|
|
|
while(cy--)
|
|
{
|
|
cxTemp = cx;
|
|
|
|
pjDstTemp = pjDst;
|
|
pjSrcTemp = (PUSHORT) pjSrc;
|
|
|
|
while (cxTemp--)
|
|
{
|
|
jSrc = *pjSrcTemp++;
|
|
|
|
//
|
|
// If 5-5-5 we should mask out the 16th bit so that we'd recognize the transparent
|
|
// color
|
|
//
|
|
if ((!(pDibInfoSrc->pbmi->bmiHeader.biCompression == BI_BITFIELDS)) ||
|
|
((*(DWORD *)&pDibInfoSrc->pbmi->bmiColors[1] == 0x03E0)))
|
|
{
|
|
jSrc &= 0x7fff;
|
|
TransColor &= 0x7fff;
|
|
}
|
|
|
|
if (jSrc != (USHORT)TransColor)
|
|
{
|
|
|
|
//
|
|
// figure out 5-5-5 or 5-6-5
|
|
//
|
|
if (pDibInfoSrc->pbmi->bmiHeader.biCompression == BI_BITFIELDS)
|
|
{
|
|
//5-5-5
|
|
if (*(DWORD *)&pDibInfoSrc->pbmi->bmiColors[1] == 0x03E0)
|
|
{
|
|
rgbBlue = (jSrc & 0x1f) << 3;
|
|
rgbGreen = ((jSrc >> 5) & 0x1f) << 3;
|
|
rgbRed = ((jSrc >> 10) & 0x1f) << 3;
|
|
}
|
|
// 5-6-5
|
|
else if (*(DWORD *)&pDibInfoDst->pbmi->bmiColors[1] == 0x07E0)
|
|
{
|
|
rgbBlue = (jSrc & 0x1f) << 3;
|
|
rgbGreen = ((jSrc >> 5) & 0x3f) << 2;
|
|
rgbRed = ((jSrc >> 11) & 0x1f) << 3;
|
|
}
|
|
else
|
|
{
|
|
WARNING ("unsupported BITFIELDS\n");
|
|
}
|
|
}
|
|
else
|
|
{
|
|
rgbBlue = (jSrc & 0x1f) << 3;
|
|
rgbGreen = ((jSrc >> 5) & 0x1f) << 3;
|
|
rgbRed = ((jSrc >> 10) & 0x1f) << 3;
|
|
}
|
|
|
|
*(PULONG)pjDstTemp = (DWORD) (rgbBlue << 0 | (WORD)rgbGreen << 8 | (DWORD)rgbRed << 16);
|
|
}
|
|
pjDstTemp += 4;
|
|
}
|
|
|
|
pjDst += pDibInfoDst->stride;
|
|
pjSrc += pDibInfoSrc->stride;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
/******************************Public*Routine******************************\
|
|
* vTransparentS24D32
|
|
*
|
|
* Doing a transparent copy from 24BPP to 32BPP
|
|
*
|
|
* Returns:
|
|
* VOID.
|
|
*
|
|
* History:
|
|
* 22-Aug-1997 -by- Ori Gershony [orig]
|
|
* Wrote it.
|
|
\**************************************************************************/
|
|
VOID vTransparentS24D32 (
|
|
PDIBINFO pDibInfoDst,
|
|
PDIBINFO pDibInfoSrc,
|
|
ULONG TransColor)
|
|
{
|
|
PBYTE pjDst = (PBYTE)pDibInfoDst->pvBase + pDibInfoDst->stride*pDibInfoDst->rclDIB.top
|
|
+ pDibInfoDst->rclDIB.left*4;
|
|
PBYTE pjSrc = (PBYTE)pDibInfoSrc->pvBase + pDibInfoSrc->stride*pDibInfoSrc->rclDIB.top
|
|
+ pDibInfoSrc->rclDIB.left*3;
|
|
LONG cx = pDibInfoDst->rclDIB.right - pDibInfoDst->rclDIB.left;
|
|
LONG cy = pDibInfoDst->rclDIB.bottom - pDibInfoDst->rclDIB.top;
|
|
PBYTE pjDstTemp;
|
|
PBYTE pjSrcTemp;
|
|
ULONG jSrc;
|
|
LONG cxTemp;
|
|
BYTE rgbBlue, rgbGreen, rgbRed;
|
|
|
|
while(cy--)
|
|
{
|
|
cxTemp = cx;
|
|
|
|
pjDstTemp = pjDst;
|
|
pjSrcTemp = pjSrc;
|
|
|
|
while (cxTemp--)
|
|
{
|
|
jSrc = (ULONG) *(pjSrcTemp+2);
|
|
jSrc <<= 8;
|
|
jSrc |= (ULONG) *(pjSrcTemp+1);
|
|
jSrc <<= 8;
|
|
jSrc |= (ULONG) *(pjSrcTemp);
|
|
pjSrcTemp +=3;
|
|
|
|
if (jSrc != TransColor)
|
|
{
|
|
*(PULONG)pjDstTemp = jSrc;
|
|
}
|
|
pjDstTemp += 4;
|
|
}
|
|
|
|
pjDst += pDibInfoDst->stride;
|
|
pjSrc += pDibInfoSrc->stride;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
/******************************Public*Routine******************************\
|
|
* vTransparentS32D32
|
|
*
|
|
* Doing a transparent copy from 32BPP to 32BPP
|
|
*
|
|
* Returns:
|
|
* VOID.
|
|
*
|
|
* History:
|
|
* 22-Aug-1997 -by- Ori Gershony [orig]
|
|
* Wrote it.
|
|
\**************************************************************************/
|
|
|
|
#define vTransparentS32D32 vTransparentIdentityCopy32
|
|
|
|
|
|
|
|
|
|
/******************************Public*Routine******************************\
|
|
* MapTransparentColor
|
|
*
|
|
* Getting the correct transparent color mapped to the specified DIB format
|
|
* by creating a solid brush on the colorref, then PatBlt to a 1X1 DIB, the
|
|
* resulting pixel is the mapped transparent color
|
|
*
|
|
* Returns:
|
|
* VOID.
|
|
*
|
|
* History:
|
|
* 09-Dec-1996 -by- Lingyun Wang [lingyunw]
|
|
* Wrote it.
|
|
\**************************************************************************/
|
|
DWORD MapTransparentColor(
|
|
PDIBINFO pDibInfo,
|
|
COLORREF Color
|
|
)
|
|
{
|
|
HBRUSH hbr, hbrDefault;
|
|
HBITMAP hbm, hbmDefault;
|
|
HDC hdcTemp;
|
|
UINT iUsage;
|
|
PVOID pvBits = NULL;
|
|
DWORD trancolor;
|
|
ULONG ulWidth, ulHeight;
|
|
|
|
hdcTemp = CreateCompatibleDC(pDibInfo->hdc);
|
|
|
|
hbr = CreateSolidBrush (Color);
|
|
|
|
//
|
|
// save the original width/height
|
|
//
|
|
ulWidth = pDibInfo->pbmi->bmiHeader.biWidth;
|
|
ulHeight = pDibInfo->pbmi->bmiHeader.biHeight;
|
|
|
|
pDibInfo->pbmi->bmiHeader.biWidth = 1;
|
|
pDibInfo->pbmi->bmiHeader.biHeight = 1;
|
|
|
|
//
|
|
// Create a 1X1 DIB
|
|
//
|
|
hbm = CreateDIBSection(hdcTemp, (PBITMAPINFO)pDibInfo->pbmi, DIB_RGB_COLORS, &pvBits, NULL, 0);
|
|
|
|
if (hbm && hbr)
|
|
{
|
|
hbmDefault = (HBITMAP)SelectObject (hdcTemp, hbm);
|
|
hbrDefault = (HBRUSH)SelectObject (hdcTemp, hbr);
|
|
|
|
PatBlt (hdcTemp, 0, 0, 1, 1, PATCOPY);
|
|
|
|
SelectObject (hdcTemp, hbrDefault);
|
|
SelectObject (hdcTemp, hbmDefault);
|
|
}
|
|
|
|
if (pvBits)
|
|
{
|
|
switch (pDibInfo->pbmi->bmiHeader.biBitCount)
|
|
{
|
|
case 1:
|
|
trancolor = *(BYTE *)pvBits;
|
|
trancolor = (DWORD)(((BYTE)trancolor) & 0x80) >>7;
|
|
break;
|
|
|
|
case 4:
|
|
trancolor = *(BYTE *)pvBits;
|
|
trancolor = (DWORD)(((BYTE)trancolor) & 0xF0) >>4;
|
|
break;
|
|
case 8:
|
|
trancolor = (DWORD)(*(BYTE *)pvBits);
|
|
trancolor &= 0x000000FF;
|
|
break;
|
|
case 16:
|
|
trancolor = (DWORD)(*(USHORT *)pvBits);
|
|
trancolor &= 0x0000FFFF;
|
|
break;
|
|
case 24:
|
|
trancolor = *(DWORD *)pvBits;
|
|
trancolor &= 0x00FFFFFF;
|
|
break;
|
|
case 32:
|
|
trancolor = *(DWORD *)pvBits;
|
|
trancolor &= 0x00FFFFFF;
|
|
break;
|
|
}
|
|
}
|
|
|
|
pDibInfo->pbmi->bmiHeader.biWidth = ulWidth;
|
|
pDibInfo->pbmi->bmiHeader.biHeight = ulHeight;
|
|
|
|
//
|
|
// cleanup
|
|
//
|
|
DeleteObject (hbm);
|
|
DeleteObject (hbr);
|
|
DeleteDC(hdcTemp);
|
|
|
|
return (trancolor);
|
|
}
|
|
|
|
/******************************Public*Routine******************************\
|
|
* DIBMapTransparentColor
|
|
*
|
|
* Getting the correct transparent color mapped to the specified DIB format
|
|
* This is only for DIB_PAL_COLORS passed into transparentDIBits
|
|
*
|
|
* Returns:
|
|
* VOID.
|
|
*
|
|
* History:
|
|
* 09-Dec-1996 -by- Lingyun Wang [lingyunw]
|
|
* Wrote it.
|
|
\**************************************************************************/
|
|
DWORD DIBMapTransparentColor(
|
|
PDIBINFO pDibInfoDst,
|
|
PDIBINFO pDibInfoSrc,
|
|
COLORREF Color
|
|
)
|
|
{
|
|
HBITMAP hbm, hbmDefault;
|
|
HDC hdcTemp;
|
|
UINT iUsage;
|
|
PVOID pvBits;
|
|
DWORD trancolor;
|
|
ULONG ulWidth, ulHeight;
|
|
|
|
hdcTemp = CreateCompatibleDC(pDibInfoDst->hdc);
|
|
|
|
//
|
|
// save the original width/height
|
|
//
|
|
ulWidth = pDibInfoDst->pbmi->bmiHeader.biWidth;
|
|
ulHeight = pDibInfoDst->pbmi->bmiHeader.biHeight;
|
|
|
|
pDibInfoDst->pbmi->bmiHeader.biWidth = 1;
|
|
pDibInfoDst->pbmi->bmiHeader.biHeight = 1;
|
|
|
|
//
|
|
// Create a 1X1 DIB
|
|
//
|
|
hbm = CreateDIBSection(hdcTemp, (PBITMAPINFO)pDibInfoDst->pbmi, DIB_RGB_COLORS, &pvBits, NULL, 0);
|
|
|
|
if (hbm)
|
|
{
|
|
hbmDefault = (HBITMAP)SelectObject (hdcTemp, hbm);
|
|
|
|
StretchDIBits (hdcTemp,
|
|
0,
|
|
0,
|
|
1,
|
|
1,
|
|
0,
|
|
0,
|
|
1,
|
|
1,
|
|
&Color,
|
|
pDibInfoSrc->pbmi,
|
|
pDibInfoSrc->iUsage,
|
|
SRCCOPY);
|
|
|
|
SelectObject (hdcTemp, hbmDefault);
|
|
}
|
|
|
|
if (pvBits)
|
|
{
|
|
switch (pDibInfoDst->pbmi->bmiHeader.biBitCount)
|
|
{
|
|
case 4:
|
|
trancolor = *(BYTE *)pvBits;
|
|
trancolor = (DWORD)(((BYTE)trancolor) & 0xF0) >>4;
|
|
break;
|
|
case 8:
|
|
trancolor = (DWORD)(*(BYTE *)pvBits);
|
|
trancolor &= 0x000000FF;
|
|
break;
|
|
case 16:
|
|
trancolor = (DWORD)(*(USHORT *)pvBits);
|
|
trancolor &= 0x0000FFFF;
|
|
break;
|
|
case 24:
|
|
trancolor = *(DWORD *)pvBits;
|
|
trancolor &= 0x00FFFFFF;
|
|
break;
|
|
case 32:
|
|
trancolor = *(DWORD *)pvBits;
|
|
trancolor &= 0x00FFFFFF;
|
|
break;
|
|
}
|
|
}
|
|
|
|
pDibInfoDst->pbmi->bmiHeader.biWidth = ulWidth;
|
|
pDibInfoDst->pbmi->bmiHeader.biHeight = ulHeight;
|
|
|
|
//
|
|
// cleanup
|
|
//
|
|
DeleteObject (hbm);
|
|
DeleteDC(hdcTemp);
|
|
|
|
return (trancolor);
|
|
}
|
|
|
|
|
|
/******************************Public*Routine******************************\
|
|
* vTransparentMapCopy
|
|
*
|
|
* Map the Dest surface to 32bpp and does transparent on to that
|
|
*
|
|
* Returns:
|
|
* VOID.
|
|
*
|
|
* History:
|
|
* 09-Dec-1996 -by- Lingyun Wang [lingyunw]
|
|
* Wrote it.
|
|
\**************************************************************************/
|
|
VOID vTransparentMapCopy (
|
|
PDIBINFO pDibInfoDst,
|
|
PDIBINFO pDibInfoSrc,
|
|
ULONG TransColor)
|
|
{
|
|
HDC hdc = pDibInfoSrc->hdc;
|
|
ULONG cxDst = pDibInfoDst->rclDIB.right - pDibInfoDst->rclDIB.left;
|
|
ULONG cyDst = pDibInfoDst->rclDIB.bottom - pDibInfoDst->rclDIB.top;
|
|
HBITMAP hbm;
|
|
PVOID pBits;
|
|
ULONG cBytes = sizeof(BITMAPINFO) + sizeof(RGBQUAD) * 255;
|
|
PBITMAPINFO pbmi;
|
|
PVOID p = LOCALALLOC(cBytes);
|
|
|
|
if (!p)
|
|
{
|
|
WARNING("MapCopy fail to alloc mem\n");
|
|
return ;
|
|
}
|
|
|
|
ZeroMemory (p,cBytes);
|
|
|
|
pbmi = (PBITMAPINFO)p;
|
|
|
|
vCopyBitmapInfo (pbmi, pDibInfoDst->pbmi);
|
|
|
|
hdc = CreateCompatibleDC (hdc);
|
|
|
|
pbmi->bmiHeader.biBitCount = 32;
|
|
pbmi->bmiHeader.biCompression = BI_RGB;
|
|
|
|
// create a dib using 32 format
|
|
if (!(hbm = CreateCompatibleDIB (hdc, cxDst, cyDst, &pBits, pbmi)))
|
|
{
|
|
WARNING("Error in msimg32!vTransparentMapCopy: call to CreateCompatibleDIB failed\n");
|
|
|
|
if (hdc)
|
|
{
|
|
DeleteDC(hdc);
|
|
}
|
|
|
|
if (p)
|
|
{
|
|
LOCALFREE(p);
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
SetDIBits (hdc, hbm, 0, cyDst, pDibInfoDst->pvBits, pDibInfoDst->pbmi, DIB_RGB_COLORS);
|
|
|
|
vCopyBitmapInfo (pDibInfoDst->pbmi,pbmi);
|
|
|
|
GetCompatibleDIBInfo (hbm, &pDibInfoDst->pvBase, &pDibInfoDst->stride);
|
|
|
|
PVOID pvBitsOrig = pDibInfoDst->pvBits;
|
|
pDibInfoDst->pvBits = pBits;
|
|
|
|
pDibInfoDst->rclDIB.left = 0;
|
|
pDibInfoDst->rclDIB.right = cxDst;
|
|
pDibInfoDst->rclDIB.top = 0;
|
|
pDibInfoDst->rclDIB.bottom = cyDst;
|
|
|
|
switch(pDibInfoSrc->pbmi->bmiHeader.biBitCount)
|
|
{
|
|
case 4:
|
|
vTransparentS4D32 (pDibInfoDst, pDibInfoSrc, TransColor);
|
|
break;
|
|
|
|
case 8:
|
|
vTransparentS8D32 (pDibInfoDst, pDibInfoSrc, TransColor);
|
|
break;
|
|
|
|
case 16:
|
|
vTransparentS16D32 (pDibInfoDst, pDibInfoSrc, TransColor);
|
|
break;
|
|
|
|
case 24:
|
|
vTransparentS24D32 (pDibInfoDst, pDibInfoSrc, TransColor);
|
|
break;
|
|
|
|
case 32:
|
|
vTransparentS32D32 (pDibInfoDst, pDibInfoSrc, TransColor);
|
|
break;
|
|
}
|
|
|
|
//
|
|
// If destination is a memory dc, then now is the time to set the bits at
|
|
// the destination format.
|
|
//
|
|
HBITMAP hbmDest;
|
|
if ((GetObjectType(pDibInfoDst->hdc) == OBJ_MEMDC) &&
|
|
((hbmDest = (HBITMAP)GetCurrentObject(pDibInfoDst->hdc, OBJ_BITMAP)) != NULL))
|
|
{
|
|
SetDIBits (pDibInfoDst->hdc, hbmDest, 0, cyDst, pBits, pbmi, DIB_RGB_COLORS);
|
|
}
|
|
|
|
if (pDibInfoDst->hDIB)
|
|
{
|
|
//
|
|
// Replace the old hDIB with the one allocated above. Make sure
|
|
// the old one doesn't get leaked. pDibInfoDst->hDIB will get
|
|
// cleaned up in vCleanupDIBINFO.
|
|
//
|
|
DeleteObject(pDibInfoDst->hDIB);
|
|
pDibInfoDst->hDIB = hbm;
|
|
}
|
|
else
|
|
{
|
|
//
|
|
// This is the case where the destination was a dibsection with
|
|
// no stretching. The correct data was already written in the
|
|
// above call to SetDIBits.
|
|
//
|
|
DeleteObject(hbm);
|
|
pDibInfoDst->pvBits = pvBitsOrig;
|
|
}
|
|
|
|
if (p)
|
|
{
|
|
LOCALFREE (p);
|
|
}
|
|
|
|
if (hdc)
|
|
{
|
|
DeleteDC(hdc);
|
|
}
|
|
}
|
|
|
|
/******************************Public*Routine******************************\
|
|
* ReadScanLine
|
|
* read the scanline until it hits a transparent color pixel
|
|
*
|
|
* History:
|
|
* 26-Nov-1996 -by- Lingyun Wang [lingyunw]
|
|
* Wrote it.
|
|
\**************************************************************************/
|
|
ULONG ReadScanLine(
|
|
PBYTE pjSrc,
|
|
ULONG xStart,
|
|
ULONG xEnd,
|
|
ULONG iFormat,
|
|
ULONG TransparentColor,
|
|
PDIBINFO pDibInfoSrc)
|
|
{
|
|
ULONG cx = xEnd-xStart;
|
|
ULONG Shift = (iFormat - 3 > 0) ? iFormat : 1;
|
|
ULONG iPos;
|
|
ULONG ulSrc;
|
|
BOOL bStop = FALSE;
|
|
|
|
pjSrc = StartPixel (pjSrc, xStart, iFormat);
|
|
|
|
//
|
|
// performance can be improved by breaking this routine into many
|
|
// dealing with different format so that we can save two comparsions
|
|
// for each pixel operation. But working set size will be large
|
|
//
|
|
iPos = xStart;
|
|
|
|
//
|
|
// read one pixel at a time and compare it to the transparent color
|
|
// if it matches the transparent color, come out
|
|
//
|
|
BYTE jSrc = *pjSrc << (iPos & 0x7);
|
|
|
|
while ((iPos < xEnd) && !bStop)
|
|
{
|
|
//
|
|
// get a pixel from source and compare is to the transparent color
|
|
//
|
|
switch (iFormat)
|
|
{
|
|
case 1:
|
|
ulSrc = (ULONG) (jSrc & 0x80);
|
|
ulSrc >>= 7;
|
|
jSrc <<= 1;
|
|
|
|
if (!(iPos & 0x00000007) )
|
|
pjSrc++;
|
|
break;
|
|
|
|
case 4:
|
|
if (iPos & 0x00000001)
|
|
{
|
|
ulSrc = *pjSrc & 0x0F;
|
|
pjSrc++;
|
|
}
|
|
else
|
|
{
|
|
ulSrc = (*pjSrc & 0xF0)>>4;
|
|
}
|
|
break;
|
|
|
|
case 8:
|
|
ulSrc = (ULONG) *pjSrc;
|
|
pjSrc++;
|
|
break;
|
|
|
|
case 16:
|
|
ulSrc = (ULONG) *((PUSHORT)pjSrc);
|
|
|
|
//
|
|
// If 5-5-5 we should mask out the 16th bit so that we'd recognize the transparent
|
|
// color
|
|
//
|
|
if ((!(pDibInfoSrc->pbmi->bmiHeader.biCompression == BI_BITFIELDS)) ||
|
|
((*(DWORD *)&pDibInfoSrc->pbmi->bmiColors[1] == 0x03E0)))
|
|
{
|
|
ulSrc &= 0x7fff;
|
|
}
|
|
pjSrc += 2;
|
|
break;
|
|
|
|
case 24:
|
|
ulSrc = *(pjSrc + 2);
|
|
ulSrc = ulSrc << 8;
|
|
ulSrc |= (ULONG) *(pjSrc + 1);
|
|
ulSrc = ulSrc << 8;
|
|
ulSrc |= (ULONG) *pjSrc;
|
|
pjSrc += 3;
|
|
break;
|
|
|
|
case 32:
|
|
ulSrc = *(PULONG)(pjSrc);
|
|
ulSrc &= 0x00ffffff; // Ignore upper byte since it doesn't contain color information
|
|
pjSrc +=4;
|
|
break;
|
|
|
|
default:
|
|
WARNING ("vTransparentScan -- bad iFormatSrc\n");
|
|
return(0);
|
|
|
|
} /*switch*/
|
|
|
|
if (ulSrc == TransparentColor)
|
|
bStop = TRUE;
|
|
|
|
iPos++;
|
|
}
|
|
|
|
return (iPos);
|
|
}
|
|
|
|
/******************************Public*Routine******************************\
|
|
* SkipScanLine
|
|
* read the scanline until it hits a non-transparent color pixel
|
|
*
|
|
* History:
|
|
* 26-Nov-1996 -by- Lingyun Wang [lingyunw]
|
|
* Wrote it.
|
|
\**************************************************************************/
|
|
ULONG SkipScanLine(
|
|
PBYTE pjSrc,
|
|
ULONG xStart,
|
|
ULONG xEnd,
|
|
ULONG iFormat,
|
|
ULONG TransparentColor,
|
|
PDIBINFO pDibInfoSrc)
|
|
{
|
|
ULONG Shift = (iFormat - 3 > 0) ? iFormat : 1;
|
|
ULONG iPos = xStart;
|
|
ULONG ulSrc;
|
|
BOOL bStop = FALSE;
|
|
|
|
pjSrc = StartPixel (pjSrc, xStart, iFormat);
|
|
|
|
//
|
|
// performance can be improved by breaking this routine into many
|
|
// dealing with different format so that we can save two comparsions
|
|
// for each pixel operation. But working set size will be large
|
|
//
|
|
|
|
//
|
|
// read one pixel at a time and compare it to the transparent color
|
|
// if it matches the transparent color, come out
|
|
//
|
|
BYTE jSrc = *pjSrc << (iPos & 0x7);
|
|
|
|
while ((iPos < xEnd) && !bStop)
|
|
{
|
|
//
|
|
// get a pixel from source and compare is to the transparent color
|
|
//
|
|
switch (iFormat)
|
|
{
|
|
case 1:
|
|
ulSrc = *pjSrc & 0x00000001;
|
|
ulSrc = (ULONG) (jSrc & 0x80);
|
|
ulSrc >>= 7;
|
|
jSrc <<= 1;
|
|
|
|
if (!(iPos & 0x00000007) )
|
|
pjSrc++;
|
|
break;
|
|
|
|
case 4:
|
|
if (iPos & 0x00000001)
|
|
{
|
|
ulSrc = *pjSrc & 0x0F;
|
|
pjSrc++;
|
|
}
|
|
else
|
|
{
|
|
ulSrc = (*pjSrc & 0xF0)>>4;
|
|
}
|
|
break;
|
|
|
|
case 8:
|
|
ulSrc = (ULONG) *pjSrc;
|
|
pjSrc++;
|
|
break;
|
|
|
|
case 16:
|
|
|
|
ulSrc = (ULONG) *((PUSHORT)pjSrc);
|
|
//
|
|
// If 5-5-5 we should mask out the 16th bit so that we'd recognize the transparent
|
|
// color
|
|
//
|
|
if ((!(pDibInfoSrc->pbmi->bmiHeader.biCompression == BI_BITFIELDS)) ||
|
|
((*(DWORD *)&pDibInfoSrc->pbmi->bmiColors[1] == 0x03E0)))
|
|
{
|
|
ulSrc &= 0x7fff;
|
|
}
|
|
pjSrc += 2;
|
|
break;
|
|
|
|
case 24:
|
|
ulSrc = *(pjSrc + 2);
|
|
ulSrc = ulSrc << 8;
|
|
ulSrc |= (ULONG) *(pjSrc + 1);
|
|
ulSrc = ulSrc << 8;
|
|
ulSrc |= (ULONG) *pjSrc;
|
|
pjSrc += 3;
|
|
break;
|
|
|
|
case 32:
|
|
ulSrc = *(PULONG)(pjSrc);
|
|
ulSrc &= 0x00ffffff; // Ignore upper two bytes since they don't contain color information
|
|
pjSrc +=4;
|
|
break;
|
|
|
|
default:
|
|
WARNING ("vTransparentScan -- bad iFormatSrc\n");
|
|
return (0);
|
|
|
|
} /*switch*/
|
|
|
|
if (ulSrc != TransparentColor)
|
|
bStop = TRUE;
|
|
|
|
iPos++; // move to the next pixel
|
|
}
|
|
|
|
return (iPos);
|
|
}
|
|
|
|
/******************************Public*Routine******************************\
|
|
* VOID vTransparentCopyScan
|
|
*
|
|
* Read a scanline at a time and send the non-transparent pixel scans over
|
|
*
|
|
* History:
|
|
* 2-Dec-1996 -by- Lingyun Wang [lingyunw]
|
|
* Wrote it.
|
|
\**************************************************************************/
|
|
|
|
VOID vTransparentCopyScan (
|
|
PDIBINFO pDibInfoDst,
|
|
PDIBINFO pDibInfoSrc,
|
|
ULONG TransparentColor)
|
|
{
|
|
ULONG xStart;
|
|
ULONG cx = pDibInfoSrc->rclDIB.right - pDibInfoSrc->rclDIB.left;
|
|
ULONG cy = pDibInfoSrc->rclDIB.bottom - pDibInfoSrc->rclDIB.top;
|
|
ULONG xEnd;
|
|
ULONG xSrc;
|
|
ULONG ySrc = pDibInfoSrc->rclDIB.bottom;
|
|
ULONG xDst;
|
|
ULONG yDst = pDibInfoDst->rclBoundsTrim.top;
|
|
ULONG xStop, xReStart;
|
|
|
|
PBYTE pjSrc = (PBYTE)pDibInfoSrc->pvBase + pDibInfoSrc->rclDIB.top*pDibInfoSrc->stride;
|
|
|
|
//
|
|
// make the bitmap into one scanline bitmap
|
|
// since pscript will send entire bitmap over otherwise
|
|
//
|
|
LONG OldHeight = pDibInfoSrc->pbmi->bmiHeader.biHeight;
|
|
pDibInfoSrc->pbmi->bmiHeader.biHeight = 1;
|
|
|
|
while (cy--)
|
|
{
|
|
xStart = pDibInfoSrc->rclDIB.left;
|
|
xEnd = xStart + cx;
|
|
|
|
xSrc = pDibInfoSrc->rclDIB.left;
|
|
xDst = pDibInfoDst->rclBoundsTrim.left;
|
|
|
|
while (xStart < xEnd)
|
|
{
|
|
xStop = ReadScanLine((PBYTE)pjSrc,
|
|
xStart,
|
|
xEnd,
|
|
pDibInfoSrc->pbmi->bmiHeader.biBitCount,
|
|
TransparentColor,
|
|
pDibInfoSrc);
|
|
|
|
if (xStop-1 > xStart)
|
|
{
|
|
//
|
|
// send the partial scan line over
|
|
//
|
|
|
|
StretchDIBits (
|
|
pDibInfoDst->hdc,
|
|
xDst,
|
|
yDst,
|
|
xStop-xStart-1, //width
|
|
1,
|
|
xSrc-1,
|
|
0,
|
|
xStop-xStart-1,
|
|
1,
|
|
(PBYTE)pjSrc,
|
|
pDibInfoSrc->pbmi,
|
|
DIB_RGB_COLORS,
|
|
SRCCOPY);
|
|
|
|
//Dprintf("StretchDIBits xDst=%x, yDst=%x, width=%x, pjSrc=%x\n",
|
|
// xDst, yDst, xStop-xStart-1,pjSrc);
|
|
|
|
}
|
|
|
|
//get to the next non transparent pixel
|
|
xReStart = SkipScanLine((PBYTE)pjSrc,
|
|
xStop-1,
|
|
xEnd,
|
|
pDibInfoSrc->pbmi->bmiHeader.biBitCount,
|
|
TransparentColor,
|
|
pDibInfoSrc);
|
|
|
|
xDst = xDst + xReStart-xStart;
|
|
|
|
xSrc = xReStart;
|
|
|
|
xStart = xReStart;
|
|
}
|
|
|
|
pjSrc += pDibInfoSrc->stride;
|
|
|
|
ySrc--;
|
|
yDst++;
|
|
}
|
|
|
|
//
|
|
// restore biHeight
|
|
//
|
|
pDibInfoSrc->pbmi->bmiHeader.biHeight = OldHeight;
|
|
|
|
//Dprintf("out of copyscan\n");
|
|
}
|
|
|
|
|
|
/******************************Public*Routine******************************\
|
|
* WinTransparentBlt
|
|
*
|
|
* Returns:
|
|
* BOOL.
|
|
*
|
|
* History:
|
|
* 09-Dec-1996 -by- Lingyun Wang [lingyunw]
|
|
* Wrote it.
|
|
\**************************************************************************/
|
|
|
|
|
|
BOOL
|
|
WinTransparentBlt(
|
|
HDC hdcDst,
|
|
int xDst,
|
|
int yDst,
|
|
int cxDst,
|
|
int cyDst,
|
|
HDC hdcSrc,
|
|
int xSrc,
|
|
int ySrc,
|
|
int cxSrc,
|
|
int cySrc,
|
|
UINT TransColor
|
|
)
|
|
|
|
{
|
|
BOOL bRet = TRUE;
|
|
DIBINFO DibInfoDst, DibInfoSrc;
|
|
PDIBINFO pDibInfoDst, pDibInfoSrc;
|
|
BOOL bReadable;
|
|
//
|
|
// parameter checking
|
|
//
|
|
|
|
if (cxDst < 0 || cyDst < 0 || cxSrc < 0 || cySrc < 0)
|
|
{
|
|
WARNING("bad parameters\n");
|
|
return (FALSE);
|
|
}
|
|
|
|
pDibInfoDst = &DibInfoDst;
|
|
ZeroMemory (pDibInfoDst, sizeof(DIBINFO));
|
|
|
|
if (!bInitDIBINFO (hdcDst, xDst, yDst, cxDst, cyDst, pDibInfoDst))
|
|
return (FALSE);
|
|
|
|
pDibInfoSrc = &DibInfoSrc;
|
|
ZeroMemory (pDibInfoSrc, sizeof(DIBINFO));
|
|
|
|
if (!bInitDIBINFO (hdcSrc, xSrc, ySrc, cxSrc, cySrc, pDibInfoSrc))
|
|
return (FALSE);
|
|
|
|
bRet = bSetupBitmapInfos (pDibInfoDst, pDibInfoSrc);
|
|
|
|
if (bRet)
|
|
{
|
|
TransColor = MapTransparentColor (pDibInfoSrc, TransColor);
|
|
|
|
bRet = bGetSrcDIBits(pDibInfoDst, pDibInfoSrc, SOURCE_TRAN, TransColor);
|
|
|
|
if (bRet)
|
|
{
|
|
// DST can be printer DC
|
|
if (pDibInfoDst->flag & PRINTER_DC)
|
|
{
|
|
bRet = TRUE;
|
|
bReadable = FALSE;
|
|
}
|
|
else
|
|
{
|
|
bRet = bGetDstDIBits (pDibInfoDst, &bReadable, SOURCE_TRAN);
|
|
}
|
|
|
|
if (bRet)
|
|
{
|
|
if (bReadable)
|
|
{
|
|
switch (pDibInfoSrc->pbmi->bmiHeader.biBitCount)
|
|
{
|
|
case 1:
|
|
// The performance of the 1BPP source case is not critical. Easiest to
|
|
// just send it through the printer code path...
|
|
vTransparentCopyScan (pDibInfoDst, pDibInfoSrc, TransColor);
|
|
break;
|
|
|
|
case 4:
|
|
if (bSameDIBformat(pDibInfoDst->pbmi,pDibInfoSrc->pbmi))
|
|
{
|
|
vTransparentIdentityCopy4 (pDibInfoDst, pDibInfoSrc, TransColor);
|
|
}
|
|
else if (pDibInfoDst->pbmi->bmiHeader.biBitCount == 4)
|
|
{
|
|
vTransparentS4D4 (pDibInfoDst, pDibInfoSrc, TransColor);
|
|
}
|
|
else if (pDibInfoDst->pbmi->bmiHeader.biBitCount == 8)
|
|
{
|
|
vTransparentS4D8(pDibInfoDst, pDibInfoSrc, TransColor);
|
|
}
|
|
else if (pDibInfoDst->pbmi->bmiHeader.biBitCount == 16)
|
|
{
|
|
vTransparentS4D16 (pDibInfoDst, pDibInfoSrc, TransColor);
|
|
}
|
|
else if (pDibInfoDst->pbmi->bmiHeader.biBitCount == 24)
|
|
{
|
|
vTransparentS4D24 (pDibInfoDst, pDibInfoSrc, TransColor);
|
|
}
|
|
else if (pDibInfoDst->pbmi->bmiHeader.biBitCount == 32)
|
|
{
|
|
vTransparentS4D32 (pDibInfoDst, pDibInfoSrc, TransColor);
|
|
}
|
|
else
|
|
{ //1
|
|
vTransparentMapCopy (pDibInfoDst, pDibInfoSrc, TransColor);
|
|
}
|
|
break;
|
|
|
|
case 8:
|
|
if (bSameDIBformat(pDibInfoDst->pbmi,pDibInfoSrc->pbmi))
|
|
{
|
|
vTransparentIdentityCopy8 (pDibInfoDst, pDibInfoSrc, TransColor);
|
|
}
|
|
else if (pDibInfoDst->pbmi->bmiHeader.biBitCount == 8)
|
|
{
|
|
vTransparentS8D8 (pDibInfoDst, pDibInfoSrc, TransColor);
|
|
}
|
|
else if (pDibInfoDst->pbmi->bmiHeader.biBitCount == 16)
|
|
{
|
|
vTransparentS8D16 (pDibInfoDst, pDibInfoSrc, TransColor);
|
|
}
|
|
else if (pDibInfoDst->pbmi->bmiHeader.biBitCount == 24)
|
|
{
|
|
vTransparentS8D24 (pDibInfoDst, pDibInfoSrc, TransColor);
|
|
}
|
|
else if (pDibInfoDst->pbmi->bmiHeader.biBitCount == 32)
|
|
{
|
|
vTransparentS8D32 (pDibInfoDst, pDibInfoSrc, TransColor);
|
|
}
|
|
else
|
|
{
|
|
//1, 4
|
|
vTransparentMapCopy (pDibInfoDst, pDibInfoSrc, TransColor);
|
|
}
|
|
break;
|
|
|
|
case 16:
|
|
case 24:
|
|
case 32:
|
|
vTransparentMapCopy (pDibInfoDst, pDibInfoSrc, TransColor);
|
|
break;
|
|
|
|
default:
|
|
WARNING ("src format not currently supported\n");
|
|
bRet = FALSE;
|
|
goto CleanUp;
|
|
break;
|
|
}
|
|
|
|
//
|
|
// if we have created a temp destination DIB, send the final result to destination
|
|
// Note: do this only if we haven't called vTransparentCopyScan
|
|
//
|
|
|
|
if (pDibInfoSrc->pbmi->bmiHeader.biBitCount != 1)
|
|
{
|
|
bRet = bSendDIBINFO (hdcDst, pDibInfoDst);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
//
|
|
// non-readable dest surface
|
|
//
|
|
vTransparentCopyScan (pDibInfoDst, pDibInfoSrc, TransColor);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
WARNING ("GetSrcDIBits failed\n");
|
|
bRet = FALSE;
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
WARNING ("GetDstDIBits failed \n");
|
|
bRet = FALSE;
|
|
}
|
|
//
|
|
// clean up
|
|
//
|
|
CleanUp:
|
|
vCleanupDIBINFO (pDibInfoDst);
|
|
vCleanupDIBINFO (pDibInfoSrc);
|
|
|
|
|
|
return (bRet);
|
|
}
|
|
|
|
#endif
|
|
|
|
BOOL
|
|
TransparentBlt(
|
|
HDC hdcDest,
|
|
int DstX,
|
|
int DstY,
|
|
int DstCx,
|
|
int DstCy,
|
|
HDC hSrc,
|
|
int SrcX,
|
|
int SrcY,
|
|
int SrcCx,
|
|
int SrcCy,
|
|
UINT Color
|
|
)
|
|
{
|
|
BOOL bRet = FALSE;
|
|
|
|
bRet = gpfnTransparentBlt(
|
|
hdcDest,
|
|
DstX,
|
|
DstY,
|
|
DstCx,
|
|
DstCy,
|
|
(HDC)hSrc,
|
|
SrcX,
|
|
SrcY,
|
|
SrcCx,
|
|
SrcCy,
|
|
Color
|
|
);
|
|
|
|
return(bRet);
|
|
}
|
|
|
|
|