;*DDK*************************************************************************/
;
; COPYRIGHT (C) Microsoft 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 = CONVINT.ASM
;*
;* DESCRIPTIVE NAME = Convert internal formats
;*
;*
;* VERSION      V2.0
;*
;* DATE
;*
;* DESCRIPTION  Display Device Driver subroutines to convert
;*              between the device driver internal format and
;*              and the PM formats
;*
;*
;* FUNCTIONS    ConvertIntToExt
;*              TableIntToPM
;*
;*
;*
;* NOTES        NONE
;*
;* STRUCTURES   NONE
;*
;* EXTERNAL REFERENCES
;*
;*              NONE
;*
;* EXTERNAL FUNCTIONS
;*
;*              NONE
;*
;* CHANGE ACTIVITY =
;*   DATE      FLAG        APAR   CHANGE DESCRIPTION
;*   --------  ----------  -----  --------------------------------------
;*   mm/dd/yy  @Vr.mpppxx  xxxxx  xxxxxxx
ifdef  JFIX        ;IBMJ
;*   06/22/93              60394  Modification for defect 60394 from XGA.
endif ;JFIX        ;IBMJ
;*
;*****************************************************************************/

        .386

        .xlist

INCL_GRE_BITMAPS        equ     1
INCL_GPIBITMAPS         equ     1
INCL_GPIERRORS          equ     1

        include pmgre.inc

DINCL_ENABLE            equ     1
DINCL_BITMAP            equ     1

        include driver.inc
        include assert.mac
        include extern.inc
        include protos.inc
        include palette.inc
        .list

        .MODEL FLAT

        ASSUME  CS:FLAT,SS:FLAT,DS:FLAT,ES:FLAT
        ASSUME  ESI:PTR ITE_STRUCT

SetRGBAndInc PROTO SYSCALL,
        rgb:DWORD



.CODE

;/***************************************************************************
;*
;* FUNCTION NAME = NearestRestrictedColourIndex
;*
;* DESCRIPTION   = Returns the index to pbColourTable table which maps to the
;*                 colour nearest rgb.  Index returned will be less than
;*                 ulMaxIndex, ie.  only the first ulMaxIndex entries of
;*                 pbColorTable are examined.
;*
;*
;*
;* INPUT         =
;*
;*        pbColourTable     pointer to the colour table to use (may actually
;*                          be a palette as well)
;*        ulColTabIncrement the amount by which pbColourTable needs to be
;*                          incremented to point to the next entry
;*        rgb               the RGB value for which the nearest index is to
;*                          be found
;*        ulMaxIndex        the maximum number of indices in the colour            = NONE
;*                          table which can be examined for a match
;*
;* OUTPUT
;*
;* RETURN-NORMAL =
;* RETURN-ERROR  =
;*
;**************************************************************************/
NearestRestrictedColourIndex PROC SYSCALL USES EDI ECX,
        pbColourTable          :PBYTE,
        ulColTabIncrement      :ULONG,
        rgb                    :RGB2,
        ulMaxIndex             :ULONG
LOCAL   ulMinDiff       :ULONG,
        ulBestIndex     :ULONG


;/*
;**{
;**    ULONG   ulCount;
;**    ULONG   ulDiff;
;**
;**    /******************************************************************/
;**    /* Check to first index outside the loop.                         */
;**    /******************************************************************/
;*/

        mov     edi,pbColourTable

;/*
;**    ulMinDiff = rgb2_diff(*(PRGB2)pbColourTable, rgb);
;*/
        INVOKE  rgb2_diff,
                RGB2 PTR [edi],
                rgb

        mov     ulMinDiff,eax
;/*
;**
;**    if ( ulMinDiff == 0 )
;*/
        or      eax,eax
        jz      nrci_exit

