/*DDK*************************************************************************/
/*                                                                           */
/* COPYRIGHT (C) Lexmark Corporation, 1989                                   */
/* COPYRIGHT    Copyright (C) 1995 IBM Corporation                           */
/*                                                                           */
/*    The following IBM OS/2 WARP source code is provided to you solely for  */
/*    the purpose of assisting you in your development of OS/2 WARP device   */
/*    drivers. You may use this code in accordance with the IBM License      */
/*    Agreement provided in the IBM Device Driver Source Kit for OS/2. This  */
/*    Copyright statement may not be removed.                                */
/*                                                                           */
/*****************************************************************************/
/**************************************************************************
 *
 * SOURCE FILE NAME = PRDBINEX
 *
 * DESCRIPTIVE NAME =
 *
 *
 * VERSION
 *
 * DATE
 *
 * DESCRIPTION
 *
 * FUNCTIONS   prdb_ConvertInttoExt
 *             prdb_SetExternalColourTable
 *             prdb_CopyInttoExt
 *             prdb_TransferInttoExt
 *             convert_int1_to_ext4
 *             convert_int1_to_ext8
 *             convert_int1_to_ext24
 *             convert_int4_to_ext1
 *             convert_int4_to_ext8
 *             convert_int4_to_ext24
 *
 * ENTRY POINTS:
 *
 * DEPENDENCIES:
 *
 * NOTES
 *
 *
 * STRUCTURES
 *
 * EXTERNAL REFERENCES
 *
 * EXTERNAL FUNCTIONS
 *
*/
#define INCL_32                         /* Convert to C/SET2    CON3201       */
#define INCL_DOSPROCESS                 /* Convert to C/SET2    CON3201       */
#define INCL_DOSSEMAPHORES
#define INCL_GPIERRORS
#define INCL_GPIPRIMITIVES
#define INCL_WINHEAP
#define INCL_GPIBITMAPS
#define INCL_DOSMEMMGR
#include <os2.h>
#undef INCL_DOSPROCESS                  /* Convert to C/SET2    CON3201       */
#undef INCL_DOSSEMAPHORES
#undef INCL_GPIERRORS
#undef INCL_GPIPRIMITIVES
#undef INCL_WINHEAP
#undef INCL_GPIBITMAPS
#undef INCL_DOSMEMMGR

#define INCL_DDIMISC
#define INCL_DDIBUNDLES
#define INCL_DDIFONTSTRUCS
#define INCL_DDIDEFS
#define INCL_DDICOMFLAGS
#include <pmddi.h>
#undef INCL_DDIMISC
#undef INCL_DDIBUNDLES
#undef INCL_DDIFONTSTRUCS
#undef INCL_DDIDEFS
#undef INCL_DDICOMFLAGS

#define INCL_WINP_SELECTIVE
#define INCL_WINP_SEI
#include <pmwinx.h>
#undef INCL_WINP_SELECTIVE
#undef INCL_WINP_SEI
#undef INCL_32                          /* Convert to C/SET2    CON3201       */

#define NO_SYS
#define NO_CONSTANT_INCL
#include <prdinclt.h>
#undef NO_CONSTANT_INCL
#undef NO_SYS

#include <prdbtyp1.h>
#include <prdbextf.h>
#include <prdgextf.h>
#include <prdcextf.h>
#include <prdyextf.h>
#include <prduextf.h>
#include <prdbsize.h>

extern USHORT           ConvertTablei1toe4[16];
extern ULONG            ConvertTablei1toe8[16];
extern BYTE             ConvertTablei4toe1[8];
extern RGB2             DVTHardwarePalette[8];      /* CON3201 - Now use RGB2 */
extern USHORT            prdd_HugeInc;

/**********************************************************************/
/*                                                                    */
/*   FUNCTION: prdb_ConvertInttoExt                                   */
/*                                                                    */
/*   PARAMETERS:                                                      */
/*                                                                    */
/*   pBMListEntry      InfoList    Pointer to bitmap list entry       */
/*   PBYTE             DestAddress Pointer to external bitmap         */
/*   PBITMAPINFO       ArgInfo     Pointer to external bitmap info    */
/*   ULONG             StartLine   First line to convert              */
/*   USHORT            ScanLines   Number of lines to convert         */
/*   lpDCI             DCIData     DCIData       PD00400 :            */
/*                                                                    */
/*   DESCRIPTION:                                                     */
/*                                                                    */
/*   Convert an internal to an external bitmap. This routine does     */
/*   the main work. It assumes that all the parameters of the         */
/*   bitmaps have already been verified.                              */
/*                                                                    */
/**********************************************************************/

void prdb_ConvertInttoExt(pBMListEntry InfoList,
                          PBYTE        DestAddress,
/* CON3201 - GRE CHANGE*/ PBITMAPINFO2 ArgInfo,
                          ULONG        StartLine,
                          USHORT        ScanLines,
                          lpDCI        DCIData)

{
#define TFUNC "prdb_ConvertInttoExt"

  /********************************************************************/
  /* Local variables                                                  */
  /********************************************************************/

  ULONG       MoveAlong;
lpBMSPad      SPad;              /* PD00400 : Pointer to bitmap scratch pad */
                                 /* lpBMSPad is a typedef pointer to  */
                                 /*  the structure BMConvertScratch   */
                                 /*  (see PRDBTYPT.H)...              */
  RGB2       *ColorTable;        /* CON32                                     */
  /******************************************************************/
  /* PD00400 :     Allocate the memory used for the BM scratch pad  */
  /******************************************************************/
  if ( prdg_AllocHeapItem(
                   DCIData,
                   sizeof(BMConvertScratch),
                   (PUSHORT *)&SPad) != OK )
  {
      return;
  }

  /**********************************************************************/
  /* PD00400 : GWD.    Set the allocated heap space to all zero's       */
  /**********************************************************************/
           prdu_memset((PBYTE)SPad, 0, sizeof(BMConvertScratch));

  /********************************************************************/
  /* Set up a scratchpad to reduce parameter passing between routines */
  /* Note that we update SrcPtr to move to the first line from which  */
  /* conversion is requested.                                         */
  /********************************************************************/
  SPad->SrcPtr    = InfoList->Bitmap;
  MoveAlong      = StartLine * InfoList->Parms.BytesPerRow;
/*OFFSETOF(SPad->SrcPtr)   += (USHORT)(MoveAlong&0x0000FFFFL);          */
/*SELECTOROF(SPad->SrcPtr) += ((USHORT)(MoveAlong>>16)) * prdd_HugeInc; */
  SPad->SrcPtr    += MoveAlong;                            /* CON3201 */
/*SPad->DestPtr   = (void far *)DestAddress; */
  SPad->DestPtr   = (void *)DestAddress;                   /* CON3201 */
  SPad->IntBpp    = (USHORT) InfoList->Parms.Bitcount;
  SPad->ExtBpp    = ArgInfo->cBitCount;
  SPad->PelsPerLine    = (USHORT) InfoList->Parms.Width;
  SPad->LinesToConvert = ScanLines;
  SPad->BytesToConvert = InfoList->Parms.BytesPerRow * ScanLines;
  ColorTable                 = (RGB2*)((PBYTE)ArgInfo + ArgInfo->cbFix);/* CON3201 */

  /********************************************************************/
  /* Set up the colour table                                          */
  /********************************************************************/
  prdb_SetExternalColourTable( ColorTable, SPad );         /* CON3201 */

  /********************************************************************/
  /* If no lines need to be got then we can return now having only    */
  /* filled in the colour table.                                      */
  /********************************************************************/
  if ( ScanLines == 0 )
      return;

  if (SPad->IntBpp == SPad->ExtBpp)
  {
      /****************************************************************/
      /* Both bitmaps have the same number of bits per pel - so we can*/
      /* just splat bytes from one to the other without worrying about*/
      /* conversions.                                                 */
      /****************************************************************/
      (VOID) prdb_CopyInttoExt( SPad );
  }
  else
  {
      /****************************************************************/
      /* The bitmaps have a different number of bits per pel - thus we*/
      /* need to do some sort of conversion. These conversion tables  */
      /* are all hard coded, since they never change.                 */
      /****************************************************************/
      (VOID) prdb_TransferInttoExt( SPad );
  }
  /******************************************************************/
  /* PD00400 :       Free the memory used for the BM scratch pad    */
  /******************************************************************/
   (void) prdg_FreeHeapItem( DCIData,
                             sizeof(BMConvertScratch),
                             (PUSHORT)SPad );
} /* ConvertInttoExt */
#undef TFUNC

