;*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.;
;*****************************************************************************/
        page    ,132
OPTION EPILOGUE:NONE
;/*****************************************************************************
;*
;* SOURCE FILE NAME = BMC_ITE.ASM
;*
;* DESCRIPTIVE NAME = Bitmap Conversion - Internal to External
;*
;*
;* VERSION      V2.0
;*
;* DATE         05/16/87
;*
;* DESCRIPTION
;*              There are four standard bitmap formats.  All device drivers
;*              are required to be able to translate between any of these
;*              formats and their own internal formats. The standard formats
;*              are as follows:
;*
;*                                    Bitcount                 Planes
;*                                    --------                 ------
;*                                         1                   1
;*                                         4                   1
;*                                         8                   1
;*                                        24                   1
;*
;*              These formats are chosen because they are identical or similar
;*              to all formats commonly used by raster devices.  Only single
;*              plane formats are standard, but it is very easy to convert these
;*              to any multiple plane format used internally by a device.
;*
;*              The pixel data is stored in the bitmap in the order of the co-
;*              ordinates as they would appear on a display screen.  That is,
;*              the pixel in the lower left corner is the first in the bitmap.
;*              Pixels are scanned to the right and up from there.  The first
;*              pixel's bits are stored beginning in the lowest order bits of
;*              the first byte.  The data for pixels in each scan line is packed
;*              together tightly.  Each scanline, however, will be padded at the
;*              end so that each scan line begins on a DWORD boundary.
;*
;* FUNCTIONS    bmc_int_to_ext
;*
;*
;* NOTES        NONE
;*
;* STRUCTURES   NONE
;*
;* EXTERNAL REFERENCES
;*
;*              NONE
;*
;* EXTERNAL FUNCTIONS
;*
;*              NONE
;*
;* CHANGE ACTIVITY =
;*   DATE      FLAG        APAR   CHANGE DESCRIPTION
;*   --------  ----------  -----  --------------------------------------
;*   mm/dd/yy  @Vr.mpppxx  xxxxx  xxxxxxx
;*   05/16/87                     Written by Walt Moore
;*   11/09/87                     Bob Grudem [bobgru] Internal color bitmaps
;*                                always use interleaved (i.e. huge)
;*                                scanline format.
;*   05/01/90                     Viroon Touranachun [viroont] Add the inquiry
;*                                option, i.e., pBuf = NULL, for requesting just
;*                                the extracted size.
;*   01/26/93              60847  DH counter getting destroyed in copy_i8e24.
;*   04/13/94              80041  fbPal local not initialized bmc_int_to_ext.
;*   06/23/94              85526  Changed the Copy_i1e8... functions to convert
;*                                to 0's and 1's instead of 0's and ff's.
;*
;*****************************************************************************/

        .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

        .DATA
        extern  argbDefCT16Reorg:byte
        extern  PalColor:byte

        .xlist
        include bmi2.inc

        .list

;/*
;** The CAN_CROSS_SEG flag is overlayed on top of the sd_fb flag taken
;** from the surface definition of the bitmap.  SD_DEVICE must be null
;** else we don't have a bitmap.
;*/

CAN_CROSS_SEG   equ     SD_DEVICE       ;User's buffer will cross seg boundary

;/*
;** anpfnPreProc is the dispatch table for the function to perform
;** any preprocessing required for the given format
;*/

anpfnPreProc    label   DWORD

        DWORD   ite_1
        DWORD   ite_4
        DWORD   ite_8
        DWORD   ite_24

;/*
;**    temp_color_table will be for translating 4 to 24 until
;**    the dynamic color tables are in place.
;**    must match that in phycolor until phycolor can be modifed
;**    to have it's table in CS
;*/

temp_color_table label BYTE

        DWORD   00000000h               ;Black
        DWORD   00000080h               ;Blue
        DWORD   00008000h               ;Green
        DWORD   00008080h               ;Cyan
        DWORD   00800000h               ;Red
        DWORD   00800080h               ;Magenta
        DWORD   00808000h               ;Yellow
        DWORD   00808080h               ;White

ifdef VGA

        DWORD   00CCCCCCh               ;Light Gray
else
        DWORD   00202020h               ;Black
endif
        DWORD   000000FFh               ;Blue
        DWORD   0000FF00h               ;Green
        DWORD   0000FFFFh               ;Cyan
        DWORD   00FF0000h               ;Red
        DWORD   00FF00FFh               ;Magenta
        DWORD   00FFFF00h               ;Yellow
        DWORD   00FFFFFFh               ;White

;/*
;**    fixed_color_table is the default color table which the
;**    device is programmed with.
;*/

fixed_color_table label byte

        BYTE    000h,000h,000h          ;Black
        BYTE    080h,000h,000h          ;Blue
        BYTE    000h,080h,000h          ;Green
        BYTE    080h,080h,000h          ;Cyan
        BYTE    000h,000h,080h          ;Red
        BYTE    080h,000h,080h          ;Magenta
        BYTE    000h,080h,080h          ;Yellow
        BYTE    080h,080h,080h          ;White

ifdef VGA

        BYTE    0CCh,0CCh,0CCh          ;Light Gray
else
        BYTE    020h,020h,020h          ;Black
endif
        BYTE    0FFh,000h,000h          ;Blue
        BYTE    000h,0FFh,000h          ;Green
        BYTE    0FFh,0FFh,000h          ;Cyan
        BYTE    000h,000h,0FFh          ;Red
        BYTE    0FFh,000h,0FFh          ;Magenta
        BYTE    000h,0FFh,0FFh          ;Yellow
        BYTE    0FFh,0FFh,0FFh          ;White

SIZE_FIXED_COLOR_TABLE  = $-fixed_color_table

fixed_color_table2 label byte

        BYTE    000h,000h,000h,000h             ;Black
        BYTE    080h,000h,000h,000h             ;Blue
        BYTE    000h,080h,000h,000h             ;Green
        BYTE    080h,080h,000h,000h             ;Cyan
        BYTE    000h,000h,080h,000h             ;Red
        BYTE    080h,000h,080h,000h             ;Magenta
        BYTE    000h,080h,080h,000h             ;Yellow
        BYTE    080h,080h,080h,000h             ;White

ifdef VGA

        BYTE    0CCh,0CCh,0CCh,000h             ;Light Gray
else
        BYTE    020h,020h,020h,000h             ;Black
endif
        BYTE    0FFh,000h,000h,000h             ;Blue
        BYTE    000h,0FFh,000h,000h             ;Green
        BYTE    0FFh,0FFh,000h,000h             ;Cyan
        BYTE    000h,000h,0FFh,000h             ;Red
        BYTE    0FFh,000h,0FFh,000h             ;Magenta
        BYTE    000h,0FFh,0FFh,000h             ;Yellow
        BYTE    0FFh,0FFh,0FFh,000h             ;White

SIZE_FIXED_COLOR_TABLE2 = $-fixed_color_table2

bmi2_fill_point    label   byte

        BYTE      0                            ; Should never be invalid
        BYTE      ite_cBitCount - ite_ulIdentifier
        BYTE      ite_ulCompression - ite_ulIdentifier
        BYTE      ite_cbImage - ite_ulIdentifier
        BYTE      ite_cxResolution - ite_ulIdentifier
        BYTE      ite_cyResolution - ite_ulIdentifier
        BYTE      ite_cclrUsed - ite_ulIdentifier
        BYTE      ite_cclrImportant - ite_ulIdentifier
        BYTE      ite_usUnits - ite_ulIdentifier
        BYTE      ite_usReserved - ite_ulIdentifier
        BYTE      ite_usRecording - ite_ulIdentifier
        BYTE      ite_usRendering - ite_ulIdentifier
        BYTE      ite_cSize1 - ite_ulIdentifier
        BYTE      ite_cSize2 - ite_ulIdentifier
        BYTE      ite_ulColorEncoding - ite_ulIdentifier
        BYTE      ite_ulIdentifier - ite_ulIdentifier

