/*DDK*************************************************************************/
/*                                                                           */
/* 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.                                */
/*                                                                           */
/*****************************************************************************/
/**********************************************************************/
/*                                                                    */
/*   Module          = CONVFUNS.H                                     */
/*                                                                    */
/*   Description     = Header file for bitmap conversion functions.   */
/*                                                                    */
/*                                                                    */
/*                                                                    */
/*   77638 - JOHNB     Added support for 16 bit external bitmaps.     */
/*                     These will only be used when we are using      */
/*                     16 bit internal bitmaps ( we are in 64K        */
/*                     color mode )                                   */
/*                                                                    */
/**********************************************************************/


/**********************************************************************/
/* Typedefs.                                                          */
/**********************************************************************/
typedef ULONG ( * PFNUS)(RGB2);
/**********************************************************************/
/* Bitmap conversion function pointer type.                           */
/**********************************************************************/
typedef VOID ( * PFNV)(VOID);

typedef VOID ( * PRGBFN)(PRGB *,BYTE,BYTE,BYTE);

/**********************************************************************/
/* Define types for a 16bpp rgb value.                                */
/**********************************************************************/
typedef USHORT RGB16;
typedef RGB16 * PRGB16;

/**********************************************************************/
/* Scratch pad redefinition for bitmap conversion functions           */
/* common to external to internal and internal to external            */
/* During a drawbits operation the scrath pad needs to be accessed    */
/* by both the pixblt routines and the conversion routines.           */
/* To allow this, this structure includes the BltSpad as its first    */
/* parameter. This will force the first part of the SPad to be the    */
/* pixblt scrath pad and the conversion routines can access the       */
/* scrath pad area following the pixblt scrath pad.                   */
/*                                                                    */
/* Warning: The assembler version of this structure is defined in     */
/*          convert.asm.  Do not change this structure without        */
/*          also changing that one.                                   */
/**********************************************************************/
typedef struct _CONVERTCOMMON  { /* cc */
    BltSPad        BltSpad;
    PBYTE          pbExternalBitmap;
    PBITMAPINFO2   pExternalHeader;
    pBitmapHeader  pbhInternalBitmap;
    PPOINTL        pptlScanStart;
    LONG           lScanLines;
    USHORT         cInternalBitCount;
    USHORT         cExternalBitCount;
    PBYTE          pbSrcPointer;
    PBYTE          pbTrgPointer;
    ULONG          cx;
    PFNUS          pfnRGBToIndex;
    PRGBFN         pfnSetRGBAndInc;
    USHORT         usIncrement;
    USHORT         usExtTabSize;
    UCHAR          fbFlags;
    /******************************************************************/
    /* there should still be space for 512 bytes in this structure    */
    /* (SPAD is defined as 1000 bytes long)                           */
    /* @DMS I need to increase the size by 512 bytes for bpp24        */
    /******************************************************************/
    #ifndef   BPP24
    USHORT         ausConvertTable[256];
    #else
    ULONG          ausConvertTable[256];
    #endif

    /******************************************************************/
    /* The following values are only used by the DrawBits code, not   */
    /* accessed by the conversion routines.                           */
    /******************************************************************/
    PFNV           pfnvConvertLine;     /* routine to convert a line  */
    ULONG          cExternalBytesPerPel;
    ULONG          ulRLE_last_x;        /* Last known position ...    */
    ULONG          ulRLE_last_y;        /* ...within the RLE ...      */
    PBYTE          pbRLE_last_pos;      /* ...bitmap.                 */
    USHORT         fRLE_delta;          /* delat-type rec. encounterd */
    USHORT         fConvertPal;         /* Conversion required?       */
    PFNV           pfnvConvertColour;   /* routine to convert colour  */
    USHORT         usColour;            /* the converted colour       */
    ULONG          ulPelsOnChunkLine;
    ULONG          ulLinesInChunk;
    ULONG          ulInternalBytesPerLine;
    ULONG          ulExternalBytesPerLine;
    ULONG          ulExternalCx;
    ULONG          ulExternalCy;
    ULONG          ulChunkPosX;         /* offset of chunk within ... */
    ULONG          ulChunkPosY;         /* source and target bitmaps. */
                                        /* (bottom left corner)       */
    ULONG          ulChunkEndX;         /* end of chunk within ...    */
    ULONG          ulChunkEndY;         /* source and target bitmaps. */
                                        /* (top right corner)         */
    ULONG          ulCurrentX;          /* The current position in ...*/
    ULONG          ulCurrentY;          /* ...the bitmaps.            */
    ULONG          ulState;             /* The current state:         */
                                        /* RLE_IN_CHUNK               */
                                        /* RLE_LEFT_CHUNK,            */
                                        /* RLE_RIGHT_CHUNK            */
                                        /* RLE_BELOW_CHUNK            */
                                        /* RLE_ABOVE_CHUNK            */
#ifdef FIREWALLS
    PBYTE          pbExternalEnd;
#endif
} CONVERTCOMMON;


