;***************************************************************************
; unit:    raster_MSVC.asm      release 0.18                               *
; purpose: general manipulation n dimensional matrices n = 1, 2 and 3.     *
;          Use this file or rasterc.c. You cannot link both files together *
; licency:     GPL or LGPL                                                 *
; Copyright: (c) 1998-2019 Jaroslav Fojtik                                 *
;***************************************************************************

.486              ;Target processor.  Use instructions for Pentium class machines
.MODEL FLAT, C    ;Use the flat memory model. Use C calling conventions

.CODE             ;Indicates the start of a code segment.


;void Conv1_8(BYTE *Dest, const BYTE *Src, unsigned Size1D)
        public  Conv1_8
Conv1_8 proc \
        uses edi esi, \
        Dest:ptr byte, \
        Src:ptr byte, \
        count:DWORD

        mov     ecx,[count]     ; cx=amount of pixels
        or	ecx,ecx
        jz	toend     ; it's as if strings are equal

        mov     edi,[Dest]     ; di=destination pointer (es=segment part)
        mov     esi,[Src]      ; 

octet:  mov     al,[esi]	; new octet        
        inc	esi

	cbw			; Extend 8th bit to AH
	mov	[edi],ah	; store converted byte
	inc	edi

	dec	ecx
        jz      toend
        
        rol     al,1		; 40h
        cbw			; Extend 7th bit to AH
	mov	[edi],ah	; store converted byte
	inc	edi        

	dec	ecx
        jz      toend
        
        rol     al,1		; 20h
        cbw			; Extend 6th bit to AH
	mov	[edi],ah	; store converted byte
	inc	edi

	dec	ecx
        jz      toend
        
        rol     al,1		; 10h
        cbw			; Extend 5th bit to AH
	mov	[edi],ah	; store converted byte
	inc	edi   

	dec	ecx
        jz      toend

        rol     al,1		; 08h
        cbw			; Extend 4th bit to AH
	mov	[edi],ah	; store converted byte
	inc	edi        

	dec	ecx
        jz      toend
        
        rol     al,1		; 04h
	cbw			; Extend 3rd bit to AH
	mov	[edi],ah	; store converted byte
	inc	edi        

	dec	ecx
        jz      toend
        
        rol     al,1		; 02h
        cbw			; Extend 2nd bit to AH
	mov	[edi],ah	; store converted byte
	inc	edi        

	dec	ecx
        jz      toend
        
        rol     al,1		; 01h
        cbw			; Extend 1st bit to AH
	mov	[edi],ah	; store converted byte
	inc	edi

	dec	ecx
	jne	octet

toend:
        ret                     ; _cdecl return

Conv1_8 endp


;*************************************************************************************

        public  Conv1_16
Conv1_16 proc \
        uses edi esi, \
        Dest:ptr word, \
        Src:ptr byte, \
        count:DWORD

        mov     ecx,[count]     ; cx=amount of pixels
        or	ecx,ecx
        jz	toend		; array has zero size

        mov     edi,[Dest]     ; di=first pointer (es=segment part)
        mov     esi,[Src]      ; 

	cld
Octet:  mov     ah,[esi]	; new octet        
        inc	esi
        
        cwd			; extend 8th bit to DX
        mov	[edi],dx
        add	edi,2

	dec	ecx
        jz      toend
        
        rol	ax,1        
        cwd			; extend 7th bit to DX
        mov	[edi],dx
        add	edi,2

	dec	ecx
        jz      toend
        
        rol	ax,1        
        cwd			; extend 6th bit to DX
        mov	[edi],dx
        add	edi,2

	dec	ecx
        jz      toend        
        
        rol	ax,1        
        cwd			; extend 5th bit to DX
        mov	[edi],dx
        add	edi,2

	dec	ecx
        jz      toend                


        rol	ax,1        
        cwd			; extend 4th bit to DX
        mov	[edi],dx
        add	edi,2

	dec	ecx
        jz      toend
        
        
        rol	ax,1        
        cwd			; extend 3rd bit to DX
        mov	[edi],dx
        add	edi,2

	dec	ecx
        jz      toend
        
        rol	ax,1        
        cwd			; extend 2nd bit to DX
        mov	[edi],dx
        add	edi,2

	dec	ecx
        jz      toend        
        
        rol	ax,1        
        cwd			; extend 1st bit to DX
        mov	[edi],dx
        add	edi,2

	dec	ecx
	jnz	Octet

toend:
        ret                     ; _cdecl return

Conv1_16 endp



;void Conv1_24(BYTE *Dest, const BYTE *Src, unsigned Size1D)
        public  Conv1_24