/**********************************************************************/
/*                                                                    */
/*   FUNCTION: prdb_SetExternalColourTable                            */
/*                                                                    */
/*   PARAMETERS:                                                      */
/*                                                                    */
/*   RGB far *         RGBTable      Pointer to external colour table */
/*   lpBMSPad          SPad        PD00400 :Pointer to bitmap scratch */
/*                                                                    */
/*   DESCRIPTION:                                                     */
/*                                                                    */
/*   This function sets up a colour table for return to the           */
/*   application. It assumes that the application has made enough     */
/*   space for the colour table, i.e that RGBTable has space for      */
/*   2^(ExtBpp) entries.                                              */
/*                                                                    */
/*   CON3201:                                                         */
/*   We are now using an RGB2 table so will set the extra byte        */
/*   fcOptions to equal zero throughtout                              */
/**********************************************************************/

void prdb_SetExternalColourTable( RGB2     *RGBTable,        /* CON3201 */
                                  lpBMSPad  SPad )
#if 0
RGB far * RGBTable;
lpBMSPad      SPad;              /* PD00400 : Pointer to bitmap scratch pad */
#endif

{
#define TFUNC "prdb_SetExternalColourTable"
  int ii; /* used as general colour table index */

  if (SPad->ExtBpp == 1)
  {
      /****************************************************************/
      /* 1bpp colour tables are always 0->00 00 00, 1->FF FF FF       */
      /****************************************************************/
      RGBTable[0].bRed       = (BYTE)0x00;
      RGBTable[0].bGreen     = (BYTE)0x00;
      RGBTable[0].bBlue      = (BYTE)0x00;
      RGBTable[0].fcOptions  = (BYTE)0x00;
      RGBTable[1].bRed       = (BYTE)0xFF;
      RGBTable[1].bGreen     = (BYTE)0xFF;
      RGBTable[1].bBlue      = (BYTE)0xFF;
      RGBTable[1].fcOptions  = (BYTE)0x00;
  } /* external bitmap is 1bpp */
  else if (SPad->ExtBpp == 4)
  {
      if (SPad->IntBpp == 1)
      {
          /************************************************************/
          /* Set colour table to be returned as {0,..,14} -> 00 00 00 */
          /* 15 -> FF FF FF                                           */
          /************************************************************/
          for (ii=0; ii < 15 ;ii++)
          {
              RGBTable[ii].bRed      = (BYTE)0x00;
              RGBTable[ii].bGreen    = (BYTE)0x00;
              RGBTable[ii].bBlue     = (BYTE)0x00;
              RGBTable[ii].fcOptions = (BYTE)0x00;
          }
          RGBTable[15].bRed       = (BYTE)0xFF;
          RGBTable[15].bGreen     = (BYTE)0xFF;
          RGBTable[15].bBlue      = (BYTE)0xFF;
          RGBTable[15].fcOptions  = (BYTE)0x00;
      } /* internal bitmap is 1bpp */
      else /* SPad->IntBpp == 4 */
      {
          /************************************************************/
          /* Set colour table to be returned as the palette extended  */
          /* by {8,..,15} -> 00 00 00 as the palette only uses eight  */
          /* colours                                                  */
          /************************************************************/
          for (ii = 0; ii < 8; ii++)
          {
              RGBTable[ii] = DVTHardwarePalette[ii];
          }
          for (ii = 8; ii < 16; ii++)
          {
              RGBTable[ii].bRed   = (BYTE)0x00;
              RGBTable[ii].bGreen = (BYTE)0x00;
              RGBTable[ii].bBlue  = (BYTE)0x00;
              RGBTable[ii].fcOptions = (BYTE)0x00;
          }
      } /* internal bitmap is 4bpp */
  } /* external bitmap is 4bpp */
  else if (SPad->ExtBpp == 8)
  {
      if (SPad->IntBpp == 1)
      {
          /************************************************************/
          /* Set colour table to be returned as {0,..,254} -> 00 00 00*/
          /* 255 -> FF FF FF                                          */
          /************************************************************/
          for (ii=0; ii < 255 ;ii++)
          {
              RGBTable[ii].bRed   = (BYTE)0x00;
              RGBTable[ii].bGreen = (BYTE)0x00;
              RGBTable[ii].bBlue  = (BYTE)0x00;
              RGBTable[ii].fcOptions = (BYTE)0x00;
          }
          RGBTable[255].bRed   = (BYTE)0xFF;
          RGBTable[255].bGreen = (BYTE)0xFF;
          RGBTable[255].bBlue  = (BYTE)0xFF;
          RGBTable[255].fcOptions = (BYTE)0x00;
      } /* internal bitmap is 1bpp */
      else /* SPad->IntBpp == 4 */
      {
          /************************************************************/
          /* Set colour table to be returned as the palette extended  */
          /* by {8,..,255} -> 00 00 00 as the palette only uses eight */
          /* colours                                                  */
          /************************************************************/
          for (ii = 0; ii < 8; ii++)
          {
              RGBTable[ii] = DVTHardwarePalette[ii];
          }
          for (ii = 8; ii < 256; ii++)
          {
              RGBTable[ii].bRed   = (BYTE)0x00;
              RGBTable[ii].bGreen = (BYTE)0x00;
              RGBTable[ii].bBlue  = (BYTE)0x00;
              RGBTable[ii].fcOptions = (BYTE)0x00;
          }
      } /* internal bitmap is 4bpp */
  } /* external bitmap is 8bpp */
} /* SetExternalColourTable */
#undef TFUNC

/**********************************************************************/
/*                                                                    */
/*   FUNCTION: prdb_CopyInttoExt                                      */
/*                                                                    */
/*   PARAMETERS:                                                      */
/*   lpBMSPad          SPad        PD00400 :Pointer to bitmap scratch */
/*                                                                    */
/*   DESCRIPTION:                                                     */
/*                                                                    */
/*   This function copies data from an internal to an external        */
/*   bitmap. The two bitmaps are both of the same format, so we       */
/*   don't need to worry about colour conversion, or about end of     */
/*   line padding. We do the copying in chunks which will not overrun */
/*   segment boundaries.                                              */
/*   CON3201 : No longer have to worry about segment boundaries       */
/*   with 32-bit code.  prdu_memcopy now handles a LONG length,       */
/*   and can do the entire copy in 1 step, so much of the logic       */
/*   in this function is eliminated.                                  */
/*                                                                    */
/**********************************************************************/

VOID prdb_CopyInttoExt( lpBMSPad SPad )

#if 0
lpBMSPad      SPad;              /* PD00400 : Pointer to bitmap scratch pad */
#endif

{
/* CON3201 : don't need the following variables for 32-bit code       */
#if 0
  ULONG ChunkLength;
  ULONG BytesLeftInSrcSeg, BytesLeftInDestSeg;
#endif
#define TFUNC "prdb_CopyInttoExt"

/* CON3201 : don't have to worry about 64K chucks for 32-bit code     */
#if 0
  while (SPad->BytesToConvert)
  {
      /****************************************************************/
      /* Work out how much we can copy without worrying about segment */
      /* boundaries.                                                  */
      /****************************************************************/
      BytesLeftInSrcSeg  = 65536L - (ULONG)OFFSETOF(SPad->SrcPtr);
      BytesLeftInDestSeg = 65536L - (ULONG)OFFSETOF(SPad->DestPtr);
      ChunkLength = min3(BytesLeftInSrcSeg,
                        BytesLeftInDestSeg,
                        SPad->BytesToConvert);
      if (HIUSHORT(ChunkLength)) /* ChunkLength >= 65536L */
      {
          /************************************************************/
          /* We can't actually copy a full 65536 bytes at once        */
          /* because the last parameter of memcpy() is a word.        */
          /* Thus we reduce ChunkLength to 0x8000 and do the rest     */
          /* next time around.                                        */
          /************************************************************/
          ChunkLength = 0x8000;
      }
#endif
      /****************************************************************/
      /* Call memcpy to do the copy.                                  */
      /****************************************************************/
      prdu_memcpy( (PBYTE)SPad->DestPtr,
                   (PBYTE)SPad->SrcPtr,
                /* (USHORT)ChunkLength); */
                   SPad->BytesToConvert);                  /* CON3201 */

      /****************************************************************/
      /* Update the pointers and the numbe of bytes still to convert  */
      /****************************************************************/
   /* SPad->BytesToConvert       -= ChunkLength; */
   /* SPad->SrcPtr               += ChunkLength; */
   /* (PBYTE) SPad->DestPtr      += ChunkLength; */
      SPad->SrcPtr               += SPad->BytesToConvert;  /* CON3201 */
      SPad->DestPtr               = (PBYTE)SPad->DestPtr + /* CON3201 */
                                    SPad->BytesToConvert;  /* CON3201 */
      SPad->BytesToConvert        = 0;                     /* CON3201 */

      /* CON3201 : don't need the rest of this code                   */
#if 0
      /****************************************************************/
      /* Adjust segment boundaries if necessary                       */
      if (!OFFSETOF(SPad->SrcPtr))
          SELECTOROF(SPad->SrcPtr)  += prdd_HugeInc;
      if (!OFFSETOF(SPad->DestPtr))
          SELECTOROF(SPad->DestPtr) += prdd_HugeInc;
  } /* while bytes to convert */
#endif
} /* CopyInttoExt */
#undef TFUNC