DEFAULT_VALUE      equ    000000000h

MAX_SCANLINES      equ    65535

store_with_seg_check    macro

                        stosb

                        endm

        .CODE
page
;/***************************************************************************
;*
;* FUNCTION NAME =  bmc_int_to_ext
;*
;* DESCRIPTION   = Bitmap conversion, internal format to external format
;*
;*                 This is the driving routine for bitmap conversions from our
;*                 internal formats to the external formats which we support.
;*
;*                 Registers Preserved:
;*                       SI,DI,BP,DS
;*                 Registers Destroyed:
;*                       AX,BX,CX,DX,FLAGS
;*
;* INPUT         = npbm:DWORD
;*                 pBuf:DWORD
;*                 iStart:DWORD
;*                 pbmi:DWORD
;*                 cyScans:DWORD
;*                 DummyParamater1:DWORD
;*
;* OUTPUT        = NONE
;*
;* RETURN-NORMAL = DX:AX = # of scanlines translated
;* RETURN-ERROR  = NONE
;*
;**************************************************************************/

bmc_int_to_ext  PROC SYSCALL USES edi esi,      npbm:DWORD, pbmi:DWORD,
                                                pBuf:DWORD, cyScans:DWORD,
                                                iStart:DWORD, pddc:DWORD
                LOCAL   scans_copied:DWORD,
                        scanline_count:DWORD,
                        bitmap_width:DWORD,
                        bitmap_height:DWORD,
                        lp_bits:DWORD,
                        width_scan:DWORD,
                        next_scan:DWORD
                LOCAL   scans_per_seg:DWORD,
                        prev_offset:DWORD,
                        scan_byte_count:DWORD,
                        full_byte_proc:DWORD,
                        partial_byte_flags:DWORD,
                        partial_byte_proc:DWORD,
                        huge_scans_left:DWORD
                LOCAL   some_temp:DWORD,
                        buffer_adjust:DWORD,
                        temp_byte_count:DWORD,
                        rgb_size:DWORD,
                        scan_length:DWORD,
                        xlate_8_to_4[256]:BYTE,
                        fbsd:BYTE
                LOCAL   fbPal:BYTE

ifdef   FIREWALLS
        DebugMsg <bmc_int_to_ext CLIFFL bmc_ite.asm>

        mov     ebx,npbm

        ASSUME  ebx:PTR BITMAP

        cmp     [ebx].bm_sd.sd_usId,SURFACE_IDENT
        jne     bmc_not_a_bitmap
        test    [ebx].bm_sd.sd_fb,SD_DEVICE
        jz      bmc_its_a_Bitmap

bmc_not_a_bitmap:

        rip     text,<Bitmap Conversions - Surface is not a bitmap>

bmc_its_a_Bitmap:

endif

        cld
        xor     eax,eax

        mov     scans_copied,eax
        mov     fbPal,al                    ;          


;/*
;** Validate the parameters passed in.  We will only support the standard
;** formats.  We will not return bits in a device dependant format.  They
;** cannot give us bogus numbers for the start scan and count.
;*/

        ASSUME  ebx:NOTHING

        mov     ebx,PMERR_INV_SCAN_START ;The starting scan must be 0-65535
        cmp     iStart,MAX_SCANLINES
        jg      ite_log_error
        mov     ebx,PMERR_INV_LENGTH_OR_COUNT
        cmp     cyScans,MAX_SCANLINES
        jle     ite_numbers_ok

ite_log_error:

        xchg    eax,ebx

        save_error_code

        mov     eax,-1

ite_get_out:

        jmp     ite_exit

ite_inv_format:

        mov     ebx,PMERR_INV_INFO_TABLE
        jmp     ite_log_error

ite_numbers_ok:

        mov     ebx,pbmi                ;Validate bitmap info structure
        xor     ecx,ecx                 ; only check required fields
        call    check_bitmap_info
        jecxz   ite_inv_format

ifdef FIREWALLS

        cmp     eax,12          ;We should always get back 0,4,8,12
                                ;corresponds as follows:
                                ; 0 =>  1 bit  per pel
                                ; 4 =>  4 bits per pel
                                ; 8 =>  8 bits per pel
                                ;12 => 24 bits per pel
        jbe     @F

ite_cbi_failed:

        rip     text,<check_bitmap_info returned an illegal value>
@@:
        test    al,1
        jnz     ite_cbi_failed
endif
        xchg    eax,ebx
        mov     esi,anpfnPreProc[ebx]   ;Save preprocessor's address
        xchg    eax,ebx

;/*
;** Copy the bitmap data as necessary to local frame storage
;*/

        mov     edi,npbm

        ASSUME  edi:PTR BITMAP

        mov     eax,[edi].bm_sd.sd_cx   ;Must set height and width before
        mov     bitmap_width,eax        ;  checking for a null bitmap
        mov     edx,[edi].bm_sd.sd_cy   ;Preserve AX and DX until height
        mov     bitmap_height,edx       ;and width are set below

        ASSUME  ebx:PTR BITMAPINFO

        cmp     [ebx].bmi_cbFix,SIZE BITMAPINFOHEADER
        jne     ite_new_header

        mov     [ebx].bmi_cx,ax
        mov     [ebx].bmi_cy,dx
        mov     rgb_size,(SIZE RGB)
        jmp     ite_done_with_bmi

ite_new_header:                         ; fill in remaining fields

        push    esi                      ; save si

        ASSUME  ebx:PTR BITMAPINFO2

        assert  [ebx].bmi2_cbFix,LE,65535   ; cbFix must be valid by this point

        mov     esi,[ebx].bmi2_cbFix

        assert  esi,LE,64

        .errnz  (SIZE BITMAPINFOHEADER2)-64

        shr     esi,1

        assert  NC

        add     esi,OFFSET ok_cbFix
        movzx   esi,BYTE PTR [esi]

        assert  esi,NE,0                ; cbFix not invalid

        add     esi,OFFSET bmi2_fill_point
        movzx   esi,BYTE PTR [esi]
        add     esi,OFFSET ite_ulIdentifier
        jmp     esi

ite_ulIdentifier::

ite_ulColorEncoding::

ite_cSize2::

        mov     [ebx].bmi2_cSize2,DEFAULT_VALUE

ite_cSize1::

        mov     [ebx].bmi2_cSize1,DEFAULT_VALUE

ite_usRendering::

ite_usRecording::

ite_usReserved::

ite_usUnits::

        mov     [ebx].bmi2_usUnits,BRU_METRIC

ite_cclrImportant::

        movzx   ecx,[ebx].bmi2_cBitCount
        mov     esi,1
        shl     esi,cl                  ;24-bpp ==> SI = 0
        mov     [ebx].bmi2_cclrImportant,esi
        jmp     ite_already_computed_colors

ite_cclrUsed::

        movzx   ecx,[ebx].bmi2_cBitCount
        mov     esi,1
        shl     esi,cl                  ;24-bpp ==> SI = 0

ite_already_computed_colors:

        mov     [ebx].bmi2_cclrUsed,esi

ite_cyResolution::

        mov     [ebx].bmi2_cyResolution,DEFAULT_VALUE

ite_cxResolution::

        mov     [ebx].bmi2_cxResolution,DEFAULT_VALUE

ite_cbImage::

        mov     [ebx].bmi2_cbImage,DEFAULT_VALUE

ite_ulCompression::

ite_cBitCount::

        mov     [ebx].bmi2_cx,eax
        mov     [ebx].bmi2_cy,edx

        mov     rgb_size,(SIZE RGB2)
        pop     esi                      ; restore si

ite_done_with_bmi:

        mov     al,[edi].bm_sd.sd_fb    ;Color format, huge, CAN_CROSS_SEG
        mov     fbsd,al                 ;  (if we set it)
        mov     cl,al
        and     eax,SD_NONNULL          ;If a null surface, return
        jz      ite_get_out             ;  0 scans copied.
        mov     eax,[edi].bm_sd.sd_pBits
        mov     lp_bits,eax
        mov     eax,[edi].bm_sd.sd_cbScan
        mov     width_scan,eax
        mov     ebx,[edi].bm_sd.sd_dScan
        mov     next_scan,ebx