/**********************************************************************/
/* Globals.                                                           */
/**********************************************************************/
extern CONVERTCOMMON SPad;

/**********************************************************************/
/* Constants.                                                         */
/**********************************************************************/
/**********************************************************************/
/* Direction flags for FlipTheBitmap.                                 */
/**********************************************************************/
#define INT_TO_EXT_COPY 0
#define EXT_TO_INT_COPY 1

/**********************************************************************/
/* Values used to represent background and foreground in mono bitmaps.*/
/**********************************************************************/
#define MONO_BM_BACKGROUND 0
#define MONO_BM_FOREGROUND 1

/**********************************************************************/
/* Value above which the least squares colour comparison will map to  */
/* white.                                                             */
/**********************************************************************/
#define WHITE_THRESHOLD 0x180L

/**********************************************************************/
/* Possible value for SPad.fbFlags to say that BCE_PALETTE format is  */
/* in use.                                                            */
/**********************************************************************/
#define CONV_BCE_PALETTE   1

/**********************************************************************/
/* Macros                                                             */
/**********************************************************************/
/**********************************************************************/
/* Macro to set an RGB2 structure from an RGB16 value.                */
/**********************************************************************/
#define RGB2FromRGB16(rgb2,rgb16)                                      \
    rgb2.bBlue  = (BYTE)BlueFromRGB16(rgb16);                          \
    rgb2.bGreen = (BYTE)GreenFromRGB16(rgb16);                         \
    rgb2.bRed   = (BYTE)RedFromRGB16(rgb16);

/**********************************************************************/
/* Macro to form a ULONG holding a RGB value from an RGB16 value.     */
/**********************************************************************/
#define ULONGFromRGB16(rgb16)                                          \
    (BlueFromRGB16(rgb16)       ) |                                    \
    (GreenFromRGB16(rgb16) << 8 ) |                                    \
    (RedFromRGB16(rgb16)   << 16)                           /* @77638 */

/**********************************************************************/
/* MEBTEMP                                                            */
/* Until I change all the source to use the proper name for the       */
/* macro, we define the misleading name to use the proper name        */
/**********************************************************************/
#define MotorolaToIntel(x) EnsureIntel16bpp(x)

/**********************************************************************/
/* Macro to return the blue component from an RGB16 value.            */
/* The blue is in the same place for both the XGA and the Matrox      */
/* RGB16 structures.                                                  */
/**********************************************************************/
#define BlueFromRGB16(rgb16)                                           \
    ((rgb16 & 0x001F) << 3)


#ifdef MATROX
#define SetInternal16BppPel(value)                                    \
    if (RunningOnMatrox())                                            \
    {                                                                 \
        MTX_SetInternal16BppPel(value);                               \
    }                                                                 \
    else                                                              \
    {                                                                 \
        XGA_SetInternal16BppPel(value);                               \
    }

#define EnsureIntel16bpp(word)                                        \
    ( RunningOnMatrox() ? MTX_EnsureIntel16bpp(word) :                \
                          XGA_EnsureIntel16bpp(word) )
#define RGB16FromPRGB2(prgb2)                                         \
    ( RunningOnMatrox() ? MTX_RGB16FromPRGB2(prgb2) :                 \
                          XGA_RGB16FromPRGB2(prgb2) )
#define RedFromRGB16(rgb16)                                           \
    ( RunningOnMatrox() ? MTX_RedFromRGB16(rgb16) :                   \
                          XGA_RedFromRGB16(rgb16) )
#define GreenFromRGB16(rgb16)                                         \
    ( RunningOnMatrox() ? MTX_GreenFromRGB16(rgb16) :                 \
                          XGA_GreenFromRGB16(rgb16) )
#define Default8BppIndexFromRGB16(rgb16)                              \
    ( RunningOnMatrox() ? MTX_Default8BppIndexFromRGB16(rgb16) :      \
                          XGA_Default8BppIndexFromRGB16(rgb16) )