/**********************************************************************/
/*                                                                    */
/*   FUNCTION: prdb_TransferInttoExt                                  */
/*                                                                    */
/*   PARAMETERS:                                                      */
/*   lpBMSPad          SPad        PD00400 :Pointer to bitmap scratch */
/*                                                                    */
/*   DESCRIPTION:                                                     */
/*                                                                    */
/*   This function transfers data from an internal to an external     */
/*   bitmap. We do the transfers line by line, and for each line we   */
/*   calculate in advance whether we will hit a segment boundary.     */
/*   Each of the routines convert_intX_to_extY which convert a line   */
/*   have two arms depending on whether the segment boundary flag is  */
/*   set. If there is a segment boundary somewhere in the line, the   */
/*   code uses the POSTINC macro for each increment of the pointers;  */
/*   otherwise it uses a plain ++ operation. This is a tradeoff which */
/*   gives a large increase in speed for an increase in occupancy.    */
/*                                                                    */
/**********************************************************************/

VOID prdb_TransferInttoExt( lpBMSPad SPad )

#if 0
lpBMSPad      SPad;              /* PD00400 : Pointer to bitmap scratch pad */
#endif

{

  ULONG  BytesPerLine;
  ULONG  TotalSrcBytesPerLine;
  ULONG  TotalDestBytesPerLine;
  ULONG  BytesLeftInSrcSeg, BytesLeftInDestSeg;
  USHORT  SrcPadLength, DestPadLength;
/*void (pascal near *inner_convert)(); */
  void (*inner_convert)();                                      /* CON3201 */
#define TFUNC "prdb_TransferInttoExt"

  /********************************************************************/
  /* Work out which routine will do the copying                       */
  /********************************************************************/
  if (SPad->IntBpp==1)
  {
     if (SPad->ExtBpp==4)
     {
         inner_convert = convert_int1_to_ext4;
     }
     else if (SPad->ExtBpp==8)
     {
         inner_convert = convert_int1_to_ext8;
     }
     else /* SPad->ExtBpp==24 */
     {
         inner_convert = convert_int1_to_ext24;
     }
  } /* SPad->IntBpp==1 */
  else /* SPad->IntBpp==4 */
  {
     if (SPad->ExtBpp==1)
     {
         inner_convert = convert_int4_to_ext1;
     }
     else if (SPad->ExtBpp==8)
     {
         inner_convert = convert_int4_to_ext8;
     }
     else /* SPad->ExtBpp==24 */
     {
         inner_convert = convert_int4_to_ext24;
     }
  } /* SPad->IntBpp==4 */

  /********************************************************************/
  /* We now set up variables concerning line lengths. We require this */
  /* information in several different forms, so we do all calculations*/
  /* outside the main copying loop. The usage of the various local    */
  /* variables is exemplified below.                                  */
  /*                                                                  */
  /* For example, if we are converting from 4bpp to 8bpp and we have  */
  /* a line length of 25 pels we would have:                          */
  /*                                                                  */
  /*   BytesPerLine          = 12    (12 full bytes)                  */
  /*   SPad->PelsLeftOver     = 1     (plus one pel=a nibble)          */
  /*   TotalSrcBytesPerLine  = 13    (makes a total 13 bytes)         */
  /*   SrcPadLength          = 3     (+3bytes to be DWORD aligned)    */
  /*   TotalDestBytesPerLine = 25                                     */
  /*   DestPadLength         = 3                                      */
  /*                                                                  */
  /* Or if we are converting from 1bpp to 24bpp and we have a line    */
  /* length of 85 pels we would have:                                 */
  /*                                                                  */
  /*   BytesPerLine          = 10    (10 full bytes)                  */
  /*   SPad->PelsLeftOver     = 5     (plus 5pels=5bits)               */
  /*   TotalSrcBytesPerLine  = 11    (makes a total 11 bytes)         */
  /*   SrcPadLength          = 1     (+1byte to be DWORD aligned)     */
  /*   TotalDestBytesPerLine = 255                                    */
  /*   DestPadLength         = 1                                      */
  /*                                                                  */
  /********************************************************************/

  /********************************************************************/
  /* Set up total number of bytes per line variables. These include   */
  /* any incomplete extra bytes at the end of the line.               */
  /********************************************************************/
  TotalSrcBytesPerLine  = (SPad->PelsPerLine * SPad->IntBpp + 7) / 8;

  /****************************************************************************/
  /* PD00708 : Added ULONG cast to prevent overflow for 24:1 bitmap           */
  /****************************************************************************/
  TotalDestBytesPerLine = ( (ULONG)SPad->PelsPerLine *
                                                 (ULONG)SPad->ExtBpp + 7) / 8;

  /********************************************************************/
  /* Set up pads to DWORD boundaries at ends of lines                 */
  /********************************************************************/
  if (SrcPadLength = (USHORT) (TotalSrcBytesPerLine % 4))
  {
      SrcPadLength  = 4 - SrcPadLength;
  }
  if (DestPadLength = (USHORT) (TotalDestBytesPerLine % 4))
  {
      DestPadLength = 4 - DestPadLength;
  }

  /********************************************************************/
  /* Set up line length in terms of whole source bytes (BytesPerLine) */
  /* and extra pels (PelsLeftOver).                                   */
  /********************************************************************/
  BytesPerLine      = (SPad->PelsPerLine * SPad->IntBpp) / 8;
  SPad->PelsLeftOver = (SPad->PelsPerLine * SPad->IntBpp) % 8;

  /********************************************************************/
  /* Main Loop: Loop through all of the lines to be converted.        */
  /********************************************************************/
  while (SPad->LinesToConvert--)
  {
      /****************************************************************/
      /* Check if it is possible that this line can overrun a segment */
      /* boundary.                                                    */
      /****************************************************************/
      /* CON3201 : don't have to worry about seg boundaries for       */
      /*           32-bit code                                        */
#if 0
      BytesLeftInSrcSeg  = 65536L - (ULONG)OFFSETOF(SPad->SrcPtr);
      BytesLeftInDestSeg = 65536L - (ULONG)OFFSETOF(SPad->DestPtr);

      SPad->Safe = ((TotalDestBytesPerLine < BytesLeftInDestSeg) &&
                   (TotalSrcBytesPerLine  < BytesLeftInSrcSeg));
#endif
      SPad->Safe = TRUE;                                   /* CON3201 */

      /****************************************************************/
      /* Call a routine to convert one line. This routine will        */
      /* update SPad->SrcPtr and SPad->DestPtr to point just past the   */
      /* end of the line.                                             */
      /****************************************************************/
      SPad->ChunkLength = BytesPerLine;
      (VOID) inner_convert( SPad );

      /****************************************************************/
      /* Now move to DWORD boundaries, as each line must start on a   */
      /* DWORD boundary.                                              */
      /****************************************************************/
      SPad->SrcPtr  += SrcPadLength;
   /* (PBYTE)SPad->DestPtr += DestPadLength; */
      SPad->DestPtr  = (PBYTE)SPad->DestPtr + DestPadLength; /*CON3201*/

      /****************************************************************/
      /* Check whether this last action has brought us to the start   */
      /* of a new segment, and if so adjust accordingly.              */
      /****************************************************************/
      /* CON3201 : don't worry about segments for 32-bit code         */
#if 0
      if (SrcPadLength && !OFFSETOF(SPad->SrcPtr))
          SELECTOROF(SPad->SrcPtr) += prdd_HugeInc;
      if (DestPadLength && !OFFSETOF(SPad->DestPtr))
          SELECTOROF(SPad->DestPtr) += prdd_HugeInc;
#endif

  } /* looping through lines to convert */
} /* TransferInttoExt */


  PBYTE   pTemp;            /* CON3201 : temp pointer      */
  PUSHORT  pSTemp;           /* CON3201 : temp pointer      */
  PULONG  pLTemp;           /* CON3201 : temp pointer      */