;/*
;**    {
;**        return(0);
;**    }
;**    else /* first index does not give exact match */
;**    {
;**        ulBestIndex = 0;
;*/
        mov     ulBestIndex,0

;/*
;**        pbColourTable += ulColTabIncrement;
;*/

        add     edi,ulColTabIncrement
;/*
;**
;**        for (ulCount = 1;
;**             ulCount < ulMaxIndex;
;**             ulCount++, pbColourTable += ulColTabIncrement)
;*/

        mov     ecx,1

loop_top:
;/*
;**        {
;**            ulDiff = rgb2_diff(*(PRGB2)pbColourTable,
;**                               rgb);
;*/

        INVOKE  rgb2_diff,
                RGB2 PTR [edi],
                rgb


;/*
;**            if (ulDiff == 0)
;*/

        cmp     eax,0
        jnz     do_else

;/*
;**            {
;**                /******************************************************/
;**                /* Exact match so this must be the closest!           */
;**                /******************************************************/
;**                ulBestIndex = ulCount;
;**                break;
;*/

        mov     ulBestIndex,ecx
        jmp     loop_exit

;/*
;**            }
;**            else if (ulDiff < ulMinDiff)
;*/

do_else:

;/*
;**            {
;**                /******************************************************/
;**                /* This is a closer match than the previous best.     */
;**                /******************************************************/
;**                ulMinDiff = ulDiff;
;**                ulBestIndex = ulCount;
;*/

        cmp     eax,ulMinDiff
        jae     @f
        mov     ulMinDiff,eax
        mov     ulBestIndex,ecx
@@:
;/*
;**            }
;**        } /* for each entry in colour table */
;*/
        add     edi,ulColTabIncrement
        inc     ecx
loop_entry:
        cmp     ecx,ulMaxIndex
        jb      loop_top
loop_exit:
        mov     eax,ulBestIndex
;/*
;**    }  /* first index does not give exact match */
;**
;**    return(ulBestIndex);
;*/
nrci_exit:
        ret
NearestRestrictedColourIndex ENDP

;/***************************************************************************
;*
;* FUNCTION NAME = GetPaletteEncoding
;*
;* DESCRIPTION   =  pExtRGB  pointer to external colour table
;*
;*                  Sets an identity mapping rather than RGB colours in the colour
;*                  table pointed to by pExtRGB.
;*                  The mapping goes in the blue component since this is the
;*                  first byte in the RGB2 structure.
;*
;* INPUT         = edi = pExtRgb
;* OUTPUT        = NONE
;*
;* RETURN-NORMAL =
;* RETURN-ERROR  =
;*
;**************************************************************************/

;/*
;** VOID DRIVERCALL GetPaletteEncoding(PRGB  pExtRGB)
;*/

GetPaletteEncoding PROC SYSCALL

;/*
;**{
;**    ULONG   i;
;**    ULONG   ulPaletteSize;
;**
;**    ulPaletteSize = 1 << SPad.cExternalBitCount;
;**
;**    for (i = 0; i < ulPaletteSize; i++)
;*/

        mov     eax,0
        jmp     gpe_loop_entry
gpe_loop_top:

;/*
;**    {
;**        /**************************************************************/
;**        /* Palette encoding only applies when we are using the new    */
;**        /* bitmap header, and hence RGB2 values, which means each     */
;**        /* external color table entry is a dword.                     */
;**        /**************************************************************/
;**        *((PULONG)pExtRGB)++ = i;
;*/

        mov     DWORD PTR [edi+eax*sizeof ULONG],eax
        inc     eax
gpe_loop_entry:
        cmp     eax,[esi].ite_ExtColorCount
        jb      gpe_loop_top
        ret

;/*
;**    }
;*/

GetPaletteEncoding ENDP


;/***************************************************************************
;*
;* FUNCTION NAME = GetPalEncodeWithConvTab
;*
;* DESCRIPTION   = pExtRGB  pointer to external colour table
;*
;*                 Sets an identity mapping rather than RGB colours in the colour
;*                 table pointed to by pExtRGB and also a convert table between the
;*                 internal and external tables.
;*                 The mapping goes in the blue component since this is the
;*                 first byte in the RGB2 structure.
;*
;* INPUT         = edi = pExtRgb
;*                 ecx = #entries to put into table
;*
;*
;* OUTPUT        = NONE
;*
;* RETURN-NORMAL =
;* RETURN-ERROR  =
;*
;**************************************************************************/

;/*
;**VOID DRIVERCALL GetPalEncodeWithConvTab(PRGB pExtRGB)
;*/

GetPalEncodeWithConvTab PROC SYSCALL USES EBX ECX

;/*
;**{
;**    ULONG   i;
;**    ULONG   ulMaxColours;
;**    /******************************************************************/
;**    /* Set up the external color table.                               */
;**    /******************************************************************/
;**    GetPaletteEncoding(pExtRGB);
;*/

        INVOKE  GetPaletteEncoding

;/*
;**
;**    ulMaxColours = 1 << SPad.cExternalBitCount;
;**
;**    /******************************************************************/
;**    /* Identity map all the external values we can.                   */
;**    /******************************************************************/
;**    for (i = 0; i < ulMaxColours; i++)
;*/

        mov     edx,[esi].ite_ExtColorCount
        mov     ebx,[esi].ite_pbConvertTable
        mov     ecx,0
        jmp     gpewt_loop1_entry
gpewt_loop1_top:
;/*
;**    {
;**        SPad.ausConvertTable[i] = (BYTE)i;
;*/
        mov     BYTE PTR [ebx+ecx],cl
        inc     ecx
gpewt_loop1_entry:
        cmp     ecx,edx
        jb      gpewt_loop1_top


;/*
;**    }
;**    /******************************************************************/
;**    /* Map any excess internal colours which cannot be identity       */
;**    /* mapped to 0.                                                   */
;**    /******************************************************************/
;**    for (ulMaxColours = 1 << SPad.cInternalBitCount; i < ulMaxColours; i++)
;*/

        mov     ecx,[esi].ite_IntColorCount
        jmp     gpewt_loop2_entry

;/*
;**    {
;**        SPad.ausConvertTable[i] = 0;
;*/

gpewt_loop2_top:
        mov     BYTE PTR [ebx+ecx],0
        inc     ecx
gpewt_loop2_entry:
        cmp     ecx,edx
        jb      gpewt_loop2_top

;/*
;**    }
;*/

        ret
GetPalEncodeWithConvTab ENDP

;/***************************************************************************
;*
;* FUNCTION NAME = GetMonoTable
;*
;* DESCRIPTION   = pExtRGB  pointer to external colour table
;*
;*                 Sets up the external colour table for a monochrome bitmap. The
;*                 table is pointed to by pExtRGB.
;*
;* INPUT         = edi = pExtRgb
;*                 ecx = #entries to put into table
;*
;* OUTPUT        = NONE
;*
;* RETURN-NORMAL =
;* RETURN-ERROR  =
;*
;**************************************************************************/

;/*
;**VOID DRIVERCALL GetMonoTable(PRGB pExtRGB)
;*/

GetMonoTable PROC SYSCALL
;/*
;**{
;**   SPad.pfnSetRGBAndInc(&pExtRGB, 0x00, 0x00, 0x00);
;*/
        INVOKE  SetRGBAndInc,
                0

;/*
;**   SPad.pfnSetRGBAndInc(&pExtRGB, 0xFF, 0xFF, 0xFF);
;*/

        INVOKE  SetRGBAndInc,
                0FFFFFFh
        ret
GetMonoTable ENDP


;/***************************************************************************
;*
;* FUNCTION NAME = GetSrcMonoCTWithConvTab
;*
;* DESCRIPTION   = pExtRGB  pointer to external colour table
;*
;*                 Sets up the external colour table for a monochrome source bitmap
;*                 and the conversion table from internal (source) to external tables
;*
;*
;*
;* INPUT         = edi = pExtRgb
;* OUTPUT        = NONE
;*
;* RETURN-NORMAL =
;* RETURN-ERROR  =
;*
;**************************************************************************/


;/*
;**VOID DRIVERCALL GetSrcMonoCTWithConvTab(PRGB pExtRGB)
;*/

GetSrcMonoCTWithConvTab PROC SYSCALL

;/*
;**{
;**    /******************************************************************/
;**    /* Set up the external color table.                               */
;**    /******************************************************************/
;**    GetMonoTable(pExtRGB);
;*/

        INVOKE  GetMonoTable

;/*
;**
;**    /******************************************************************/
;**    /* The conversion table, if used, is an identity mapping!         */
;**    /******************************************************************/
;**    SPad.ausConvertTable[0] = 0;
;*/

        mov     eax,[esi].ite_pbConvertTable
        mov     BYTE PTR [eax],0

;/*
;**    SPad.ausConvertTable[1] = 1;
;*/

        mov     BYTE PTR [eax+1],1
        ret
GetSrcMonoCTWithConvTab ENDP


;/***************************************************************************
;*
;* FUNCTION NAME = GetConvTabFromLogicalPalette
;*
;* DESCRIPTION   = Sets up the conversion table when the internal bitmap uses a
;*                 logical palette.
;*
;*
;*
;*
;*
;* INPUT         =
;*
;*
;*
;*
;* OUTPUT        = NONE
;*
;* RETURN-NORMAL =
;* RETURN-ERROR  =
;*
;**************************************************************************/


;/*
;**VOID DRIVERCALL GetConvTabFromLogicalPalette(VOID)
;*/

GetConvTabFromLogicalPalette PROC SYSCALL USES EBX ECX EDI

;/*
;**{
;**    ULONG   i;
;**    ULONG   ulUsedPaletteSize;
;**    ULONG   ulSourcePaletteSize;
;**
;**    /*******************************************************************/
;**    /* Our bitmap contents are indices into our logical palette.       */
;**    /* We can only use the logical palette for as many entries as are  */
;**    /* actually valid in it.                                           */
;**    /*******************************************************************/
;**    ulSourcePaletteSize = 1 << SPad.cInternalBitCount;
;**    ulUsedPaletteSize =
;**             min(ulSourcePaletteSize, pdc->Palette->usCountStored);
;*/

        ddc?    ebx
        mov     ebx,[ebx].DDC.ddc_npdevpal
        mov     edx,[ebx].DEVPAL.usCountStored
        cmp     edx,[esi].ite_IntColorCount
        jl      @F
        mov     edx,[esi].ite_IntColorCount
@@:

;/*
;** Fill in the used part of the palette.
;*/
        mov     ecx,0
        mov     edi,[esi].ite_pbConvertTable
        push    esi
        mov     esi,edx
        jmp     gctflp_for_entry


;/*
;**    for ( i = 0; i < ulUsedPaletteSize; i++ )
;*/

gctflp_for_top:
;/*
;**    {
;**        SPad.ausConvertTable[i] =
;**                            MapRGBToMono(&pdc->Palette->entries[i].rgb);
;*/

        MapRGBToMono <RGB2 PTR [ebx].DEVPAL.entries[ecx*sizeof PALENTRY].rgb>,TRASHEDX
        mov     BYTE PTR [edi+ecx*sizeof BYTE],al
        inc     ecx
gctflp_for_entry:
        cmp     ecx,esi
        jb      gctflp_for_top
        pop     esi


;/*
;**    }
;**
;**    /******************************************************************/
;**    /* Map all remaining values to zero.                              */
;**    /******************************************************************/
;**    while (i < ulSourcePaletteSize)
;*/

        mov     edx,[esi].ite_IntColorCount
        jmp     gctflp_while_entry
gctflp_while_top:
;/*
;**    {
;**        SPad.ausConvertTable[i++] = 0;
;*/

        mov     BYTE PTR [edi+ecx*sizeof BYTE],0
        inc     ecx
gctflp_while_entry:
        cmp     ecx,edx
        jb      gctflp_while_top


;/*
;**    }
;*/

gctflp_exit:
        ret
GetConvTabFromLogicalPalette ENDP


;/***************************************************************************
;*
;* FUNCTION NAME = GetConvTabFromPhysicalPalette
;*
;* DESCRIPTION   = Sets up the conversion table when the internal bitmap uses a
;*                 logical color table.
;*
;*
;*
;*
;*
;* INPUT         =
;*
;*
;*
;*
;* OUTPUT        = NONE
;*
;* RETURN-NORMAL =
;* RETURN-ERROR  =
;*
;**************************************************************************/


;/*
;**VOID DRIVERCALL GetConvTabFromPhysicalPalette(VOID)
;*/

GetConvTabFromPhysicalPalette PROC SYSCALL USES EBX ECX

;/*
;**{
;**    ULONG   ulSourcePaletteSize;
;**    ULONG   i;
;**
;**    RGB2    PhyRGB;
;**
;**    /******************************************************************/
;**    /* We are in the Color Table model, where indices in bitmaps are  */
;**    /* indices into the device default physical palette.              */
;**    /******************************************************************/
;**    ulSourcePaletteSize = 1 << SPad.cInternalBitCount;
;*/

        mov     ecx,0
        mov     ebx,[esi].ite_pbConvertTable
        jmp     loop_entry

;/*
;**    for ( i = 0; i < ulSourcePaletteSize; i++ )
;**    {
;*/

loop_top:

;/*
;**        PhyRGB = MemoryDeviceDefaultRGB2(i);
;*/

        MemoryDeviceDefaultRGB2 ecx,eax

;/*
;**        SPad.ausConvertTable[i] = MapRGBToMono(&PhyRGB);
;*/

        MapRGBToMono <eax>,TRASHEDX
        mov     BYTE PTR [ebx+ecx*sizeof BYTE],al
        inc     ecx
loop_entry:
        cmp     ecx,[esi].ite_IntColorCount
        jb      loop_top

;/*
;**    }
;*/

        ret
GetConvTabFromPhysicalPalette ENDP

;/***************************************************************************
;*
;* FUNCTION NAME = GetDstMonoCTWithConvTab
;*
;* DESCRIPTION   = pExtRGB  pointer to external colour table
;*
;*                 Sets up the external colour table for a monochrome destination
;*                 bitmap and the conversion table from internal (source) to external
;*                 (destination) tables
;*
;*
;* INPUT         =
;*
;*
;*
;*
;* OUTPUT        = NONE
;*
;* RETURN-NORMAL =
;* RETURN-ERROR  =
;*
;**************************************************************************/

;/*
;**VOID DRIVERCALL GetDstMonoCTWithConvTab(PRGB pExtRGB)
;*/

GetDstMonoCTWithConvTab PROC SYSCALL
;/*
;**{
;**    /******************************************************************/
;**    /* Set up the external mono color table.                          */
;**    /******************************************************************/
;**    GetMonoTable(pExtRGB);
;*/

        INVOKE  GetMonoTable

;/*
;**    /**********************************************************/
;**    /* We are are going to from an internal colour bitmap to  */
;**    /* an external monochrome one. After much discussion with */
;**    /* Microsoft it appears that we map the colour pixels to  */
;**    /* black or white depending on which they are nearer to   */
;**    /* (using least squares). The external colour table is    */
;**    /* set to white (foreground) and black (background)       */
;**    /**********************************************************/
;**    if (pdc->DCIColFormat == LCOLF_PALETTE)
;*/

        cmp     ebx,0                   ;CMVC_53469
        jz      not_pal                 ;CMVC_53469
        ddc?    ebx
        cmp     [ebx].DDC.ddc_fbClrTbl,DDC_PALETTE
        jz      not_pal

;/*
;**    {
;**        GetConvTabFromLogicalPalette();
;*/

        INVOKE  GetConvTabFromLogicalPalette
        jmp     exit

;/*
;**    }
;**    else
;*/

not_pal:

;/*
;**    {
;**        GetConvTabFromPhysicalPalette();
;*/

        INVOKE  GetConvTabFromPhysicalPalette

;/*
;**    }
;*/
exit:
        ret
GetDstMonoCTWithConvTab ENDP

;/***************************************************************************
;*
;* FUNCTION NAME = GetSelectedPalette
;*
;* DESCRIPTION   = pExtRGB  pointer to external colour table
;*
;*                 Copy the selected palette to the external table, pExtRGB, and fill
;*                 any unused entries with black.
;*
;*
;*
;* INPUT         =
;*
;*
;*
;*
;* OUTPUT        = NONE
;*
;* RETURN-NORMAL =
;* RETURN-ERROR  =
;*
;**************************************************************************/

;/*
;**VOID DRIVERCALL GetSelectedPalette(PRGB pExtRGB)
;*/

GetSelectedPalette PROC SYSCALL USES EBX ECX


;/*
;**{
;**    ULONG   i;
;**    ULONG   ulPaletteSize;
;**
;**    ulPaletteSize = min(1 << SPad.cExternalBitCount,
;**                        pdc->Palette->usCountStored);
;*/

        ddc?    ebx
        mov     ebx,[ebx].DDC.ddc_npdevpal
        mov     edx,[ebx].DEVPAL.usCountStored
        cmp     edx,[esi].ite_ExtColorCount
        jb      @F
        mov     edx,[esi].ite_ExtColorCount
@@:

;/*
;** Fill in the entries from the palette.
;*/
        mov     ecx,0
        jmp     loop_entry


;/*
;**    for (i = 0; i < ulPaletteSize; i++ )
;*/

loop_top:
;/*
;**    {
;**        SPad.pfnSetRGBAndInc(&pExtRGB,
;**                             pdc->Palette->entries[i].rgb.bRed,
;**                             pdc->Palette->entries[i].rgb.bGreen,
;**                             pdc->Palette->entries[i].rgb.bBlue);
;*/

        INVOKE  SetRGBAndInc,
                DWORD PTR [ebx].DEVPAL.entries[ecx*sizeof PALENTRY].rgb



        inc     ecx
loop_entry:
        cmp     ecx,edx
        jb      loop_top


;/*
;**    }
;**
;**    /******************************************************************/
;**    /* Now fill all remaining entries with black.                     */
;**    /******************************************************************/
;**    for (ulPaletteSize = 1 << SPad.cExternalBitCount;
;**         i < ulPaletteSize;
;**         i++)
;*/

        mov     ecx,[esi].ite_ExtColorCount
        jmp     loop2_entry
loop2_top:
;/*
;**    {
;**        SPad.pfnSetRGBAndInc(&pExtRGB, 0, 0, 0);
;*/

        INVOKE  SetRGBAndInc,
                0

        inc     ecx
loop2_entry:
        cmp     ecx,edx
        jb      loop2_top


;/*
;**    }
;*/

        ret
GetSelectedPalette ENDP


;/***************************************************************************
;*
;* FUNCTION NAME = MapManyRGBToLess
;*
;* DESCRIPTION   = Makes the internal to external conversiontable, if any, for a
;*                 source with bitcount greater than the destination.
;*                 Returns TRUE if a mapping from internal to external is set up,
;*                 FALSE otherwise.
;*
;* INPUT         =
;* OUTPUT        = NONE
;*
;* RETURN-NORMAL =
;* RETURN-ERROR  =
;*
;**************************************************************************/


;/*
;**BOOL DRIVERCALL MapManyRGBToLess(VOID)
;*/

MapManyRGBToLess PROC SYSCALL USES EBX ECX EDI

;/*
;**{
;**    ULONG   i;
;**    ULONG   ulMaxSource;
;**    ULONG   ulMaxTarget;
;**    ULONG   ulUsedSource;
;**    ULONG   ulUsedTarget;
;**
;**    /**********************************************************/
;**    /* we are going from more bits to less, so we must        */
;**    /* produce a conversion table to map the bits down into   */
;**    /* the restricted number of entries available.            */
;**    /**********************************************************/
;**    ulMaxSource = 1 << SPad.cInternalBitCount;
;**    ulMaxTarget = 1 << SPad.cExternalBitCount;
;**    ulUsedSource = min(ulMaxSource, pdc->Palette->usCountStored);
;*/

        ddc?    ebx
        mov     ebx,[ebx].DDC.ddc_npdevpal
        mov     edx,[ebx].DEVPAL.usCountStored
        cmp     edx,[esi].ite_IntColorCount
        jb      @F
        mov     edx,[esi].ite_IntColorCount
@@:

;/*
;**    ulUsedTarget = min(ulMaxTarget, pdc->Palette->usCountStored);
;*/

        mov     eax,[ebx].DEVPAL.usCountStored
        cmp     eax,[esi].ite_ExtColorCount
        jb      @F
        mov     eax,[esi].ite_ExtColorCount
@@:

;/*
;**#ifdef OPTIMIZATION
;**    /**********************************************************/
;**    /* We still might get away without having to use a        */
;**    /* conversion mapping if the palette is such that our     */
;**    /* source (although more bits per pel than the target)    */
;**    /* only contains indices within the target range.         */
;**    /*                                                        */
;**    /* However our code elsewhere is not clever enough to     */
;**    /* do without a conversion table, so just set up          */
;**    /* an identity mapping.                                   */
;**    /**********************************************************/
;**    if ( ulUsedSource < ulMaxTarget )
;**    {
;**        /******************************************************/
;**        /* NB. dont return until we change the code elsewhere */
;**        /* to do without the mapping table.                   */
;**        /* If we don't return then we will get an identity    */
;**        /* mapping.                                           */
;**        /******************************************************/
;**        return (FALSE);
;**    }
;**#endif /* OPTIMIZATION */
;**
;**    /**********************************************************/
;**    /* The mapping is the identity for all source entries     */
;**    /* which are valid in the target size.                    */
;**    /**********************************************************/
;*/

        mov     ecx,0
        mov     edi,[esi].ite_pbConvertTable
        jmp     loop1_entry
loop1_top:
;/*
;**    for (i = 0; i < ulUsedTarget; i++)
;**    {
;**        SPad.ausConvertTable[i] = (USHORT)i;
;*/

        mov     BYTE PTR [edi+ecx*sizeof BYTE],cl
        inc     ecx
loop1_entry:
        cmp     ecx,eax
        jb      loop1_top


;/*
;**    }
;**
;**    /**********************************************************/
;**    /* now we consider the entries which have to be mapped    */
;**    /* down                                                   */
;**    /**********************************************************/
;**    while (i < ulUsedSource)
;*/

        push    esi
        mov     esi,eax
        jmp     loop2_entry
loop2_top:

;/*
;**    {
;**        SPad.ausConvertTable[i] = (USHORT)
;**              NearestRestrictedColourIndex(
;**                           (PBYTE)pdc->Palette->entries,
;**                           sizeof(PALENTRY),
;**                           pdc->Palette->entries[i].rgb,
;**                           ulUsedTarget);
;*/


        INVOKE  NearestRestrictedColourIndex,
                ADDR BYTE PTR [ebx].DEVPAL.entries,
                sizeof PALENTRY,
                [ebx].DEVPAL.entries[ecx*sizeof PALENTRY].rgb,
                esi


        mov     BYTE PTR [edi+ecx*sizeof BYTE],al


;/*
;**        i++;
;*/

        inc     ecx
loop2_entry:
        cmp     ecx,edx
        jb      loop2_top
        pop     edi


;/*
;**    }
;**
;**    /**********************************************************/
;**    /* now zero map any remaining entries since they are      */
;**    /* probably errors which we cant do much else with        */
;**    /**********************************************************/
;*/

        jmp     loop3_entry


;/*
;**    for ( ; i < ulMaxSource; i++)
;*/

loop3_top:
;/*
;**    {
;**        SPad.ausConvertTable[i] = (USHORT)0;
;*/

        mov     BYTE PTR [edi+ecx*sizeof BYTE],0
        inc     ecx
loop3_entry:
        cmp     ecx,[esi].ite_IntColorCount
        jb      loop3_top
;/*
;**    }
;**
;**    return(TRUE);
;*/

        mov     eax,1
        ret
MapManyRGBToLess ENDP


;/***************************************************************************
;*
;* FUNCTION NAME = GetSelectedPalWithConvTab
;*
;* DESCRIPTION   = pExtRGB  pointer to external colour table
;*
;*                 Copy the selected palette to the external table, pExtRGB, filling
;*                 any unused entries with black and set up the internal to external
;*                 conversion table.
;*
;*
;* INPUT         =
;* OUTPUT        = NONE
;*
;* RETURN-NORMAL = TRUE if a mapping from internal to external is set up,
;* RETURN-ERROR  = FALSE otherwise.
;*
;**************************************************************************/


;/*
;**BOOL DRIVERCALL GetSelectedPalWithConvTab(PRGB pExtRGB)
;*/

GetSelectedPalWithConvTab PROC SYSCALL

;/*
;**{
;**    /******************************************************************/
;**    /* Set up the external color table.                               */
;**    /******************************************************************/
;**    GetSelectedPalette(pExtRGB);
;*/

        INVOKE  GetSelectedPalette

;/*
;**
;**    if (SPad.cInternalBitCount < SPad.cExternalBitCount)
;*/

        mov     eax,[esi].ite_IntColorCount
        cmp     eax,[esi].ite_ExtColorCount
        jae     do_else


;/*
;**    {
;**        /**********************************************************/
;**        /* no mapping needed if we are going from less bits to    */
;**        /* more                                                   */
;**        /**********************************************************/
;**        return(FALSE);
;*/

        mov     eax,0
        jmp     exit

;/*
;**    }
;**    else /* target bitcount greater than source */
;**    {
;*/

do_else:

;/*
;**        return(MapManyRGBToLess());
;*/

        INVOKE  MapManyRGBToLess


;/*
;**    }
;*/

exit:
        ret
GetSelectedPalWithConvTab ENDP


;/***************************************************************************
;*
;* FUNCTION NAME = GetDefaultHWPalette
;*
;* DESCRIPTION   = pExtRGB  pointer to external colour table
;*
;*                 Copy the default h/w palette to the external table, pExtRGB.
;*
;* INPUT         =
;* OUTPUT        = NONE
;*
;* RETURN-NORMAL =
;* RETURN-ERROR  =
;*
;**************************************************************************/

;/*
;**VOID DRIVERCALL GetDefaultHWPalette(PRGB pExtRGB)
;*/

GetDefaultHWPalette PROC SYSCALL

;/*
;**{
;**    ULONG   i;
;**    ULONG   ulPaletteSize;
;**    ULONG   ulPhyRGB;
;**    PBYTE   pbLogRGB;
;**
;**    ulPaletteSize = 1 << SPad.cExternalBitCount;
;**
;**   for (i = 0; i < ulPaletteSize; i++ )
;*/

        mov     ecx,0
        jmp     loop_entry
loop_top:

;/*
;**   {
;**      /**************************************************/
;**      /* Take this entry from the DeviceDefaultPalette  */
;**      /**************************************************/
;**      ulPhyRGB = MemoryDeviceDefaultULONG(i);
;*/

        MemoryDeviceDefaultRGB2 ecx,eax

;/*
;**      pbLogRGB = (PBYTE)&ulPhyRGB;
;**      SPad.pfnSetRGBAndInc(&pExtRGB,
;**                           pbLogRGB[2],
;**                           pbLogRGB[1],
;**                           pbLogRGB[0]);
;*/

        INVOKE  SetRGBAndInc,
                eax

        inc     ecx
loop_entry:
        cmp     ecx,[esi].ite_ExtColorCount
        jb      loop_top

;/*
;**   }
;**
;*/

        ret
GetDefaultHWPalette ENDP

;/***************************************************************************
;*
;* FUNCTION NAME = GetRealizableTable
;*
;* DESCRIPTION   = pExtRGB  pointer to external colour table
;*
;*                 Copy the current, realizable colour table to the external table,
;*                 pExtRGB.
;*
;* INPUT         =
;* OUTPUT        = NONE
;*
;* RETURN-NORMAL =
;* RETURN-ERROR  =
;*
;**************************************************************************/


;/*
;**VOID DRIVERCALL GetRealizableTable(PRGB pExtRGB)
;*/

GetRealizableTable PROC SYSCALL

;/*
;**{
;**    ULONG   i;
;**    ULONG   ulPaletteSize;
;**    RGB2    RGBValue;
;**
;**    ulPaletteSize = 1 << SPad.cExternalBitCount;
;**
;**    for (i = 0; i < ulPaletteSize; i++ )
;*/

        mov     ecx,0
        ddc?    ebx
        mov     edx,[ebx].DDC.ddc_pClrTbl

        jmp     loop_entry
loop_top:

;/*
;**    {
;**        /******************************************************/
;**        /* if this is a valid entry take it from color table  */
;**        /******************************************************/
;**        if ((i <= pdc->DCIHighIndex) &&
;**            (pdc->DCIColorTable[i].PhyIndex != CLR_NOPHYINDEX) )
;*/

        cmp     ecx,[ebx].DDC.ddc_ctMax
        ja      do_else
        .ERRNZ  8-sizeof COLORTABLETYPE
        cmp     [edx+ecx*8].COLORTABLETYPE.PhyIndex,CLR_NOPHYINDEX
        je      do_else

;/*
;**        {
;**            /**************************************************/
;**            /* This is a valid entry in the LCT so use its    */
;**            /* logical RGB value.                             */
;**            /**************************************************/
;**            RGBValue = pdc->DCIColorTable[i].LogRGB;
;*/

        mov     eax,[edx+ecx*8].COLORTABLETYPE.LogRGB
        jmp     end_if


;/*
;**        }
;*/

do_else:


;/*
;**        else
;**        {
;**            /**************************************************/
;**            /* Take this entry from the DeviceDefaultPalette  */
;**            /**************************************************/
;**            RGBValue = MemoryDeviceDefaultRGB2(i);
;*/

        MemoryDeviceDefaultRGB2 ecx,eax


;/*
;**        }
;*/

end_if:
;/*
;**        SPad.pfnSetRGBAndInc(&pExtRGB,
;**                             RGBValue.bRed,
;**                             RGBValue.bGreen,
;**                             RGBValue.bBlue);
;*/

        INVOKE  SetRGBAndInc,
                eax

        inc     ecx
loop_entry:
        cmp     ecx,[esi].ite_ExtColorCount
        jb      loop_top


;/*
;**    }
;*/

        ret
GetRealizableTable ENDP

;/***************************************************************************
;*
;* FUNCTION NAME = Get4Or8BppTable
;*
;* DESCRIPTION   = pExtRGB  pointer to external colour table
;*
;*                 Copy the current colour table to the external table, pExtRGB.
;*                 If the logical colour table is realizable then copy that,
;*                 otherwise copy the palette.
;*
;*
;* INPUT         =
;* OUTPUT        = NONE
;*
;* RETURN-NORMAL =
;* RETURN-ERROR  =
;*
;**************************************************************************/


;/*
;**VOID DRIVERCALL Get4Or8BppTable(PRGB pExtRGB)
;*/

Get4Or8BppTable PROC SYSCALL
;/*
;**{
;**    if (fRealizeSupported &&
;**        (pdc->DCIColStatus & LCOL_REALIZABLE))
;**    {
;*/

        cmp     ebx,0                   ;CMVC_53469
        jz      not_real                ;CMVC_53469
        ddc?    ebx
        test    [ebx].DDC.ddc_fbClrTbl,DDC_REALIZABLE
        jz      not_real


;/*
;**        GetRealizableTable(pExtRGB);
;*/

        INVOKE  GetRealizableTable
        jmp     exit

;/*
;**    }
;**    else /* non-realizable colour table */
;*/

not_real:
;/*
;**    {
;**        GetDefaultHWPalette(pExtRGB);
;*/

        INVOKE  GetDefaultHWPalette

;/*
;**    }
;*/


exit:
        ret
Get4Or8BppTable ENDP

;/***************************************************************************
;*
;* FUNCTION NAME = SetExternalColorTable
;*
;* DESCRIPTION   = Function to create a packed external colour table.
;*                 Only called when internal and external bitcounts are the same.
;*                 (NB. we can't be called for 24 bpp because internal bitcount is
;*                 never 24 bpp; can't be called for 16 bpp as this always requires
;*                 a conversion to external format).
;*
;* INPUT         =
;* OUTPUT        = NONE
;*
;* RETURN-NORMAL =
;* RETURN-ERROR  =
;*
;**************************************************************************/


;/*
;**VOID DRIVERCALL SetExternalColorTable(VOID)
;*/

SetExternalColorTable PROC SYSCALL

;/*
;**{
;**    PRGB   pExtRGB;
;**
;**    pExtRGB = (PRGB)
;**            ((PBYTE)SPad.pExternalHeader + SPad.pExternalHeader->cbFix);
;**
;**    if ( SPad.fbFlags & CONV_BCE_PALETTE )
;*/

        test    [esi].ite_Flags,ITE_BCE
        jz      not_bce

;/*
;**    {
;**        GetPaletteEncoding(pExtRGB);
;*/

        INVOKE  GetPaletteEncoding
        jmp     exit
not_bce:
;/*
;**    }
;**    else if (SPad.cExternalBitCount == 1)
;*/

        cmp     [esi].ite_ExtColorCount,2
        jne     not_extmono

;/*
;**    {
;**        GetMonoTable(pExtRGB);
;*/
        INVOKE  GetMonoTable
        jmp     exit

;/*
;**    }
;**    else if (pdc->DCIColFormat == LCOLF_PALETTE)
;*/

not_extmono:
        cmp     ebx,0                   ;CMVC_53469
        jz      not_pal                 ;CMVC_53469
        ddc?    ebx
        test    [ebx].DDC.ddc_fbClrTbl,DDC_PALETTE
        jz      not_pal

;/*
;**    {
;**        GetSelectedPalette(pExtRGB);
;*/

        INVOKE  GetSelectedPalette
        jmp     exit

;/*
;**    }
;**    else if (SPad.cExternalBitCount != 24)
;*/

not_pal:
        cmp     [esi].ite_ExtColorCount,12      ;24 bpp
        je      exit

;/*
;**    {
;**        Get4Or8BppTable(pExtRGB);
;*/

        INVOKE  Get4Or8BppTable


;/*
;**    }
;*/

exit:
        ret
SetExternalColorTable ENDP


;/***************************************************************************
;*
;* FUNCTION NAME = DisplayedRGB
;*
;* DESCRIPTION   = Maps Index to the RGB value which is actually used when this index
;*                 is applied.
;*
;* INPUT         =
;* OUTPUT        = NONE
;*
;* RETURN-NORMAL =
;* RETURN-ERROR  =
;*
;**************************************************************************/


;/*
;**RGB2 DRIVERCALL DisplayedRGB(ULONG   ulIndex)
;*/

DisplayedRGB PROC SYSCALL,
        ulIndex:ULONG
;/*
;**{
;**    if (fRealizeSupported                     &&
;**        (pdc->DCIColStatus & LCOL_REALIZABLE) &&
;**        (ulIndex < pdc->DCIColTabSize) )
;*/

        mov     edx,ulIndex
        cmp     ebx,0                   ;CMVC_53469
        jz      do_else                 ;CMVC_53469
        ddc?    ebx
        test    [ebx].DDC.ddc_fbClrTbl,DDC_REALIZABLE
        jz      do_else
        cmp     edx,[ebx].DDC.ddc_ctMax
        jae     do_else


;/*
;**    {
;**        /**********************************************/
;**        /* There is a LCT and it is realizable so we  */
;**        /* take the RGB value from it.                */
;**        /**********************************************/
;**        return(pdc->DCIColorTable[ulIndex].LogRGB);
;*/

        mov     eax,[ebx].DDC.ddc_pClrTbl
        mov     eax,[eax+edx*8].COLORTABLETYPE.LogRGB
        jmp     exit

;/*
;**    }
;**    else
;*/

do_else:

;/*
;**    {
;**        /**********************************************/
;**        /* There is no LCT, or an unrealizable LCT so */
;**        /* take the RGB value from the default        */
;**        /* physical palette.                          */
;**        /**********************************************/
;**        return(MemoryDeviceDefaultRGB2(ulIndex));
;*/

        mov     edx,ulIndex
        MemoryDeviceDefaultRGB2 edx,eax


;/*
;**    }
;*/

exit:
        ret
DisplayedRGB ENDP


;/***************************************************************************
;*
;* FUNCTION NAME = MapTo4BppWithConvTab
;*
;* DESCRIPTION   = pExtRGB  pointer to external colour table
;*
;*                 Maps the internal colour table to a 4 bpp external table and makes
;*                 a conversion table for translating from internal to external.
;*
;* INPUT         =
;* OUTPUT        = NONE
;*
;* RETURN-NORMAL =
;* RETURN-ERROR  =
;*
;**************************************************************************/


;/*
;**VOID DRIVERCALL MapTo4BppWithConvTab(PRGB pExtRGB)
;*/

MapTo4BppWithConvTab PROC SYSCALL

;/*
;**{
;**    ULONG    ulIndex;
;**    PBYTE    pbLogRGB;
;**    PBYTE    pbExtRGBTable = (PBYTE)pExtRGB;
;*/

LOCAL rgb :RGB2

TARGET_COLOURS  EQU     16


;/*
;** Set up the external color table.
;*/
        mov     ecx,0
        push    edi

for1_top:
;/*
;**    for ( ulIndex = 0; ulIndex < TARGET_COLOURS ; ulIndex++)
;**    {
;**        pbLogRGB =  (PBYTE)&(DefaultFourBppTable[ulIndex].LogRGB);
;*/

ifdef  JFIX ;               ;IBMJ
        ; Modification for defect 60394 was picked up from XGA C source code.
        ; 06/22/93 N.Ichikawa.

        ;/**********************************************************/
        ;/* Defect 60394 - If the DC has a 16 entry logical color  */
        ;/* table loaded then we should use it.                    */
        ;/**********************************************************/
        ;if( pdc->DCIHighIndex == (TARGET_COLOURS-1))
        ;  pbLogRGB =  (PBYTE)&(pdc->DCIColorTable[ulIndex].LogRGB);

        cmp     [ebx].DDC.ddc_ctMax,TARGET_COLOURS-1
        jnz     mt4_else_1
        mov     eax,[ebx].DDC.ddc_pClrTbl       ; EAX -> DDC's own color table
        mov     eax,[eax+ecx*sizeof(COLORTABLETYPE)].COLORTABLETYPE.LogRGB
        jmp     mt4_endif_1
mt4_else_1:
        ;else
        ;  pbLogRGB =  (PBYTE)&(DefaultFourBppTable[ulIndex].LogRGB);

        mov     eax,DefaultFourBppTable[ecx*sizeof COLORTABLETYPE].LogRGB
mt4_endif_1:
else  ;JFIX ;               ;IBMJ
        mov     eax,DefaultFourBppTable[ecx*sizeof COLORTABLETYPE].LogRGB
endif ;JFIX        ;IBMJ

;/*
;**
;**        SPad.pfnSetRGBAndInc(&pExtRGB,
;**                             pbLogRGB[2],
;**                             pbLogRGB[1],
;**                             pbLogRGB[0]);
;*/

        INVOKE  SetRGBAndInc,
                eax

        inc     ecx

for1_entry:
        cmp     ecx,TARGET_COLOURS
        jb      for1_top

        pop     edi


;/*
;**    }
;**
;**    /******************************************************************/
;**    /* Set up the conversion table.                                   */
;**    /******************************************************************/
;**    for ( ulIndex = 1 << SPad.cInternalBitCount; ulIndex--; )
;*/

        mov     ecx,[esi].ite_IntColorCount
        dec     ecx
for2_top:

;/*
;**    {
;**        SPad.ausConvertTable[ulIndex] = (USHORT)
;**            NearestRestrictedColourIndex(pbExtRGBTable,
;**                                         SPad.usIncrement,
;**                                         DisplayedRGB(ulIndex),
;**                                         TARGET_COLOURS);
;*/

        INVOKE  DisplayedRGB,
                ecx

        mov     rgb,eax

        INVOKE  NearestRestrictedColourIndex,
                edi,
                [esi].ite_RgbIncrement,
                rgb,
                TARGET_COLOURS

        mov     edx,[esi].ite_pbConvertTable
        mov     BYTE PTR [edx+ecx*sizeof BYTE],al
        dec     ecx
for2_entry:
        cmp     ecx,0
        jns     for2_top


;/*
;**    }
;*/

        ret
MapTo4BppWithConvTab ENDP


;/***************************************************************************
;*
;* FUNCTION NAME = TableIntToPM
;*
;* DESCRIPTION   = Creates a packed external colour table and a conversion table
;*                 between the internal and external colour tables.
;*
;*                 Returns TRUE is an internal to external mapping has been set up,
;*                 FALSE otherwise.
;*
;*                 Only called when source and destination bitcounts differ.
;* INPUT         =
;* OUTPUT        = NONE
;*
;* RETURN-NORMAL =
;* RETURN-ERROR  =
;*
;**************************************************************************/

TableIntToPM PROC SYSCALL


;/*
;**{
;**    PRGB   pExtRGB;
;**
;**    pExtRGB = (PRGB)
;**            ((PBYTE)SPad.pExternalHeader + SPad.pExternalHeader->cbFix);
;**
;**    if ( SPad.fbFlags & CONV_BCE_PALETTE )
;*/

        test    [esi].ite_Flags,ITE_BCE
        jz      tip_not_bce

;/*
;**    {
;**        GetPalEncodeWithConvTab(pExtRGB);
;*/

        INVOKE  GetPalEncodeWithConvTab

;/*
;**    }
;**    else if (SPad.cInternalBitCount == 1)
;*/

tip_not_bce:
        cmp     [esi].ite_IntColorCount,2  ;Monochrome source?
        jnz     tip_not_intmono
;/*
;**    {
;**        GetSrcMonoCTWithConvTab(pExtRGB);
;*/

        INVOKE  GetSrcMonoCTWithConvTab

;/*
;**    }
;**    else if (SPad.cExternalBitCount == 1)
;*/

tip_not_intmono:
        cmp     ecx,2
        jne     tip_not_extmono

;/*
;**    {
;**        GetDstMonoCTWithConvTab(pExtRGB);
;*/

        INVOKE  GetDstMonoCTWithConvTab
;/*
;**    }
;**    else if (pdc->DCIColFormat == LCOLF_PALETTE)
;*/

tip_not_extmono:
        cmp     ebx,0                   ;CMVC_53469
        jz      tip_not_pal             ;CMVC_53469
        ddc?    ebx
        test    [ebx].DDC.ddc_fbClrTbl,DDC_PALETTE
        jz      tip_not_pal

;/*
;**    {
;**        return(GetSelectedPalWithConvTab(pExtRGB));
;*/

        INVOKE  GetSelectedPalWithConvTab
;/*
;**    }
;**    else if (SPad.cExternalBitCount == 4)
;*/

tip_not_pal:
        cmp     ecx,16
        jne     tip_not_4

;/*
;**    {
;**        MapTo4BppWithConvTab(pExtRGB);
;*/

        INVOKE  MapTo4BppWithConvTab
;/*
;**    }
;**    else if (SPad.cExternalBitCount == 8)
;*/

tip_not_4:
        cmp     ecx,256
        jne     tip_done

;/*
;**    {
;**        Get4Or8BppTable(pExtRGB);
;*/

        INVOKE  Get4Or8BppTable
;/*
;**    }
;**    return (TRUE);
;*/

tip_done:
     mov        eax,1
        ret
TableIntToPM ENDP

;/***************************************************************************
;*
;* FUNCTION NAME = SetRGBAndInc
;*
;* DESCRIPTION   = ppExtRGB pointer to the pointer to the external colour table in
;*                          old format
;*                 bRed     red component of the colour to set
;*                 bGreen   green component of the colour to set
;*                 bBlue    blue component of the colour to set
;*
;*                 Sets one entry in the old format external colour table, ppExtRGB,
;*                 and increments the pointer to point to the next entry.
;* INPUT         =
;* OUTPUT        = NONE
;*
;* RETURN-NORMAL =
;* RETURN-ERROR  =
;*
;**************************************************************************/

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

SetRGBAndInc PROC SYSCALL,
        rgb:DWORD


;/*
;**{
;**   SetRGBAndIncEither(*ppExtRGB, bRed, bGreen, bBlue)
;**        (p)->bRed=(BYTE)(r);                                           \
;**        (p)->bGreen=(BYTE)(g);                                         \
;**        (p)->bBlue=(BYTE)(b);                                          \
;**        (p)++;                                                         \
;**        ite?    esi
;*/

        mov     eax,rgb

        cmp     [esi].ite_RgbIncrement,sizeof RGB2
        je      do_rgb2

        mov     WORD PTR [edi],ax
        shr     eax,16
        mov     BYTE PTR [edi+2],al
        add     edi,sizeof RGB
        jmp     done
do_rgb2:
        and     eax,00FFFFFFh   ;zap fcOptions
        mov     DWORD PTR [edi],eax
        add     edi,sizeof RGB2
done:
        ret


;/*
;** }
;*/

SetRGBAndInc ENDP

END