#else /* MATROX */
#define EnsureIntel16bpp(word)           XGA_EnsureIntel16bpp(word)
#define SetInternal16BppPel(value)       XGA_SetInternal16BppPel(value)
#define RGB16FromPRGB2(prgb2)            XGA_RGB16FromPRGB2(prgb2)
#ifdef   BPP24
#define SetInternal24BppPel(value)       XGA_SetInternal24BppPel(value)
#define RGB24FromPRGB2(prgb2)            XGA_RGB24FromPRGB2(prgb2)
#define RGB24FromPRGB2ATT(prgb2)         XGA_RGB24FromPRGB2ATT(prgb2)
#define Default8BppIndexFromRGB24(rgb)   XGA_Default8BppIndexFromRGB24(rgb)
#define Default8BppIndexFromRGB24ATT(rgb) XGA_Default8BppIndexFromRGB24ATT(rgb)
#endif
#define RedFromRGB16(rgb16)              XGA_RedFromRGB16(rgb16)
#define GreenFromRGB16(rgb16)            XGA_GreenFromRGB16(rgb16)
#define Default8BppIndexFromRGB16(rgb16) XGA_Default8BppIndexFromRGB16(rgb16)
#endif /* MATROX */

#ifdef MATROX
/**********************************************************************/
/* MATROX card requires a 1:5:5:5 format for its 16 bpp color value   */
/* where the fields are as follows:                                   */
/*                                                                    */
/*          ---------------------------------                         */
/*          |o|r|r|r|r|r|g|g|g|g|g|b|b|b|b|b|                         */
/*          ---------------------------------                         */
/*                                                                    */
/*  o - overlay  (assumed fixed)                                      */
/*  r - red                                                           */
/*  g - green                                                         */
/*  b - blue                                                          */
/*                                                                    */
/**********************************************************************/
/**********************************************************************/
/* Macro to convert a 16bpp value as stored in a bitmap, to a 16 bit  */
/* value in Intel format.                                             */
/*                                                                    */
/* VRAM located bitmaps already use Intel ordering, so this is a NOP  */
/* for this configuration.                                            */
/**********************************************************************/
#define MTX_EnsureIntel16bpp(word) (word)

/**********************************************************************/
/* Macro to write a 16bpp value into the internal bitmap, and to      */
/* increment the internal bitmap pointer to the next 16bpp pel.       */
/*                                                                    */
/* This is simple because VRAM bitmaps use Intel words.               */
/**********************************************************************/
#define MTX_SetInternal16BppPel(value)                                 \
    *((PRGB16)SPad.pbTrgPointer)++ = value;

/**********************************************************************/
/* Macro to return an RGB16 value when given a pointer to an RGB2 one.*/
/**********************************************************************/
#define MTX_RGB16FromPRGB2(prgb2)                                      \
    ((((USHORT)((prgb2)->bRed)   & 0xF8) << 7) |                       \
     (((USHORT)((prgb2)->bGreen) & 0xF8) << 2) |                       \
     (((USHORT)((prgb2)->bBlue)  & 0xF8) >> 3)  )

/**********************************************************************/
/* Macro to return the red component from an RGB16 value.             */
/**********************************************************************/
#define MTX_RedFromRGB16(rgb16)                                        \
    ((rgb16 & 0x7c00) >> 7)

/**********************************************************************/
/* Macro to return the green component from an RGB16 value.           */
/**********************************************************************/
#define MTX_GreenFromRGB16(rgb16)                                      \
    ((rgb16 & 0x03E0) >> 2)

/**********************************************************************/
/* Macro to return an 8bpp index into some Default external 8bpp      */
/* color table, given an RGB16 value.                                 */
/*   The external 8bpp table we have chosen is defined by             */
/*        rrrgggbb                                                    */
/*   The RGB16 value holds                                            */
/*       Xrrrrrgggggbbbbb                                             */
/**********************************************************************/
#define MTX_Default8BppIndexFromRGB16(rgb16)                           \
    (((rgb16 & 0x7000) >> 7) |                                         \
     ((rgb16 & 0x0380) >> 5) |                                         \
     ((rgb16 & 0x0018) >> 3)  )

#endif /* MATROX */

/* START OF XGA VERSIONS OF THE MACROS */