Conv1_24 proc \
        uses edi esi, \
        Dest:ptr byte, \
        Src:ptr byte, \
        count:DWORD

        mov     ecx,[count]     ; cx=amount of pixels
        or	ecx,ecx
        jz	toend     ; it's as if strings are equal

        mov     edi,[Dest]     ; di=destination pointer (es=segment part)
        mov     esi,[Src]      ; 

octet:  mov     al,[esi]	; new octet        
        inc	esi

	cbw			; Extend 8th bit to AH
	mov	[edi],ah	; store converted byte
	inc	edi
	mov	[edi],ah
	inc	edi
	mov	[edi],ah
	inc	edi

	dec	ecx
        jz      toend
        
        rol     al,1		; 40h
        cbw			; Extend 7th bit to AH
	mov	[edi],ah	; store converted byte
	inc	edi
	mov	[edi],ah
	inc	edi
	mov	[edi],ah
	inc	edi        

	dec	ecx
        jz      toend
        
        rol     al,1		; 20h
        cbw			; Extend 6th bit to AH
	mov	[edi],ah	; store converted byte
	inc	edi
	mov	[edi],ah
	inc	edi
	mov	[edi],ah
	inc	edi

	dec	ecx
        jz      toend
        
        rol     al,1		; 10h
        cbw			; Extend 5th bit to AH
	mov	[edi],ah	; store converted byte
	inc	edi
	mov	[edi],ah
	inc	edi
	mov	[edi],ah
	inc	edi   

	dec	ecx
        jz      toend

        rol     al,1		; 08h
        cbw			; Extend 4th bit to AH
	mov	[edi],ah	; store converted byte
	inc	edi
	mov	[edi],ah
	inc	edi
	mov	[edi],ah
	inc	edi        

	dec	ecx
        jz      toend
        
        rol     al,1		; 04h
	cbw			; Extend 3rd bit to AH
	mov	[edi],ah	; store converted byte
	inc	edi
	mov	[edi],ah
	inc	edi
	mov	[edi],ah
	inc	edi        

	dec	ecx
        jz      toend
        
        rol     al,1		; 02h
        cbw			; Extend 2nd bit to AH
	mov	[edi],ah	; store converted byte
	inc	edi
	mov	[edi],ah
	inc	edi
	mov	[edi],ah
	inc	edi        

	dec	ecx
        jz      toend
        
        rol     al,1		; 01h
        cbw			; Extend 1st bit to AH
	mov	[edi],ah	; store converted byte
	inc	edi
	mov	[edi],ah
	inc	edi
	mov	[edi],ah
	inc	edi

	dec	ecx
	jne	octet

toend:
        ret                     ; _cdecl return

Conv1_24 endp


;*************************************************************************************

        public  Conv1_32
Conv1_32 proc \
        uses edi esi, \
        Dest:ptr dword, \
        Src:ptr byte, \
        count:DWORD
        
        mov     ecx,[count]     ; cx=amount of pixels
        or	ecx,ecx
        jz	toend		; array has zero size

        mov     edi,[Dest]     ; di=first pointer (es=segment part)
        mov     esi,[Src]      ; 

	cld
Octet:  mov     ah,[esi]	; new octet        
        inc	esi
        
        cwd			; extend 8th bit to DX
        shl	edx,16
        cwd
        mov	[edi],edx
        add	edi,4

	dec	ecx
        jz      toend
        
        rol	ax,1        
        cwd			; extend 7th bit to DX
        shl	edx,16
        cwd
        mov	[edi],edx
        add	edi,4

	dec	ecx
        jz      toend
        
        rol	ax,1        
        cwd			; extend 6th bit to DX
        shl	edx,16
        cwd
        mov	[edi],edx
        add	edi,4

	dec	ecx
        jz      toend        
        
        rol	ax,1        
        cwd			; extend 5th bit to DX
        shl	edx,16
        cwd
        mov	[edi],edx
        add	edi,4

	dec	ecx
        jz      toend                

        rol	ax,1        
        cwd			; extend 4th bit to DX
        shl	edx,16
        cwd
        mov	[edi],edx
        add	edi,4

	dec	ecx
        jz      toend
        
        
        rol	ax,1        
        cwd			; extend 3rd bit to DX
        shl	edx,16
        cwd
        mov	[edi],edx
        add	edi,4

	dec	ecx
        jz      toend
        
        rol	ax,1        
        cwd			; extend 2nd bit to DX
        shl	edx,16
        cwd
        mov	[edi],edx        
        add	edi,4

	dec	ecx
        jz      toend        
        
        rol	ax,1        
        cwd			; extend 1st bit to DX
        shl	edx,16
        cwd
        mov	[edi],edx
        add	edi,4

	dec	ecx
	jnz	Octet