ite_isnt_huge_bitmap:

;/*
;** We have gathered up most of the bitmap data necessary for doing
;** the conversion.  Compute the real starting scan Y and the number
;** of scanlines to copy.
;*/

        mov     ecx,iStart
        mov     ebx,bitmap_height
        cmp     ecx,ebx                 ;If starting scan is outside bitmap
        jb      @F                      ;  want count to become 0 so we'll
        mov     ecx,ebx                 ;  exit after color table is set
@@:     sub     ebx,ecx                 ;Compute number of scans to move
        mov     eax,cyScans

        usmin_ax   ebx

        mov     scanline_count,eax
        mov     scans_copied,eax        ;We will return this value

;/*
;** Now perform the format specific initialization.
;*/

        mov     edi,pbmi

        ASSUME  edi:PTR BITMAPINFO2

        add     edi,[edi].bmi2_cbFix    ;ES:DI --> where color table is
        call    esi
;/*
;** If pBuf is NULL, it is an inquiry and we have retreived all the information.
;*/

        cmp     pBuf,0                  ;is it an inquiry?
        je      ite_xfered_all

        cmp     scanline_count,0
        je      ite_xfered_all

;/*
;**       Format specific initialization has been performed.  Compute
;**       the real starting scan Y and the number of scanlines to copy.
;**       If a huge bitmap and the scans to be copied are contained
;**       within the same segment, then we can treat it as a normal bitmap.
;*/


        mov     eax,bitmap_height       ;Invert the Y coordinate
        sub     eax,iStart
        dec     eax
        xor     edx,edx

ite_finish_y_calc:

        mul     next_scan               ;Compute offset within the segment
        add     eax,lp_bits             ;Compute segment of the bits
        xchg    eax,esi

        mov     edi,pBuf                ;Dest is user's buffer (this pointer


ite_in_segment:

        push    esi                     ;Save bitmap scan start address
        mov     ecx,scan_byte_count     ;Set translation procedure loop count
        jecxz   ite_see_about_partial   ;No full bytes!
        call    full_byte_proc          ;Process all complete bytes

ite_see_about_partial:

        mov     ecx,partial_byte_flags  ;Process any partial byte
        jecxz   ite_no_partial_byte
        call    partial_byte_proc

ite_no_partial_byte:

        pop     esi
        dec     scanline_count
        jz      ite_xfered_all          ;Transfered all scans

        sub     esi,next_scan           ;--> next bitmap scanline
        add     edi,buffer_adjust       ;Align to dword boundary


        jmp     ite_in_segment          ; !!!! -CL-  !!!!!

;/*
;** compute and save the size of the bitmap extracted
;*/

ite_xfered_all:

        mov     ebx,pbmi                ;calculate the number of bytes returned
        cmp     [ebx].bmi2_cbFix,OFFSET BITMAPINFO2.bmi2_cbImage
        jbe     ite_return_val
        movzx   eax,[ebx].bmi2_cBitCount
        mul     [ebx].bmi2_cx
        add     eax,31                   ;Don't forget 32 bit aligned
        shr     eax,3
        and     eax,not 3
        mul     scans_copied            ;multiply with the number of scans
        mov     [ebx].bmi2_cbImage,eax

ite_return_val:

        mov     eax,scans_copied        ;Return number of scans copied
        xor     edx,edx

ite_exit:
OPTION EPILOGUE:EPILOGUEDEF

        fw_zero <ecx>

        RET

OPTION EPILOGUE:NONE
page
;/***************************************************************************
;*
;* PRIVATE ROUTINE ite_1
;*
;* DESCRIPTION   = Bitmap conversion, internal format to external 1 bit
;*
;*                 This routine is responsible for all preprocessing for converting
;*                 from our internal formats to external 1 bit format
;*
;*                 Registers Preserved:
;*                       BP,DS,ES
;*                 Registers Destroyed:
;*                       AX,BX,CX,DX,SI,DI,FLAGS
;*
;* INPUT         = ES:DI --> where color table would go
;* OUTPUT        = NONE
;*
;* RETURN-NORMAL = NONE
;* RETURN-ERROR  = NONE
;*
;**************************************************************************/

ite_1::

        xor     eax,eax
        mov     buffer_adjust,eax       ;Everything will be dword aligned
        mov     partial_byte_flags,eax  ;Will never have a partial byte
ifdef   FIREWALLS
        DebugMsg <copy_i1e1>
endif
        lea     eax,copy_i1e1            ;Assume monochrome bitmap
        lea     ebx,copy_i1e1_partial
        test    fbsd,SD_COLOR           ;Monochrome source?
        jz      ite_1_have_proc         ;  Yes
ifdef   FIREWALLS
        DebugMsg <copy_i8e1>
endif

;/*
;**  need to somehow build the color table translation data here
;**  when we decide how to throw out information when going 4 to 1
;*/

        lea     eax,copy_i8e1           ;Color bitmap
        lea     ebx,copy_i8e1_partial

ite_1_have_proc:

        mov     full_byte_proc,eax
        mov     partial_byte_proc,ebx

        mov     ecx,2                   ;Two color table entries
        call    create_mono_color_table

;/*
;**       Whenever we allocated a scanline (or each scan of a color
;**       bitmap), we allocated to a dword boundary.  If we just
;**       translate for the width of the scan in bytes, the required
;**       dword alignment will be maintained.
;*/

        mov     eax,bitmap_width                ;Moving all bytes of the scan
        mov     edx,eax
        mov     ecx, 31
        add     eax, ecx                        ; try to allign to dword
        not     ecx
        and     eax, ecx                        ; ax is alligned to dwords
        mov     ebx,eax
        mov     eax,edx
        shr     eax,3
        mov     scan_byte_count,eax

        shl     eax,3
        sub     edx,eax
        mov     partial_byte_flags,edx  ;Will never have a partial byte
                                                ;  for one bitmap scan
        sub     ebx,bitmap_width
        shr     ebx,3
        mov     buffer_adjust,ebx

        ret

page
;/***************************************************************************
;*
;* PRIVATE ROUTINE ite_4
;*
;* DESCRIPTION   = Bitmap conversion, internal format to external 4 bit
;*
;*                 This routine is responsible for all preprocessing for converting
;*                 from our internal formats to external 4 bit format
;*
;*                 Registers Preserved:
;*                       BP,DS,ES
;*                 Registers Destroyed:
;*                       AX,BX,CX,DX,SI,DI,FLAGS
;*
;* INPUT         = ES:DI --> where color table would go
;* OUTPUT        = NONE
;*
;* RETURN-NORMAL = NONE
;* RETURN-ERROR  = NONE
;*
;**************************************************************************/


ite_4::

        xor     eax,eax
        mov     buffer_adjust,eax       ;Everything will be dword aligned
        mov     partial_byte_flags,eax  ;Will never have a partial byte
        mov     ecx,16                  ;There will be 16 color table entries
        test    fbsd,SD_COLOR           ;Monochrome source?
        jnz     ite_4_not_mono          ;Not mono, must be color
ifdef   FIREWALLS
        DebugMsg <copy_i1e4>
endif

        call    create_mono_color_table
        lea     eax,copy_i1e4
        lea     ebx,copy_i1e4_partial
        mov     ecx, 15                 ; to allign to word boundary
        jmp     ite_4_have_proc

ite_4_not_mono:
ifdef   FIREWALLS
        DebugMsg <copy_i8e4>
endif
        call    create_color_color_table
        lea     eax,copy_i8e4
        lea     ebx,copy_i8e4_partial
        mov     ecx,1
