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.
705 lines
37 KiB
705 lines
37 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) \
|
|
{ \
|
|
UINT 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) \
|
|
{ \
|
|
UINT 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 */
|
|
/****************************************************************************/
|
|
/****************************************************************************/
|
|
/* */
|
|
/* PBYTE pSrc */
|
|
/* PBYTE pDstBuffer */
|
|
/* UINT srcDataSize total bytes in image */
|
|
/* UINT rowDelta scanline length in bytes */
|
|
/* */
|
|
/****************************************************************************/
|
|
{
|
|
HRESULT hr = S_OK;
|
|
UINT codeLength;
|
|
int pixelLength;
|
|
BYTE bitMask;
|
|
BYTE decode;
|
|
BYTE decodeLite;
|
|
BYTE decodeMega;
|
|
BC_PIXEL fgPel = BC_DEFAULT_FGPEL;
|
|
BC_PIXEL pixelA;
|
|
BC_PIXEL pixelB;
|
|
PBYTE destbuf = pDstBuffer;
|
|
PBYTE endSrc = pSrc + srcDataSize;
|
|
PBYTE pEndDst = destbuf + dstBufferSize;
|
|
BOOL backgroundNeedsPel = FALSE;
|
|
BOOL 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 ((UINT)(destbuf - pDstBuffer) >= rowDelta)
|
|
{
|
|
firstLine = FALSE;
|
|
backgroundNeedsPel = FALSE;
|
|
}
|
|
}
|
|
|
|
/********************************************************************/
|
|
/* Get the decode */
|
|
/********************************************************************/
|
|
BD_CHECK_READ_ONE_BYTE(pSrc, endSrc, hr);
|
|
decode = (BYTE)(*pSrc & CODE_MASK);
|
|
decodeLite = (BYTE)(*pSrc & CODE_MASK_LITE);
|
|
decodeMega = (BYTE)(*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, "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, "Set FGBG image %u, fgPel %06lx",
|
|
codeLength, (TSUINT32)fgPel));
|
|
}
|
|
else
|
|
{
|
|
BCTRACE((TB, "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, "Set FG run %u",codeLength));
|
|
fgPel = BC_GET_PIXEL(pSrc);
|
|
BC_TO_NEXT_PIXEL(pSrc);
|
|
}
|
|
else
|
|
{
|
|
BCTRACE((TB, "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, "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, "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, "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, "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:
|
|
{
|
|
BCTRACE((TB, "Invalid compression data %x",decodeMega));
|
|
}
|
|
break;
|
|
}
|
|
pSrc++;
|
|
|
|
}
|
|
|
|
BCTRACE((TB, "Decompressed to %u bytes", destbuf - pDstBuffer));
|
|
|
|
DC_EXIT_POINT:
|
|
DC_END_FN();
|
|
return hr;
|
|
}
|