/**********************************************************************/
/*                                                                    */
/*   FUNCTION: convert_intX_to_extY                                   */
/*                                                                    */
/*   PARAMETERS:                                                      */
/*   lpBMSPad          SPad        PD00400 :Pointer to bitmap scratch */
/*                                                                    */
/*   DESCRIPTION:                                                     */
/*                                                                    */
/*   These functions all transfer one whole line from the internal    */
/*   bitmap to the external bitmap, performing any necessary colour   */
/*   conversions. They take their parameters from the scratchpad      */
/*   area SPad, mainly using the fields:                              */
/*                                                                    */
/*     SPad->ChunkLength       Number of whole bytes to convert        */
/*     SPad->PelsLeftOver      Number of pels in incomplete last byte  */
/*     SPad->Col.ConvertTable  Colour conversion table (array of bytes)*/
/*     SPad->Safe              Indicates whether to check for segment  */
/*                            boundaries or not.                      */
/*     SPad->SrcPtr            Pointer to current position in external */
/*                            bitmap                                  */
/*     SPad->DestPtr           Pointer to current position in internal */
/*                            bitmap                                  */
/*                                                                    */
/*   Each routine contains two arms, depending on the value of        */
/*   SPad->Safe. If it is TRUE, this means that there are no segment   */
/*   boundaries contained in this line, and thus we can use the       */
/*   increment (++) operator on pointers to increase speed. The       */
/*   second arm is the same as the first, but with increments         */
/*   replaced with the POSTINC macro, which checks for segment        */
/*   boundaries. It is IMPERATIVE that if you change any of these     */
/*   routines that you make sure to change BOTH arms in the same way. */
/*                                                                    */
/*   Also note that, since each line in the bitmap will always start  */
/*   on a DWORD (4 byte) boundary, in some cases we can use the       */
/*   increment (++) operator in the segment boundary checking arm.    */
/*                                                                    */
/**********************************************************************/

VOID convert_int1_to_ext4( lpBMSPad SPad )
#if 0
lpBMSPad      SPad;              /* PD00400 : Pointer to bitmap scratch pad */
#endif

{

  BYTE SrcByte;
  BYTE DestByte=0;
  int NibbleIndicator = 4; /* always start on high nibble */
  int BitIndicator = 7;    /* always start on top bit     */

  /********************************************************************/
  /* See if we need to worry about segment boundaries.                */
  /* CON3201 : don't have to worry about segment boundaries for       */
  /*           32-bit code                                            */
  /********************************************************************/
#if 0
  if (SPad->Safe)
  {
#endif
      /****************************************************************/
      /* Loop through converting all the source bytes in the line. We */
      /* know that we don't need to worry about segment boundaries.   */
      /* We do 4 pels at a time, using the lookup table. This maps    */
      /* 4 source bits to 2 destination bytes.                        */
      /****************************************************************/
      while (SPad->ChunkLength--)
      {
          SrcByte = *SPad->SrcPtr++;
       /* *((PUSHORT) SPad->DestPtr)++ =                                 */
       /*                              ConvertTablei1toe4[SrcByte >> 4]; */
       /* *((PUSHORT) SPad->DestPtr)++ =                                 */
       /*                            ConvertTablei1toe4[SrcByte & 0x0f]; */
          pSTemp = (PUSHORT) SPad->DestPtr;                 /* CON3201 */
          *pSTemp++ = ConvertTablei1toe4[SrcByte >> 4];    /* CON3201 */
          *pSTemp++ = ConvertTablei1toe4[SrcByte & 0x0f];  /* CON3201 */
          SPad->DestPtr = (PVOID)pSTemp;                   /* CON3201 */
      } /* while source bytes left */

      /****************************************************************/
      /* We may have some pels left over to convert from the next     */
      /* source byte.                                                 */
      /****************************************************************/
      if (SPad->PelsLeftOver)
      {
          SrcByte = *SPad->SrcPtr++;
          /************************************************************/
          /* Loop through the remaining pels, starting with the first */
          /* pel, which is the top bit.                               */
          /************************************************************/
          for (;BitIndicator > (7 - SPad->PelsLeftOver); BitIndicator--)
          {
              /********************************************************/
              /* Check whether the pel is a one or a zero.            */
              /********************************************************/
              if (SrcByte & (1 << BitIndicator))
              {
                  /****************************************************/
                  /* This pel is a one - fill either the high or low  */
                  /* nibble of the destination byte with 0xF          */
                  /****************************************************/
                  DestByte |= (0x0f << NibbleIndicator);
              }

              /********************************************************/
              /* Move to the next nibble of the destination byte. If  */
              /* the NibbleIndicator is now 4 then this means that    */
              /* we have dealt with the low nibble of DestByte, and   */
              /* thus we should write DestByte to the bitmap and      */
              /* then clear it.                                       */
              /********************************************************/
              if (NibbleIndicator ^= 4)
              {
               /* *((PBYTE) SPad->DestPtr)++ = DestByte; */
                  pTemp         = SPad->DestPtr;           /* CON3201 */
                  *pTemp++      = DestByte;                /* CON3201 */
                  SPad->DestPtr = pTemp;                   /* CON3201 */
                  DestByte = 0;
              }
          } /* looping through the leftover pels */

          /************************************************************/
          /* We may have finished halfway through a destination byte  */
          /* - if so, we need to write it.                            */
          /************************************************************/
          if (!NibbleIndicator)
          {
           /* *((PBYTE) SPad->DestPtr)++ = DestByte; */
              pTemp         = SPad->DestPtr;               /* CON3201 */
              *pTemp++      = DestByte;                    /* CON3201 */
              SPad->DestPtr = pTemp;                       /* CON3201 */
          }
      } /* pels left over to convert */
  /********************************************************************/
  /* CON3201 : don't have to worry about segment boundaries for       */
  /*           32-bit code                                            */
  /********************************************************************/
#if 0
  } /* no segment boundaries to worry about */
  else
  {
      /****************************************************************/
      /* Loop through converting all the source bytes in the line. We */
      /* use the POSTINC macro to check for segment boundaries.       */
      /* We do 4 pels at a time, using the lookup table. This maps    */
      /* 4 source bits to 2 destination bytes.                        */
      /*                                                              */
      /* Although we need to check for segment boundaries, as we know */
      /* that both lines and segments start on DWORD boundaries, in   */
      /* the following loop, we only check for segment boundaries on  */
      /* every fourth destination byte.                               */
      /*   NOW every second destination byte (PD00680).               */
      /****************************************************************/
      /* NOTE: The casting to "(PUSHORT)" below causes the "++" to    */
      /*       increment by 2.                                        */
      /*       The casting to "(PBYTE)" below allows the "++" to      */
      /*       increment by 1.                                        */
      /*       POSTINC always increments by 1.                        */
      /****************************************************************/
      while (SPad->ChunkLength--)
      {
          SrcByte = *SPad->SrcPtr;
          POSTINC(SPad->SrcPtr);
          *((PUSHORT) SPad->DestPtr) =                            /* PD00680 */
                                       ConvertTablei1toe4[SrcByte >> 4];
          ((PBYTE) SPad->DestPtr)++; /* increment by 2 */         /* PD00680 */
          POSTINC(SPad->DestPtr);                                 /* PD00680 */
          *((PUSHORT) SPad->DestPtr)=
                                     ConvertTablei1toe4[SrcByte & 0x0f];
          ((PBYTE) SPad->DestPtr)++;
          POSTINC(SPad->DestPtr);  /* we can put 4 at a time */
      } /* while source bytes left */

      /****************************************************************/
      /* We may have some pels left over to convert from the next     */
      /* source byte.                                                 */
      /****************************************************************/
      if (SPad->PelsLeftOver)
      {
          SrcByte = *SPad->SrcPtr;
          POSTINC(SPad->SrcPtr);
          /************************************************************/
          /* Loop through the remaining pels, starting with the first */
          /* pel, which is the top bit.                               */
          /************************************************************/
          for (;BitIndicator > (7 - SPad->PelsLeftOver); BitIndicator--)
          {
              /********************************************************/
              /* Check whether the pel is a one or a zero             */
              /********************************************************/
              if (SrcByte & (1 << BitIndicator))
              {
                  /****************************************************/
                  /* This pel is a one - fill either the high or low  */
                  /* nibble of the destination byte with 0xF          */
                  /****************************************************/
                  DestByte |= (0x0f << NibbleIndicator);
              }

              /********************************************************/
              /* Move to the next nibble of the destination byte. If  */
              /* the NibbleIndicator is now 4 then this means that    */
              /* we have dealt with the low nibble of DestByte, and   */
              /* thus we should write DestByte to the bitmap and      */
              /* then clear it.                                       */
              /********************************************************/
              if (NibbleIndicator ^= 4)
              {
                  *((PBYTE) SPad->DestPtr) = DestByte;
                  POSTINC(SPad->DestPtr);
                  DestByte = 0;
              }
          } /* looping through the leftover pels */
          /************************************************************/
          /* We may have finished halfway through a destination byte  */
          /* - if so, we need to write it.                            */
          /************************************************************/
          if (!NibbleIndicator)
          {
              *((PBYTE) SPad->DestPtr) = DestByte;
              POSTINC(SPad->DestPtr);
          }
      } /* pels left over to convert */
  } /* checking for segment boundaries */
#endif
} /* convert_int1_to_ext4 */