ite_4_have_proc:

        mov     full_byte_proc,eax
        mov     partial_byte_proc,ebx   ;Might need this for seg boundaries


        test    fbsd, SD_COLOR
        jne     ite_4_color3

        mov     eax,bitmap_width
        mov     ecx, 15                 ; to allign to word boundary
        add     eax, ecx                        ; 
        not     ecx                     ; fff0
        and     eax, ecx                        ; # of bits a multiple of 32
        shr     eax, 3                  ; get the number of bytes to store
        mov     ebx,eax
        mov     scan_byte_count, ebx
        ret

ite_4_color3:
        mov     eax,bitmap_width
        add     eax,1                   ;force word alignment on int. bmps
        and     eax,-2
        mov     ebx,eax
        shr     eax, 3
        mov     scan_byte_count, eax    ;main copy will do multiple of 8
        shl     eax, 3
        sub     ebx,eax
        mov     partial_byte_flags,ebx  ; 
        or      ebx, ebx
        je      ite_4_colorx
        mov     eax,8
        sub     eax,ebx
        shr     eax,1
        mov     buffer_adjust,eax
ite_4_colorx:

        ret                             ;  for one bitmap scan
page

;/***************************************************************************
;*
;* PRIVATE ROUTINE ite_8
;*
;* DESCRIPTION   = Bitmap conversion, internal format to external 8 bit
;*
;*                 This routine is responsible for all preprocessing for converting
;*                 from our internal formats to external 8 bit format
;*
;*                 Registers Preserved:
;*                       BP,DS,ES
;*                 Registers Destroyed:
;*                       AX,BX,CX,DX,SI,DI,FLAGS
;*
;* INPUT         = ES:DI --> where color table would go
;* OUTPUT        = NONE
;*
;* RETURN-NORMAL = NONE
;* RETURN-ERROR  = NONE
;*
;**************************************************************************/

public ite_8
ite_8::

        xor     eax,eax                 ;Will not require any buffer adjustment
        mov     buffer_adjust,eax

        test    fbsd,SD_COLOR           ;Monochrome source?
        jnz     ite_8_not_mono          ;Not mono, must be color
ifdef   FIREWALLS
        DebugMsg <copy_i1e8>
endif

        mov     ecx,256
        call    create_mono_color_table
        lea     eax,copy_i1e8
        lea     ebx,copy_i1e8_partial
        mov     ecx,3
        jmp     ite_8_have_proc

ite_8_not_mono:
ifdef   FIREWALLS
        DebugMsg <copy_i8e8>
endif
        mov     ecx,256                 ;There will be 256 color table entries
        call    create_color_color_table
        lea     eax,copy_i8e8
        lea     ebx,copy_i8e8_partial
        mov     ecx,0
ite_8_have_proc:
        mov     full_byte_proc,eax
        mov     partial_byte_proc,ebx

        mov     eax,bitmap_width        ;Compute the number of source bytes
        mov     edx,eax

        test    fbsd, SD_COLOR
        jne     ite_8_color3

        add     eax, 3                  ; to convert.   Each dword becomes
        and     al, 11111100b           ; 4 source bytes = 1 dest nibble
        mov     ebx, eax
        shr     eax, 3
        mov     scan_byte_count,eax
        and     ebx, 4
        mov     partial_byte_flags,ebx  ;  no extra nibble to xlate
        ret

ite_8_color3:
        inc     eax                     ; allign to word boundary
        and     eax, 0fffeh             ; 
        mov     ebx,eax
        mov     eax, edx                ; Moving all bytes of the scan
        shr     eax, 3
        mov     scan_byte_count,eax
        shl     eax, 3
        sub     ebx, eax
        mov     partial_byte_flags,ebx  ;  no extra nibble to xlate
        neg     ebx                     ; shift the last byte
        add     ebx, 4
        and     ebx, 00000011b          ; Compute number of bytes to pad with
        mov     buffer_adjust, ebx

        ret

page
;/***************************************************************************
;*
;* PRIVATE ROUTINE ite_24
;*
;* DESCRIPTION   = Bitmap conversion, internal format to external 24 bit RGB
;*
;*                 This routine is responsible for all preprocessing for converting
;*                 from our internal formats to external 24 bit RGB format
;*
;*                 Registers Preserved:
;*                       BP,DS,ES
;*                 Registers Destroyed:
;*                       AX,BX,CX,DX,SI,DI,FLAGS
;*
;* INPUT         = ES:DI --> where color table would go
;* OUTPUT        = NONE
;*
;* RETURN-NORMAL = NONE
;* RETURN-ERROR  = NONE
;*
;**************************************************************************/

ite_24::
ifdef   FIREWALLS
        DebugMsg <copy_i1e24>
endif
        lea     eax,copy_i1e24
        lea     ebx,copy_i1e24_partial
        test    fbsd,SD_COLOR           ;Monochrome source?
        jz      ite_24_have_proc        ;  Yes

ite_24_not_mono:
ifdef   FIREWALLS
        DebugMsg <copy_i8e24>
endif

        lea     eax,copy_i8e24
        lea     ebx,copy_i8e24_partial

ite_24_have_proc:
        mov     full_byte_proc,eax
        mov     partial_byte_proc,ebx
        mov     ecx,3
        mov     eax,bitmap_width        ;Compute the number of source bytes
        mov     ebx,eax                 ;  to convert.  Each bit becomes
        shr     eax,cl                  ;  three bytes in the destination
        mov     scan_byte_count,eax
        mov     eax,ebx                 ;1 source bit = 3 dest bytes
        mul     ecx
        add     eax,ecx                 ;Need to round up to a double word
        and     al,11111100b
        and     ebx,00000111b           ;Can have up to 7 bits in the last
        mov     partial_byte_flags,ebx  ;  byte to convert
        and     bl,00000011b            ;Compute number of bytes to pad with
        mov     buffer_adjust,ebx
        ret

page

;/***************************************************************************
;*
;* PRIVATE ROUTINE create_mono_color_table:
;*
;* DESCRIPTION   = Sets up some registers and jumps to cct_start in
;*                 create_color_color_table
;*
;* INPUT         = NONE
;* OUTPUT        = NONE
;*
;* RETURN-NORMAL = NONE
;* RETURN-ERROR  = NONE
;*
;**************************************************************************/

create_mono_color_table:

        mov     al,0            ;mono
        mov     ah,1
        jmp     cct_start

;/***************************************************************************
;*
;* PRIVATE ROUTINE create_color_color_table
;*
;* DESCRIPTION   = The color table for color source bitmaps is created.  The table
;*                 will consists of the 16 fixed colors for the driver.  The remaining
;*                 entries will be set to black, even though we will never generate
;*                 those indicies.
;*
;* INPUT         = NONE
;* OUTPUT        = NONE
;*
;* RETURN-NORMAL = NONE
;* RETURN-ERROR  = NONE
;*
;**************************************************************************/

public create_color_color_table
create_color_color_table::

        mov     al,SD_COLOR     ;color
        mov     ah,255
cct_start:
        push    ebx
        mov     ebx,pddc
        ddc?    ebx
        sub     esp,sizeof ITE_STRUCT
        mov     esi,esp
        ASSUME  esi:PTR ITE_STRUCT
        mov     [esi].ite_Flags,al       ;SD_COLOR = color,0=mono
        movzx   eax,ah
        inc     eax
        mov     [esi].ite_IntColorCount,eax     ;2 or 256
        mov     [esi].ite_ExtColorCount,ecx
        lea     eax,xlate_8_to_4
        mov     [esi].ite_pbConvertTable,eax
        mov     eax,rgb_size
        mov     [esi].ite_RgbIncrement,eax

ifdef PALMGR2

