home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
vis-ftp.cs.umass.edu
/
vis-ftp.cs.umass.edu.tar
/
vis-ftp.cs.umass.edu
/
pub
/
Software
/
ASCENDER
/
ascendMar8.tar
/
UMass
/
ISR
/
isr2pix.lisp
< prev
next >
Wrap
Lisp/Scheme
|
1995-04-11
|
19KB
|
362 lines
;;; -*- Mode:Common-Lisp; Package:ISR2; Base:10 -*-
(in-package "ISR2")
#-:EXPLORER
(defun bitblt (alu width height from-array from-x from-y to-array to-x to-y)
"Replace the functionality of the lisp machine's bitblt function,
albeit slower. In other words, copy a rectangular portion of from-array
to to-array according to a boolean function. ALU must be one of
:set :and, :ior, :xor or :andc1"
(dotimes (w width)
(dotimes (h height)
(setf (aref to-array (+ to-y h) (+ to-x w))
(case alu
((:set) (aref from-array (+ from-y h) (+ from-x w)))
((:and) (and (aref to-array (+ to-y h) (+ to-x w))
(aref from-array (+ from-y h) (+ from-x w))))
((:ior) (or (aref to-array (+ to-y h) (+ to-x w))
(aref from-array (+ from-y h) (+ from-x w))))
((:xor)
(let ((both? (and (aref to-array (+ to-y h) (+ to-x w))
(aref from-array (+ from-y h) (+ from-x w)))))
(if both?
0
(or (aref to-array (+ to-y h) (+ to-x w))
(aref from-array (+ from-y h) (+ from-x w))))))
((:andc1 :andca)
(and (aref to-array (+ to-y h) (+ to-x w))
(mod (1+ (aref from-array (+ from-y h) (+ from-x w)))
2)))
(t (error "Unimplemented ALU function")))))))
(defun make-pixelmap-extents (minx miny maxx maxy)
(let* ((byte-bound (* 8 (floor minx 8)))
(vax-byte-width (1+ (floor (- maxx byte-bound) 8)))
#-:LUCIS (default-cons-area *bitplane-area*)
(extents (make-extents-struct :byte-bound byte-bound
:byte-width (* (ceiling vax-byte-width 4) 4)
:minx minx
:miny miny
:maxx maxx
:maxy maxy)))
#+:EXPLORER (declare (special default-cons-area))
extents))
(defun make-bitplane (extents)
(make-array (list (- (extents-maxy extents) (extents-miny extents) -1)
(* 8 (extents-byte-width extents)))
:element-type 'bit :initial-element 0))
(defun extract-bitplane-and-extents (pixelmap)
(unless (pixelmap-p pixelmap)
(error "Object is not a pixelmap: ~A" pixelmap))
(let ((extents (pixelmap-extents pixelmap))
(bitplane (pixelmap-bitplane pixelmap)))
(cond ((and (not (extents-p extents))
(not (extents-p extents)))
(error "Pixelmap does not contain an extents: ~A" pixelmap))
((not (arrayp extents))
(error "Pixelmap does not contain a bitplane: ~A" pixelmap))
(t (values bitplane extents)))))
(defun bitplane-emptyp (bitplane)
(dotimes (x (array-dimension bitplane 0) t)
(dotimes (y (array-dimension bitplane 1))
(when (= 1 (aref bitplane x y))
(return-from bitplane-emptyp nil)))))
(defun bitplane-count (bitplane &aux (sum 0))
(dotimes (x (array-dimension bitplane 0) sum)
(dotimes (y (array-dimension bitplane 1))
(when (= 1 (aref bitplane x y))
(incf sum)))))
(defun pix-emptyp (pixelmap)
(cond ((not (pixelmap-p pixelmap))
(error "Object is not a pixelmap: ~A" pixelmap))
((not (arrayp (pixelmap-bitplane pixelmap)))
(error "Pixelmap does not contain bitplane"))
(t (bitplane-emptyp (pixelmap-bitplane pixelmap)))))
(defun pix-count (pixelmap)
(cond ((not (pixelmap-p pixelmap))
(error "Object is not a pixelmap: ~A" pixelmap))
((not (arrayp (pixelmap-bitplane pixelmap)))
(error "Pixelmap does not contain bitplane"))
(t (setf (extents-pixel-count (pixelmap-extents pixelmap))
(bitplane-count (pixelmap-bitplane pixelmap))))))
(defun pix-aref (row col pixelmap)
(when (and (<= (extents-miny (pixelmap-extents pixelmap))
row
(extents-maxy (pixelmap-extents pixelmap)))
(<= (extents-minx (pixelmap-extents pixelmap))
col
(extents-maxx (pixelmap-extents pixelmap))))
(= 1 (aref (pixelmap-bitplane pixelmap)
(round (- row (extents-miny (pixelmap-extents pixelmap))))
(round (- col (extents-byte-bound (pixelmap-extents pixelmap))))))))
(defun set-pix-aref (row col pixelmap value)
(if (and (<= (extents-miny (pixelmap-extents pixelmap))
row
(extents-maxy (pixelmap-extents pixelmap)))
(<= (extents-minx (pixelmap-extents pixelmap))
col
(extents-maxx (pixelmap-extents pixelmap))))
(setf (aref (pixelmap-bitplane pixelmap)
(round (- row (extents-miny (pixelmap-extents pixelmap))))
(round (- col (extents-byte-bound (pixelmap-extents pixelmap)))))
value)
(error "Row and Col specify a point outside the extents of Pixelmap")))
(defsetf pix-aref set-pix-aref)
(defun update-min-values (bitplane extents)
"This function determines whether a bitplane `fills up' an extents structure. It
checks to see if miny, minx are smaller then they ought to be, or if maxy and maxx
are bigger then they ought to be. Returns as four values delta-miny, delta-maxy,
delta-minx, delta-maxx, where delta-min's are the number to be added to the min
values and delta-max's should be subtracted from the max values."
(let ((x-dimension (array-dimension bitplane 1))
(y-dimension (array-dimension bitplane 0))
(x-start (- (extents-minx extents) (extents-byte-bound extents)))
(x-stop (- ( + (* 8 (extents-byte-width extents)) (extents-byte-bound extents))
(extents-maxx extents)))
(delta-miny 0)
(delta-maxy 0)
(delta-minx 0)
(delta-maxx 0))
(block miny
(dotimes (y y-dimension)
(dotimes (x x-dimension)
(when (= 1 (aref bitplane y x))
(return-from miny)))
(incf delta-miny)))
(block maxy
(dotimes (y y-dimension)
(dotimes (x x-dimension)
(when (= 1 (aref bitplane (- y-dimension y 1) x))
(return-from maxy)))
(incf delta-maxy)))
(block minx
(dotimes (x x-dimension)
(dotimes (y y-dimension)
(when (= 1 (aref bitplane y (+ x-start x)))
(return-from minx)))
(incf delta-minx)))
(block maxx
(dotimes (x x-dimension)
(dotimes (y y-dimension)
(when (= 1 (aref bitplane y (- x-stop x 1)))
(return-from maxx)))
(incf delta-maxx)))
(values delta-miny delta-maxy delta-minx delta-maxx)))
(defun trim-bitplane-and-extents! (bitplane extents)
"`Trims' a pixelmap if this is possible. That is, it sees if the min and max variables
in the extents structure can be tightened. If a smaller bitplane can be used, makes
a smaller bitplane to substitute for the original. If the bitplane is completely
empty return NIL. This routine is destructive to its extents argument only; it does
not modify -- although it may replace -- the original bitplane."
(multiple-value-bind (delta-miny delta-maxy delta-minx delta-maxx)
(update-min-values bitplane extents)
(let* ((new-byte-bound (* 8 (floor (+ (extents-minx extents) delta-minx) 8)))
(new-byte-width (1+ (floor (- (- (extents-maxx extents) delta-maxx) new-byte-bound) 8))))
(unless (bitplane-emptyp bitplane) ;; return nil if no pixels are set!
(when (or (< 0 delta-miny)
(< 0 delta-maxy)
(/= new-byte-bound (extents-byte-bound extents))
(/= new-byte-width (extents-byte-width extents)))
(let* ((new-height (- (extents-maxy extents) (extents-miny extents) -1 delta-miny delta-maxy))
(new-bitplane (make-array (list new-height (* 8 new-byte-width))
:element-type 'bit :initial-element 0)))
(bitblt #-:EXPLORER :set #+:EXPLORER boole-1 (* 8 new-byte-width) new-height
bitplane (- (extents-byte-bound extents) new-byte-bound) delta-miny
new-bitplane 0 0)
(setf bitplane new-bitplane)
(setf (extents-miny extents) (+ (extents-miny extents) delta-miny))
(setf (extents-maxy extents) (+ (extents-maxy extents) delta-maxy))
(setf (extents-byte-bound extents) new-byte-bound)
(setf (extents-byte-width extents) new-byte-width)))
(setf (extents-minx extents) (+ (extents-minx extents) delta-minx))
(setf (extents-maxx extents) (+ (extents-maxx extents) delta-maxx))
(values bitplane extents)))))
(defun pix-union! (pixelmap1 pixelmap2)
"Returns a pixelmap containing the union of the pixels in pixelmap1 and pixelmap2.
If the extents box of pixelmap1 does not completely contain the extents box of pixelmap2,
then a new pixelmap is created and neither argument is altered. If Pixelmap1's extents box
does contain that of pixelmap2, then pixelmap1 is destructively altered."
(declare (notinline bitblt))
(let ((extents1 (pixelmap-extents pixelmap1))
(extents2 (pixelmap-extents pixelmap2)))
(if (or (> (extents-byte-bound extents1) (extents-byte-bound extents2))
(< (+ (extents-byte-bound extents1) (* 8 (extents-byte-width extents1)))
(+ (extents-byte-bound extents2) (* 8 (extents-byte-width extents2))))
(> (extents-miny extents1) (extents-miny extents2))
(< (extents-maxy extents1) (extents-maxy extents2)))
(pix-union pixelmap1 pixelmap2)
(let ((transfer-width (- (extents-maxx extents2) (extents-byte-bound extents2) -1))
(transfer-height (- (extents-maxy extents2) (extents-miny extents2) -1))
(new-x-offset (- (extents-byte-bound extents2) (extents-byte-bound extents1)))
(new-y-offset (- (extents-miny extents2) (extents-miny extents1)))
(bitplane1 (pixelmap-bitplane pixelmap1))
(bitplane2 (pixelmap-bitplane pixelmap2)))
(bitblt #-:EXPLORER :ior #+:EXPLORER boole-ior ;;; ALU
transfer-width ;;; width
transfer-height ;;; height
bitplane2 ;;; source
0 ;;; from-x
0 ;;; from-y
bitplane1 ;;; destination
new-x-offset ;;; to-x
new-y-offset)
pixelmap1))))
(defun pix-union (pixelmap1 pixelmap2)
"Returns a pixelmap containing the union of the pixels in pixelmap1 and pixelmap2.
Neither of the arguments are altered."
(declare (notinline bitblt))
(multiple-value-bind (bitplane1 extents1)
(extract-bitplane-and-extents pixelmap1)
(multiple-value-bind (bitplane2 extents2)
(extract-bitplane-and-extents pixelmap2)
(let* ((new-extents (make-pixelmap-extents (min (extents-minx extents1) (extents-minx extents2))
(min (extents-miny extents1) (extents-miny extents2))
(max (extents-maxx extents1) (extents-maxx extents2))
(max (extents-maxy extents1) (extents-maxy extents2))))
(new-bitplane (make-bitplane new-extents)))
(let ((transfer-width (- (extents-maxx extents1) (extents-byte-bound extents1) -1))
(transfer-height (- (extents-maxy extents1) (extents-miny extents1) -1))
(new-x-offset (- (extents-byte-bound extents1) (extents-byte-bound new-extents)))
(new-y-offset (- (extents-miny extents1) (extents-miny new-extents))))
(bitblt #-:EXPLORER :set #+:EXPLORER boole-1 ;;; ALU
transfer-width ;;; width
transfer-height ;;; height
bitplane1 ;;; source
0 ;;; from-x
0 ;;; from-y
new-bitplane ;;; destination
new-x-offset ;;; to-x
new-y-offset)) ;;; to-y
(let ((transfer-width (- (extents-maxx extents2) (extents-byte-bound extents2) -1))
(transfer-height (- (extents-maxy extents2) (extents-miny extents2) -1))
(new-x-offset (- (extents-byte-bound extents2) (extents-byte-bound new-extents)))
(new-y-offset (- (extents-miny extents2) (extents-miny new-extents))))
(bitblt #-:EXPLORER :ior #+:EXPLORER boole-ior ;;; ALU
transfer-width ;;; width
transfer-height ;;; height
bitplane2 ;;; source
0 ;;; from-x
0 ;;; from-y
new-bitplane ;;; destination
new-x-offset ;;; to-x
new-y-offset)) ;;; to-y
(make-pixelmap :extents new-extents :bitplane new-bitplane)))))
(defun pix-intersection (pixelmap1 pixelmap2)
(multiple-value-bind (bitplane1 extents1)
(extract-bitplane-and-extents pixelmap1)
(multiple-value-bind (bitplane2 extents2)
(extract-bitplane-and-extents pixelmap2)
(let ((new-extents (make-pixelmap-extents (max (extents-minx extents1) (extents-minx extents2))
(max (extents-miny extents1) (extents-miny extents2))
(min (extents-maxx extents1) (extents-maxx extents2))
(min (extents-maxy extents1) (extents-maxy extents2)))))
(when (and (>= (extents-maxx new-extents) (extents-minx new-extents))
(>= (extents-maxy new-extents) (extents-miny new-extents)))
(let ((new-bitplane (make-bitplane new-extents)))
(bitblt #-:EXPLORER :set #+:EXPLORER boole-1 ;;; ALU
(- (extents-maxx new-extents) (extents-byte-bound new-extents) -1) ;;; width
(- (extents-maxy new-extents) (extents-miny new-extents) -1) ;;; height
bitplane1 ;;; source
(- (extents-byte-bound new-extents) (extents-byte-bound extents1)) ;;; from-x
(- (extents-miny new-extents) (extents-miny extents1)) ;;; from-y
new-bitplane ;;; destination
0 ;;; to-x
0) ;;; to-y
(bitblt #-:EXPLORER :and #+:EXPLORER boole-and ;;; ALU
(- (extents-maxx new-extents) (extents-byte-bound new-extents) -1)
(- (extents-maxy new-extents) (extents-miny new-extents) -1) ;;; height
bitplane2 ;;; source
(- (extents-byte-bound new-extents) (extents-byte-bound extents2)) ;;; from-x
(- (extents-miny new-extents) (extents-miny extents2)) ;;; from-y
new-bitplane ;;; destination
0 ;;; to-x
0) ;;; to-y
(unless (bitplane-emptyp new-bitplane)
(make-pixelmap :extents new-extents :bitplane new-bitplane))))))))
(defun pix-set-difference! (pixelmap1 pixelmap2)
(multiple-value-bind (bitplane1 extents1)
(extract-bitplane-and-extents pixelmap1)
(multiple-value-bind (bitplane2 extents2)
(extract-bitplane-and-extents pixelmap2)
(let ((width-to-copy (- (min (+ (extents-byte-bound extents1) (* 8 (extents-byte-width extents1)))
(+ (extents-byte-bound extents2) (* 8 (extents-byte-width extents2))))
(max (extents-byte-bound extents1) (extents-byte-bound extents2))))
(height-to-copy (- (min (extents-maxy extents1) (extents-maxy extents2))
(max (extents-miny extents1) (extents-miny extents2))
-1)))
(unless (or (>= 0 width-to-copy)
(>= 0 height-to-copy))
(bitblt #-:EXPLORER :andc1 #+:EXPLORER boole-andc1 ;;; ALU
width-to-copy ;;; width
height-to-copy ;;; height
bitplane2 ;;; source
(max 0 (- (extents-byte-bound extents1) (extents-byte-bound extents2)));;; from-x
(max 0 (- (extents-miny extents1) (extents-miny extents2))) ;;; from-y
bitplane1 ;;; destination
(max 0 (- (extents-byte-bound extents2) (extents-byte-bound extents1)));;; to-x
(max 0 (- (extents-miny extents2) (extents-miny extents1))))) ;;; to-y
pixelmap1))))
(defun pix-set-difference (pixelmap1 pixelmap2)
(multiple-value-bind (bitplane1 extents1)
(extract-bitplane-and-extents pixelmap1)
(let ((new-extents (make-pixelmap-extents (extents-minx extents1)
(extents-miny extents1)
(extents-maxx extents1)
(extents-maxy extents1)))
(new-bitplane (make-bitplane extents1)))
(bitblt #-:EXPLORER :set #+:EXPLORER boole-1 ;;; ALU
(* 8 (extents-byte-width extents1)) ;;; width
(- (extents-maxy extents1) (extents-miny extents1) -1) ;;; height
bitplane1 ;;; source
0 ;;; from-x
0 ;;; from-y
new-bitplane ;;; destination
0 ;;; to-x
0) ;;; to-y
(pix-set-difference! (make-pixelmap :bitplane new-bitplane :extents new-extents) pixelmap2))))
(defun print-pixelmap (pixelmap &optional (stream t))
(let ((bitplane (pixelmap-bitplane pixelmap))
(extents (pixelmap-extents pixelmap)))
(format stream "~%BYTE BOUND = ~A; BYTE WIDTH = ~A; MINY = ~A; MINX = ~A; MAXY = ~A; MAXX = ~A~% "
(extents-byte-bound extents)(extents-byte-width extents)
(extents-miny extents)(extents-minx extents)
(extents-maxy extents)(extents-maxx extents))
(dotimes (x (* 8 (extents-byte-width extents))) (format stream "-"))
(dotimes (y (1+ (- (extents-maxy extents)(extents-miny extents))))
(format stream "~%|")
(dotimes (x (* 8 (extents-byte-width extents)))
(if (= 1 (aref bitplane y x))
(format stream "*")
(format stream " ")))
(format stream "|"))
(format stream "~% ")
(dotimes (x (* 8 (extents-byte-width extents)) t) (format stream "-"))))