toend:
        ret                     ; _cdecl return

Conv1_32 endp


;*************************************************************************************


        public  Conv1_64
Conv1_64 proc \
        uses edi esi, \
        Dest:ptr dword, \
        Src:ptr byte, \
        count:DWORD
        
        mov     ecx,[count]     ; cx=amount of pixels
        or	ecx,ecx
        jz	toend		; array has zero size

        mov     edi,[Dest]     ; di=first pointer (es=segment part)
        mov     esi,[Src]      ; 

	cld
Octet:  mov     ah,[esi]	; new octet        
        inc	esi
        
        cwd			; extend 8th bit to DX
        shl	edx,16
        cwd
        mov	[edi],edx
        add	edi,4
        mov	[edi],edx
        add	edi,4

	dec	ecx
        jz      toend
        
        rol	ax,1        
        cwd			; extend 7th bit to DX
        shl	edx,16
        cwd
        mov	[edi],edx
        add	edi,4
        mov	[edi],edx
        add	edi,4

	dec	ecx
        jz      toend
        
        rol	ax,1        
        cwd			; extend 6th bit to DX
        shl	edx,16
        cwd
        mov	[edi],edx
        add	edi,4
        mov	[edi],edx
        add	edi,4

	dec	ecx
        jz      toend        
        
        rol	ax,1        
        cwd			; extend 5th bit to DX
        shl	edx,16
        cwd
        mov	[edi],edx
        add	edi,4
        mov	[edi],edx
        add	edi,4

	dec	ecx
        jz      toend                

        rol	ax,1        
        cwd			; extend 4th bit to DX
        shl	edx,16
        cwd
        mov	[edi],edx
        add	edi,4
        mov	[edi],edx
        add	edi,4

	dec	ecx
        jz      toend
        
        
        rol	ax,1        
        cwd			; extend 3rd bit to DX
        shl	edx,16
        cwd
        mov	[edi],edx
        add	edi,4
        mov	[edi],edx
        add	edi,4

	dec	ecx
        jz      toend
        
        rol	ax,1        
        cwd			; extend 2nd bit to DX
        shl	edx,16
        cwd
        mov	[edi],edx        
        add	edi,4
        mov	[edi],edx        
        add	edi,4

	dec	ecx
        jz      toend        
        
        rol	ax,1        
        cwd			; extend 1st bit to DX
        shl	edx,16
        cwd
        mov	[edi],edx
        add	edi,4
        mov	[edi],edx
        add	edi,4

	dec	ecx
	jnz	Octet

toend:
        ret                     ; _cdecl return

Conv1_64 endp


;*************************************************************************************
;*************************************************************************************


;void Conv4_1(BYTE *Dest, const BYTE *Src, unsigned Size1D)
        public  Conv4_1
Conv4_1 proc \
        uses edi esi, \
        Dest:ptr qword, \
        Src:ptr byte, \
        count:DWORD

        mov     ecx,[count]     ; cx=amount of pixels
        or	ecx,ecx
        jz	toend		; array has zero size

        mov     edi,[Dest]     ; di = destination pointer (es=segment part)
        mov     esi,[Src]      ; di = source pointer
        
        cld        
        mov	ah,1		; add end byte mark
PIXEL:	lodsb
	rol	al,1		; copy the highest bit to CY
	rcl	ah,1		; transfer bit from CY to AH
	
	dec	ecx		; 2nd nibble
	jz	First1
	rol	al,4		; copy original 4th bit to CY
	rcl	ah,1		; transfer bit from CY to AH
			
	jnc	NoOctet			
	mov	[edi],ah	; Full 8 bits finished, 1 travelled to CY.
	inc	edi
	mov	ah,1		; add end byte mark
	loop	PIXEL
	jmp	toend		; all done here
	
NoOctet:loop	PIXEL

First1:	sal	ah,1		; shift must be finished to 8th bit
	jnc	First1
	mov	[edi],ah	; store last incomplete byte

toend:
        ret                     ; _cdecl return
                
Conv4_1 endp



;void Conv4_8(BYTE *Dest, const BYTE *Src, unsigned Size1D)
        public  Conv4_8
Conv4_8 proc \
        uses edi esi ebx, \
        Dest:ptr byte, \
        Src:ptr byte, \
        count:DWORD

        mov     ecx,[count]     ; cx=amount of pixels
        or	ecx,ecx
        jz	toend		; array has zero size

        mov     edi,[Dest]     ; di = destination pointer (es=segment part)
        mov     esi,[Src]      ; di = source pointer
        
        cld