;/*
;**
;**        /**************************************************************/
;**        /* Check to see if we have been passed the special BCE_PALETTE*/
;**        /* format.                                                    */
;**        /* This only applies if there is a palette in the current DC  */
;**        /* (Higher level code will have raised an error if they asked */
;**        /* for the special format without having a palette)           */
;**        /**************************************************************/
;**        if ((pdc->DCIColFormat == LCOLF_PALETTE) &&
;**            (pSourceHeader->cbFix >= SIZE_ALL_BM2_FIELDS(pSourceHeader)) &&
;**            (SPad.pExternalHeader->ulColorEncoding == BCE_PALETTE))
;**        {
;**            SPad.fbFlags = CONV_BCE_PALETTE;
;**        }
;**        else
;**        {
;**            SPad.fbFlags = 0;
;**        }
;*/


        ASSUME  EBX:NOTHING
        cmp     ebx,0                   
        jz      @f                      
        test    [ebx].DDC.ddc_fbClrTbl,DDC_PALETTE
        jz      @F
        mov     eax,pbmi                ;Validate bitmap info structure
        cmp     [eax].BITMAPINFO2.bmi2_cbFix,SIZEOF BITMAPINFOHEADER
        je      @F      ;must be new header, not old
        cmp     [eax].BITMAPINFO2.bmi2_ulColorEncoding,BCE_PALETTE
;JMW        jz      @F
        jnz     @F                            ;JMW
        or      [esi].ite_Flags,ITE_BCE       ;SD_COLOR = color,0=mono
@@:
        mov     al,[esi].ite_Flags
        mov     fbPal,al

endif

;/*
;**    if ( SPad.cInternalBitCount != SPad.cExternalBitCount )
;*/

        cmp     ecx,[esi].ite_IntColorCount
        je      cct_same

;/*
;**    {
;**        /**************************************************************/
;**        /* set up the external color table and the conversion table   */
;**        /*                                                            */
;**        /* NB. TableIntToPM  actually returns a BOOL which tells us   */
;**        /* if an identity mapping is possible (ie that it did not     */
;**        /* bother to set up a mapping vector)                         */
;**        /**************************************************************/
;**        TableIntToPM();
;*/

        INVOKE  TableIntToPM

;/*
;**
;**        /**************************************************************/
;**        /* call the conversion and inversion                          */
;**        /**************************************************************/
;**        ConvertPMInt(GetConvertFn(),
;**                     &SPad.pbSrcPointer,
;**                     &SPad.pbTrgPointer);
;*/

        jmp     cct_done

;/*
;**    }
;**    else /* no conversion */
;*/

cct_same:

;/*
;**    {
;**        /**************************************************************/
;**        /* set up the external color table                            */
;**        /**************************************************************/
;**        SetExternalColorTable();
;*/

        INVOKE  SetExternalColorTable

;/*
;**        /**************************************************************/
;**        /* no colour conversion is required and so call subroutine to */
;**        /* perform the flipping of the order of the rows              */
;**        /**************************************************************/
;**        FlipTheBitmap(INT_TO_EXT_COPY);
;**    }
;*/

cct_done:
        add     esp,sizeof ITE_STRUCT
        pop     ebx
        ret


xlate_1_to_4    label   word

        dw      0000000000000000b       ;0000b
        dw      0000000000001111b       ;0001b
        dw      0000000011110000b       ;0010b
        dw      0000000011111111b       ;0011b
        dw      0000111100000000b       ;0100b
        dw      0000111100001111b       ;0101b
        dw      0000111111110000b       ;0110b
        dw      0000111111111111b       ;0111b
        dw      1111000000000000b       ;1000b
        dw      1111000000001111b       ;1001b
        dw      1111000011110000b       ;1010b
        dw      1111000011111111b       ;1011b
        dw      1111111100000000b       ;1100b
        dw      1111111100001111b       ;1101b
        dw      1111111111110000b       ;1110b
        dw      1111111111111111b       ;1111b

page
;/***************************************************************************
;*
;* PRIVATE ROUTINE copy_i1e1
;*
;* DESCRIPTION   = The given number of bytes are copied from source to destination.
;*                                                                                   g
;*                 It is the caller's responsibility to handle all segment crossings.
;*
;*                 This routine is used for:
;*                     internal mono to external mono
;*                     external mono to internal mono
;*
;*                 Registers Preserved:
;*                       DX,BP,ES,DS,BP
;*                 Registers Destroyed:
;*                       AX,SI,FLAGS
;*
;* INPUT         = DS:SI --> source
;*                 ES:DI --> destination
;*                 CX     =  number of bytes to copy
;*                 Direction flag cleared
;* OUTPUT        = ES:DI --> next destination byte
;*                 Direction flag cleared
;*
;* RETURN-NORMAL = NONE
;* RETURN-ERROR  = NONE
;**************************************************************************/

PUBLIC copy_i1e1
copy_i1e1::
        xchg    eax,ecx                 ;Save count of bytes to mov in AX
        xor     ecx,ecx
        ror     esi,1                   ;Set 'C' if source on odd boundary
        rcl     ecx,1                   ;CX = 1 if on odd boundary
        sub     eax,ecx
        rol     esi,1                   ;Restore initial source address
        rep     movsb                   ;Move possible odd aligned byte
        xchg    eax,ecx                 ;Move complete words
        shr     ecx,1
        rep     movsw
        rcl     ecx,1                   ;Process trailing odd byte
        rep     movsb
        ret

page
;/***************************************************************************
;*
;* PRIVATE ROUTINE copy_i1e4
;*
;* DESCRIPTION   = copy internal 1 bit to external 4 bit packed pixel
;*
;*                 The destination is filled with the source data, with each source
;*                 bit expanded to a nibble in the destination.
;*
;*                 It is the caller's responsibility to handle all segment crossings,
;*                 and to ensure that there are enough bytes of destination available
;*                 to hold the data.
;*
;*                 This routine is used for:
;*                     internal mono to external four-bit packed pixels
;*
;*                 Registers Preserved:
;*                       BP,ES,DS,BP
;*                 Registers Destroyed:
;*                       AX,BX,DX,SI,FLAGS
;*
;* INPUT         = DS:SI --> source
;*                 ES:DI --> destination
;*                 CX     =  number of bytes to xlate
;* OUTPUT        = ES:DI --> next destination byte
;*
;* RETURN-NORMAL = NONE
;* RETURN-ERROR  = NONE
;**************************************************************************/

PUBLIC copy_i1e4
copy_i1e4::

        mov     edx,00011110b           ;Mask for bits to convert

ci1e4_next_byte:

        lodsb
        mov     bl,al ;save it
        shr     al,3
        and     eax,edx
        mov     ax,WORD PTR xlate_1_to_4[eax]
        xchg    ah,al
        stosw
        shl     bl,1
        and     ebx,edx
        mov     ax,WORD PTR xlate_1_to_4[ebx]
        xchg    ah,al
        stosw
        loop    ci1e4_next_byte
        ret

page

;/***************************************************************************
;*
;* PRIVATE ROUTINE copy_i1e4_partial
;*
;* DESCRIPTION   =
;*
;*            copy internal 1 bit to external 4 bit packed pixel, partial byte
;*
;*            The destination is filled with the source data, with each source
;*            bit expanded to a nibble in the destination.  This routine handles
;*            partial bytes where some portion of the first or last byte needs
;*            to be saved.
;*
;*            This routine will handle the destination (user's buffer) crossing
;*            a segment boundary during the translation of the source byte.
;*            The source will never cross a segment boundary since it is an
;*            internal bitmap and all scans are allocated to fit within a
;*            segment.
;*
;*            Since this routine always writes nibbles, it is guaranteed that
;*            the shift count passed in is even.
;*
;*            This routine shouldn't be called very often, so a short loop will
;*            be sufficient for our needs.
;*
;*            This routine is used for:
;*                internal mono to external four-bit packed pixels
;*
;*                 Registers Preserved:
;*                       BP,ES,DS,BP
;*                 Registers Destroyed:
;*                       AX,BX,DX,SI,FLAGS
;*
;* INPUT         = DS:SI --> source
;*                 ES:DI --> destination
;*                 CX     =  number of bytes to xlate
;* OUTPUT        = ES:DI --> next destination byte
;*
;* RETURN-NORMAL = NONE
;* RETURN-ERROR  = NONE
;**************************************************************************/

PUBLIC copy_i1e4_partial
copy_i1e4_partial::

        lea     ebx,xlate_1_to_4 + 1
        lodsb
        mov     ah,al
        shr     ecx,1                   ;/2 for number of iterations
        movzx   ecx,cl