/**********************************************************************/
/* XGA uses a 5:6:5 format for its 16 bpp color value                 */
/* where the fields are as follows:                                   */
/*                                                                    */
/*          ---------------------------------                         */
/*          |r|r|r|r|r|g|g|g|g|g|g|b|b|b|b|b|                         */
/*          ---------------------------------                         */
/*                                                                    */
/*  r - red     (5 bits)                                              */
/*  g - green   (6 bits)                                              */
/*  b - blue    (5 bits)                                              */
/*                                                                    */
/**********************************************************************/
/**********************************************************************/
/* Macro to convert a 16bpp value as stored in a bitmap, to a 16 bit  */
/* value in Intel format.                                             */
/*                                                                    */
/* Since XGA bitmaps in system memory are stored in motorola format,  */
/* this requires swapping the low and high bytes.                     */
/**********************************************************************/
#define XGA_EnsureIntel16bpp(word)                                     \
    ((((word) & 0xFF00) >> 8) | (((word) & 0x00FF) << 8))

/**********************************************************************/
/* Macro to write a 16bpp value into the internal bitmap, and to      */
/* increment the internal bitmap pointer to the next 16bpp pel.       */
/* This must be done in Motorola format (high byte, low byte).        */
/**********************************************************************/
#define XGA_SetInternal16BppPel(value)                                 \
    *((PBYTE)SPad.pbTrgPointer)++ = ((value) >> 8);                    \
    *((PBYTE)SPad.pbTrgPointer)++ = ((value) & 0xFF);

#ifdef   BPP24
/**********************************************************************/
/* Macro to write a 24bpp value into the internal bitmap, and to      */
/* increment the internal bitmap pointer to the next 24bpp pel.       */
/* This must be done in Motorola format (high byte,Middle,low byte).  */
/**********************************************************************/
#define XGA_SetInternal24BppPel(value)                                 \
    *((PBYTE)SPad.pbTrgPointer)++ = ((value) >> 16);                   \
    *((PBYTE)SPad.pbTrgPointer)++ = ((value) >> 8);                    \
    *((PBYTE)SPad.pbTrgPointer)++ = (value);

#endif

/**********************************************************************/
/* Macro to return an RGB16 value when given a pointer to an RGB2 one.*/
/**********************************************************************/
#define XGA_RGB16FromPRGB2(prgb2)                                      \
    ((((USHORT)((prgb2)->bRed)   & 0xF8) << 8) |                       \
     (((USHORT)((prgb2)->bGreen) & 0xFC) << 3) |                       \
     (((USHORT)((prgb2)->bBlue)  & 0xF8) >> 3)  )

#ifdef   BPP24
/**********************************************************************/
/* Macro to return an RGB24 value when given a pointer to an RGB2 one.*/
/**********************************************************************/
#define XGA_RGB24FromPRGB2(prgb2)                                      \
      *(PULONG)(prgb2)

#define XGA_RGB24FromPRGB2ATT(prgb2)                           \
    ((((ULONG)((prgb2)->bRed))) |                              \
     (((ULONG)((prgb2)->bGreen)) << 8) |                       \
     (((ULONG)((prgb2)->bBlue)) << 16)  )

#define RGB2FromRGB2ATT(rgb24,rgb2)                      \
    rgb24.bBlue  = rgb2.bRed;                            \
    rgb24.bGreen = rgb2.bGreen;                          \
    rgb24.bRed   = rgb2.bBlue;
#endif


/**********************************************************************/
/* Macro to return the red component from an RGB16 value.             */
/**********************************************************************/
#define XGA_RedFromRGB16(rgb16)                                        \
    ((rgb16 & 0xF800) >> 8)

/**********************************************************************/
/* Macro to return the green component from an RGB16 value.           */
/**********************************************************************/
#define XGA_GreenFromRGB16(rgb16)                                      \
    ((rgb16 & 0x07E0) >> 3)

/**********************************************************************/
/* Macro to return an 8bpp index into some Default external 8bpp      */
/* color table, given an RGB16 value.                                 */
/*   The external 8bpp table we have chosen is defined by             */
/*        rrrgggbb                                                    */
/*   The RGB16 value holds                                            */
/*        rrrrrggggggbbbbb                                            */
/**********************************************************************/
#define XGA_Default8BppIndexFromRGB16(rgb16)                           \
    (((rgb16 & 0xE000) >> 8) |                                         \
     ((rgb16 & 0x0700) >> 6) |                                         \
     ((rgb16 & 0x0018) >> 3)  )