PIXEL:	lodsb
        mov	bl,al
	mov	ah,al
	and	al,0F0h		; copy the highest bit to CY
	shr	ah,4
	or	al,ah		; byte from 1st nibble finished
	stosb

	dec	ecx		; 2nd nibble
	jz	toend

	mov	al,bl
	and	al,0Fh
	sal	bl,4
	or	al,bl		; byte from 2nd nibble finished
	stosb
NoOctet:loop	PIXEL

toend:
        ret                     ; _cdecl return
                
Conv4_8 endp



;void Conv4_16(WORD *Dest, const BYTE *Src, unsigned Size1D)
        public  Conv4_16
Conv4_16 proc \
        uses edi esi ebx, \
        Dest:ptr word, \
        Src:ptr byte, \
        count:DWORD

        mov     ecx,[count]     ; cx=amount of pixels
        or	ecx,ecx
        jz	toend		; array has zero size

        mov     edi,[Dest]     ; di = destination pointer (es=segment part)
        mov     esi,[Src]      ; di = source pointer
        
        cld
PIXEL:	lodsb
        mov	bl,al
	mov	ah,al
	and	al,0F0h		; copy the highest bit to CY
	shr	ah,4
	or	al,ah		; byte from 1st nibble finished
	mov	ah,al
	stosw

	dec	ecx		; 2nd nibble
	jz	toend

	mov	al,bl
	and	al,0Fh
	sal	bl,4
	or	al,bl		; byte from 2nd nibble finished
	mov	ah,al
	stosw
NoOctet:loop	PIXEL

toend:
        ret                     ; _cdecl return
                
Conv4_16 endp



;void Conv4_32(DWORD *Dest, const BYTE *Src, unsigned Size1D)
        public  Conv4_32
Conv4_32 proc \
        uses edi esi ebx, \
        Dest:ptr dword, \
        Src:ptr byte, \
        count:DWORD

        mov     ecx,[count]     ; cx=amount of pixels
        or	ecx,ecx
        jz	toend		; array has zero size

        mov     edi,[Dest]     ; di = destination pointer (es=segment part)
        mov     esi,[Src]      ; di = source pointer
        
        cld
PIXEL:	lodsb
        mov	bl,al
	mov	ah,al
	and	al,0F0h		; copy the highest bit to CY
	shr	ah,4
	or	al,ah		; byte from 1st nibble finished
	mov	ah,al	
	stosw
	stosw

	dec	ecx		; 2nd nibble
	jz	toend

	mov	al,bl
	and	al,0Fh
	sal	bl,4
	or	al,bl		; byte from 2nd nibble finished
	mov	ah,al
	mov	bx,ax
	shl	eax,16
	mov	ax,bx		; dword from 2nd nibble finished
	stosd
NoOctet:loop	PIXEL

toend:
        ret                     ; _cdecl return
                
Conv4_32 endp




;*************************************************************************************
;*************************************************************************************

        public  Conv8_1
Conv8_1 proc \
        uses edi esi ebx, \
        Dest:ptr qword, \
        Src:ptr byte, \
        count:DWORD

        mov     ecx,[count]     ; cx=amount of pixels
        or	ecx,ecx
        jz	toend		; array has zero size

        mov     edi,[Dest]     ; di=first pointer (es=segment part)
        mov     esi,[Src]      ;
        
        cld        
        mov	ah,1		; add end byte mark
PIXEL:	lodsb
	rol	al,1		; copy the highest bit to CY
	rcl	ah,1		; transfer bit from CY
	jnc	NoOctet
	mov	[edi],ah
	inc	edi
	mov	ah,1		; add end byte mark
	loop	PIXEL
	jmp	toend		; all done here
	
NoOctet:loop	PIXEL

First1:	sal	ah,1		; shift must be finished to 8th bit
	jnc	First1
	mov	[edi],ah	; store last incomplete byte

toend:
        ret                     ; _cdecl return
                
Conv8_1 endp


;*************************************************************************************


        public  Conv8_4
Conv8_4 proc \
        uses edi esi, \
        Dest:ptr byte, \
        Src:ptr byte, \
        count:DWORD

        mov     ecx,[count]     ; cx=amount of pixels
        or	ecx,ecx
        jz	toend		; array has zero size

        mov     edi,[Dest]     ; di=first pointer (es=segment part)
        mov     esi,[Src]      ;
        
        cld
PIXEL:	lodsb			; load 1st byte
	and	al,0F0h
	
	dec	ecx
	jnz	NIBBLE2
	stosb			;store incomplete nibble
	jmp	toend

