Leaked source code of windows server 2003
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.
 
 
 
 
 
 

715 lines
38 KiB

/****************************************************************************/
/* */
/* abdcom.c */
/* */
/* Copyright (c) Data Connection Limited 1998 */
/* */
/* */
/* Bitmap decompression routine and macros for 16 and 24bpp protocol */
/* */
/****************************************************************************/
#ifdef BC_TRACE
#define BCTRACE TRC_DBG
#else
#define BCTRACE(string)
#endif
/****************************************************************************/
/* We use the same helper macros as the 8bpp code except for STORE_FGBG. */
/****************************************************************************/
/****************************************************************************/
/* Macro to store an FGBG image at destbuf */
/* */
/* xorPel is either the value 0 or an expression containing the local */
/* variable destbuf. */
/* */
/* THIS MEANS THAT xorPel HAS A DIFFERENT VALUE EVERY TIME destbuf IS */
/* CHANGED. */
/* */
/* fgPel is a BC_PIXEL and the FG color to XOR with xorbyte */
/* fgbgChar is a bitmask telling which color to put where */
/* */
/* This macro expects that the function defines pDst, pEndDst, hr */
/* If there is not enough data to write the full run, this will set error */
/* and quit */
/****************************************************************************/
#undef STORE_FGBG
#define STORE_FGBG(xorPelIn, fgbgChar, fgPel, bits) \
{ \
DCUINT numbits = bits; \
BC_PIXEL xorPel; \
BD_CHECK_WRITE_N_BYTES( destbuf, pEndDst, max(1, min(numbits, 8)) * BC_PIXEL_LEN, hr ) \
\
xorPel = BC_GET_PIXEL(xorPelIn); \
if (fgbgChar & 0x01) \
{ \
BC_SET_PIXEL(destbuf, xorPel ^ fgPel); \
} \
else \
{ \
BC_SET_PIXEL(destbuf, xorPel); \
} \
BC_TO_NEXT_PIXEL(destbuf); \
\
if (--numbits > 0) \
{ \
xorPel = BC_GET_PIXEL(xorPelIn); \
if (fgbgChar & 0x02) \
{ \
BC_SET_PIXEL(destbuf, xorPel ^ fgPel); \
} \
else \
{ \
BC_SET_PIXEL(destbuf, xorPel) \
} \
BC_TO_NEXT_PIXEL(destbuf); \
\
if (--numbits > 0) \
{ \
xorPel = BC_GET_PIXEL(xorPelIn); \
if (fgbgChar & 0x04) \
{ \
BC_SET_PIXEL(destbuf, xorPel ^ fgPel); \
} \
else \
{ \
BC_SET_PIXEL(destbuf, xorPel) \
} \
BC_TO_NEXT_PIXEL(destbuf); \
\
if (--numbits > 0) \
{ \
xorPel = BC_GET_PIXEL(xorPelIn); \
if (fgbgChar & 0x08) \
{ \
BC_SET_PIXEL(destbuf, xorPel ^ fgPel); \
} \
else \
{ \
BC_SET_PIXEL(destbuf, xorPel); \
} \
BC_TO_NEXT_PIXEL(destbuf); \
\
if (--numbits > 0) \
{ \
xorPel = BC_GET_PIXEL(xorPelIn); \
if (fgbgChar & 0x10) \
{ \
BC_SET_PIXEL(destbuf, xorPel ^ fgPel); \
} \
else \
{ \
BC_SET_PIXEL(destbuf, xorPel); \
} \
BC_TO_NEXT_PIXEL(destbuf); \
\
if (--numbits > 0) \
{ \
xorPel = BC_GET_PIXEL(xorPelIn); \
if (fgbgChar & 0x20) \
{ \
BC_SET_PIXEL(destbuf, xorPel ^ fgPel); \
} \
else \
{ \
BC_SET_PIXEL(destbuf, xorPel); \
} \
BC_TO_NEXT_PIXEL(destbuf); \
\
if (--numbits > 0) \
{ \
xorPel = BC_GET_PIXEL(xorPelIn); \
if (fgbgChar & 0x40) \
{ \
BC_SET_PIXEL(destbuf, xorPel ^ fgPel); \
} \
else \
{ \
BC_SET_PIXEL(destbuf, xorPel); \
} \
BC_TO_NEXT_PIXEL(destbuf); \
\
if (--numbits > 0) \
{ \
xorPel = BC_GET_PIXEL(xorPelIn); \
if (fgbgChar & 0x80) \
{ \
BC_SET_PIXEL(destbuf, xorPel ^ fgPel); \
} \
else \
{ \
BC_SET_PIXEL(destbuf, xorPel); \
} \
BC_TO_NEXT_PIXEL(destbuf); \
} \
} \
} \
} \
} \
} \
} \
}
#define STORE_LINE1_FGBG(fgbgChar, fgPel, bits) \
{ \
DCUINT numbits = bits; \
BD_CHECK_WRITE_N_BYTES( destbuf, pEndDst, max(1, min(numbits, 8)) * BC_PIXEL_LEN, hr ) \
\
if (fgbgChar & 0x01) \
{ \
BC_SET_PIXEL(destbuf, fgPel); \
} \
else \
{ \
BC_SET_PIXEL(destbuf, 0); \
} \
BC_TO_NEXT_PIXEL(destbuf); \
\
if (--numbits > 0) \
{ \
if (fgbgChar & 0x02) \
{ \
BC_SET_PIXEL(destbuf, fgPel); \
} \
else \
{ \
BC_SET_PIXEL(destbuf, 0) \
} \
BC_TO_NEXT_PIXEL(destbuf); \
\
if (--numbits > 0) \
{ \
if (fgbgChar & 0x04) \
{ \
BC_SET_PIXEL(destbuf, fgPel); \
} \
else \
{ \
BC_SET_PIXEL(destbuf, 0) \
} \
BC_TO_NEXT_PIXEL(destbuf); \
\
if (--numbits > 0) \
{ \
if (fgbgChar & 0x08) \
{ \
BC_SET_PIXEL(destbuf, fgPel); \
} \
else \
{ \
BC_SET_PIXEL(destbuf, 0); \
} \
BC_TO_NEXT_PIXEL(destbuf); \
\
if (--numbits > 0) \
{ \
if (fgbgChar & 0x10) \
{ \
BC_SET_PIXEL(destbuf, fgPel); \
} \
else \
{ \
BC_SET_PIXEL(destbuf, 0); \
} \
BC_TO_NEXT_PIXEL(destbuf); \
\
if (--numbits > 0) \
{ \
if (fgbgChar & 0x20) \
{ \
BC_SET_PIXEL(destbuf, fgPel); \
} \
else \
{ \
BC_SET_PIXEL(destbuf, 0); \
} \
BC_TO_NEXT_PIXEL(destbuf); \
\
if (--numbits > 0) \
{ \
if (fgbgChar & 0x40) \
{ \
BC_SET_PIXEL(destbuf, fgPel); \
} \
else \
{ \
BC_SET_PIXEL(destbuf, 0); \
} \
BC_TO_NEXT_PIXEL(destbuf); \
\
if (--numbits > 0) \
{ \
if (fgbgChar & 0x80) \
{ \
BC_SET_PIXEL(destbuf, fgPel); \
} \
else \
{ \
BC_SET_PIXEL(destbuf, 0); \
} \
BC_TO_NEXT_PIXEL(destbuf); \
} \
} \
} \
} \
} \
} \
} \
}
/****************************************************************************/
/* Decompression function begins here */
/****************************************************************************/
/****************************************************************************/
/* */
/* PDCUINT8 pSrc */
/* PDCUINT8 pDstBuffer */
/* DCUINT srcDataSize total bytes in image */
/* DCUINT rowDelta scanline length in bytes */
/* */
/****************************************************************************/
{
HRESULT hr = S_OK;
DCUINT codeLength;
DCINT pixelLength;
DCUINT8 bitMask;
DCUINT8 decode;
DCUINT8 decodeLite;
DCUINT8 decodeMega;
BC_PIXEL fgPel = BC_DEFAULT_FGPEL;
BC_PIXEL pixelA;
BC_PIXEL pixelB;
PDCUINT8 destbuf = pDstBuffer;
PDCUINT8 endSrc = pSrc + srcDataSize;
PDCUINT8 pEndDst = pDstBuffer + dstBufferSize;
DCBOOL backgroundNeedsPel = FALSE;
DCBOOL firstLine = TRUE;
DC_BEGIN_FN(BC_FN_NAME);
/************************************************************************/
/* Loop processing the input */
/************************************************************************/
while (pSrc < endSrc)
{
/********************************************************************/
/* While we are processing the first line we should keep a look out */
/* for the end of the line */
/********************************************************************/
if (firstLine)
{
if ((DCUINT)(destbuf - pDstBuffer) >= rowDelta)
{
firstLine = FALSE;
backgroundNeedsPel = FALSE;
}
}
/********************************************************************/
/* Get the decode */
/********************************************************************/
BD_CHECK_READ_ONE_BYTE(pSrc, endSrc, hr);
decode = (DCUINT8)(*pSrc & CODE_MASK);
decodeLite = (DCUINT8)(*pSrc & CODE_MASK_LITE);
decodeMega = (DCUINT8)(*pSrc);
/********************************************************************/
/* BG RUN */
/********************************************************************/
if ((decode == CODE_BG_RUN) ||
(decodeMega == CODE_MEGA_MEGA_BG_RUN))
{
if (decode == CODE_BG_RUN)
{
EXTRACT_LENGTH(pSrc, endSrc, codeLength, hr);
}
else
{
BD_CHECK_READ_N_BYTES(pSrc+1, endSrc, 2, hr);
codeLength = DC_EXTRACT_UINT16_UA(pSrc+1);
pSrc += 3;
}
BCTRACE((TB, _T("Background run %u"),codeLength));
if (!firstLine)
{
if (backgroundNeedsPel)
{
BD_CHECK_WRITE_N_BYTES(destbuf, pEndDst, BC_PIXEL_LEN, hr);
BD_CHECK_READ_N_BYTES_2ENDED(destbuf - rowDelta, pDstBuffer, pEndDst, BC_PIXEL_LEN, hr)
BC_SET_PIXEL(destbuf,
BC_GET_PIXEL(destbuf - rowDelta) ^ fgPel);
BC_TO_NEXT_PIXEL(destbuf);
codeLength--;
}
BD_CHECK_WRITE_N_BYTES(destbuf, pEndDst, BC_PIXEL_LEN * codeLength, hr);
while (codeLength-- > 0)
{
BD_CHECK_READ_N_BYTES_2ENDED(destbuf - rowDelta, pDstBuffer, pEndDst, BC_PIXEL_LEN, hr)
BC_SET_PIXEL(destbuf, BC_GET_PIXEL(destbuf - rowDelta));
BC_TO_NEXT_PIXEL(destbuf);
}
}
else
{
if (backgroundNeedsPel)
{
BD_CHECK_WRITE_N_BYTES(destbuf, pEndDst, BC_PIXEL_LEN, hr);
BC_SET_PIXEL(destbuf, fgPel);
BC_TO_NEXT_PIXEL(destbuf);
codeLength--;
}
BD_CHECK_WRITE_N_BYTES(destbuf, pEndDst, BC_PIXEL_LEN * codeLength, hr);
while (codeLength-- > 0)
{
/********************************************************/
/* On the first line BG colour means 0 */
/********************************************************/
BC_SET_PIXEL(destbuf, (BC_PIXEL)0);
BC_TO_NEXT_PIXEL(destbuf);
}
}
/****************************************************************/
/* A follow on BG run will need a pel inserted */
/****************************************************************/
backgroundNeedsPel = TRUE;
continue;
}
/********************************************************************/
/* For any of the other runtypes a follow on BG run does not need */
/* a FG pel inserted */
/********************************************************************/
backgroundNeedsPel = FALSE;
/********************************************************************/
/* FGBG IMAGE */
/********************************************************************/
if ((decode == CODE_FG_BG_IMAGE) ||
(decodeLite == CODE_SET_FG_FG_BG) ||
(decodeMega == CODE_MEGA_MEGA_FGBG) ||
(decodeMega == CODE_MEGA_MEGA_SET_FGBG))
{
if ((decodeMega == CODE_MEGA_MEGA_FGBG) ||
(decodeMega == CODE_MEGA_MEGA_SET_FGBG))
{
BD_CHECK_READ_N_BYTES(pSrc+1, endSrc, 2, hr);
codeLength = DC_EXTRACT_UINT16_UA(pSrc+1);
pSrc += 3;
}
else
{
if (decode == CODE_FG_BG_IMAGE)
{
EXTRACT_LENGTH_FGBG(pSrc, endSrc, codeLength, hr);
}
else
{
EXTRACT_LENGTH_FGBG_LITE(pSrc, endSrc, codeLength, hr);
}
}
if ((decodeLite == CODE_SET_FG_FG_BG) ||
(decodeMega == CODE_MEGA_MEGA_SET_FGBG))
{
BD_CHECK_READ_N_BYTES(pSrc, endSrc, BC_PIXEL_LEN, hr);
fgPel = BC_GET_PIXEL(pSrc);
BC_TO_NEXT_PIXEL(pSrc);
BCTRACE((TB, _T("Set FGBG image %u, fgPel %06lx"),
codeLength, (DCUINT32)fgPel));
}
else
{
BCTRACE((TB, _T("FGBG image %u"),codeLength));
}
while (codeLength > 8)
{
/************************************************************/
/* A FGBG image is a set of bitmasks describing the */
/* positions of the FG and BG colors. */
/************************************************************/
BD_CHECK_READ_ONE_BYTE(pSrc, endSrc, hr);
bitMask = *pSrc++;
if (!firstLine)
{
BD_CHECK_READ_N_BYTES_2ENDED(destbuf - rowDelta, pDstBuffer, pEndDst, BC_PIXEL_LEN, hr)
STORE_FGBG((destbuf - rowDelta),
bitMask,
fgPel,
8);
}
else
{
STORE_LINE1_FGBG(bitMask, fgPel, 8);
}
codeLength -= 8;
}
if (codeLength > 0)
{
BD_CHECK_READ_ONE_BYTE(pSrc, endSrc, hr);
bitMask = *pSrc++;
if (!firstLine)
{
BD_CHECK_READ_N_BYTES_2ENDED(destbuf - rowDelta, pDstBuffer, pEndDst, BC_PIXEL_LEN, hr)
STORE_FGBG((destbuf - rowDelta),
bitMask,
fgPel,
codeLength);
}
else
{
STORE_LINE1_FGBG(bitMask, fgPel, codeLength);
}
}
continue;
}
/********************************************************************/
/* FG RUN */
/********************************************************************/
if ((decode == CODE_FG_RUN) ||
(decodeLite == CODE_SET_FG_FG_RUN) ||
(decodeMega == CODE_MEGA_MEGA_FG_RUN) ||
(decodeMega == CODE_MEGA_MEGA_SET_FG_RUN))
{
if ((decodeMega == CODE_MEGA_MEGA_FG_RUN) ||
(decodeMega == CODE_MEGA_MEGA_SET_FG_RUN))
{
BD_CHECK_READ_N_BYTES(pSrc+1, endSrc, 2, hr);
codeLength = DC_EXTRACT_UINT16_UA(pSrc+1);
pSrc += 3;
}
else
{
if (decode == CODE_FG_RUN)
{
EXTRACT_LENGTH(pSrc, endSrc, codeLength, hr);
}
else
{
EXTRACT_LENGTH_LITE(pSrc, endSrc, codeLength, hr);
}
}
/****************************************************************/
/* Push the old fgPel down to the ALT position */
/****************************************************************/
if ((decodeLite == CODE_SET_FG_FG_RUN) ||
(decodeMega == CODE_MEGA_MEGA_SET_FG_RUN))
{
BD_CHECK_READ_N_BYTES(pSrc, endSrc, BC_PIXEL_LEN, hr);
BCTRACE((TB, _T("Set FG run %u"),codeLength));
fgPel = BC_GET_PIXEL(pSrc);
BC_TO_NEXT_PIXEL(pSrc);
}
else
{
BCTRACE((TB, _T("FG run %u"),codeLength));
}
BD_CHECK_WRITE_N_BYTES(destbuf, pEndDst, BC_PIXEL_LEN * codeLength, hr)
while (codeLength-- > 0)
{
if (!firstLine)
{
BD_CHECK_READ_N_BYTES_2ENDED(destbuf - rowDelta, pDstBuffer, pEndDst, BC_PIXEL_LEN, hr)
BC_SET_PIXEL(destbuf,
BC_GET_PIXEL(destbuf - rowDelta) ^ fgPel);
BC_TO_NEXT_PIXEL(destbuf);
}
else
{
BC_SET_PIXEL(destbuf, fgPel);
BC_TO_NEXT_PIXEL(destbuf);
}
}
continue;
}
/********************************************************************/
/* DITHERED RUN */
/********************************************************************/
if ((decodeLite == CODE_DITHERED_RUN) ||
(decodeMega == CODE_MEGA_MEGA_DITHER))
{
if (decodeMega == CODE_MEGA_MEGA_DITHER)
{
BD_CHECK_READ_N_BYTES(pSrc+1, endSrc, 2, hr);
codeLength = DC_EXTRACT_UINT16_UA(pSrc+1);
pSrc += 3;
}
else
{
EXTRACT_LENGTH_LITE(pSrc, endSrc, codeLength, hr);
}
BCTRACE((TB, _T("Dithered run %u"),codeLength));
BD_CHECK_READ_N_BYTES(pSrc, endSrc, BC_PIXEL_LEN * 2, hr);
pixelA = BC_GET_PIXEL(pSrc);
BC_TO_NEXT_PIXEL(pSrc);
pixelB = BC_GET_PIXEL(pSrc);
BC_TO_NEXT_PIXEL(pSrc);
BD_CHECK_WRITE_N_BYTES(destbuf, pEndDst, 2 * codeLength * BC_PIXEL_LEN, hr)
while (codeLength-- > 0)
{
BC_SET_PIXEL(destbuf, pixelA);
BC_TO_NEXT_PIXEL(destbuf);
BC_SET_PIXEL(destbuf, pixelB);
BC_TO_NEXT_PIXEL(destbuf);
}
continue;
}
/********************************************************************/
/* COLOR IMAGE */
/********************************************************************/
if ((decode == CODE_COLOR_IMAGE) ||
(decodeMega == CODE_MEGA_MEGA_CLR_IMG))
{
if (decodeMega == CODE_MEGA_MEGA_CLR_IMG)
{
BD_CHECK_READ_N_BYTES(pSrc+1, endSrc, 2, hr);
codeLength = DC_EXTRACT_UINT16_UA(pSrc+1);
pSrc += 3;
}
else
{
EXTRACT_LENGTH(pSrc, endSrc, codeLength, hr);
}
BCTRACE((TB, _T("Color image %u"),codeLength));
/****************************************************************/
/* Just copy the pixel values across */
/****************************************************************/
pixelLength = (codeLength * BC_PIXEL_LEN);
BD_CHECK_READ_N_BYTES(pSrc, endSrc, pixelLength, hr);
BD_CHECK_WRITE_N_BYTES(destbuf, pEndDst, pixelLength, hr);
while (pixelLength-- > 0)
{
*destbuf++ = *pSrc++;
}
continue;
}
/********************************************************************/
/* COLOR RUN */
/********************************************************************/
if ((decode == CODE_COLOR_RUN) ||
(decodeMega == CODE_MEGA_MEGA_COLOR_RUN))
{
if (decodeMega == CODE_MEGA_MEGA_COLOR_RUN)
{
BD_CHECK_READ_N_BYTES(pSrc+1, endSrc, 2, hr);
codeLength = DC_EXTRACT_UINT16_UA(pSrc+1);
pSrc += 3;
}
else
{
EXTRACT_LENGTH(pSrc, endSrc, codeLength, hr);
}
BCTRACE((TB, _T("Color run %u"),codeLength));
BD_CHECK_READ_N_BYTES(pSrc, endSrc, BC_PIXEL_LEN, hr);
pixelA = BC_GET_PIXEL(pSrc);
BC_TO_NEXT_PIXEL(pSrc);
BD_CHECK_WRITE_N_BYTES(destbuf, pEndDst, codeLength * BC_PIXEL_LEN, hr)
while (codeLength-- > 0)
{
BC_SET_PIXEL(destbuf, pixelA);
BC_TO_NEXT_PIXEL(destbuf);
}
continue;
}
/********************************************************************/
/* If we get here then the code must be a special one */
/********************************************************************/
BCTRACE((TB, _T("Special code %x"),decodeMega));
switch (decodeMega)
{
case CODE_BLACK:
BD_CHECK_WRITE_N_BYTES(destbuf, pEndDst, BC_PIXEL_LEN, hr)
BC_SET_PIXEL(destbuf, (BC_PIXEL)0);
BC_TO_NEXT_PIXEL(destbuf);
break;
case CODE_WHITE:
BD_CHECK_WRITE_N_BYTES(destbuf, pEndDst, BC_PIXEL_LEN, hr)
BC_SET_PIXEL(destbuf, BC_DEFAULT_FGPEL);
BC_TO_NEXT_PIXEL(destbuf);
break;
/****************************************************************/
/* Ignore the unreachable code warnings that follow */
/* Simply because we use the STORE_FGBG macro with a constant */
/* value */
/****************************************************************/
case CODE_SPECIAL_FGBG_1:
if (!firstLine)
{
BD_CHECK_READ_N_BYTES_2ENDED(destbuf - rowDelta, pDstBuffer, pEndDst, BC_PIXEL_LEN, hr)
STORE_FGBG((destbuf - rowDelta),
SPECIAL_FGBG_CODE_1,
fgPel,
8);
}
else
{
STORE_LINE1_FGBG(SPECIAL_FGBG_CODE_1, fgPel, 8);
}
break;
case CODE_SPECIAL_FGBG_2:
if (!firstLine)
{
BD_CHECK_READ_N_BYTES_2ENDED(destbuf - rowDelta, pDstBuffer, pEndDst, BC_PIXEL_LEN, hr)
STORE_FGBG((destbuf - rowDelta),
SPECIAL_FGBG_CODE_2,
fgPel,
8);
}
else
{
STORE_LINE1_FGBG(SPECIAL_FGBG_CODE_2, fgPel, 8);
}
break;
default:
{
TRC_ERR((TB, _T("Invalid compression data %x"),decodeMega));
}
break;
}
pSrc++;
}
BCTRACE((TB, _T("Decompressed to %u bytes"), destbuf - pDstBuffer));
#if 0
#ifdef DC_DEBUG
if ((destbuf - pDstBuffer) != decompLen)
{
TRC_ABORT((TB, _T("calculated decomp len %d != actual len %d"),
decompLen, (destbuf - pDstBuffer) ));
}
#endif
#endif
DC_EXIT_POINT:
DC_END_FN();
return hr;
}