#ifdef   BPP24
/**********************************************************************/
/* Macro to return an 8bpp index into some Default external 8bpp      */
/* color table, given an RGB value.                                   */
/*   The external 8bpp table we have chosen is defined by             */
/*        rrrgggbb                                                    */
/*   The RGB value holds                                              */
/*        rrrrrrrrggggggggbbbbbbbb                                    */
/**********************************************************************/
#define XGA_Default8BppIndexFromRGB24(rgb)                             \
    (((rgb & 0x00E00000) >> 16 ) |                                     \
     ((rgb & 0x0000E000) >> 11 ) |                                     \
     ((rgb & 0x000000C0) >> 6 )  )

#define XGA_Default8BppIndexFromRGB24ATT(rgb)                          \
    (((rgb & 0x00E00000) >> 6 ) |                                      \
     ((rgb & 0x0000E000) >> 11 ) |                                     \
     ((rgb & 0x000000C0) >> 16 )  )
#endif

/* END OF XGA VERSIONS OF THE MACROS */

/**********************************************************************/
/* Macro to go from an 8bpp index to the RGB value in the default     */
/* external 8bbp color table.                                         */
/**********************************************************************/
#define GetDefault8BppExtEntry(rgb,index)                              \
    rgb.bRed   = (BYTE)( index & 0xE0      );                          \
    rgb.bGreen = (BYTE)((index & 0x1C) << 3);                          \
    rgb.bBlue  = (BYTE)((index & 0x03) << 6);

/**********************************************************************/
/* MapRGBToMono                                                       */
/* Returns 1 if prgb is closer to white, 0 if closer to black.        */
/**********************************************************************/
#define MapRGBToMono(prgb)                                             \
   (BYTE)(((USHORT)(prgb)->bRed   +                                    \
           (USHORT)(prgb)->bGreen +                                    \
           (USHORT)(prgb)->bBlue  ) > WHITE_THRESHOLD )

/**********************************************************************/
/* MapRGB16ToMono                                                     */
/* Returns 1 if prgb16 is closer to white, 0 if closer to black.      */
/**********************************************************************/
#define MapRGB16ToMono(prgb16)                                         \
    (BYTE)((BlueFromRGB16(*(prgb16)) +                                 \
            GreenFromRGB16(*(prgb16)) +                                \
            RedFromRGB16(*(prgb16))) > WHITE_THRESHOLD)

/**********************************************************************/
/* Function prototypes                                                */
/**********************************************************************/
VOID SetRGBAndInc(PRGB * ppExtRGB,
                  BYTE   bRed,
                  BYTE   bGreen,
                  BYTE   bBlue);

VOID SetRGB2AndInc(PRGB * ppExtRGB,
                   BYTE   bRed,
                   BYTE   bGreen,
                   BYTE   bBlue);

ULONG BytesInOneBMRow(USHORT usBitsPerPel,
                      ULONG  ulPels);

VOID ConvertPMInt(PFNV     pfnvInnerConvert,
                  PBYTE *  ppbInternalPointer,
                  PBYTE *  ppbExternalPointer);

VOID FlipTheBitmap(USHORT  usDirection);

VOID CopyTheBitmap(VOID);

VOID ConvertIntToExt( PBYTE         pbTargetBitmap,
                      PBITMAPINFO2  pTargetHeader,
                      pBitmapHeader pbhSourceBitmap,
                      PPOINTL       pptlScanStart,
                      LONG          lScanLines);

VOID ConvertExtToInt( PBYTE         pbSourceBitmap,
                      PBITMAPINFO2  pSourceHeader,
                      pBitmapHeader pbhTargetBitmap,
                      PPOINTL       pptlScanStart,
                      LONG          lScanLines);

VOID Convert1To4(VOID);

VOID Convert8To1(VOID);

VOID Convert4To1(VOID);

VOID Convert16To1(VOID);

/**********************************************************************/
/* These functions were originally just used for external to internal */
/* bitmap conversion. They are now used by the drawbits code as well  */
/**********************************************************************/
VOID TableExtToInt(VOID);
PFNUS RGBToIndexFunction(VOID);
ULONG BytesPerExternalLine(PBITMAPINFO2  pExt,
                           ULONG         cpels);
PFNV GetExternalConvertFn(VOID);
VOID ConvertExt8ToInt8NoConversion( VOID );
BOOL DRIVERCALL ConversionRequired(VOID);
