/****************************************************************************/
/*                                                                          */
/* 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;
}