NIBBLE2:mov	ah,al
        lodsb			; load 2nd byte
        and	al,0F0h
	ror	al,4
	or	al,ah
	stosb			;store both nibbles
	loop	PIXEL
        
toend:
        ret                     ; _cdecl return
                
Conv8_4 endp



;*************************************************************************************


        public  Conv8_16
Conv8_16 proc \
        uses edi esi ebx, \
        Dest:ptr qword, \
        Src:ptr byte, \
        count:DWORD

        mov     ecx,[count]     ; cx=amount of pixels
        or	ecx,ecx
        jz	toend		; array has zero size

        mov     edi,[Dest]     ; di=first pointer (es=segment part)
        mov     esi,[Src]      ;
        
        cld
PIXEL4: cmp	ecx,4	
        jl	PIXEL
       
        lodsd			; pixels 1,2,3,4
        mov	ebx,eax
        
        mov	al,bh
        sal	eax,16
        mov	ah,bl
        mov	al,bl
        stosd			; converted pixel 1 & 2
        
        shr	ebx,16
        mov	al,bh
        mov	ah,bh
        sal	eax,16
        mov	ah,bl
        mov	al,bl
        stosd			; converted pixel 3 & 4
        
        sub	ecx,4
        jnz	PIXEL4
        jmp	ToEnd
                
PIXEL:	lodsb
	mov	ah,al
	stosw
	loop	PIXEL
        
ToEnd:	ret			; _cdecl return
                
Conv8_16 endp


;*************************************************************************************

        public  Conv8_24
Conv8_24 proc \
        uses edi esi, \
        Dest:ptr qword, \
        Src:ptr byte, \
        count:DWORD

        mov     ecx,[count]     ; cx=amount of pixels
        or	ecx,ecx
        jz	toend		; array has zero size

        mov     edi,[Dest]     ; di=first pointer (es=segment part)
        mov     esi,[Src]      ;
        
        cld
PIXEL:	lodsb	
	stosb
	stosb
	stosb
	loop	PIXEL
        
toend:
        ret                     ; _cdecl return
                
Conv8_24 endp


;*************************************************************************************

        public  Conv8_32
Conv8_32 proc \
        uses edi esi, \
        Dest:ptr qword, \
        Src:ptr byte, \
        count:DWORD

        mov     ecx,[count]     ; cx=amount of pixels
        or	ecx,ecx
        jz	toend		; array has zero size

        mov     edi,[Dest]     ; di=first pointer (es=segment part)
        mov     esi,[Src]      ;
        
        cld
PIXEL:	lodsb
	mov	ah,al
	mov	dx,ax
	rol	eax,16
	mov	ax,dx
	stosd
	loop	PIXEL
        
toend:
        ret                     ; _cdecl return
                
Conv8_32 endp


;*************************************************************************************

        public  Conv8_64
Conv8_64 proc \
        uses edi esi ebx, \
        Dest:ptr qword, \
        Src:ptr byte, \
        count:DWORD

        mov     ecx,[count]     ; cx=amount of pixels
        or	ecx,ecx
        jz	toend		; array has zero size

        mov     edi,[Dest]     ; di=first pointer (es=segment part)
        mov     esi,[Src]      ;
        
        cld
PIXEL:	lodsb
	mov	ah,al
	mov	bx,ax
	rol	eax,16
	mov	ax,bx
	stosd
	stosd
	loop	PIXEL
        
toend:
        ret                     ; _cdecl return
                
Conv8_64 endp


;*************************************************************************************
;*************************************************************************************

        public  Conv16_1
Conv16_1 proc \
        uses edi esi ebx, \
        Dest:ptr byte, \
        Src:ptr word, \
        count:DWORD

        mov     ecx,[count]     ; cx=amount of pixels
        or	ecx,ecx
        jz	toend		; array has zero size

        mov     edi,[Dest]     ; di=first pointer (es=segment part)
        mov     esi,[Src]      ;
        
        cld        
        mov	bl,1		; add end byte mark
PIXEL:	lodsw
	rol	ax,1		; copy the highest bit to CY
	rcl	bl,1		; transfer bit from CY
	jnc	NoOctet
	mov	[edi],bl
	inc	edi
	mov	bl,1		; add end byte mark
	loop	PIXEL
	jmp	toend		; all done here
	
NoOctet:loop	PIXEL

First1:	sal	bl,1		; shift must be finished to 8th bit
	jnc	First1
	mov	[edi],bl	; store last incomplete byte

toend:
        ret                     ; _cdecl return
                
Conv16_1 endp



