home *** CD-ROM | disk | FTP | other *** search
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
- ;;
- ;; rgbflop.asm
- ;;
- ;; Copyright 1999 G. Adam Stanislav
- ;; All rights reserved
- ;;
- ;; Started: 18-Nov-1999
- ;; Updated: 18-Nov-1999
- ;;
- ;; This is a Photoshop plugin which flops the red, green. and blue channels
- ;; of an image. In other words, it creates a negative.
- ;;
- ;; This source code can be assembled by NASM:
- ;;
- ;; nasm -f win32 rgbflop.asm
- ;;
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-
- %include 'filter.inc'
-
- global filter.parameters, filter.prepare, filter.start
- global filter.continue, filter.finish
-
- section .drectve info
- db "-out:rpFlop.8bf "
-
- section .data
- total dd 0
- partial dd 0
- global filter.name
- filter.name db "Flop All", 0
-
- section .text align=4
-
- ; These procedures receive four parameters:
- ;
- ; [esp+ 4] = selector (word) = EAX
- ; [esp+ 8] = address of filterParamBlock
- ; [esp+12] = address of data
- ; [esp+16] = address of result word, contains 0 (success)
-
- align 4
- error.return:
- mov ecx, [esp+16]
- mov word [ecx], filterBadParameters
- ret
-
- align 4
- filter.start:
- ; Get the pointer to the parameter block
- mov ecx, [esp+8]
-
- ; Quit if NULL.
- jecxz error.return
-
- ; Tell the host to give us r,g,b planes
- mov eax, 2 << 16
- mov [ecx+inLoPlane], eax
- mov [ecx+outLoPlane], eax
-
- ; Calculate the total number of pixels
- movzx eax, word [ecx+filterRect+right]
- sub ax, [ecx+filterRect+left]
- movzx edx, word [ecx+filterRect+bottom]
- sub dx, [ecx+filterRect+top]
- mul edx
- mov [total], eax
- sub edx, edx
- mov [partial], edx
-
- ; Ask the host for a NUMCOLSxNUMROWS input and output data. Less if the
- ; image is small.
- movzx eax, word [ecx+filterRect+right]
- movzx edx, word [ecx+filterRect+left]
- sub ax, dx
-
- cmp ax, NUMCOLS
- jb .X
- mov ax, NUMCOLS-1
-
- .X:
- mov [ecx+inRect+left], dx
- mov [ecx+outRect+left], dx
- add ax, dx
- mov [ecx+inRect+right], ax
- mov [ecx+outRect+right], ax
-
- mov ax, [ecx+filterRect+bottom]
- mov dx, [ecx+filterRect+top]
- sub ax, dx
-
- cmp ax, NUMROWS
- jb .Y
- mov ax, NUMROWS-1
-
- .Y:
- mov [ecx+inRect+top], dx
- mov [ecx+outRect+top], dx
- add ax, dx
- mov [ecx+inRect+bottom], ax
- mov [ecx+outRect+bottom], ax
-
- ret
-
- align 4
- filter.continue:
-
- mov ecx, [esp+8]
- or ecx, ecx
- je near error.return
-
- ; Calculate how far we are
- movzx eax, word [ecx+inRect+right]
- sub ax, [ecx+inRect+left]
- movzx edx, word [ecx+inRect+bottom]
- sub dx, [ecx+inRect+top]
- mul edx
- add [partial], eax
-
- push ecx
- push dword [total]
- push dword [partial]
- call [ecx+progressProc]
- add esp, 8
- pop edx
-
- push esi
- push edi
-
- mov esi, [edx+inData]
- mov edi, [edx+outData]
-
- movzx ecx, word [edx+inRect+bottom]
- sub cx, [edx+inRect+top]
-
- sub eax, eax
- cld
-
- ; ECX = number of rows
-
- .bigloop:
- push ecx
-
- mov cx, word [edx+inRect+right]
- sub cx, [edx+inRect+left]
-
- ; ECX = number of columns
-
- push esi
- push edi
-
- ; To produce a negative, we do not negate the channel.
- ; We invert it.
- .filterloop:
- lodsb
- not al
- stosb
-
- lodsb
- not al
- stosb
-
- lodsb
- not al
- stosb
-
- loop .filterloop
-
- pop edi
- pop esi
-
- add esi, [edx+inRowBytes]
- add edi, [edx+outRowBytes]
- pop ecx
- loop .bigloop
-
- pop edi
- pop esi
-
- mov ecx, edx
-
- ; See if there are more columns to process within these rows.
- movzx eax, word [ecx+inRect+right]
- cmp ax, [ecx+filterRect+right]
- jae .rows
-
- .left:
- mov [ecx+inRect+left], ax
- mov [ecx+outRect+left], ax
- add ax, NUMCOLS-1
- cmp ax, [ecx+filterRect+right]
- jbe .right
- mov ax, [ecx+filterRect+right]
-
- .right:
- mov [ecx+inRect+right], ax
- mov [ecx+outRect+right], ax
-
- ret
-
- .rows:
- ; See if there are any unprocessed rows
- movzx eax, word [ecx+inRect+bottom]
- cmp ax, [ecx+filterRect+bottom]
- jae filter.cleanup ; all done
- mov [ecx+inRect+top], ax
- mov [ecx+outRect+top], ax
- add ax, NUMROWS-1
- cmp ax, [ecx+filterRect+bottom]
- jbe .bottom
- mov ax, [ecx+filterRect+bottom]
-
- .bottom:
- mov [ecx+inRect+bottom], ax
- mov [ecx+outRect+bottom], ax
-
- movzx eax, word [ecx+filterRect+left]
- jmp .left
-
-
- align 4
- filter.cleanup:
- sub eax, eax
- mov [ecx+inRect], eax
- mov [ecx+inRect+4], eax
- mov [ecx+outRect], eax
- mov [ecx+outRect+4], eax
- mov [ecx+inLoPlane], eax
- mov [ecx+outLoPlane], eax
-
- .done:
- ret
-
- align 4
- filter.prepare:
- mov ecx, [esp+8]
- or ecx, ecx
- jz near error.return
-
- mov eax, NUMROWS*NUMCOLS*4
- cmp eax, [ecx+maxSpace]
- ja near error.return
- mov [ecx+maxSpace], eax
- sub eax, eax
- mov [ecx+bufferSpace], eax
-
- ; FALL THROUGH
-
- filter.finish:
- ; Nothing to finish. Just return.
-
- ; FALL THROUGH
-
- filter.parameters:
- ; No parameters required. Just return.
-
- ret
-
- align 4
-