/**********************************************************************/
/*                                                                    */
/*   FUNCTION: convert_int1_to_ext8                                   */
/*                                                                    */
/*   PARAMETERS:                                                      */
/*   lpBMSPad          SPad                                           */
/*                                                                    */
/*   DESCRIPTION:                                                     */
/*                                                                    */
/**********************************************************************/

VOID  convert_int1_to_ext8( lpBMSPad SPad )
#if 0
lpBMSPad      SPad;              /* PD00400 : Pointer to bitmap scratch pad */
#endif

{

  BYTE SrcByte;
  int BitIndicator = 7;    /* always start on top bit     */

  /********************************************************************/
  /* See if we need to worry about segment boundaries.                */
  /* CON3201 : don't have to worry about segment boundaries for       */
  /*           32-bit code                                            */
  /********************************************************************/
#if 0
  if (SPad->Safe)
  {
#endif
      /****************************************************************/
      /* Loop through converting all the source bytes in the line. We */
      /* know that we don't need to worry about segment boundaries.   */
      /* We do 4 pels at a time, using the lookup table. This maps    */
      /* 4 source bits to 4 destination bytes.                        */
      /****************************************************************/
      while (SPad->ChunkLength--)
      {
          SrcByte  = *SPad->SrcPtr++;
       /* *((PULONG) SPad->DestPtr)++ =                                  */
       /*                              ConvertTablei1toe8[SrcByte >> 4]; */
       /* *((PULONG) SPad->DestPtr)++ =                                  */
       /*                            ConvertTablei1toe8[SrcByte & 0x0f]; */
          pLTemp =  SPad->DestPtr;                         /* CON3201 */
          *pLTemp++ = ConvertTablei1toe8[SrcByte >> 4];    /* CON3201 */
          *pLTemp++ = ConvertTablei1toe8[SrcByte & 0x0f];  /* CON3201 */
          SPad->DestPtr = pLTemp;                          /* CON3201 */
      } /* while source bytes left */

      /****************************************************************/
      /* We may have some pels left over to convert from the next     */
      /* source byte.                                                 */
      /****************************************************************/
      if (SPad->PelsLeftOver)
      {
          SrcByte = *SPad->SrcPtr++;
          /************************************************************/
          /* Loop through the remaining pels, starting with the first */
          /* pel, which is the top bit.                               */
          /************************************************************/
          for (;BitIndicator > (7 - SPad->PelsLeftOver); BitIndicator--)
          {
              /********************************************************/
              /* Check whether the pel is a one or a zero             */
              /********************************************************/
              if (SrcByte & (1 << BitIndicator))
              {
               /* *((PBYTE) SPad->DestPtr)++ = 0xFF; */
                  pTemp         = SPad->DestPtr;           /* CON3201 */
                  *pTemp++      = 0xFF;                    /* CON3201 */
                  SPad->DestPtr = pTemp;                   /* CON3201 */
              }
              else /* pel is a zero */
              {
               /* *((PBYTE) SPad->DestPtr)++ = 0; */
                  pTemp         = SPad->DestPtr;           /* CON3201 */
                  *pTemp++      = 0;                       /* CON3201 */
                  SPad->DestPtr = pTemp;                   /* CON3201 */
              }
          } /* looping through the leftover pels */
      } /* pels left over to convert */
  /********************************************************************/
  /* CON3201 : don't have to worry about segment boundaries for       */
  /*           32-bit code                                            */
  /********************************************************************/
#if 0
  } /* no segment boundaries to worry about */
  else
  {
      /****************************************************************/
      /* Loop through converting all the source bytes in the line. We */
      /* use the POSTINC macro to check for segment boundaries.       */
      /* We do 4 pels at a time, using the lookup table. This maps    */
      /* 4 source bits to 4 destination bytes.                        */
      /*                                                              */
      /* Although we need to check for segment boundaries, as we know */
      /* that both lines and segments start on DWORD boundaries, in   */
      /* the following loop, we only check for segment boundaries on  */
      /* every fourth destination byte.                               */
      /*   NOW every second destination byte (PD00680).               */
      /****************************************************************/
      /* NOTE: The casting to "(PBYTE)" below allows the "++" to      */
      /*       increment by 1.                                        */
      /*       POSTINC always increments by 1.                        */
      /****************************************************************/
      while (SPad->ChunkLength--)
      {
          SrcByte  = *SPad->SrcPtr;
          POSTINC(SPad->SrcPtr);
          *((PULONG) SPad->DestPtr) =
                                       ConvertTablei1toe8[SrcByte >> 4];
          ((PBYTE)SPad->DestPtr)++;                               /* PD00680 */
          POSTINC(SPad->DestPtr);                                 /* PD00680 */
          ((PBYTE)SPad->DestPtr)++;                               /* PD00680 */
          POSTINC(SPad->DestPtr);
          *((PULONG) SPad->DestPtr) =
                                     ConvertTablei1toe8[SrcByte & 0x0f];
          ((PBYTE)SPad->DestPtr)++;                               /* PD00680 */
          POSTINC(SPad->DestPtr);                                 /* PD00680 */
          ((PBYTE)SPad->DestPtr)++;                               /* PD00680 */
          POSTINC(SPad->DestPtr);
      } /* while source bytes left */

      /****************************************************************/
      /* We may have some pels left over to convert from the next     */
      /* source byte.                                                 */
      /****************************************************************/
      if (SPad->PelsLeftOver)
      {
          SrcByte = *SPad->SrcPtr;
          POSTINC(SPad->SrcPtr);
          /************************************************************/
          /* Loop through the remaining pels, starting with the first */
          /* pel, which is the top bit.                               */
          /************************************************************/
          for (;BitIndicator > (7 - SPad->PelsLeftOver); BitIndicator--)
          {
              /********************************************************/
              /* Check whether the pel is a one or a zero             */
              /********************************************************/
              if (SrcByte & (1 << BitIndicator))
              {
                  *((PBYTE) SPad->DestPtr) = 0xFF;
                  POSTINC(SPad->DestPtr);
              }
              else /* pel is a zero */
              {
                  *((PBYTE) SPad->DestPtr) = 0;
                  POSTINC(SPad->DestPtr);
              }
          } /* looping through the leftover pels */
      } /* pels left over to convert */
  } /* checking for segment boundaries */
#endif
} /* convert_int1_to_ext8 */

/**********************************************************************/
/*                                                                    */
/*   FUNCTION: convert_int1_to_ext24                                  */
/*                                                                    */
/*   PARAMETERS:                                                      */
/*   lpBMSPad          SPad                                           */
/*                                                                    */
/*   DESCRIPTION:                                                     */
/*                                                                    */
/**********************************************************************/

VOID convert_int1_to_ext24( lpBMSPad SPad )
#if 0
lpBMSPad      SPad;              /* PD00400 : Pointer to bitmap scratch pad */
#endif