ci1e4p_next_byte:

        rol     ax,2
        and     al,00000011b
        shl     ax,1                    ;Fetching bytes from a word table
        xlat

        store_with_seg_check

        loop    ci1e4p_next_byte
        ret

page

;/***************************************************************************
;*
;* PRIVATE ROUTINE copy_i1e8
;*
;* DESCRIPTION   = copy internal 1 bit to external 8 bit packed pixel
;*
;*                 The destination is filled with the source data, with each source
;*                 bit expanded to a byte in the destination.
;*
;*                 It is the caller's responsibility to handle all segment crossings,
;*                 and to ensure that there are eight bytes of destination available
;*                 to hold each byte of source data.
;*
;*                 This routine is used for:
;*                     internal mono to external eight-bit packed pixels
;*
;*                 Registers Preserved:
;*                       BP,ES,DS,BP
;*                 Registers Destroyed:
;*                       AX,BX,DX,SI,FLAGS
;*
;* INPUT         = DS:SI --> source
;*                 ES:DI --> destination
;*                 CX     =  number of bytes to xlate
;* OUTPUT        = ES:DI --> next destination byte
;*
;* RETURN-NORMAL = NONE
;* RETURN-ERROR  = NONE
;**************************************************************************/

PUBLIC copy_i1e8
copy_i1e8::

ci1e8_next_byte:

;           **** Begin Fix ***************************************************
;           Old routine was converting 1's to ff's
;       lodsb
;       xchg    eax,ebx
;       shl     bl,1
;       sbb     al,al
;       shl     bl,1
;       sbb     ah,ah
;       stosw
;       shl     bl,1
;       sbb     al,al
;       shl     bl,1
;       sbb     ah,ah
;       stosw
;       shl     bl,1
;       sbb     al,al
;       shl     bl,1
;       sbb     ah,ah
;       stosw
;       shl     bl,1
;       sbb     al,al
;       shl     bl,1
;       sbb     ah,ah
;       stosw
;       loop    ci1e8_next_byte
;       ret
;           End of old routine
;           ******************************************************************
;           New routine begins
        lodsb
        xchg    eax,ebx
        shl     bl,1
        setc    al
        shl     bl,1
        setc    ah
        stosw
        shl     bl,1
        setc    al
        shl     bl,1
        setc    ah
        stosw
        shl     bl,1
        setc    al
        shl     bl,1
        setc    ah
        stosw
        shl     bl,1
        setc    al
        shl     bl,1
        setc    ah
        stosw
        loop    ci1e8_next_byte
        ret
;           New routine ends
;           **** End Fix *****************************************************

page

;/***************************************************************************
;*
;* PRIVATE ROUTINE copy_i1e8_partial
;*
;* DESCRIPTION   =
;*
;*            copy internal 1 bit to external 8 bit packed pixel, partial byte
;*
;*            The destination is filled with the source data, with each source
;*            bit expanded to a byte in the destination.   This routine handles
;*            partial bytes where some portion of the first or last byte needs
;*            to be saved.
;*
;*            This routine will handle the destination (user's buffer) crossing
;*            a segment boundary during the translation of the source byte.
;*            The source will never cross a segment boundary since it is an
;*            internal bitmap and all scans are allocated to fit within a
;*            segment.
;*
;*            This routine shouldn't be called very often, so a short loop will
;*            be sufficient for our needs.
;*
;*            This routine is used for:
;*                internal mono to external eight-bit packed pixels
;*
;*                 Registers Preserved:
;*                       BP,ES,DS,BP
;*                 Registers Destroyed:
;*                       AX,BX,DX,SI,FLAGS
;*
;* INPUT         = DS:SI --> source
;*                 ES:DI --> destination
;*                 CX     =  number of bytes to xlate
;* OUTPUT        = ES:DI --> next destination byte
;*
;* RETURN-NORMAL = NONE
;* RETURN-ERROR  = NONE
;**************************************************************************/


PUBLIC copy_i1e8_partial
copy_i1e8_partial::

        lodsb
        xchg    eax,ebx
        movzx   ecx,cl

ci1e8p_next_byte:

        shl     bl,1
;               sbb     al,al
        setc    al   ;            Set to 0 or 1 instead of 0 or ff

        store_with_seg_check

        loop    ci1e8p_next_byte
        ret

page

;/***************************************************************************
;*
;* PRIVATE ROUTINE copy_i1e24
;*
;* DESCRIPTION   = copy internal 1 bit to external 24 bit RGB
;*
;*                 The destination is filled with the source data, with each source
;*                 bit expanded to a full RGB triplet in the destination.  The colors
;*                 being translated are black and white, so no color lookup is required
;*
;*                 It is the caller's responsibility to handle all segment crossings,
;*                 and to ensure that there are 24 bytes of destination available to
;*                 hold each source byte of data.
;*
;*                 This routine is used for:
;*                     internal mono to external RGB (24-bit packed pixels)
;*
;*                 Registers Preserved:
;*                       BP,ES,DS,BP
;*                 Registers Destroyed:
;*                       AX,BX,DX,SI,FLAGS
;*
;* INPUT         = DS:SI --> source
;*                 ES:DI --> destination
;*                 CX     =  number of bytes to xlate
;* OUTPUT        = ES:DI --> next destination byte
;*
;* RETURN-NORMAL = NONE
;* RETURN-ERROR  = NONE
;**************************************************************************/


PUBLIC copy_i1e24
copy_i1e24::
ci1e24_next_byte:
        lodsb
        mov     bl,al
        shl     bl,1
        sbb     ax,ax
        stosw
        stosb
        shl     bl,1
        sbb     ax,ax
        stosw
        stosb
        shl     bl,1
        sbb     ax,ax
        stosw
        stosb
        shl     bl,1
        sbb     ax,ax
        stosw
        stosb
        shl     bl,1
        sbb     ax,ax
        stosw
        stosb
        shl     bl,1
        sbb     ax,ax
        stosw
        stosb
        shl     bl,1
        sbb     ax,ax
        stosw
        stosb
        shl     bl,1
        sbb     ax,ax
        stosw
        stosb
        loop    ci1e24_next_byte
        ret

page
;/***************************************************************************
;*
;* PRIVATE ROUTINE copy_i1e24_partial
;*
;* DESCRIPTION   =
;*
;*            copy internal 1 bit to external 24 bit RGB, partial byte
;*
;*            The destination is filled with the source data, with each source
;*            bit expanded to a full RGB triplet in the destination.  The colors
;*            being translated are black and white, so no color lookup is required.
;*
;*            This routine handles partial bytes where some portion of the first
;*            or last byte needs to be saved.
;*
;*            This routine will handle the destination (user's buffer) crossing
;*            a segment boundary during the translation of the source byte.
;*            The source will never cross a segment boundary since it is an
;*            internal bitmap and all scans are allocated to fit within a
;*            segment.
;*
;*            This routine shouldn't be called very often, so a short loop will
;*            be sufficient for our needs.
;*
;*            This routine is used for:
;*                internal mono to external RGB (24-bit packed pixels)
;*
;*                 Registers Preserved:
;*                       BP,ES,DS,BP
;*                 Registers Destroyed:
;*                       AX,BX,DX,SI,FLAGS
;*
;* INPUT         = DS:SI --> source
;*                 ES:DI --> destination
;*                 CX     =  number of bytes to xlate
;* OUTPUT        = ES:DI --> next destination byte
;*
;* RETURN-NORMAL = NONE
;* RETURN-ERROR  = NONE
;**************************************************************************/


PUBLIC copy_i1e24_partial
copy_i1e24_partial::

        lodsb
        xchg    ax,dx
        movzx   ecx,cl

ci1e24p_next_byte:

        shl     dl,1
        sbb     ax,ax
        stosw
        stosb

ci1e24p_loop_next:

        loop    ci1e24p_next_byte

ci1e24p_no_more_sels:

        ret

page

