;;; -*- Mode:LISP; Package:TIGER; Base:8; Fonts:(CPTFONT TR12I); Readtable:T -*- ; Copyright LISP Machine, Inc. 1984 ; See filename "Copyright" for ; licensing and release information. (defconst aray-check-string "ARAY" "First characters of any array dump file.") (defconst aray-version-number 1 "Current version number of ARAY file format.") (defvar aray-serial-number 0 "Number of array files dumped to tape during this session.") (defsubst print-word (word stream) (send stream :tyo (ldb #O0010 word)) (send stream :tyo (ldb #O1010 word)) (send stream :tyo (ldb #O2007 word)) (send stream :tyo 0)) (defsubst read-word (stream) (prog1 (dpb (send stream :tyi) #O0010 (dpb (send stream :tyi) #O1010 (dpb (send stream :tyi) #O2007 0))) (send stream :tyi))) (defun dump-pixel-array-to-file (filename array &optional left top right bottom) (with-open-file (stream filename :direction :output :characters nil :byte-size 8.) (dump-pixel-array-to-stream stream array left top right bottom))) (defflavor kount-em ((kount 0)) () :gettable-instance-variables) (defmethod (kount-em :tyo) (ignore) (incf kount)) (defmethod (kount-em :string-out) (string &optional (start 0) (end (array-active-length string))) (incf kount (- end start))) (defun dump-pixel-array-to-tape (filename array &optional left top right bottom) (let ((pathname (fs:merge-pathname-defaults filename)) (length-in-bytes (let ((x (make-instance 'kount-em))) (dump-pixel-array-to-stream x array left top right bottom) (send x :kount)))) (with-open-stream (mt (fs:make-mt-file-stream :characters nil :direction :output :plist (list :characters nil :directory (send pathname :directory) :name (string-append (send pathname :name) (format nil "-~D" (incf aray-serial-number))) :type (send pathname :type) :version (send pathname :version) :author (status userid) :creation-date (time:get-universal-time) :length-in-bytes length-in-bytes :length length-in-bytes :byte-size 8.))) (dump-pixel-array-to-stream mt array left top right bottom)))) (defun dump-pixel-array-to-stream (stream array &optional left top right bottom) (cond ((typep array 'array) (unless left (setq left 0)) (unless top (setq top 0)) (unless right (setq right (pixel-array-width array))) (unless bottom (setq bottom (pixel-array-height array)))) ((typep array 'tv:minimum-window) (multiple-value-bind (new-left new-top new-right new-bottom) (send array :edges) (unless (setq array (send array :screen-array)) (ferror nil "The array argument is a window with no screen array.")) (unless left (setq left new-left)) (unless top (setq top new-top)) (unless right (setq right new-right)) (unless bottom (setq bottom new-bottom)))) (t (ferror nil "The array argument is not an array or window."))) (unless (zerop (remainder (pixel-array-width array) 32.)) (ferror nil "The array argument has rows which are not a multiple of 32. bits long.")) (multiple-value-bind (words-before-left new-left) (floor left 32.) (let* ((width (pixel-array-width array)) (height (pixel-array-height array)) (new-right (- right (* words-before-left 32.))) (new-top 0) (new-bottom (- bottom top)) (new-width (* (ceiling new-right 32.) 32.)) (new-height new-bottom) (bytes-before-left (* words-before-left 4)) (output-bytes-per-row (floor new-width 8.)) (bytes-per-row (floor width 8.)) (array-size-in-bytes (// (* width height) 8.)) (array-8b (make-array array-size-in-bytes :type 'art-8b :displaced-to array))) (send stream :string-out aray-check-string) (print-word aray-version-number stream) (print-word new-width stream) (print-word new-height stream) (print-word new-left stream) (print-word new-top stream) (print-word new-right stream) (print-word new-bottom stream) (loop for byte from bytes-before-left below array-size-in-bytes by bytes-per-row do (send stream :string-out array-8b byte (+ byte output-bytes-per-row)))))) (defun restore-pixel-array-from-file (filename &optional array &aux temp) (with-open-file (stream filename :direction :input) (setq temp (multiple-value-list (restore-pixel-array-from-stream stream array)))) (values-list temp)) (defun restore-pixel-array-from-tape (&optional array &aux temp) (with-open-stream (mt (fs:make-mt-file-stream :direction :input)) (setq temp (multiple-value-list (restore-pixel-array-from-stream mt array)))) (values-list temp)) (defun restore-pixel-array-from-stream (stream &optional array) (let ((check-string (make-array 4 :type 'art-string))) (send stream :string-in t check-string) (when (not (string-equal check-string aray-check-string)) (ferror nil "The specified file is not a dumped array file."))) (when (neq (read-word stream) aray-version-number) (ferror nil "The version number of the array file is not 1.")) (let* ((width (read-word stream)) (height (read-word stream)) (left (read-word stream)) (top (read-word stream)) (right (read-word stream)) (bottom (read-word stream)) (array-to-use (cond (array (setq array (adjust-tiger-array-size array width height))) (t (tv:make-pixel-array width height :type 'art-1b)))) (array-8b (make-array (floor (* width height) 8.) :type 'art-8b :displaced-to array-to-use))) (send stream :string-in t array-8b) (values array-to-use left top right bottom)))