{

  BYTE SrcByte;
  int BitIndicator;

  /********************************************************************/
  /* See if we need to worry about segment boundaries.                */
  /* CON3201 : don't have to worry about segment boundaries for       */
  /*           32-bit code                                            */
  /********************************************************************/
#if 0
  if (SPad->Safe)
  {
#endif
      /****************************************************************/
      /* Loop through converting all the source bytes in the line. We */
      /* know that we don't have to worry about segment boundaries.   */
      /****************************************************************/
      while (SPad->ChunkLength--)
      {
          SrcByte = *SPad->SrcPtr++;
          /************************************************************/
          /* Loop through all the pels in each full source byte,      */
          /* starting at the first pel which is the top bit.          */
          /************************************************************/
          for (BitIndicator=7 ; BitIndicator >= 0 ; BitIndicator--)
          {
              /********************************************************/
              /* Check whether the pel is a one or a zero             */
              /********************************************************/
              if (SrcByte & (1 << BitIndicator))
              {
               /* *((PBYTE) SPad->DestPtr)++ = (BYTE)0xFF; */
               /* *((PBYTE) SPad->DestPtr)++ = (BYTE)0xFF; */
               /* *((PBYTE) SPad->DestPtr)++ = (BYTE)0xFF; */
                  pTemp         = SPad->DestPtr;           /* CON3201 */
                  *pTemp++      = 0xFF;                    /* CON3201 */
                  *pTemp++      = 0xFF;                    /* CON3201 */
                  *pTemp++      = 0xFF;                    /* CON3201 */
                  SPad->DestPtr = pTemp;                   /* CON3201 */
              }
              else /* pel is a zero */
              {
               /* *((PBYTE) SPad->DestPtr)++ = (BYTE)0x00; */
               /* *((PBYTE) SPad->DestPtr)++ = (BYTE)0x00; */
               /* *((PBYTE) SPad->DestPtr)++ = (BYTE)0x00; */
                  pTemp         = SPad->DestPtr;           /* CON3201 */
                  *pTemp++      = 0x00;                    /* CON3201 */
                  *pTemp++      = 0x00;                    /* CON3201 */
                  *pTemp++      = 0x00;                    /* CON3201 */
                  SPad->DestPtr = pTemp;                   /* CON3201 */
              }
          } /* looping through the pels */
      } /* while source bytes left */

      /****************************************************************/
      /* We may have some pels left over to convert from the next     */
      /* source byte.                                                 */
      /****************************************************************/
      if (SPad->PelsLeftOver)
      {
          SrcByte = *SPad->SrcPtr++;
          /************************************************************/
          /* Loop through the remaining pels, starting with the first */
          /* pel, which is the top bit.                               */
          /************************************************************/
          for (BitIndicator=7; BitIndicator > (7 - SPad->PelsLeftOver);
               BitIndicator--)
          {
              /********************************************************/
              /* Check whether the pel is a one or a zero             */
              /********************************************************/
              if (SrcByte & (1 << BitIndicator))
              {
               /* *((PBYTE) SPad->DestPtr)++ = (BYTE)0xFF; */
               /* *((PBYTE) SPad->DestPtr)++ = (BYTE)0xFF; */
               /* *((PBYTE) SPad->DestPtr)++ = (BYTE)0xFF; */
                  pTemp         = SPad->DestPtr;           /* CON3201 */
                  *pTemp++      = 0xFF;                    /* CON3201 */
                  *pTemp++      = 0xFF;                    /* CON3201 */
                  *pTemp++      = 0xFF;                    /* CON3201 */
                  SPad->DestPtr = pTemp;                   /* CON3201 */
              }
              else /* pel is a zero */
              {
               /* *((PBYTE) SPad->DestPtr)++ = (BYTE)0x00; */
               /* *((PBYTE) SPad->DestPtr)++ = (BYTE)0x00; */
               /* *((PBYTE) SPad->DestPtr)++ = (BYTE)0x00; */
                  pTemp         = SPad->DestPtr;           /* CON3201 */
                  *pTemp++      = 0x00;                    /* CON3201 */
                  *pTemp++      = 0x00;                    /* CON3201 */
                  *pTemp++      = 0x00;                    /* CON3201 */
                  SPad->DestPtr = pTemp;                   /* CON3201 */
              }
          } /* looping through the leftover pels */
      } /* pels left over to convert */
  /********************************************************************/
  /* CON3201 : don't have to worry about segment boundaries for       */
  /*           32-bit code                                            */
  /********************************************************************/
#if 0
  } /* no segment boundaries to worry about */
  else
  {
      /****************************************************************/
      /* Loop through converting all the source bytes in the line. We */
      /* use the POSTINC macro to check for segment boundaries.       */
      /****************************************************************/
      while (SPad->ChunkLength--)
      {
          SrcByte = *SPad->SrcPtr;
          POSTINC(SPad->SrcPtr);
          /************************************************************/
          /* Loop through all the pels in each full source byte,      */
          /* starting at the first pel which is the top bit.          */
          /************************************************************/
          for (BitIndicator=7 ; BitIndicator >= 0 ; BitIndicator--)
          {
              /********************************************************/
              /* Check whether the pel is a one or a zero             */
              /********************************************************/
              if (SrcByte & (1 << BitIndicator))
              {
                  *((PBYTE) SPad->DestPtr) = (BYTE)0xFF;
                  POSTINC(SPad->DestPtr);
                  *((PBYTE) SPad->DestPtr) = (BYTE)0xFF;
                  POSTINC(SPad->DestPtr);
                  *((PBYTE) SPad->DestPtr) = (BYTE)0xFF;
                  POSTINC(SPad->DestPtr);
              }
              else /* pel is a zero */
              {
                  *((PBYTE) SPad->DestPtr) = (BYTE)0x00;
                  POSTINC(SPad->DestPtr);
                  *((PBYTE) SPad->DestPtr) = (BYTE)0x00;
                  POSTINC(SPad->DestPtr);
                  *((PBYTE) SPad->DestPtr) = (BYTE)0x00;
                  POSTINC(SPad->DestPtr);
              }
          } /* looping through the pels */
      } /* while source bytes left */

      /****************************************************************/
      /* We may have some pels left over to convert from the next     */
      /* source byte.                                                 */
      /****************************************************************/
      if (SPad->PelsLeftOver)
      {
          SrcByte = *SPad->SrcPtr;
          POSTINC(SPad->SrcPtr);
          /************************************************************/
          /* Loop through the remaining pels, starting with the first */
          /* pel, which is the top bit.                               */
          /************************************************************/
          for (BitIndicator=7; BitIndicator > (7 - SPad->PelsLeftOver);
               BitIndicator--)
          {
              /********************************************************/
              /* Check whether the pel is a one or a zero             */
              /********************************************************/
              if (SrcByte & (1 << BitIndicator))
              {
                  *((PBYTE) SPad->DestPtr) = (BYTE)0xFF;
                  POSTINC(SPad->DestPtr);
                  *((PBYTE) SPad->DestPtr) = (BYTE)0xFF;
                  POSTINC(SPad->DestPtr);
                  *((PBYTE) SPad->DestPtr) = (BYTE)0xFF;
                  POSTINC(SPad->DestPtr);
              }
              else
              {
                  *((PBYTE) SPad->DestPtr) = (BYTE)0x00;
                  POSTINC(SPad->DestPtr);
                  *((PBYTE) SPad->DestPtr) = (BYTE)0x00;
                  POSTINC(SPad->DestPtr);
                  *((PBYTE) SPad->DestPtr) = (BYTE)0x00;
                  POSTINC(SPad->DestPtr);
              }
          } /* looping through the leftover pels */
      } /* pels left over to convert */
  } /* checking for segment boundaries */
#endif
} /* convert_int1_to_ext24 */

/**********************************************************************/
/*                                                                    */
/*   FUNCTION: convert_int4_to_ext1                                   */
/*                                                                    */
/*   PARAMETERS:                                                      */
/*   lpBMSPad          SPad                                           */
/*                                                                    */
/*   DESCRIPTION:                                                     */
/*                                                                    */
/**********************************************************************/

VOID convert_int4_to_ext1( lpBMSPad SPad )
#if 0
lpBMSPad      SPad;              /* PD00400 : Pointer to bitmap scratch pad */
#endif