;/***************************************************************************
;*
;* PRIVATE ROUTINE copy_i1e1_partial
;*
;* DESCRIPTION   = A Byte is copied from the source to destination.
;*
;*                 This routine will handle the destination (user's buffer) crossing
;*                 a segment boundary during the translation of the source byte.
;*                 The source will never cross a segment boundary since it is an
;*                 internal bitmap and all scans are allocated to fit within a
;*                 segment.
;*
;*                 Registers Preserved:
;*                       DX,BP,ES,DS,BP
;*                 Registers Destroyed:
;*                       AX,SI,FLAGS
;*
;* INPUT         = DS:SI --> source
;*                 ES:DI --> destination
;*                 CL     =  number of pixels to translate (Will always be 8)
;*                 Direction flag cleared
;* OUTPUT        = ES:DI --> next destination byte
;*                 Direction flag cleared
;*
;* RETURN-NORMAL = NONE
;* RETURN-ERROR  = NONE
;**************************************************************************/


PUBLIC copy_i1e1_partial
copy_i1e1_partial::

;CMVC_54114        lodsb
        movsb      ;CMVC_54114
        ret

page
;/***************************************************************************
;*
;* PRIVATE ROUTINE copy_i4e1
;*
;* DESCRIPTION   =
;*
;*         copy internal 8 plane to external 1 bit
;*
;*         The destination is filled with the source data.  All four planes
;*         of the source byte are combined to form the single destination byte.
;*
;*         It is the caller's responsibility to handle all segment crossings,
;*         and to ensure that there are enough bytes of destination available
;*         to hold the data.
;*
;*         Since there will be information loss in going from four color to
;*         one color, all colors which match the  background color
;*         will be mapped to 1, and all other colors will be mapped to the
;*         forground color.  This is the same strategy used in color
;*         to mono bitblts.
;*
;*         This routine is used for:
;*             internal four-plane to external mono
;*
;*                 Registers Preserved:
;*                       DX,BP,ES,DS,BP
;*                 Registers Destroyed:
;*                       AX,SI,FLAGS
;*
;* INPUT         = DS:SI --> source
;*                 ES:DI --> destination
;*                 CL     =  number of pixels to translate (Will always be 8)
;*                 Direction flag cleared
;* OUTPUT        = ES:DI --> next destination byte
;*                 Direction flag cleared
;*
;* RETURN-NORMAL = NONE
;* RETURN-ERROR  = NONE
;**************************************************************************/


PUBLIC copy_i8e1
copy_i8e1::
        mov     dl,8
        lea     ebx,xlate_8_to_4
ci8e1_next_pixel:
        lodsb
        xlat    byte ptr [ebx]
        shr     al,1
        rcl     dh,1
        dec     dl
        jnz     ci8e1_next_pixel
        mov     al,dh
        stosb
        loop    copy_i8e1
        ret

page

;/***************************************************************************
;*
;* PRIVATE ROUTINE copy_i8e1_partial
;*
;* DESCRIPTION   =
;*
;*         copy internal 8 plane to external 1 bit, partial byte
;*
;*         The destination is filled with the source data.  All four planes
;*         of the source byte are combined to form the single destination byte.
;*
;*         This routine will handle the destination (user's buffer) crossing
;*         a segment boundary during the translation of the source byte.
;*         The source will never cross a segment boundary since it is an
;*         internal bitmap and all scans are allocated to fit within a
;*         segment.
;*
;*         Since there will be information loss in going from four color to
;*         one color, all colors which match the background color
;*         will be mapped to 1, and all other colors will be mapped to the
;*         forground color.  This is the same strategy used in color
;*         to mono bitblts.
;*
;*         This routine is used for:
;*             internal four-plane to external mono
;*
;*                 Registers Preserved:
;*                       BP,ES,DS,BP
;*                 Registers Destroyed:
;*                       AX,BX,DX,SI,FLAGS
;*
;* INPUT         = DS:SI --> source
;*                 ES:DI --> destination
;*                 CX     =  number of pixels to translate (Will always be 8)
;* OUTPUT        = ES:DI --> next destination byte
;*
;* RETURN-NORMAL = NONE
;* RETURN-ERROR  = NONE
;**************************************************************************/

PUBLIC copy_i8e1_partial
copy_i8e1_partial::
        mov     ecx,1
        call    full_byte_proc
        dec     edi
        store_with_seg_check

        ret

page

;/***************************************************************************
;*
;* PRIVATE ROUTINE copy_i8e4
;*
;* DESCRIPTION   =
;*
;*         copy internal 8 plane to external 4 bit packed pixel
;*
;*         The destination is filled with the source data.  All four planes
;*         of the source byte are used to form the nibble for the destination
;*         byte.
;*
;*         It is the caller's responsibility to handle all segment crossings,
;*         and to ensure that there are enough bytes of destination available
;*         to hold the data.
;*
;*         Since there will be information loss in going from four color to
;*         one color, all colors which match the background color
;*         will be mapped to 1, and all other colors will be mapped to the
;*         forground color.  This is the same strategy used in color
;*         to mono bitblts.
;*
;*         This routine is used for:
;*             internal four-plane to external 4-bit packed pixels
;*
;*                 Registers Preserved:
;*                       BP,ES,DS,BP
;*                 Registers Destroyed:
;*                       AX,BX,DX,SI,FLAGS
;*
;* INPUT         = DS:SI --> source
;*                 ES:DI --> destination
;*                 CX     =  number of bytes to xlate
;* OUTPUT        = ES:DI --> next destination byte
;*
;* RETURN-NORMAL = NONE
;* RETURN-ERROR  = NONE
;**************************************************************************/


PUBLIC copy_i8e4
copy_i8e4::
ci8e4_next_byte:


        mov     dl, 4                   ;8 pixel/byte - inner loop count
        lea     ebx,xlate_8_to_4
ci8e4_next_pixel:
        lodsb                           ;load 1 byte pixel
        xlat    byte ptr [ebx]
        shl     al,4
        mov     ah,al
        lodsb
        xlat    byte ptr [ebx]
        or      al,ah
        stosb
        dec     dl
        jne     ci8e4_next_pixel
        dec     ecx
        jnz     ci8e4_next_byte
        ret

page

;/***************************************************************************
;*
;* PRIVATE ROUTINE copy_i8e4_partial
;*
;* DESCRIPTION   =
;*
;*          copy internal 8 plane to external 4 bit packed pixel, partial byte
;*
;*          The destination is filled with the source data.  All four planes
;*          of the source byte are used to form the nibble for the destination
;*          byte.
;*
;*          This routine handles partial bytes where some portion of the first
;*          or last byte needs to be saved.
;*
;*          This routine will handle the destination (user's buffer) crossing
;*          a segment boundary during the translation of the source byte.
;*          The source will never cross a segment boundary since it is an
;*          internal bitmap and all scans are allocated to fit within a
;*          segment.
;*
;*          Since this routine always writes nibbles, it is guaranteed that
;*          the shift count passed in is even.
;*
;*          This routine is used for:
;*              internal eight-plane to external 4-bit packed pixels
;*
;*                 Registers Preserved:
;*                       BP,ES,DS,BP
;*                 Registers Destroyed:
;*                       AX,BX,DX,SI,FLAGS
;*
;* INPUT         = DS:SI --> source
;*                 ES:DI --> destination
;*                 BX     =  index to next plane
;*                 CL     =  number of pixels to xlate
;* OUTPUT        = ES:DI --> next destination byte
;*
;* RETURN-NORMAL = NONE
;* RETURN-ERROR  = NONE
;**************************************************************************/


PUBLIC copy_i8e4_partial
copy_i8e4_partial::
        lea     ebx,xlate_8_to_4
        shr     cl,1
copy_i8e4p_next_byte:
        lodsb
        xlat    byte ptr [ebx]
        shl     al,4
        mov     ah,al
        lodsb
        xlat    byte ptr [ebx]
        or      al,ah