;*************************************************************************************


        public  Conv16_4
Conv16_4 proc \
        uses edi esi, \
        Dest:ptr byte, \
        Src:ptr word, \
        count:DWORD

        mov     ecx,[count]     ; cx=amount of pixels
        or	ecx,ecx
        jz	toend		; array has zero size

        mov     edi,[Dest]     ; di=first pointer (es=segment part)
        mov     esi,[Src]      ;
        
        cld
PIXEL:	inc	si
	lodsb			; load 1st hi byte
	and	al,0F0h
	
	dec	ecx
	jnz	NIBBLE2
	stosb			;store incomplete nibble
	jmp	toend

NIBBLE2:mov	ah,al
	inc	si
        lodsb			; load 2nd byte
        and	al,0F0h
	ror	al,4
	or	al,ah
	stosb			;store both nibbles
	loop	PIXEL
        
toend:
        ret                     ; _cdecl return
                
Conv16_4 endp



;*************************************************************************************


        public  Conv16_8
Conv16_8 proc \
        uses edi esi ebx, \
        Dest:ptr qword, \
        Src:ptr byte, \
        count:DWORD

        mov     ecx,[count]     ; cx=amount of pixels
        or	ecx,ecx
        jz	ToEnd		; array has zero size

        mov     edi,[Dest]     ; di=first pointer (es=segment part)
        mov     esi,[Src]      ;
        
        cld
PIXEL4: cmp	ecx,4
        jl	PIXEL
        
        lodsd
        mov	bl,ah		; pixel 1
        shr	eax,16
        mov	bh,ah		; pixel 2
        
        bswap	ebx		; store pixels to high hals of EBX.
        
        lodsd
        mov	bh,ah		; pixel 3
        shr	eax,16
        mov	bl,ah		; pixel 4
        
        bswap	ebx		; store pixels to high hals of EBX.
        mov	eax,ebx
        stosd
        
        sub	ecx,4
        jnz	PIXEL4
        jmp	ToEnd
        
PIXEL:	lodsw
	mov	al,ah
	stosb
	loop	PIXEL
        
ToEnd:
        ret                     ; _cdecl return
                
Conv16_8 endp



;*************************************************************************************

        public  Conv16_32
Conv16_32 proc \
        uses edi esi ebx, \
        Dest:ptr qword, \
        Src:ptr byte, \
        count:DWORD

        mov     ecx,[count]     ; cx=amount of pixels
        or	ecx,ecx
        jz	toend		; array has zero size

        mov     edi,[Dest]     ; di=first pointer (es=segment part)
        mov     esi,[Src]      ;
        
        cld
PIXEL:	lodsw
	mov	bx,ax
	rol	eax,16
	mov	ax,bx
	stosd
	loop	PIXEL
        
toend:
        ret                     ; _cdecl return
                
Conv16_32 endp


;*************************************************************************************
;*************************************************************************************


        public  Conv24_8
Conv24_8 proc \
        uses edi esi, \
        Dest:ptr qword, \
        Src:ptr byte, \
        count:DWORD

        mov     ecx,[count]     ; cx=amount of pixels
        or	ecx,ecx
        jz	toend		; array has zero size

        mov     edi,[Dest]     ; di=destination pointer (es=segment part)
        mov     esi,[Src]      ; si=source pointer 
        
        add	esi,2
        cld
PIXEL:	mov	al,[esi]
        add	esi,3	
	stosb
	loop	PIXEL
        
toend:
        ret                     ; _cdecl return
                
Conv24_8 endp


;*************************************************************************************
;*************************************************************************************


        public  Conv32_1
Conv32_1 proc \
        uses edi esi ebx, \
        Dest:ptr dword, \
        Src:ptr byte, \
        count:DWORD

        mov     ecx,[count]     ; cx=amount of pixels
        or	ecx,ecx
        jz	toend		; array has zero size

        mov     edi,[Dest]     ; di=first pointer (es=segment part)
        mov     esi,[Src]      ;
        
        cld        
        mov	bl,1		; add end byte mark
PIXEL:	lodsd
	rol	eax,1		; copy the highest bit to CY
	rcl	bl,1		; transfer bit from CY
	jnc	NoOctet
	mov	[edi],bl
	inc	edi
	mov	bl,1		; add end byte mark
	loop	PIXEL
	jmp	toend		; all done here
	
NoOctet:loop	PIXEL

First1:	sal	bl,1		; shift must be finished to 8th bit
	jnc	First1
	mov	[edi],bl	; store last incomplete byte

toend:
        ret                     ; _cdecl return
                
Conv32_1 endp


;*************************************************************************************


        public  Conv32_4