{

  BYTE SrcByte, DestByte;
/*USHORT BytesToConvert; */
  ULONG  BytesToConvert;                                   /* CON3201 */
  int BitIndicator = 7;

  /********************************************************************/
  /* See if we need to worry about segment boundaries.                */
  /* CON3201 : don't have to worry about segment boundaries for       */
  /*           32-bit code                                            */
  /********************************************************************/
#if 0
  if (SPad->Safe)
  {
#endif
      /****************************************************************/
      /* Loop through converting four source bytes to one target byte.*/
      /* We don't need to worry about segment boundaries.             */
      /****************************************************************/
   /* BytesToConvert = (USHORT) (SPad->ChunkLength / 4); */
      BytesToConvert = (SPad->ChunkLength / 4);            /* CON3201 */
      while (BytesToConvert--)
      {
          /************************************************************/
          /* Note : it is possible that, although we only use colours */
          /* 0 to 7 internally, that the top bit of each nibble may   */
          /* be set, owing to masking operations. Hence we need to    */
          /* clear the top bit of each nibble.                        */
          /************************************************************/
          SrcByte   = *SPad->SrcPtr++;
          DestByte  = ConvertTablei4toe1[(SrcByte>>4) & 0x07] << 7 |
                      ConvertTablei4toe1[SrcByte & 0x07] << 6;
          SrcByte   = *SPad->SrcPtr++;
          DestByte |= ConvertTablei4toe1[(SrcByte>>4) & 0x07] << 5 |
                      ConvertTablei4toe1[SrcByte & 0x07] << 4;
          SrcByte   = *SPad->SrcPtr++;
          DestByte |= ConvertTablei4toe1[(SrcByte>>4) & 0x07] << 3 |
                      ConvertTablei4toe1[SrcByte & 0x07] << 2;
          SrcByte   = *SPad->SrcPtr++;
       /* *((PBYTE)SPad->DestPtr)++ = DestByte | */
          pTemp         = SPad->DestPtr;                   /* CON3201 */
          *pTemp++  = DestByte |                           /* CON3201 */
                      ConvertTablei4toe1[(SrcByte>>4) & 0x07] << 1 |
                      ConvertTablei4toe1[SrcByte & 0x07];
          SPad->DestPtr = pTemp;                           /* CON3201 */
      } /* while a set of four bytes left to convert */
      DestByte = 0; /* clear ready for any leftovers */

      /****************************************************************/
      /* We may have up to three full source bytes still to convert.  */
      /****************************************************************/
      for (BytesToConvert = 0;
           BytesToConvert < (USHORT) (SPad->ChunkLength % 4);
           BytesToConvert++)
      {
          SrcByte = *SPad->SrcPtr++;
          DestByte |=
                 ConvertTablei4toe1[(SrcByte>>4)&0x07] << BitIndicator |
                 ConvertTablei4toe1[SrcByte&0x07] << (BitIndicator - 1);
          BitIndicator -= 2;
      }

      /****************************************************************/
      /* We may have one pel left over still to convert.              */
      /****************************************************************/
      if (SPad->PelsLeftOver)
      {
          SrcByte = *SPad->SrcPtr++;
          DestByte |=
              ConvertTablei4toe1[(SrcByte>>4) & 0x07] << BitIndicator--;
      }

      if (BitIndicator < 7) /* need to write this last byte */
      {
       /* *((PBYTE)SPad->DestPtr)++ = DestByte; */
          pTemp         = SPad->DestPtr;                   /* CON3201 */
          *pTemp++      = DestByte;                        /* CON3201 */
          SPad->DestPtr = pTemp;                           /* CON3201 */
      }
  /********************************************************************/
  /* CON3201 : don't have to worry about segment boundaries for       */
  /*           32-bit code                                            */
  /********************************************************************/
#if 0
  } /* no segment boundaries to worry about */
  else
  {
      /****************************************************************/
      /* Loop through converting four source bytes to one target byte.*/
      /* We use POSTINC to check for segment boundaries.              */
      /****************************************************************/
      BytesToConvert = (USHORT) (SPad->ChunkLength / 4);
      while (BytesToConvert)
      {
          /************************************************************/
          /* Although we need to check for segment boundaries, as we  */
          /* know that both lines and segments start on DWORD         */
          /* boundaries, in the following code, we only check for     */
          /* segment boundaries every fourth source byte.             */
          /*   NOW every second source byte (PD00680).                */
          /*                                                          */
          /* Note : it is possible that, although we only use colours */
          /* 0 to 7 internally, that the top bit of each nibble may   */
          /* be set, owing to masking operations. Hence we need to    */
          /* clear the top bit.                                       */
          /************************************************************/
          SrcByte   = *SPad->SrcPtr++;
          DestByte  = ConvertTablei4toe1[(SrcByte>>4)&0x07] << 7 |
                      ConvertTablei4toe1[SrcByte&0x07] << 6;
          SrcByte   = *SPad->SrcPtr;                              /* PD00680 */
          POSTINC(SPad->SrcPtr); /* check every 2nd byte */       /* PD00680 */
          DestByte |= ConvertTablei4toe1[(SrcByte>>4)&0x07] << 5 |
                      ConvertTablei4toe1[SrcByte&0x07] << 4;
          SrcByte   = *SPad->SrcPtr++;
          DestByte |= ConvertTablei4toe1[(SrcByte>>4)&0x07] << 3 |
                      ConvertTablei4toe1[SrcByte&0x07] << 2;
          SrcByte   = *SPad->SrcPtr;
          POSTINC(SPad->SrcPtr); /* we can do 4 at a time */
          *((PBYTE)SPad->DestPtr) = DestByte |
                      ConvertTablei4toe1[(SrcByte>>4)&0x07] << 1 |
                      ConvertTablei4toe1[SrcByte&0x07];
          POSTINC(SPad->DestPtr);
          BytesToConvert--;
      } /* while a set of four bytes left to convert */
      DestByte = 0;

      /****************************************************************/
      /* We may have up to three full source bytes still to convert.  */
      /* The first of these must start on a DWORD boundary, and thus  */
      /* as we are examining at most three souce bytes, we don't need */
      /* to check for source segment boundaries in this loop.         */
      /****************************************************************/
      for (BytesToConvert = 0;
           BytesToConvert < (USHORT) (SPad->ChunkLength % 4);
           BytesToConvert++)
      {
          SrcByte = *SPad->SrcPtr;                                /* PD00680 */
          POSTINC(SPad->SrcPtr);                                  /* PD00680 */
          DestByte |=
                 ConvertTablei4toe1[(SrcByte>>4)&0x07] << BitIndicator |
                 ConvertTablei4toe1[SrcByte&0x07] << (BitIndicator-1);
          BitIndicator -= 2;
      }

      /****************************************************************/
      /* We may have one pel left over still to convert.              */
      /****************************************************************/
      if (SPad->PelsLeftOver)
      {
          SrcByte = *SPad->SrcPtr;
          POSTINC(SPad->SrcPtr);
          DestByte |=
                 ConvertTablei4toe1[(SrcByte>>4)&0x07]<<BitIndicator--;
      }

      if (BitIndicator < 7) /* need to write this last byte */
      {
          *((PBYTE)SPad->DestPtr) = DestByte;
          POSTINC(SPad->DestPtr);
      }
  } /* checking for segment boundaries */
#endif
} /* convert_int4_to_ext1 */

/**********************************************************************/
/*                                                                    */
/*   FUNCTION: convert_int4_to_ext8                                   */
/*                                                                    */
/*   PARAMETERS:                                                      */
/*   lpBMSPad          SPad                                           */
/*                                                                    */
/*   DESCRIPTION:                                                     */
/*                                                                    */
/**********************************************************************/

VOID convert_int4_to_ext8( lpBMSPad SPad )
#if 0
lpBMSPad      SPad;              /* PD00400 : Pointer to bitmap scratch pad */
#endif