cigetout:
        store_with_seg_check
        dec     cl
        jne     copy_i8e4p_next_byte
        ret

page
;/***************************************************************************
;*
;* PRIVATE ROUTINE copy_i8e8
;*
;* DESCRIPTION   =
;*
;*          copy internal 8 plane to external 8 bit packed pixel
;*
;*          The destination is filled with the source data.  All four planes
;*          of the source byte are used to form the byte for the destination.
;*
;*          It is the caller's responsibility to handle all segment crossings,
;*          and to ensure that there are enough bytes of destination available
;*          to hold the data.
;*
;*          Since there will be information loss in going from four color to
;*          one color, all colors which match the background color
;*          will be mapped to 1, and all other colors will be mapped to the
;*          forground color.  This is the same strategy used in color
;*          to mono bitblts.
;*
;*          This routine is used for:
;*              internal eight-plane to external 8-bit packed pixels
;*
;*                 Registers Preserved:
;*                       BP,ES,DS,BP
;*                 Registers Destroyed:
;*                       AX,BX,DX,SI,FLAGS
;*
;* INPUT         = DS:SI --> source
;*                 ES:DI --> destination
;*                 CX     =  number of pixels to xlate
;* OUTPUT        = ES:DI --> next destination byte
;*
;* RETURN-NORMAL = NONE
;* RETURN-ERROR  = NONE
;**************************************************************************/


PUBLIC copy_i8e8
copy_i8e8::
        movsd
        movsd
        loop    copy_i8e8
        ret

page
;/***************************************************************************
;*
;* PRIVATE ROUTINE copy_i8e8_partial
;*
;* DESCRIPTION   =
;*
;*          copy internal 8 plane to external 8 bit packed pixel, partial byte
;*
;*          The destination is filled with the source data.  All four planes
;*          of the source byte are used to form the byte for the destination.
;*
;*          This routine handles partial bytes where some portion of the first
;*          or last byte needs to be saved.
;*
;*          This routine will handle the destination (user's buffer) crossing
;*          a segment boundary during the translation of the source byte.
;*          The source will never cross a segment boundary since it is an
;*          internal bitmap and all scans are allocated to fit within a
;*          segment.
;*
;*          This routine is used for:
;*              internal eight-plane to external 8-bit packed pixels
;*
;*                 Registers Preserved:
;*                       BP,ES,DS
;*                 Registers Destroyed:
;*                       AX,BX,DX,SI,FLAGS
;*
;* INPUT         = DS:SI --> source
;*                 ES:DI --> destination
;*                 CL     =  number of pixels to xlate
;* OUTPUT        = ES:DI --> next destination byte
;*
;* RETURN-NORMAL = NONE
;* RETURN-ERROR  = NONE
;**************************************************************************/


PUBLIC copy_i8e8_partial
copy_i8e8_partial::
        mov     eax,ecx
        shr     ecx,2
        rep     movsd
        mov     ecx,eax
        and     ecx,2
        rep     movsb
        ret

page

;/***************************************************************************
;*
;* PRIVATE ROUTINE copy_i8e24
;*
;* DESCRIPTION   =
;*
;*          copy internal 8 plane to external 24 bit RGB
;*
;*          The destination is filled with the source data.  All four planes
;*          of the source byte are used to form the RGB triplet for the
;*          destination.
;*
;*          It is the caller's responsibility to handle all segment crossings,
;*          and to ensure that there are enough bytes of destination available
;*          to hold the data.
;*
;*          Since there will be information loss in going from four color to
;*          one color, all colors which match the background color
;*          will be mapped to 1, and all other colors will be mapped to the
;*          forground color.  This is the same strategy used in color
;*          to mono bitblts.
;*
;*          This routine is used for:
;*              internal eight-plane to external RGB (24-bit packed)
;*
;*                 Registers Preserved:
;*                       BP,ES,DS
;*                 Registers Destroyed:
;*                       AX,BX,DX,SI,FLAGS
;*
;* INPUT         = DS:SI --> source
;*                 ES:DI --> destination
;*                 CX     =  number of pixels to xlate
;* OUTPUT        = ES:DI --> next destination byte
;*                 DS:SI --> next source byte
;* RETURN-NORMAL = NONE
;* RETURN-ERROR  = NONE
;**************************************************************************/


PUBLIC copy_i8e24
copy_i8e24::

        mov     dh,8
ci8e24_next_pixel:
        mov     eax,0

        lodsb
        push    dx              ;          
        call    ite_get_i8e24
        pop     dx              ;          
        stosw
        shr     eax,16
        stosb
        dec     dh
        jne     ci8e24_next_pixel
        loop    copy_i8e24
        ret
page

;/***************************************************************************
;*
;* PRIVATE ROUTINE copy_i8e24_partial
;*
;* DESCRIPTION   =
;*
;*          copy internal 8 plane to external 24 bit RGB, partial byte
;*
;*          The destination is filled with the source data.  All four planes
;*          of the source byte are used to form the RGB triplet for the
;*          destination.
;*
;*          This routine handles partial bytes where some portion of the first
;*          or last byte needs to be saved.
;*
;*          This routine will handle the destination (user's buffer) crossing
;*          a segment boundary during the translation of the source byte.
;*          The source will never cross a segment boundary since it is an
;*          internal bitmap and all scans are allocated to fit within a
;*          segment.
;*
;*          This routine is used for:
;*              internal eight-plane to external RGB (24-bit packed)
;*
;*                 Registers Preserved:
;*                       BP,ES,DS
;*                 Registers Destroyed:
;*                       AX,BX,DX,SI,FLAGS
;*
;* INPUT         = DS:SI --> source
;*                 ES:DI --> destination
;*                 CL     =  number of pixels to xlate
;* OUTPUT        = ES:DI --> next destination byte
;*                 DS:SI --> next source byte
;* RETURN-NORMAL = NONE
;* RETURN-ERROR  = NONE
;**************************************************************************/


PUBLIC copy_i8e24_partial
copy_i8e24_partial::

copy_i8e24p_next_byte:
        mov     eax,0
        lodsb
        call    ite_get_i8e24

        stosw
        shr     eax,16
        stosb
        dec     cl
        jne     copy_i8e24p_next_byte
        ret

ite_get_i8e24:

;/*
;**        case 24:
;**            if ( SPad.fbFlags & CONV_BCE_PALETTE )
;*/

        test    fbPal,ITE_BCE
        jz      ci8e24_not_bce

;/*
;**            {
;**                return( ConvertInt8ToExt24palindex );
;** the correct value is already in eax
;*/

        jmp     ci8e24_done

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

ci8e24_not_bce:

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

        ASSUME  EBX:NOTHING
        mov     ebx,pddc
        cmp     ebx,0                   ;CMVC_53469
        jz      ci8e24_not_pal          ;CMVC_53469
        test    [ebx].DDC.ddc_fbClrTbl,DDC_PALETTE
        jz      ci8e24_not_pal

;/*
;**                {
;**                    return( ConvertInt8ToExt24pal );
;*/

        mov     ebx,[ebx].DDC.ddc_npdevpal
        mov     eax,[ebx].DEVPAL.entries[eax*sizeof PALENTRY].rgb
        jmp     ci8e24_done

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

ci8e24_not_pal:

;/*
;**                {
;**                    return( ConvertInt8ToExt24 );
;*/

        test    [ebx].DDC.ddc_fbClrTbl,DDC_REALIZABLE
        jz      ci8e24_not_real
        INVOKE  PhyToLogIndex,
                ebx,
                eax

        cmp     eax,CLR_NOINDEX
        je      ci8e24_no_index
        mov     ebx,[ebx].DDC.ddc_pClrTbl
        mov     eax,[ebx+eax*sizeof COLORTABLETYPE].COLORTABLETYPE.LogRGB
        jmp     ci8e24_done
ci8e24_no_index:
ci8e24_not_real:
        mov     edx,eax
        MemoryDeviceDefaultRGB2 edx,eax

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

ci8e24_done:
        ret

bmc_int_to_ext  ENDP

end