Conv32_4 proc \
        uses edi esi, \
        Dest:ptr byte, \
        Src:ptr dword, \
        count:DWORD

        mov     ecx,[count]     ; cx=amount of pixels
        or	ecx,ecx
        jz	toend		; array has zero size

        mov     edi,[Dest]     ; di=first pointer (es=segment part)
        mov     esi,[Src]      ;
        
        cld
PIXEL:	add	esi,3
	lodsb			; load 1st hi byte
	and	al,0F0h
	
	dec	ecx
	jnz	NIBBLE2
	stosb			;store incomplete nibble
	jmp	toend

NIBBLE2:mov	ah,al
	add	esi,3
        lodsb			; load 2nd hi byte
        and	al,0F0h
	ror	al,4
	or	al,ah
	stosb			;store both nibbles
	loop	PIXEL
        
toend:
        ret                     ; _cdecl return
                
Conv32_4 endp



;*************************************************************************************


        public  Conv32_8
Conv32_8 proc \
        uses edi esi, \
        Dest:ptr qword, \
        Src:ptr byte, \
        count:DWORD

        mov     ecx,[count]     ; cx=amount of pixels
        or	ecx,ecx
        jz	toend		; array has zero size

        mov     edi,[Dest]     ; di=first pointer (es=segment part)
        mov     esi,[Src]      ;
        
        cld
PIXEL:	add	esi,3
	movsb
	loop	PIXEL
        
toend:
        ret                     ; _cdecl return
                
Conv32_8 endp


;*************************************************************************************


        public  Conv32_16
Conv32_16 proc \
        uses edi esi, \
        Dest:ptr qword, \
        Src:ptr byte, \
        count:DWORD

        mov     ecx,[count]     ; cx=amount of pixels
        or	ecx,ecx
        jz	toend		; array has zero size

        mov     edi,[Dest]     ; di=first pointer (es=segment part)
        mov     esi,[Src]      ;
        
        cld
PIXEL:	add	esi,2
	movsw
	loop	PIXEL
        
toend:
        ret                     ; _cdecl return
                
Conv32_16 endp



;########################################################################################
;########################################################################################
;########################################################################################


	public  Flip4
Flip4	proc \
        uses edi esi, \
        Data:ptr byte, \        
        count:DWORD

        mov     ecx,[count]     ; cx=amount of pixels
        cmp	ecx,1		; 1 or less pixels makes no sense to flip
        jle	ToEnd		; array has zero size

        mov     edi,[Data]	; di=first pointer (es=segment part)
        mov     esi,[Data]	;
        
        shr	ecx,1        
        jc	PixOdd
        
	add	esi,ecx		; pixel count is even
        dec	esi
        
        cmp	edi,esi
        je	LastNibble	; This can occur for size=2.
LoopEven:mov	al,[edi]	; Process first byte with nibbles
	mov	ah,0	
	shl	ax,4
	or	al,ah	

	mov	dl,[esi]	; Process second byte with nibbles
	mov	dh,0
	shl	dx,4
	or	dl,dh

	mov	[esi],al
	mov	[edi],dl

	inc	edi
	dec	esi
	cmp	edi,esi
	jl	LoopEven
	jne	ToEnd		; No one byte nible needs to be flipped.
LastNibble:
	mov	al,[edi]
	mov	ah,0	
	shl	ax,4
	or	al,ah
	mov	[edi],al	; Last byte needs to flip nibbles.
	jmp	ToEnd

                
PixOdd:	add	esi,ecx		; pixel count is odd i.e. >=3.
LoopOdd:mov	al,[edi]
	mov	ah,al
	and	ax,0F00Fh
	
	mov	dl,[esi]
	mov	dh,dl
	and	dx,0F00Fh	
		
	or	al,dh
	mov	[edi],al	; nibble 1 flipped with nibble n
	
	or	dl,ah
	mov	[esi],dl	; nibble n flipped with nibble 1

	dec	esi
	cmp	esi,edi
	je	ToEnd
	
	mov	ah,al
	and	ax,0F00Fh        
	
	mov	dl,[esi]
	mov	dh,dl
	and	dx,0F00Fh	
	
	or	ah,dl
	mov	[edi],ah	; nibble 2 flipped with nibble n-1
	
	or	dh,al
	mov	[esi],dh	; nibble n-1 flipped with nibble 2

	inc	edi	
	cmp	edi,esi
	jl	LoopOdd

ToEnd:
        ret                     ; _cdecl return
                
Flip4 endp


;*************************************************************************************


	public  Flip8