{

  BYTE SrcByte;

  /********************************************************************/
  /* See if we need to worry about segment boundaries.                */
  /* CON3201 : don't have to worry about segment boundaries for       */
  /*           32-bit code                                            */
  /********************************************************************/
#if 0
  if (SPad->Safe)
  {
#endif
      /****************************************************************/
      /* Loop through converting all the source bytes in the line. We */
      /* know that we don't have to worry about segment boundaries.   */
      /****************************************************************/
      while (SPad->ChunkLength--)
      {
          SrcByte = *SPad->SrcPtr++;
          /************************************************************/
          /* Note : it is possible that, although we only use colours */
          /* 0 to 7 internally, that the top bit of each nibble may   */
          /* be set, owing to masking operations. Hence we need to    */
          /* clear the top bit of each nibble.                        */
          /************************************************************/
       /* *((PBYTE)SPad->DestPtr)++ = (SrcByte >> 4) & 0x07; */
       /* *((PBYTE)SPad->DestPtr)++ = SrcByte & 0x07;        */
          pTemp         = SPad->DestPtr;                   /* CON3201 */
          *pTemp++      = (SrcByte >> 4) & 0x07;           /* CON3201 */
          *pTemp++      = SrcByte & 0x07;                  /* CON3201 */
          SPad->DestPtr = pTemp;                           /* CON3201 */
      } /* while source bytes left */

      /****************************************************************/
      /* We may have one pel left over to convert                     */
      /****************************************************************/
      if (SPad->PelsLeftOver)
      {
          SrcByte = *SPad->SrcPtr++;
       /* *((PBYTE)SPad->DestPtr)++ = (SrcByte >> 4) & 0x07; */
          pTemp         = SPad->DestPtr;                   /* CON3201 */
          *pTemp++      = (SrcByte >> 4) & 0x07;           /* CON3201 */
          SPad->DestPtr = pTemp;                           /* CON3201 */
      } /* pel left over to convert */
  /********************************************************************/
  /* CON3201 : don't have to worry about segment boundaries for       */
  /*           32-bit code                                            */
  /********************************************************************/
#if 0
  } /* no segment boundaries to worry about */
  else
  {
      /****************************************************************/
      /* Loop through converting all the source bytes in the line. We */
      /* use POSTINC to check for segment boundaries.                 */
      /****************************************************************/
      while (SPad->ChunkLength--)
      {
          SrcByte = *SPad->SrcPtr;
          POSTINC(SPad->SrcPtr);
          /************************************************************/
          /* Although we need to check for segment boundaries, as we  */
          /* know that both lines and segments start on DWORD         */
          /* boundaries, in the following code, we only check for     */
          /* segment boundaries every second destination byte.        */
          /*                                                          */
          /* Note : it is possible that, although we only use colours */
          /* 0 to 7 internally, that the top bit of each nibble may   */
          /* be set, owing to masking operations. Hence we need to    */
          /* clear the top bit.                                       */
          /************************************************************/
          *((PBYTE)SPad->DestPtr)++ = (SrcByte >> 4) & 0x07;
          *((PBYTE)SPad->DestPtr) = SrcByte & 0x07;
          POSTINC(SPad->DestPtr); /* only check every 2nd byte */
      } /* while source bytes left */

      /****************************************************************/
      /* We may have one pel left over to convert                     */
      /****************************************************************/
      if (SPad->PelsLeftOver)
      {
          SrcByte = *SPad->SrcPtr;
          POSTINC(SPad->SrcPtr);
          *((PBYTE)SPad->DestPtr) = (SrcByte >> 4) & 0x07;
          POSTINC(SPad->DestPtr);
      } /* pel left over to convert */
  } /* checking for segment boundaries */
#endif
} /* convert_int4_to_ext8 */

/**********************************************************************/
/*                                                                    */
/*   FUNCTION: convert_int4_to_ext24                                  */
/*                                                                    */
/*   PARAMETERS:                                                      */
/*   lpBMSPad          SPad                                           */
/*                                                                    */
/*   DESCRIPTION:                                                     */
/*                                                                    */
/**********************************************************************/

VOID convert_int4_to_ext24( lpBMSPad SPad )
#if 0
lpBMSPad      SPad;              /* PD00400 : Pointer to bitmap scratch pad */
#endif

{

  BYTE SrcByte;
  RGB2    *prgbTemp;                                       /* CON3201 */

  /********************************************************************/
  /* See if we need to worry about segment boundaries.                */
  /* CON3201 : don't have to worry about segment boundaries for       */
  /*           32-bit code                                            */
  /********************************************************************/
#if 0
  if (SPad->Safe)
  {
#endif
      /****************************************************************/
      /* Loop through converting all the source bytes in the line. We */
      /* know that we don't need to worry about segment boundaries.   */
      /* We use the hardware palette as our colour conversion table.  */
      /*                                                              */
      /* Note: The bytes in the external bitmap are stored in order:  */
      /*        1st byte   Blue                                       */
      /*        2nd byte   Green                                      */
      /*        3rd byte   Red                                        */
      /*                                                              */
      /*       This is the same order as the colours are stored in the*/
      /*       RGB structure; hence we can assign whole RGB structures*/
      /****************************************************************/
      while (SPad->ChunkLength--)
      {
          /************************************************************/
          /* Note : it is possible that, although we only use colours */
          /* 0 to 7 internally, that the top bit of each nibble may   */
          /* be set, owing to masking operations. Hence we need to    */
          /* clear the top bit.                                       */
          /************************************************************/
          SrcByte = *SPad->SrcPtr++;
       /* *((RGB far *) SPad->DestPtr)++ =                               */
       /*                       DVTHardwarePalette[(SrcByte>>4) & 0x07]; */
       /* *((RGB far *) SPad->DestPtr)++ =                               */
       /*                            DVTHardwarePalette[SrcByte & 0x07]; */
          prgbTemp = ((RGB2 *) SPad->SrcPtr);                    /*CON3201*/
          *prgbTemp++ = DVTHardwarePalette[(SrcByte>>4) & 0x07]; /*CON3201*/
          *prgbTemp++ = DVTHardwarePalette[SrcByte & 0x07];      /*CON3201*/
          SPad->SrcPtr = (PBYTE)prgbTemp;                        /*CON3201*/
      } /* while source bytes left */

      /****************************************************************/
      /* We may have one pel left over to convert                     */
      /****************************************************************/
      if (SPad->PelsLeftOver)
      {
          SrcByte = *SPad->SrcPtr++;
       /* *((RGB  far*) SPad->DestPtr)++ =                               */
       /*                     DVTHardwarePalette[(SrcByte >> 4) & 0x07]; */
          prgbTemp = ((RGB2 *) SPad->SrcPtr);                    /*CON3201*/
          *prgbTemp++ = DVTHardwarePalette[(SrcByte>>4) & 0x07]; /*CON3201*/
          SPad->SrcPtr = (PBYTE)prgbTemp;                        /*CON3201*/
      } /* pel left over to convert */
  /********************************************************************/
  /* CON3201 : don't have to worry about segment boundaries for       */
  /*           32-bit code                                            */
  /********************************************************************/
#if 0
  } /* no segment boundaries to worry about */
  else
  {
      /****************************************************************/
      /* Loop through converting all the source bytes in the line. We */
      /* use the POSTINC macro to check for segment boundaries.       */
      /* We use the hardware palette as our colour conversion table.  */
      /*                                                              */
      /* Note: The bytes in the bitmap are stored in order:           */
      /*        1st byte   Blue                                       */
      /*        2nd byte   Green                                      */
      /*        3rd byte   Red                                        */
      /*                                                              */
      /*       This is the same order as the colours are stored in the*/
      /*       RGB structure; hence we can assign whole RGB structures*/
      /****************************************************************/
      while (SPad->ChunkLength--)
      {
          /************************************************************/
          /* This section converts one source byte (=2 pels) to six   */
          /* destination bytes. Although we are checking for segment  */
          /* boundaries, we need only check every second byte since   */
          /* we always start the line on a DWORD (and hence WORD)     */
          /* boundary.                                                */
          /*                                                          */
          /* Note : it is possible that, although we only use colours */
          /* 0 to 7 internally, that the top bit of each nibble may   */
          /* be set, owing to masking operations. Hence we need to    */
          /* clear the top bit.                                       */
          /************************************************************/
          SrcByte = *SPad->SrcPtr;
          POSTINC(SPad->SrcPtr);
          *((PBYTE) SPad->DestPtr)++=
                           DVTHardwarePalette[(SrcByte>>4)&0x07].bBlue;
          *((PBYTE) SPad->DestPtr)=
                           DVTHardwarePalette[(SrcByte>>4)&0x07].bGreen;
          POSTINC(SPad->DestPtr);
          *((PBYTE) SPad->DestPtr)++=
                           DVTHardwarePalette[(SrcByte>>4)&0x07].bRed;
          *((PBYTE) SPad->DestPtr)=
                           DVTHardwarePalette[SrcByte&0x07].bBlue;
          POSTINC(SPad->DestPtr);
          *((PBYTE) SPad->DestPtr)++=
                           DVTHardwarePalette[SrcByte&0x07].bGreen;
          *((PBYTE) SPad->DestPtr)=
                           DVTHardwarePalette[SrcByte&0x07].bRed;
          POSTINC(SPad->DestPtr);
      } /* while source bytes left */

      /****************************************************************/
      /* We may have one pel left over to convert                     */
      /****************************************************************/
      if (SPad->PelsLeftOver)
      {
          SrcByte = *SPad->SrcPtr;
          POSTINC(SPad->SrcPtr);
          *((PBYTE) SPad->DestPtr)=
                           DVTHardwarePalette[(SrcByte>>4)&0x07].bBlue;
          POSTINC(SPad->DestPtr);
          *((PBYTE) SPad->DestPtr)=
                           DVTHardwarePalette[(SrcByte>>4)&0x07].bGreen;
          POSTINC(SPad->DestPtr);
          *((PBYTE) SPad->DestPtr)=
                           DVTHardwarePalette[(SrcByte>>4)&0x07].bRed;
          POSTINC(SPad->DestPtr);
      } /* pel left over to convert */
  } /* checking for segment boundaries */
#endif
} /* convert_int4_to_ext24 */
#undef TFUNC
