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
/
isr2readisr1file.lisp
< prev
next >
Wrap
Lisp/Scheme
|
1995-04-11
|
17KB
|
446 lines
;;; -*- Mode:Common-Lisp; Package:isr2; Base:10; -*-
;;;------------------------------------------------------------------------
;;; ISR2READISR1FILE.LISP - Code to read isr1 (old style) files
;;; Created: Mon May 23 12:47:56 1988
;;; Author: Robert Heller
;;;------------------------------------------------------------------------
;;; Copyright (c) University of Massachusetts 1988
;;;------------------------------------------------------------------------
(in-package "ISR2")
(export 'read-isr1-feature-data)
;; old (ISR1) lexicon structure (used to hold lexicon info during read).
(defstruct isr1-lexicon
name
doc
ptr-feature-count
num-feature-count
ext-feature-count
bp-feature-count
ptr-feature-slots
num-feature-slots
ext-feature-slots
bp-feature-slots
name-array
datatype-array
index-array
function-array
)
(proclaim '(special NUM-ARRAY32
TOKENSET
NUM-ARRAY
NUM-INDEX
NUM-NEXT-BLOCK-LIMIT
ON-THIS-PAGE
NUM-VIRTUAL-INDEX))
(eval-when (load eval compile)
(DEFCONSTANT S-F-EXPONENT (BYTE 8 23))
(DEFCONSTANT S-F-EXPONENT-HIGH-BITS (BYTE 6 25))
(DEFCONSTANT VAX-F-EXPONENT (BYTE 8 7))
(DEFCONSTANT MIN-EXP 1)
(DEFCONSTANT MAX-EXP 255)
(defconstant *vax-numeric-undefined* #x7FFFFFFF)
(DEFCONSTANT *VAX-BONKED-NUMERIC-UNDEFINED* #xFEFF7FFF
"What it looks like after it's been read and converted.")
(defconstant *vax-numeric-undefinable* #x7FFFFFFE)
(DEFCONSTANT *VAX-BONKED-NUMERIC-UNDEFINABLE* #xFEFE7FFF
"What it looks like after it's been read and converted.")
(defconstant *int-undefined-32b* #xafb5200)
(defconstant *int-undefinable-32b* #xafb5300)
)
;;; Defined in isr2fileio
;(DEFVAR *WORD* 0 "for byte depositing")
;
;(DEFVAR *TEMP* 0 "for macros, to avoid annoying let gensym stuff")
;(defvar *null-extents* nil)
;(eval-when (compile load eval)
; (setf *null-extents* (make-extents 0 0 0 0 0))) ;written out in place of undefined extents
;;;;======================== LOW LEVEL INPUT =======================================
;(defconstant byte0 (byte 8 0))
;(defconstant byte1 (byte 8 8))
;(defconstant byte2 (byte 8 16))
;(defconstant byte3 (byte 8 24))
(#-(or :allegro :lispworks) defsubst #+(or :allegro :lispworks) defun read-byte8 (stream)
"read an unsigned 8 bit value from the stream."
(read-byte stream))
(#-(or :allegro :lispworks) defsubst #+(or :allegro :lispworks) defun READ-BYTE16 (STREAM)
"read an unsigned 16 bit value from the stream."
(DPB (READ-BYTE STREAM) BYTE0
(DPB (READ-BYTE STREAM) BYTE1 *WORD*)))
(#-(or :allegro :lispworks) defsubst #+(or :allegro :lispworks) defun READ-INT16 (STREAM)
"read a signed 16 bit value from the stream."
(LET ((*TEMP* (READ-BYTE16 STREAM)))
(IF (> *TEMP* 32768)
(- *TEMP* 65536)
*TEMP*)))
(#-(or :allegro :lispworks) defsubst #+(or :allegro :lispworks) defun READ-BYTE32 (STREAM)
"read an unsigned 32 bit value from the stream.
Depends on left-to-right evaluation order
Abelson & Sussman forgive us."
(DPB (READ-BYTE STREAM) BYTE0
(DPB (READ-BYTE STREAM) BYTE1
(DPB (READ-BYTE STREAM) BYTE2
(DPB (READ-BYTE STREAM) BYTE3 *WORD*)))))
(#-(or :allegro :lispworks) defsubst #+(or :allegro :lispworks) defun read-string-n (stream length)
(let* ((len (max 0 (1- length)))
(string (make-array len :element-type 'string-char)))
(dotimes (i len)
(setf (aref string i) (read-char stream)))
(read-char stream) ;discard the 0 byte
string))
(#-(or :allegro :lispworks) defsubst #+(or :allegro :lispworks) defun READ-VAX-F-FLOAT-TO-SINGLE-FLOAT (STREAM)
"Convert vax-f-float to single-float
mem: byte0, byte1, byte2 byte3 memory order low to low+3
vax: lo-byte hi-byte lo-byte hi-byte (half-word)
hi-mant s/exp mid-mant lo-mant (f-float)
ti: hi-byte lo-byte hi lo (half-word)
in: 3 2 1 0
lo-mant mid-mant s/exp hi-mant (single-float)
store: 1 0 3 2
1. words. 2. subtract 2 to convert excess-128
to excess 127--why 2???"
(SETF *TEMP*
(DPB (READ-BYTE STREAM) BYTE2
(DPB (READ-BYTE STREAM) BYTE3
(DPB (READ-BYTE STREAM) BYTE0
(DPB (READ-BYTE STREAM) BYTE1 *WORD*)))))
;;is exponent less than 4?
(IF (ZEROP (LDB S-F-EXPONENT-HIGH-BITS *TEMP*))
;;ok is it zero, then leave it alone
(IF (ZEROP (LDB S-F-EXPONENT *TEMP*))
*TEMP*
;; else make it 1
(DPB MIN-EXP S-F-EXPONENT *TEMP*))
(DPB (- (LDB S-F-EXPONENT *TEMP*) 2) S-F-EXPONENT *TEMP*)))
(defconstant c255 (code-char 255))
(#-(or :allegro :lispworks) defsubst #+(or :allegro :lispworks) defun READ-STRING-N-DISCARDING-255 (STREAM LENGTH)
"THis one cannot be used for anything but pointer (string)
data. Don't use it for getting string-length for example."
(LET* ((LEN (MAX 0 (1- LENGTH)))
(STRING (MAKE-ARRAY LEN :ELEMENT-TYPE 'STRING-CHAR))
(CHAR NIL))
(DOTIMES (I LEN)
(SETF CHAR (READ-CHAR STREAM))
(WHEN (char= CHAR C255)
(SETF CHAR #\SPACE))
(SETF (AREF STRING I) CHAR))
(READ-CHAR STREAM)
STRING))
(#-(or :allegro :lispworks) defsubst #+(or :allegro :lispworks) defun read-isr-string (stream)
"read in and return a string from the stream. The ISR currently stores strings
as a length followed by the string, with ends with a 0 byte."
(read-string-n stream (read-byte16 stream)))
;;;;======================= INTERMEDIATE LEVEL INPUT ==============================
(defmacro package-read-from-string (string &optional (pkg nil package-p))
"read from string into with *package* optionally set"
(if package-p
`(let ((*package* (find-package ,pkg)))
(read-from-string ,string))
`(read-from-string ,string)))
(defmacro read-isr-name (stream &optional (pkg nil package-p))
"read name, ignore the $ at the end"
(if package-p
`(package-read-from-string (string-right-trim '(#\$) (read-isr-string ,stream)) ,pkg)
`(package-read-from-string (string-right-trim '(#\$) (read-isr-string ,stream)))))
(defmacro read-sexpr (stream &optional (pkg nil package-p))
"read in a string from the stream and and then read from that
string with the current package optionally defined."
(if package-p
`(package-read-from-string (read-isr-string ,stream) ,pkg)
`(package-read-from-string (read-isr-string ,stream))))
(defmacro read-sexpr-n (stream length &optional (pkg nil package-p))
"read in a string with length n from the stream and and then
read from that string with the current package optionally defined."
(if package-p
`(package-read-from-string (read-string-n-discarding-255 ,stream ,length) ,pkg)
`(package-read-from-string (read-string-n-discarding-255 ,stream ,length))))
(defun read-extents (stream)
"read in extents from the stream and return an extents structure"
(let (#+:EXPLORER (default-cons-area *bitplane-area*))
#+:EXPLORER (declare (special default-cons-area))
(let ((ext (make-extents-struct)))
(setf (extents-byte-bound ext) (read-int16 stream))
(setf (extents-byte-width ext) (read-byte16 stream))
(setf (extents-minx ext) (read-int16 stream))
(setf (extents-miny ext) (read-int16 stream))
(setf (extents-maxx ext) (read-int16 stream))
(setf (extents-maxy ext) (read-int16 stream))
(setf (extents-pixel-count ext) (read-byte16 stream))
ext)))
(defun read-bitplane (stream extents)
"read in bitplane having given extents from the stream and return a bitplane array.
Bitplane is padded so that it is always a multiple of 32 bits wide.
hackery alert!!, extents may be modified as a side-effect."
(let ((numbytes (read-byte32 stream)))
(if (not (zerop numbytes))
(progn
(let ((byte-width (extents-byte-width extents))
(height (1+ (- (extents-maxy extents) (extents-miny extents)))))
(if (not (= numbytes (* height byte-width)))
(error "number of bytes in bitplane is ~d, it should be ~d"
numbytes (* height byte-width))
;;else read in the bitplane, padding it accordingly
(let ((new-byte-width (* 4 (ceiling byte-width 4))) ;next highest multiple of 32 bits
#+:EXPLORER (default-cons-area *bitplane-area*))
#+:EXPLORER (declare (special default-cons-area))
(let ((bitplane
(make-array (list height new-byte-width) :element-type '(unsigned-byte 8))))
(dotimes (y height)
(dotimes (x byte-width)
(setf (aref bitplane y x)
(read-byte8 stream)))) ;read in bitplane
(setf (extents-byte-width extents) new-byte-width)
(make-array (list height (* 8 new-byte-width))
:element-type 'bit
:displaced-to bitplane))))))
*ptr-undefined*)
)
)
(defun read-isr1-lexicon (stream)
"read in a isr1-lexicon definition from the stream. Returns a isr1-lexicon structure."
(let ((lex (make-isr1-lexicon)))
(setf (isr1-lexicon-name lex) (read-sexpr stream "ISR")) ;; instead of simple-name
(setf (isr1-lexicon-doc lex) (read-isr-string stream))
(setf (isr1-lexicon-num-feature-slots lex) (read-byte16 stream))
(setf (isr1-lexicon-num-feature-count lex) (read-byte16 stream))
(setf (isr1-lexicon-ptr-feature-slots lex) (read-byte16 stream))
(setf (isr1-lexicon-ptr-feature-count lex) (read-byte16 stream))
(setf (isr1-lexicon-ext-feature-slots lex) 1)
(setf (isr1-lexicon-ext-feature-count lex) 1)
(setf (isr1-lexicon-bp-feature-slots lex) 1)
(setf (isr1-lexicon-bp-feature-count lex) 1)
(let ((total-count (+ 2 (isr1-lexicon-num-feature-count lex) (isr1-lexicon-ptr-feature-count lex))))
;; get ready for creating the feature table
(let ((name-array (make-array total-count :element-type t))
(function-array (make-array total-count :element-type t))
(datatype-array (make-array total-count :element-type '(unsigned-byte 8)))
(index-array (make-array total-count :element-type '(unsigned-byte 16))))
;; read feature names and function names into user package
;; read in feature names
(dotimes (i total-count) (setf (aref name-array i) (read-sexpr stream "ISR")))
(let ((*package* (find-package "USER")))
;; read in feature functions
(dotimes (i total-count) (setf (aref function-array i) (read-sexpr stream))))
;; read in datatypes
(dotimes (i total-count) (setf (aref datatype-array i) (read-byte8 stream)))
;; read in feature indices
(dotimes (i total-count) (setf (aref index-array i) (read-byte16 stream)))
(setf (isr1-lexicon-name-array lex) name-array
(isr1-lexicon-datatype-array lex) datatype-array
(isr1-lexicon-index-array lex) index-array
(isr1-lexicon-function-array lex) function-array
)))
lex))
(defvar user::*isrread$dir* "")
(defun read-isr1-feature-data (filename &optional default-directory)
"READ-ISR1-FEATURE-DATA filename &OPTIONAL default-directory - Read an
old (ISR1) feature data file into the ISR2 DataBase. The image name is
used as the name of a frame under root and the tokenset name is used as a
name of a frame feature (also a frame) under the imagename frame. The image
name frame is created if it does not exist. If the tokenset name exists as
a frame feature an error is generated."
(declare (special user::*isrread$dir*))
(declare (arglist (filename &optional (default-directory user::*isrread$dir*))))
(when (and (not default-directory) (boundp 'user::*isrread$dir*))
(setq default-directory user::*isrread$dir*))
(with-open-file (file (merge-pathnames filename default-directory)
:direction :input
:element-type '(unsigned-byte 8))2
(let* ((imagename (read-isr-name file "ISR2"))
(image-frame-handle (or (let ((h (%internal-handle imagename
:error-p nil :terminal-p t)))
(if (handle-p h) h nil))
(create imagename)))
(tokensetname (read-isr-name file "ISR2"))
(isr1-lexicon (read-isr1-lexicon file))
(tokenset-handle (create (list image-frame-handle tokensetname)))
(tokcount (read-byte32 file))
(name-array (isr1-lexicon-name-array isr1-lexicon))
(datatype-array (isr1-lexicon-datatype-array isr1-lexicon))
(index-array (isr1-lexicon-index-array isr1-lexicon))
(function-array (isr1-lexicon-function-array isr1-lexicon))
(num-feature-slots (isr1-lexicon-num-feature-slots isr1-lexicon))
(ptr-feature-slots (isr1-lexicon-ptr-feature-slots isr1-lexicon))
(dummy-token-handle (make-handle :type :token
:frame (handle-frame tokenset-handle)
:token :?))
num-names num-types
ptr-names
)
(read-byte32 file) ;count of token slots goes into the bitbucket
(setf #|(value (list image-frame-handle tokensetname "F_DOCUMENTATION"))
(isr1-lexicon-doc isr1-lexicon) |#
(value (list tokenset-handle "DOCUMENTATION"))
(isr1-lexicon-doc isr1-lexicon)
)
(map nil
#'(lambda (fname datatype function)
(define-feature (list dummy-token-handle fname)
(format nil "On-Demand function was ~A" function)
(case datatype
(#.*int* :integer)
(#.*real* :real)
(#.*extents* :extents)
(#.*bitplane* :bitplane)
(#.*pointer* :pointer))))
name-array datatype-array function-array)
(multiple-value-setq (num-names num-types ptr-names)
(map-and-extract-feature-block name-array datatype-array index-array
num-feature-slots ptr-feature-slots))
(define-pixelmap-feature
(list tokenset-handle "<?>pixelmap")
"Pixelmap feature (composite feature of EXTENTS and BITPLANE)"
)
;; read in tokens, keeping track of the highest index
(do ((i (max tokcount 0) (1- i))
(curtok -1)
token-handle
)
((zerop i) curtok)
(setf curtok (read-byte32 file))
(setf token-handle (create (list tokenset-handle curtok)))
(READ-EXTENTS-AND-BITPLANE file token-handle)
(READ-NUMERIC-FEATURES file token-handle num-names num-types)
(READ-POINTER-FEATURES file token-handle ptr-names))
)
)
)
(defun map-and-extract-feature-block (names datatypes indexes num-count ptr-count)
(let ((num-names (make-array num-count))
(num-types (make-array num-count))
(ptr-names (make-array ptr-count)))
(dotimes (i (length names))
(cond ((= (aref datatypes i) *pointer*)
(setf (aref ptr-names (aref indexes i)) (aref names i)))
((or (= (aref datatypes i) *int*)
(= (aref datatypes i) *real*))
(setf (aref num-names (aref indexes i)) (aref names i)
(aref num-types (aref indexes i)) (aref datatypes i)
)
)
))
(values num-names num-types ptr-names)
)
)
(defun READ-EXTENTS-AND-BITPLANE (stream token-handle)
(let* ((extents (read-extents stream))
(bitplane (read-bitplane stream extents)))
(setf (value (list token-handle "EXTENTS")) (if (zerop (extents-pixel-count
extents))
*ptr-undefined*
extents)
(value (list token-handle "BITPLANE")) bitplane)
)
)
(defun READ-NUMERIC-FEATURES (stream token-handle name-array datatype-array
&aux value (value-union (make-array 1 :element-type '(unsigned-byte 32)))
(ival (make-array 1 :element-type 'fixnum
:displaced-to value-union))
(fval (make-array 1 :element-type 'single-float
:displaced-to value-union))
)
(map nil #'(lambda (name datatype)
(cond ((null datatype) (read-byte32 stream))
((= datatype *int*)
(setf value (READ-BYTE32 stream))
(case value
(#.*vax-numeric-undefined* nil)
(#.*vax-numeric-undefinable*
(setf (value (list token-handle name))
*int-undefinable*))
(t (setf (aref value-union 0) value
(value (list token-handle name))
(aref ival 0)))))
((= datatype *real*)
(setf value (READ-VAX-F-FLOAT-TO-SINGLE-FLOAT stream))
#|(break "~&Reading (~S ~S): value = ~8,'0x" token-handle
name value)|#
(case value
(#.*vax-bonked-numeric-undefined* nil)
(#.*vax-bonked-numeric-undefinable*
(setf (value (list token-handle name))
*real-undefinable*))
(t (setf (aref value-union 0) value
(value (list token-handle name))
(aref fval 0)))))
(t t))
)
name-array
datatype-array)
)
(eval-when (compile load eval)
(defconstant ptr-feature-defined?-field (byte 1 0)))
(defconstant ptr-feature-length-field (byte 15 1))
(defconstant ptr-is-defined (dpb 1 ptr-feature-defined?-field 0))
(defmacro ptr-feature-defined? (ptr-header) `(plusp (ldb ptr-feature-defined?-field ,ptr-header)))
(defmacro ptr-feature-length (ptr-header) `(ldb ptr-feature-length-field ,ptr-header))
(defun READ-POINTER-FEATURES (stream token-handle name-array
&aux ptr-header (*package* (find-package "USER")))
(map nil #'(lambda (name)
(when (ptr-feature-defined?
(setf ptr-header (read-byte16 stream)))
(setf (value (list token-handle name))
(read-sexpr-n stream (ptr-feature-length ptr-header))))
)
name-array
)
)