Flip8	proc \
        uses edi esi, \
        Data:ptr byte, \        
        count:DWORD

        mov     ecx,[count]     ; cx=amount of pixels
        cmp	ecx,1
        jle	ToEnd		; array has zero size

        mov     edi,[Data]	; di=first pointer (es=segment part)
        mov     esi,[Data]	;
        
        add	esi,ecx
        dec	esi
                
PIXEL:	mov	al,[edi]
	mov	ah,[esi]
	mov	[edi],ah
	mov	[esi],al
	inc	edi
	dec	esi
	cmp	edi,esi
	jl	PIXEL	

ToEnd:
        ret                     ; _cdecl return
                
Flip8 endp


;*************************************************************************************


	public  Flip16
Flip16	proc \
        uses edi esi, \
        Data:ptr byte, \        
        count:DWORD

        mov     ecx,[count]     ; cx=amount of pixels
        cmp	ecx,1
        jle	ToEnd		; array has zero size

        mov     edi,[Data]	; di=first pointer (es=segment part)
        mov     esi,[Data]	;
        
        add	esi,ecx
        add	esi,ecx
        sub	esi,2
                
PIXEL:	mov	ax,[edi]
	mov	cx,[esi]
	mov	[edi],cx
	mov	[esi],ax
	add	edi,2
	sub	esi,2
	cmp	edi,esi
	jl	PIXEL	

ToEnd:
        ret                     ; _cdecl return
                
Flip16 endp


;*************************************************************************************


	public  Flip24
Flip24	proc \
        uses edi esi, \
        Data:ptr byte, \        
        count:DWORD

        mov     ecx,[count]     ; cx=amount of pixels
        cmp	ecx,1
        jle	ToEnd		; array has zero size

        mov     edi,[Data]	; di=first pointer (es=segment part)
        mov     esi,[Data]	;
        
        dec	ecx
        add	esi,ecx
        add	esi,ecx
        add	esi,ecx		; 3*(size-1)        
                
PIXEL:	mov	al,[edi]	; byte 1
        mov	cl,[esi]
        mov	[edi],cl
        mov	[esi],al
        
        inc	edi
        inc	esi
        mov	al,[edi]	; byte 2
        mov	cl,[esi]
        mov	[edi],cl
        mov	[esi],al
        
        inc	edi
        inc	esi
        mov	al,[edi]	; byte 3
        mov	cl,[esi]
        mov	[edi],cl
        mov	[esi],al
        
        inc	edi
        sub	esi,5		; move to previous pixel +2 needs to shift -3 ...  ofs -5
	
	cmp	edi,esi
	jl	PIXEL	

ToEnd:
        ret                     ; _cdecl return
                
Flip24 endp


;*************************************************************************************


	public  Flip32
Flip32	proc \
        uses edi esi, \
        Data:ptr byte, \        
        count:DWORD

        mov     ecx,[count]     ; cx=amount of pixels
        cmp	ecx,1
        jle	ToEnd		; array has zero size

        mov     edi,[Data]	; di=first pointer (es=segment part)
        mov     esi,[Data]	;

	dec	ecx        
        add	ecx,ecx		; count*2 - 2
        add	ecx,ecx		; count*4 - 4
        add	esi,ecx        
                
PIXEL:	mov	eax,[edi]
	mov	ecx,[esi]
	mov	[edi],ecx
	mov	[esi],eax
	add	edi,4
	sub	esi,4
	cmp	edi,esi
	jl	PIXEL	

ToEnd:
        ret                     ; _cdecl return
                
Flip32	endp


;*************************************************************************************


	public  Flip64
Flip64	proc \
        uses edi esi, \
        Data:ptr byte, \        
        count:DWORD

        mov     ecx,[count]     ; cx=amount of pixels
        cmp	ecx,1
        jle	ToEnd		; array has zero size

        mov     edi,[Data]	; di=first pointer (es=segment part)
        mov     esi,[Data]	;

	dec	ecx        
        add	ecx,ecx		; count*2 - 2
        add	ecx,ecx		; count*4 - 4
        add	ecx,ecx		; count*8 - 8
        add	esi,ecx        
                
PIXEL:	mov	eax,[edi]
	mov	ecx,[esi]
	mov	[edi],ecx
	mov	[esi],eax
	add	edi,4
	add	esi,4
	
	mov	eax,[edi]
	mov	ecx,[esi]
	mov	[edi],ecx
	mov	[esi],eax
	add	edi,4
	
	sub	esi,12		; +4 needs to shift -8 i.e. -12
	cmp	edi,esi
	jl	PIXEL	

ToEnd:
        ret                     ; _cdecl return
                
Flip64	endp


        end
