home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Source Code 1993 July / THE_SOURCE_CODE_CD_ROM.iso / X / mit / lib / CLX / image.l < prev    next >
Encoding:
Text File  |  1991-08-18  |  100.0 KB  |  2,667 lines

  1. ;;; -*- Mode:Lisp; Package:XLIB; Syntax:COMMON-LISP; Base:10; Lowercase:T -*-
  2.  
  3. ;;; CLX Image functions
  4.  
  5. ;;;
  6. ;;;             TEXAS INSTRUMENTS INCORPORATED
  7. ;;;                  P.O. BOX 2909
  8. ;;;                   AUSTIN, TEXAS 78769
  9. ;;;
  10. ;;; Copyright (C) 1987 Texas Instruments Incorporated.
  11. ;;;
  12. ;;; Permission is granted to any individual or institution to use, copy, modify,
  13. ;;; and distribute this software, provided that this complete copyright and
  14. ;;; permission notice is maintained, intact, in all copies and supporting
  15. ;;; documentation.
  16. ;;;
  17. ;;; Texas Instruments Incorporated provides this software "as is" without
  18. ;;; express or implied warranty.
  19. ;;;
  20.  
  21. (in-package :xlib)
  22.  
  23. (defmacro with-image-data-buffer ((buffer size) &body body)
  24.   (declare (indentation 0 4 1 1))
  25.   `(let ((.reply-buffer. (allocate-reply-buffer ,size)))
  26.      (declare (type reply-buffer .reply-buffer.))
  27.      (unwind-protect
  28.      (let ((,buffer (reply-ibuf8 .reply-buffer.)))
  29.        (declare (type buffer-bytes ,buffer))
  30.        (with-vector (,buffer buffer-bytes)
  31.          ,@body))
  32.        (deallocate-reply-buffer .reply-buffer.))))
  33.  
  34. (def-clx-class (image (:constructor nil) (:copier nil) (:predicate nil))
  35.   ;; Public structure
  36.   (width 0 :type card16 :read-only t)
  37.   (height 0 :type card16 :read-only t)
  38.   (depth 1 :type card8 :read-only t)
  39.   (plist nil :type list))
  40.  
  41. ;; Image-Plist accessors:
  42. (defmacro image-name (image) `(getf (image-plist ,image) :name))
  43. (defmacro image-x-hot (image) `(getf (image-plist ,image) :x-hot))
  44. (defmacro image-y-hot (image) `(getf (image-plist ,image) :y-hot))
  45. (defmacro image-red-mask (image) `(getf (image-plist ,image) :red-mask))
  46. (defmacro image-blue-mask (image) `(getf (image-plist ,image) :blue-mask))
  47. (defmacro image-green-mask (image) `(getf (image-plist ,image) :green-mask))
  48.  
  49. (defun print-image (image stream depth)
  50.   (declare (type image image)
  51.        (ignore depth))
  52.   (print-unreadable-object (image stream :type t)
  53.     (when (image-name image)
  54.       (write-string (string (image-name image)) stream)
  55.       (write-string " " stream))
  56.     (prin1 (image-width image) stream)
  57.     (write-string "x" stream)
  58.     (prin1 (image-height image) stream)
  59.     (write-string "x" stream)
  60.     (prin1 (image-depth image) stream)))
  61.  
  62. (defconstant *empty-data-x* '#.(make-sequence '(array card8 (*)) 0))
  63.  
  64. (defconstant *empty-data-z*
  65.          '#.(make-array '(0 0) :element-type 'pixarray-1-element-type))
  66.  
  67. (def-clx-class (image-x (:include image) (:copier nil)
  68.             (:print-function print-image))
  69.   ;; Use this format for shoveling image data
  70.   ;; Private structure. Accessors for these NOT exported.
  71.   (format :z-pixmap :type (member :bitmap :xy-pixmap :z-pixmap))
  72.   (bytes-per-line 0 :type card16)
  73.   (bits-per-pixel 1 :type (member 1 4 8 16 24 32))
  74.   (bit-lsb-first-p *image-bit-lsb-first-p* :type boolean)    ; Bit order
  75.   (byte-lsb-first-p *image-byte-lsb-first-p* :type boolean)    ; Byte order
  76.   (data *empty-data-x* :type (array card8 (*)))            ; row-major
  77.   (unit *image-unit* :type (member 8 16 32))            ; Bitmap unit
  78.   (pad *image-pad* :type (member 8 16 32))            ; Scanline pad
  79.   (left-pad 0 :type card8))                    ; Left pad
  80.  
  81. (def-clx-class (image-xy (:include image) (:copier nil)
  82.              (:print-function print-image))
  83.   ;; Public structure
  84.   ;; Use this format for image processing
  85.   (bitmap-list nil :type list)) ;; list of bitmaps
  86.  
  87. (def-clx-class (image-z (:include image) (:copier nil)
  88.             (:print-function print-image))
  89.   ;; Public structure
  90.   ;; Use this format for image processing
  91.   (bits-per-pixel 1 :type (member 1 4 8 16 24 32))
  92.   (pixarray *empty-data-z* :type pixarray))
  93.  
  94. (defun create-image (&key width height depth
  95.              (data (required-arg data))
  96.              plist name x-hot y-hot
  97.              red-mask blue-mask green-mask
  98.              bits-per-pixel format bytes-per-line
  99.              (byte-lsb-first-p 
  100.                #+clx-little-endian t
  101.                #-clx-little-endian nil)
  102.              (bit-lsb-first-p
  103.                #+clx-little-endian t
  104.                #-clx-little-endian nil)
  105.              unit pad left-pad)
  106.   ;; Returns an image-x image-xy or image-z structure, depending on the
  107.   ;; type of the :DATA parameter.
  108.   (declare
  109.     (type (or null card16) width height)    ; Required
  110.     (type (or null card8) depth)        ; Defualts to 1
  111.     (type (or buffer-bytes            ; Returns image-x
  112.           list                ; Returns image-xy
  113.           pixarray) data)            ; Returns image-z
  114.     (type list plist)
  115.     (type (or null stringable) name)
  116.     (type (or null card16) x-hot y-hot)
  117.     (type (or null pixel) red-mask blue-mask green-mask)
  118.     (type (or null (member 1 4 8 16 24 32)) bits-per-pixel)
  119.     
  120.     ;; The following parameters are ignored for image-xy and image-z:
  121.     (type (or null (member :bitmap :xy-pixmap :z-pixmap))
  122.       format)                ; defaults to :z-pixmap
  123.     (type (or null card16) bytes-per-line)
  124.     (type boolean byte-lsb-first-p bit-lsb-first-p)
  125.     (type (or null (member 8 16 32)) unit pad)
  126.     (type (or null card8) left-pad))
  127.   (declare (values image))
  128.   (let ((image
  129.       (etypecase data
  130.         (buffer-bytes            ; image-x
  131.           (let ((data data))
  132.         (declare (type buffer-bytes data))
  133.         (unless depth (setq depth (or bits-per-pixel 1)))
  134.         (unless format
  135.           (setq format (if (= depth 1) :xy-pixmap :z-pixmap)))
  136.         (unless bits-per-pixel
  137.           (setq bits-per-pixel
  138.             (cond ((eq format :xy-pixmap) 1)
  139.                   ((index> depth 24) 32)
  140.                   ((index> depth 16) 24)
  141.                   ((index> depth 8)  16)
  142.                   ((index> depth 4)   8)
  143.                   ((index> depth 1)   4)
  144.                   (t                  1))))
  145.         (unless width (required-arg width))
  146.         (unless height (required-arg height))
  147.         (unless bytes-per-line
  148.           (let* ((pad (or pad 8))
  149.              (bits-per-line (index* width bits-per-pixel))
  150.              (padded-bits-per-line
  151.                (index* (index-ceiling bits-per-line pad) pad)))
  152.             (declare (type array-index pad bits-per-line
  153.                    padded-bits-per-line))
  154.             (setq bytes-per-line (index-ceiling padded-bits-per-line 8))))
  155.         (unless unit (setq unit *image-unit*))
  156.         (unless pad
  157.           (setq pad
  158.             (dolist (pad '(32 16 8))
  159.               (when (and (index<= pad *image-pad*)
  160.                      (zerop
  161.                        (index-mod
  162.                      (index* bytes-per-line 8) pad)))
  163.                 (return pad)))))
  164.         (unless left-pad (setq left-pad 0))
  165.         (make-image-x
  166.           :width width :height height :depth depth :plist plist
  167.           :format format :data data
  168.           :bits-per-pixel bits-per-pixel 
  169.           :bytes-per-line bytes-per-line
  170.           :byte-lsb-first-p byte-lsb-first-p
  171.           :bit-lsb-first-p bit-lsb-first-p
  172.           :unit unit :pad pad :left-pad left-pad)))
  173.         (list                ; image-xy
  174.           (let ((data data))
  175.         (declare (type list data))
  176.         (unless depth (setq depth (length data)))
  177.         (when data
  178.           (unless width (setq width (array-dimension (car data) 1)))
  179.           (unless height (setq height (array-dimension (car data) 0))))
  180.         (make-image-xy
  181.           :width width :height height :plist plist :depth depth
  182.           :bitmap-list data)))
  183.         (pixarray                ; image-z
  184.           (let ((data data))
  185.         (declare (type pixarray data))
  186.         (unless width (setq width (array-dimension data 1)))
  187.         (unless height (setq height (array-dimension data 0)))
  188.         (unless bits-per-pixel
  189.           (setq bits-per-pixel
  190.             (etypecase data
  191.               (pixarray-32 32)
  192.               (pixarray-24 24)
  193.               (pixarray-16 16)
  194.               (pixarray-8   8)
  195.               (pixarray-4   4)
  196.               (pixarray-1   1)))))
  197.           (unless depth (setq depth bits-per-pixel))
  198.           (make-image-z
  199.         :width width :height height :depth depth :plist plist
  200.         :bits-per-pixel bits-per-pixel :pixarray data)))))
  201.     (declare (type image image))
  202.     (when name (setf (image-name image) name))
  203.     (when x-hot (setf (image-x-hot image) x-hot))
  204.     (when y-hot (setf (image-y-hot image) y-hot))
  205.     (when red-mask (setf (image-red-mask image) red-mask))
  206.     (when blue-mask (setf (image-blue-mask image) blue-mask))
  207.     (when green-mask (setf (image-green-mask image) green-mask))
  208.     image))
  209.  
  210. ;;;-----------------------------------------------------------------------------
  211. ;;; Swapping stuff
  212.  
  213. (defun image-noswap
  214.        (src dest srcoff destoff srclen srcinc destinc height lsb-first-p)
  215.   (declare (type buffer-bytes src dest)
  216.        (type array-index srcoff destoff srclen srcinc destinc)
  217.        (type card16 height)
  218.        (type boolean lsb-first-p)
  219.        (ignore lsb-first-p))
  220.   #.(declare-buffun)
  221.   (if (index= srcinc destinc)
  222.       (buffer-replace
  223.     dest src destoff
  224.     (index+ destoff (index* srcinc (index1- height)) srclen)
  225.     srcoff)
  226.     (do* ((h height (index1- h))
  227.       (srcstart srcoff (index+ srcstart srcinc))
  228.       (deststart destoff (index+ deststart destinc))
  229.       (destend (index+ deststart srclen) (index+ deststart srclen)))
  230.      ((index-zerop h))
  231.       (declare (type array-index srcstart deststart destend)
  232.            (type card16 h))
  233.       (buffer-replace dest src deststart destend srcstart))))
  234.  
  235. (defun image-swap-two-bytes
  236.        (src dest srcoff destoff srclen srcinc destinc height lsb-first-p)
  237.   (declare (type buffer-bytes src dest)
  238.        (type array-index srcoff destoff srclen srcinc destinc)
  239.        (type card16 height)
  240.        (type boolean lsb-first-p))
  241.   #.(declare-buffun)
  242.   (with-vector (src buffer-bytes)
  243.     (with-vector (dest buffer-bytes)
  244.       (do ((length (index* (index-ceiling srclen 2) 2))
  245.        (h height (index1- h))
  246.        (srcstart srcoff (index+ srcstart srcinc))
  247.        (deststart destoff (index+ deststart destinc)))
  248.       ((index-zerop h))
  249.     (declare (type array-index length srcstart deststart)
  250.          (type card16 h))
  251.     (when (and (index= h 1) (not (index= srclen length)))
  252.       (index-decf length 2)
  253.       (if lsb-first-p
  254.           (setf (aref dest (index1+ (index+ deststart length)))
  255.             (the card8 (aref src (index+ srcstart length))))
  256.         (setf (aref dest (index+ deststart length))
  257.           (the card8 (aref src (index1+ (index+ srcstart length)))))))
  258.     (do ((i length (index- i 2))
  259.          (srcidx srcstart (index+ srcidx 2))
  260.          (destidx deststart (index+ destidx 2)))
  261.         ((index-zerop i))
  262.       (declare (type array-index i srcidx destidx))
  263.       (setf (aref dest destidx)
  264.         (the card8 (aref src (index1+ srcidx))))
  265.       (setf (aref dest (index1+ destidx))
  266.         (the card8 (aref src srcidx))))))))
  267.  
  268. (defun image-swap-three-bytes
  269.        (src dest srcoff destoff srclen srcinc destinc height lsb-first-p)
  270.   (declare (type buffer-bytes src dest)
  271.        (type array-index srcoff destoff srclen srcinc destinc)
  272.        (type card16 height)
  273.        (type boolean lsb-first-p))
  274.   #.(declare-buffun)
  275.   (with-vector (src buffer-bytes)
  276.     (with-vector (dest buffer-bytes)
  277.       (do ((length (index* (index-ceiling srclen 3) 3))
  278.        (h height (index1- h))
  279.        (srcstart srcoff (index+ srcstart srcinc))
  280.        (deststart destoff (index+ deststart destinc)))
  281.       ((index-zerop h))
  282.     (declare (type array-index length srcstart deststart)
  283.          (type card16 h))
  284.     (when (and (index= h 1) (not (index= srclen length)))
  285.       (index-decf length 3)
  286.       (when (index= (index- srclen length) 2)
  287.         (setf (aref dest (index+ deststart length 1))
  288.           (the card8 (aref src (index+ srcstart length 1)))))
  289.       (if lsb-first-p
  290.           (setf (aref dest (index+ deststart length 2))
  291.             (the card8 (aref src (index+ srcstart length))))
  292.         (setf (aref dest (index+ deststart length))
  293.           (the card8 (aref src (index+ srcstart length 2))))))
  294.     (do ((i length (index- i 3))
  295.          (srcidx srcstart (index+ srcidx 3))
  296.          (destidx deststart (index+ destidx 3)))
  297.         ((index-zerop i))
  298.       (declare (type array-index i srcidx destidx))
  299.       (setf (aref dest destidx)
  300.         (the card8 (aref src (index+ srcidx 2))))
  301.       (setf (aref dest (index1+ destidx))
  302.         (the card8 (aref src (index1+ srcidx))))
  303.       (setf (aref dest (index+ destidx 2))
  304.         (the card8 (aref src srcidx))))))))
  305.  
  306. (defun image-swap-four-bytes
  307.        (src dest srcoff destoff srclen srcinc destinc height lsb-first-p)
  308.   (declare (type buffer-bytes src dest)
  309.        (type array-index srcoff destoff srclen srcinc destinc)
  310.        (type card16 height)
  311.        (type boolean lsb-first-p))
  312.   #.(declare-buffun)
  313.   (with-vector (src buffer-bytes)
  314.     (with-vector (dest buffer-bytes)
  315.       (do ((length (index* (index-ceiling srclen 4) 4))
  316.        (h height (index1- h))
  317.        (srcstart srcoff (index+ srcstart srcinc))
  318.        (deststart destoff (index+ deststart destinc)))
  319.       ((index-zerop h))
  320.     (declare (type array-index length srcstart deststart)
  321.          (type card16 h))
  322.     (when (and (index= h 1) (not (index= srclen length)))
  323.       (index-decf length 4)
  324.       (unless lsb-first-p
  325.         (setf (aref dest (index+ deststart length))
  326.           (the card8 (aref src (index+ srcstart length 3)))))
  327.       (when (if lsb-first-p
  328.             (index= (index- srclen length) 3)
  329.           (not (index-zerop (index-logand srclen 2))))
  330.         (setf (aref dest (index+ deststart length 1))
  331.           (the card8 (aref src (index+ srcstart length 2)))))
  332.       (when (if (null lsb-first-p)
  333.             (index= (index- srclen length) 3)
  334.           (not (index-zerop (index-logand srclen 2))))
  335.         (setf (aref dest (index+ deststart length 2))
  336.           (the card8 (aref src (index+ srcstart length 1)))))
  337.       (when lsb-first-p
  338.         (setf (aref dest (index+ deststart length 3))
  339.           (the card8 (aref src (index+ srcstart length))))))
  340.     (do ((i length (index- i 4))
  341.          (srcidx srcstart (index+ srcidx 4))
  342.          (destidx deststart (index+ destidx 4)))
  343.         ((index-zerop i))
  344.       (declare (type array-index i srcidx destidx))
  345.       (setf (aref dest destidx)
  346.         (the card8 (aref src (index+ srcidx 3))))
  347.       (setf (aref dest (index1+ destidx))
  348.         (the card8 (aref src (index+ srcidx 2))))
  349.       (setf (aref dest (index+ destidx 2))
  350.         (the card8 (aref src (index1+ srcidx))))
  351.       (setf (aref dest (index+ destidx 3))
  352.         (the card8 (aref src srcidx))))))))
  353.  
  354. (defun image-swap-words
  355.        (src dest srcoff destoff srclen srcinc destinc height lsb-first-p)
  356.   (declare (type buffer-bytes src dest)
  357.        (type array-index srcoff destoff srclen srcinc destinc)
  358.        (type card16 height)
  359.        (type boolean lsb-first-p))
  360.   #.(declare-buffun)
  361.   (with-vector (src buffer-bytes)
  362.     (with-vector (dest buffer-bytes)
  363.       (do ((length (index* (index-ceiling srclen 4) 4))
  364.        (h height (index1- h))
  365.        (srcstart srcoff (index+ srcstart srcinc))
  366.        (deststart destoff (index+ deststart destinc)))
  367.       ((index-zerop h))
  368.     (declare (type array-index length srcstart deststart)
  369.          (type card16 h))
  370.     (when (and (index= h 1) (not (index= srclen length)))
  371.       (index-decf length 4)
  372.       (unless lsb-first-p
  373.         (setf (aref dest (index+ deststart length 1))
  374.           (the card8 (aref src (index+ srcstart length 3)))))
  375.       (when (if lsb-first-p
  376.             (index= (index- srclen length) 3)
  377.           (not (index-zerop (index-logand srclen 2))))
  378.         (setf (aref dest (index+ deststart length))
  379.           (the card8 (aref src (index+ srcstart length 2)))))
  380.       (when (if (null lsb-first-p)
  381.             (index= (index- srclen length) 3)
  382.           (not (index-zerop (index-logand srclen 2))))
  383.         (setf (aref dest (index+ deststart length 3))
  384.           (the card8 (aref src (index+ srcstart length 1)))))
  385.       (when lsb-first-p
  386.         (setf (aref dest (index+ deststart length 2))
  387.           (the card8 (aref src (index+ srcstart length))))))
  388.     (do ((i length (index- i 4))
  389.          (srcidx srcstart (index+ srcidx 4))
  390.          (destidx deststart (index+ destidx 4)))
  391.         ((index-zerop i))
  392.       (declare (type array-index i srcidx destidx))
  393.       (setf (aref dest destidx)
  394.         (the card8 (aref src (index+ srcidx 2))))
  395.       (setf (aref dest (index1+ destidx))
  396.         (the card8 (aref src (index+ srcidx 3))))
  397.       (setf (aref dest (index+ destidx 2))
  398.         (the card8 (aref src srcidx)))
  399.       (setf (aref dest (index+ destidx 3))
  400.         (the card8 (aref src (index1+ srcidx)))))))))
  401.  
  402. (defun image-swap-nibbles
  403.        (src dest srcoff destoff srclen srcinc destinc height lsb-first-p)
  404.   (declare (type buffer-bytes src dest)
  405.        (type array-index srcoff destoff srclen srcinc destinc)
  406.        (type card16 height)
  407.        (type boolean lsb-first-p)
  408.        (ignore lsb-first-p))
  409.   #.(declare-buffun)
  410.   (with-vector (src buffer-bytes)
  411.     (with-vector (dest buffer-bytes)
  412.       (do ((h height (index1- h))
  413.        (srcstart srcoff (index+ srcstart srcinc))
  414.        (deststart destoff (index+ deststart destinc)))
  415.       ((index-zerop h))
  416.     (declare (type array-index srcstart deststart)
  417.          (type card16 h))
  418.     (do ((i srclen (index1- i))
  419.          (srcidx srcstart (index1+ srcidx))
  420.          (destidx deststart (index1+ destidx)))
  421.         ((index-zerop i))
  422.       (declare (type array-index i srcidx destidx))
  423.       (setf (aref dest destidx)
  424.         (the card8
  425.              (let ((byte (aref src srcidx)))
  426.                (declare (type card8 byte))
  427.                (dpb (the card4 (ldb (byte 4 0) byte))
  428.                 (byte 4 4)
  429.                 (the card4 (ldb (byte 4 4) byte)))))))))))
  430.  
  431. (defun image-swap-nibbles-left
  432.        (src dest srcoff destoff srclen srcinc destinc height lsb-first-p)
  433.   (declare (type buffer-bytes src dest)
  434.        (type array-index srcoff destoff srclen srcinc destinc)
  435.        (type card16 height)
  436.        (type boolean lsb-first-p)
  437.        (ignore lsb-first-p))
  438.   #.(declare-buffun)
  439.   (with-vector (src buffer-bytes)
  440.     (with-vector (dest buffer-bytes)
  441.       (do ((h height (index1- h))
  442.        (srcstart srcoff (index+ srcstart srcinc))
  443.        (deststart destoff (index+ deststart destinc)))
  444.       ((index-zerop h))
  445.     (declare (type array-index srcstart deststart)
  446.          (type card16 h))
  447.     (do ((i srclen (index1- i))
  448.          (srcidx srcstart (index1+ srcidx))
  449.          (destidx deststart (index1+ destidx)))
  450.         ((index= i 1)
  451.          (setf (aref dest destidx)
  452.            (the card8
  453.             (let ((byte1 (aref src srcidx)))
  454.               (declare (type card8 byte1))
  455.               (dpb (the card4 (ldb (byte 4 0) byte1))
  456.                    (byte 4 4)
  457.                    0)))))
  458.       (declare (type array-index i srcidx destidx))
  459.       (setf (aref dest destidx)
  460.         (the card8
  461.              (let ((byte1 (aref src srcidx))
  462.                (byte2 (aref src (index1+ srcidx))))
  463.                (declare (type card8 byte1 byte2))
  464.                (dpb (the card4 (ldb (byte 4 0) byte1))
  465.                 (byte 4 4)
  466.                 (the card4 (ldb (byte 4 4) byte2)))))))))))
  467.  
  468. (defconstant
  469.   *image-byte-reverse*
  470.   '#.(coerce
  471.        '#(
  472.       0 128 64 192 32 160 96 224 16 144 80 208 48 176 112 240
  473.       8 136 72 200 40 168 104 232 24 152 88 216 56 184 120 248
  474.       4 132 68 196 36 164 100 228 20 148 84 212 52 180 116 244
  475.       12 140 76 204 44 172 108 236 28 156 92 220 60 188 124 252
  476.       2 130 66 194 34 162 98 226 18 146 82 210 50 178 114 242
  477.       10 138 74 202 42 170 106 234 26 154 90 218 58 186 122 250
  478.       6 134 70 198 38 166 102 230 22 150 86 214 54 182 118 246
  479.       14 142 78 206 46 174 110 238 30 158 94 222 62 190 126 254
  480.       1 129 65 193 33 161 97 225 17 145 81 209 49 177 113 241
  481.       9 137 73 201 41 169 105 233 25 153 89 217 57 185 121 249
  482.       5 133 69 197 37 165 101 229 21 149 85 213 53 181 117 245
  483.       13 141 77 205 45 173 109 237 29 157 93 221 61 189 125 253
  484.       3 131 67 195 35 163 99 227 19 147 83 211 51 179 115 243
  485.       11 139 75 203 43 171 107 235 27 155 91 219 59 187 123 251
  486.       7 135 71 199 39 167 103 231 23 151 87 215 55 183 119 247
  487.       15 143 79 207 47 175 111 239 31 159 95 223 63 191 127 255)
  488.        '(vector card8)))
  489.  
  490. (defun image-swap-bits
  491.        (src dest srcoff destoff srclen srcinc destinc height lsb-first-p)
  492.   (declare (type buffer-bytes src dest)
  493.        (type array-index srcoff destoff srclen srcinc destinc)
  494.        (type card16 height)
  495.        (type boolean lsb-first-p)
  496.        (ignore lsb-first-p))
  497.   #.(declare-buffun)
  498.   (with-vector (src buffer-bytes)
  499.     (with-vector (dest buffer-bytes)
  500.       (let ((byte-reverse *image-byte-reverse*))
  501.     (with-vector (byte-reverse (simple-array card8 (256)))
  502.       (macrolet ((br (byte)
  503.                `(the card8 (aref byte-reverse (the card8 ,byte)))))
  504.         (do ((h height (index1- h))
  505.          (srcstart srcoff (index+ srcstart srcinc))
  506.          (deststart destoff (index+ deststart destinc)))
  507.         ((index-zerop h))
  508.           (declare (type array-index srcstart deststart)
  509.                (type card16 h))
  510.           (do ((i srclen (index1- i))
  511.            (srcidx srcstart (index1+ srcidx))
  512.            (destidx deststart (index1+ destidx)))
  513.           ((index-zerop i))
  514.         (declare (type array-index i srcidx destidx))
  515.         (setf (aref dest destidx) (br (aref src srcidx)))))))))))
  516.  
  517. (defun image-swap-bits-and-two-bytes
  518.        (src dest srcoff destoff srclen srcinc destinc height lsb-first-p)
  519.   (declare (type buffer-bytes src dest)
  520.        (type array-index srcoff destoff srclen srcinc destinc)
  521.        (type card16 height)
  522.        (type boolean lsb-first-p))
  523.   #.(declare-buffun)
  524.   (with-vector (src buffer-bytes)
  525.     (with-vector (dest buffer-bytes)
  526.       (let ((byte-reverse *image-byte-reverse*))
  527.     (with-vector (byte-reverse (simple-array card8 (256)))
  528.       (macrolet ((br (byte)
  529.                `(the card8 (aref byte-reverse (the card8 ,byte)))))
  530.         (do ((length (index* (index-ceiling srclen 2) 2))
  531.          (h height (index1- h))
  532.          (srcstart srcoff (index+ srcstart srcinc))
  533.          (deststart destoff (index+ deststart destinc)))
  534.         ((index-zerop h))
  535.           (declare (type array-index length srcstart deststart)
  536.                (type card16 h))
  537.           (when (and (index= h 1) (not (index= srclen length)))
  538.         (index-decf length 2)
  539.         (if lsb-first-p
  540.             (setf (aref dest (index1+ (index+ deststart length)))
  541.               (br (aref src (index+ srcstart length))))
  542.           (setf (aref dest (index+ deststart length))
  543.             (br (aref src (index1+ (index+ srcstart length)))))))
  544.           (do ((i length (index- i 2))
  545.            (srcidx srcstart (index+ srcidx 2))
  546.            (destidx deststart (index+ destidx 2)))
  547.           ((index-zerop i))
  548.         (declare (type array-index i srcidx destidx))
  549.         (setf (aref dest destidx)
  550.               (br (aref src (index1+ srcidx))))
  551.         (setf (aref dest (index1+ destidx))
  552.               (br (aref src srcidx)))))))))))
  553.  
  554. (defun image-swap-bits-and-four-bytes
  555.        (src dest srcoff destoff srclen srcinc destinc height lsb-first-p)
  556.   (declare (type buffer-bytes src dest)
  557.        (type array-index srcoff destoff srclen srcinc destinc)
  558.        (type card16 height)
  559.        (type boolean lsb-first-p))
  560.   #.(declare-buffun)
  561.   (with-vector (src buffer-bytes)
  562.     (with-vector (dest buffer-bytes)
  563.       (let ((byte-reverse *image-byte-reverse*))
  564.     (with-vector (byte-reverse (simple-array card8 (256)))
  565.       (macrolet ((br (byte)
  566.                `(the card8 (aref byte-reverse (the card8 ,byte)))))
  567.         (do ((length (index* (index-ceiling srclen 4) 4))
  568.          (h height (index1- h))
  569.          (srcstart srcoff (index+ srcstart srcinc))
  570.          (deststart destoff (index+ deststart destinc)))
  571.         ((index-zerop h))
  572.           (declare (type array-index length srcstart deststart)
  573.                (type card16 h))
  574.           (when (and (index= h 1) (not (index= srclen length)))
  575.         (index-decf length 4)
  576.         (unless lsb-first-p
  577.           (setf (aref dest (index+ deststart length))
  578.             (br (aref src (index+ srcstart length 3)))))
  579.         (when (if lsb-first-p
  580.               (index= (index- srclen length) 3)
  581.             (not (index-zerop (index-logand srclen 2))))
  582.           (setf (aref dest (index+ deststart length 1))
  583.             (br (aref src (index+ srcstart length 2)))))
  584.         (when (if (null lsb-first-p)
  585.               (index= (index- srclen length) 3)
  586.             (not (index-zerop (index-logand srclen 2))))
  587.           (setf (aref dest (index+ deststart length 2))
  588.             (br (aref src (index+ srcstart length 1)))))
  589.         (when lsb-first-p
  590.           (setf (aref dest (index+ deststart length 3))
  591.             (br (aref src (index+ srcstart length))))))
  592.           (do ((i length (index- i 4))
  593.            (srcidx srcstart (index+ srcidx 4))
  594.            (destidx deststart (index+ destidx 4)))
  595.           ((index-zerop i))
  596.         (declare (type array-index i srcidx destidx))
  597.         (setf (aref dest destidx)
  598.               (br (aref src (index+ srcidx 3))))
  599.         (setf (aref dest (index1+ destidx))
  600.               (br (aref src (index+ srcidx 2))))
  601.         (setf (aref dest (index+ destidx 2))
  602.               (br (aref src (index1+ srcidx))))
  603.         (setf (aref dest (index+ destidx 3))
  604.               (br (aref src srcidx)))))))))))
  605.  
  606. (defun image-swap-bits-and-words
  607.        (src dest srcoff destoff srclen srcinc destinc height lsb-first-p)
  608.   (declare (type buffer-bytes src dest)
  609.        (type array-index srcoff destoff srclen srcinc destinc)
  610.        (type card16 height)
  611.        (type boolean lsb-first-p))
  612.   #.(declare-buffun)
  613.   (with-vector (src buffer-bytes)
  614.     (with-vector (dest buffer-bytes)
  615.       (let ((byte-reverse *image-byte-reverse*))
  616.     (with-vector (byte-reverse (simple-array card8 (256)))
  617.       (macrolet ((br (byte)
  618.                `(the card8 (aref byte-reverse (the card8 ,byte)))))
  619.         (do ((length (index* (index-ceiling srclen 4) 4))
  620.          (h height (index1- h))
  621.          (srcstart srcoff (index+ srcstart srcinc))
  622.          (deststart destoff (index+ deststart destinc)))
  623.         ((index-zerop h))
  624.           (declare (type array-index length srcstart deststart)
  625.                (type card16 h))
  626.           (when (and (index= h 1) (not (index= srclen length)))
  627.         (index-decf length 4)
  628.         (unless lsb-first-p
  629.           (setf (aref dest (index+ deststart length 1))
  630.             (br (aref src (index+ srcstart length 3)))))
  631.         (when (if lsb-first-p
  632.               (index= (index- srclen length) 3)
  633.             (not (index-zerop (index-logand srclen 2))))
  634.           (setf (aref dest (index+ deststart length))
  635.             (br (aref src (index+ srcstart length 2)))))
  636.         (when (if (null lsb-first-p)
  637.               (index= (index- srclen length) 3)
  638.             (not (index-zerop (index-logand srclen 2))))
  639.           (setf (aref dest (index+ deststart length 3))
  640.             (br (aref src (index+ srcstart length 1)))))
  641.         (when lsb-first-p
  642.           (setf (aref dest (index+ deststart length 2))
  643.             (br (aref src (index+ srcstart length))))))
  644.           (do ((i length (index- i 4))
  645.            (srcidx srcstart (index+ srcidx 4))
  646.            (destidx deststart (index+ destidx 4)))
  647.           ((index-zerop i))
  648.         (declare (type array-index i srcidx destidx))
  649.         (setf (aref dest destidx)
  650.               (br (aref src (index+ srcidx 2))))
  651.         (setf (aref dest (index1+ destidx))
  652.               (br (aref src (index+ srcidx 3))))
  653.         (setf (aref dest (index+ destidx 2))
  654.               (br (aref src srcidx)))
  655.         (setf (aref dest (index+ destidx 3))
  656.               (br (aref src (index1+ srcidx))))))))))))
  657.  
  658. ;;; The following table gives the bit ordering within bytes (when accessed
  659. ;;; sequentially) for a scanline containing 32 bits, with bits numbered 0 to
  660. ;;; 31, where bit 0 should be leftmost on the display.  For a given byte
  661. ;;; labelled A-B, A is for the most significant bit of the byte, and B is
  662. ;;; for the least significant bit.
  663. ;;; 
  664. ;;; legend:
  665. ;;;     1   scanline-unit = 8
  666. ;;;     2   scanline-unit = 16
  667. ;;;     4   scanline-unit = 32
  668. ;;;     M   byte-order = MostSignificant
  669. ;;;     L   byte-order = LeastSignificant
  670. ;;;     m   bit-order = MostSignificant
  671. ;;;     l   bit-order = LeastSignificant
  672. ;;; 
  673. ;;; 
  674. ;;; format    ordering
  675. ;;; 
  676. ;;; 1Mm    00-07 08-15 16-23 24-31
  677. ;;; 2Mm    00-07 08-15 16-23 24-31
  678. ;;; 4Mm    00-07 08-15 16-23 24-31
  679. ;;; 1Ml    07-00 15-08 23-16 31-24
  680. ;;; 2Ml    15-08 07-00 31-24 23-16
  681. ;;; 4Ml    31-24 23-16 15-08 07-00
  682. ;;; 1Lm    00-07 08-15 16-23 24-31
  683. ;;; 2Lm    08-15 00-07 24-31 16-23
  684. ;;; 4Lm    24-31 16-23 08-15 00-07
  685. ;;; 1Ll    07-00 15-08 23-16 31-24
  686. ;;; 2Ll    07-00 15-08 23-16 31-24
  687. ;;; 4Ll    07-00 15-08 23-16 31-24
  688. ;;; 
  689. ;;; 
  690. ;;; The following table gives the required conversion between any two
  691. ;;; formats.  It is based strictly on the table above.  If you believe one,
  692. ;;; you should believe the other.
  693. ;;; 
  694. ;;; legend:
  695. ;;;     n   no changes
  696. ;;;     s   reverse 8-bit units within 16-bit units
  697. ;;;     l   reverse 8-bit units within 32-bit units
  698. ;;;     w   reverse 16-bit units within 32-bit units
  699. ;;;     r   reverse bits within 8-bit units
  700. ;;;     sr  s+R
  701. ;;;     lr  l+R
  702. ;;;     wr  w+R
  703.  
  704. (defconstant 
  705.   *image-swap-function*
  706.   '#.(make-array
  707.        '(12 12) :initial-contents
  708.        (let ((n  'image-noswap)
  709.          (s  'image-swap-two-bytes)
  710.          (l  'image-swap-four-bytes)
  711.          (w  'image-swap-words)
  712.          (r  'image-swap-bits)
  713.          (sr 'image-swap-bits-and-two-bytes)
  714.          (lr 'image-swap-bits-and-four-bytes)
  715.          (wr 'image-swap-bits-and-words))
  716.      (list #|             1Mm 2Mm 4Mm 1Ml 2Ml 4Ml 1Lm 2Lm 4Lm 1Ll 2Ll 4Ll  |#
  717.            (list #| 1Mm |# n   n   n   r   sr  lr  n   s   l   r   r   r )
  718.            (list #| 2Mm |# n   n   n   r   sr  lr  n   s   l   r   r   r )
  719.            (list #| 4Mm |# n   n   n   r   sr  lr  n   s   l   r   r   r )
  720.            (list #| 1Ml |# r   r   r   n   s   l   r   sr  lr  n   n   n )
  721.            (list #| 2Ml |# sr  sr  sr  s   n   w   sr  r   wr  s   s   s )
  722.            (list #| 4Ml |# lr  lr  lr  l   w   n   lr  wr  r   l   l   l )
  723.            (list #| 1Lm |# n   n   n   r   sr  lr  n   s   l   r   r   r )
  724.            (list #| 2Lm |# s   s   s   sr  r   wr  s   n   w   sr  sr  sr)
  725.            (list #| 4Lm |# l   l   l   lr  wr  r   l   w   n   lr  lr  lr)
  726.            (list #| 1Ll |# r   r   r   n   s   l   r   sr  lr  n   n   n )
  727.            (list #| 2Ll |# r   r   r   n   s   l   r   sr  lr  n   n   n )
  728.            (list #| 4Ll |# r   r   r   n   s   l   r   sr  lr  n   n   n )))))
  729.  
  730. ;;; Of course, the table above is a lie.  We also need to factor in the
  731. ;;; order of the source data to cope with swapping half of a unit at the
  732. ;;; end of a scanline, since we are trying to avoid de-ref'ing off the
  733. ;;; end of the source.
  734. ;;;
  735. ;;; Defines whether the first half of a unit has the first half of the data
  736.  
  737. (defconstant
  738.   *image-swap-lsb-first-p*
  739.   '#.(make-array
  740.        12 :initial-contents
  741.        (list t   #| 1mm |#
  742.          t   #| 2mm |#
  743.          t   #| 4mm |#
  744.          t   #| 1ml |#
  745.          nil #| 2ml |#
  746.          nil #| 4ml |#
  747.          t   #| 1lm |#
  748.          nil #| 2lm |#
  749.          nil #| 4lm |#
  750.          t   #| 1ll |#
  751.          t   #| 2ll |#
  752.          t   #| 4ll |#
  753.          )))
  754.  
  755. (defun image-swap-function
  756.        (bits-per-pixel
  757.     from-bitmap-unit from-byte-lsb-first-p from-bit-lsb-first-p
  758.     to-bitmap-unit to-byte-lsb-first-p to-bit-lsb-first-p)
  759.   (declare (type (member 1 4 8 16 24 32) bits-per-pixel)
  760.        (type (member 8 16 32) from-bitmap-unit to-bitmap-unit)
  761.        (type boolean from-byte-lsb-first-p from-bit-lsb-first-p
  762.          to-byte-lsb-first-p to-bit-lsb-first-p)
  763.        (values function lsb-first-p))
  764.   (cond ((index= bits-per-pixel 1)
  765.      (let ((from-index
  766.          (index+
  767.            (ecase from-bitmap-unit (32 2) (16 1) (8 0))
  768.            (if from-bit-lsb-first-p 3 0)
  769.            (if from-byte-lsb-first-p 6 0))))
  770.        (values
  771.          (aref *image-swap-function* from-index
  772.            (index+
  773.              (ecase to-bitmap-unit (32 2) (16 1) (8 0))
  774.              (if to-bit-lsb-first-p 3 0)
  775.              (if to-byte-lsb-first-p 6 0)))
  776.          (aref *image-swap-lsb-first-p* from-index))))
  777.     (t
  778.      (values 
  779.        (if (if (index= bits-per-pixel 4)
  780.            (eq from-bit-lsb-first-p to-bit-lsb-first-p)
  781.          (eq from-byte-lsb-first-p to-byte-lsb-first-p))
  782.            'image-noswap
  783.          (ecase bits-per-pixel
  784.            (4  'image-swap-nibbles)
  785.            (8  'image-noswap)
  786.            (16 'image-swap-two-bytes)
  787.            (24 'image-swap-three-bytes)
  788.            (32 'image-swap-four-bytes)))
  789.        from-byte-lsb-first-p))))
  790.  
  791.  
  792. ;;;-----------------------------------------------------------------------------
  793. ;;; GET-IMAGE
  794.  
  795. (defun read-pixarray-1 (buffer-bbuf index array x y width height  
  796.             padded-bytes-per-line bits-per-pixel)
  797.   (declare (type buffer-bytes buffer-bbuf)
  798.        (type pixarray-1 array)
  799.        (type card16 x y width height)
  800.        (type array-index index padded-bytes-per-line)
  801.        (type (member 1 4 8 16 24 32) bits-per-pixel)
  802.        (ignore bits-per-pixel))
  803.   #.(declare-buffun)
  804.   (with-vector (buffer-bbuf buffer-bytes)
  805.     (do* ((start (index+ index
  806.              (index* y padded-bytes-per-line)
  807.              (index-ceiling x 8))
  808.          (index+ start padded-bytes-per-line))
  809.       (y 0 (index1+ y))
  810.       (left-bits (index-mod (index- x) 8))
  811.       (right-bits (index-mod (index- width left-bits) 8))
  812.       (middle-bits (index- width left-bits right-bits))
  813.       (middle-bytes (index-floor middle-bits 8)))
  814.      ((index>= y height))
  815.       (declare (type array-index start y
  816.              left-bits right-bits middle-bits middle-bytes))
  817.       (cond ((index< middle-bits 0)
  818.          (let ((byte (aref buffer-bbuf (index1- start)))
  819.            (x left-bits))
  820.            (declare (type card8 byte)
  821.             (type array-index x))
  822.            (when (index> right-bits 6)
  823.          (setf (aref array y (index- x 1))
  824.                (read-image-load-byte 1 7 byte)))
  825.            (when (and (index> left-bits 1)
  826.               (index> right-bits 5))
  827.          (setf (aref array y (index- x 2))
  828.                (read-image-load-byte 1 6 byte)))
  829.            (when (and (index> left-bits 2)
  830.               (index> right-bits 4))
  831.          (setf (aref array y (index- x 3))
  832.                (read-image-load-byte 1 5 byte)))
  833.            (when (and (index> left-bits 3)
  834.               (index> right-bits 3))
  835.          (setf (aref array y (index- x 4))
  836.                (read-image-load-byte 1 4 byte)))
  837.            (when (and (index> left-bits 4)
  838.               (index> right-bits 2))
  839.          (setf (aref array y (index- x 5))
  840.                (read-image-load-byte 1 3 byte)))
  841.            (when (and (index> left-bits 5)
  842.               (index> right-bits 1))
  843.          (setf (aref array y (index- x 6))
  844.                (read-image-load-byte 1 2 byte)))
  845.            (when (index> left-bits 6)
  846.          (setf (aref array y (index- x 7))
  847.                (read-image-load-byte 1 1 byte)))))
  848.         (t
  849.          (unless (index-zerop left-bits)
  850.            (let ((byte (aref buffer-bbuf (index1- start)))
  851.              (x left-bits))
  852.          (declare (type card8 byte)
  853.               (type array-index x))
  854.          (setf (aref array y (index- x 1))
  855.                (read-image-load-byte 1 7 byte))
  856.          (when (index> left-bits 1)
  857.            (setf (aref array y (index- x 2))
  858.              (read-image-load-byte 1 6 byte))
  859.            (when (index> left-bits 2)
  860.              (setf (aref array y (index- x 3))
  861.                (read-image-load-byte 1 5 byte))
  862.              (when (index> left-bits 3)
  863.                (setf (aref array y (index- x 4))
  864.                  (read-image-load-byte 1 4 byte))
  865.                (when (index> left-bits 4)
  866.              (setf (aref array y (index- x 5))
  867.                    (read-image-load-byte 1 3 byte))
  868.              (when (index> left-bits 5)
  869.                (setf (aref array y (index- x 6))
  870.                  (read-image-load-byte 1 2 byte))
  871.                (when (index> left-bits 6)
  872.                  (setf (aref array y (index- x 7))
  873.                    (read-image-load-byte 1 1 byte))
  874.                  ))))))))
  875.          (do* ((end (index+ start middle-bytes))
  876.            (i start (index1+ i))
  877.            (x left-bits (index+ x 8)))
  878.           ((index>= i end)
  879.            (unless (index-zerop right-bits)
  880.              (let ((byte (aref buffer-bbuf end))
  881.                (x (index+ left-bits middle-bits)))
  882.                (declare (type card8 byte)
  883.                 (type array-index x))
  884.                (setf (aref array y (index+ x 0))
  885.                  (read-image-load-byte 1 0 byte))
  886.                (when (index> right-bits 1)
  887.              (setf (aref array y (index+ x 1))
  888.                    (read-image-load-byte 1 1 byte))
  889.              (when (index> right-bits 2)
  890.                (setf (aref array y (index+ x 2))
  891.                  (read-image-load-byte 1 2 byte))
  892.                (when (index> right-bits 3)
  893.                  (setf (aref array y (index+ x 3))
  894.                    (read-image-load-byte 1 3 byte))
  895.                  (when (index> right-bits 4)
  896.                    (setf (aref array y (index+ x 4))
  897.                      (read-image-load-byte 1 4 byte))
  898.                    (when (index> right-bits 5)
  899.                  (setf (aref array y (index+ x 5))
  900.                        (read-image-load-byte 1 5 byte))
  901.                  (when (index> right-bits 6)
  902.                    (setf (aref array y (index+ x 6))
  903.                      (read-image-load-byte 1 6 byte))
  904.                    )))))))))
  905.            (declare (type array-index end i x))
  906.            (let ((byte (aref buffer-bbuf i)))
  907.          (declare (type card8 byte))
  908.          (setf (aref array y (index+ x 0))
  909.                (read-image-load-byte 1 0 byte))
  910.          (setf (aref array y (index+ x 1))
  911.                (read-image-load-byte 1 1 byte))
  912.          (setf (aref array y (index+ x 2))
  913.                (read-image-load-byte 1 2 byte))
  914.          (setf (aref array y (index+ x 3))
  915.                (read-image-load-byte 1 3 byte))
  916.          (setf (aref array y (index+ x 4))
  917.                (read-image-load-byte 1 4 byte))
  918.          (setf (aref array y (index+ x 5))
  919.                (read-image-load-byte 1 5 byte))
  920.          (setf (aref array y (index+ x 6))
  921.                (read-image-load-byte 1 6 byte))
  922.          (setf (aref array y (index+ x 7))
  923.                (read-image-load-byte 1 7 byte))))
  924.          )))))
  925.  
  926. (defun read-pixarray-4 (buffer-bbuf index array x y width height 
  927.             padded-bytes-per-line bits-per-pixel)
  928.   (declare (type buffer-bytes buffer-bbuf)
  929.        (type pixarray-4 array)
  930.        (type card16 x y width height)
  931.        (type array-index index padded-bytes-per-line)
  932.        (type (member 1 4 8 16 24 32) bits-per-pixel)
  933.        (ignore bits-per-pixel))
  934.   #.(declare-buffun)
  935.   (with-vector (buffer-bbuf buffer-bytes)
  936.     (do* ((start (index+ index
  937.              (index* y padded-bytes-per-line)
  938.              (index-ceiling x 2))
  939.          (index+ start padded-bytes-per-line))
  940.       (y 0 (index1+ y))
  941.       (left-nibbles (index-mod (index- x) 2))
  942.       (right-nibbles (index-mod (index- width left-nibbles) 2))
  943.       (middle-nibbles (index- width left-nibbles right-nibbles))
  944.       (middle-bytes (index-floor middle-nibbles 2)))
  945.      ((index>= y height))
  946.       (declare (type array-index start y
  947.              left-nibbles right-nibbles middle-nibbles middle-bytes))
  948.       (unless (index-zerop left-nibbles)
  949.     (setf (aref array y 0)
  950.           (read-image-load-byte
  951.         4 4 (aref buffer-bbuf (index1- start)))))
  952.       (do* ((end (index+ start middle-bytes))
  953.         (i start (index1+ i))
  954.         (x left-nibbles (index+ x 2)))
  955.        ((index>= i end)
  956.         (unless (index-zerop right-nibbles)
  957.           (setf (aref array y (index+ left-nibbles middle-nibbles))
  958.             (read-image-load-byte 4 0 (aref buffer-bbuf end)))))
  959.     (declare (type array-index end i x))
  960.     (let ((byte (aref buffer-bbuf i)))
  961.       (declare (type card8 byte))
  962.       (setf (aref array y (index+ x 0))
  963.         (read-image-load-byte 4 0 byte))
  964.       (setf (aref array y (index+ x 1))
  965.         (read-image-load-byte 4 4 byte))))
  966.       )))
  967.  
  968. (defun read-pixarray-8 (buffer-bbuf index array x y width height 
  969.             padded-bytes-per-line bits-per-pixel)
  970.   (declare (type buffer-bytes buffer-bbuf)
  971.        (type pixarray-8 array)
  972.        (type card16 x y width height)
  973.        (type array-index index padded-bytes-per-line)
  974.        (type (member 1 4 8 16 24 32) bits-per-pixel)
  975.        (ignore bits-per-pixel))
  976.   #.(declare-buffun)
  977.   (with-vector (buffer-bbuf buffer-bytes)
  978.     (do* ((start (index+ index
  979.              (index* y padded-bytes-per-line)
  980.              x)
  981.          (index+ start padded-bytes-per-line))
  982.       (y 0 (index1+ y)))
  983.      ((index>= y height))
  984.       (declare (type array-index start y))
  985.       (do* ((end (index+ start width))
  986.         (i start (index1+ i))
  987.         (x 0 (index1+ x)))
  988.        ((index>= i end))
  989.     (declare (type array-index end i x))
  990.     (setf (aref array y x)
  991.           (the card8 (aref buffer-bbuf i)))))))
  992.  
  993. (defun read-pixarray-16 (buffer-bbuf index array x y width height 
  994.              padded-bytes-per-line bits-per-pixel)
  995.   (declare (type buffer-bytes buffer-bbuf)
  996.        (type pixarray-16 array)
  997.        (type card16 width height)
  998.        (type array-index index padded-bytes-per-line)
  999.        (type (member 1 4 8 16 24 32) bits-per-pixel)
  1000.        (ignore bits-per-pixel))
  1001.   #.(declare-buffun)
  1002.   (with-vector (buffer-bbuf buffer-bytes)
  1003.     (do* ((start (index+ index
  1004.              (index* y padded-bytes-per-line)
  1005.              (index* x 2))
  1006.          (index+ start padded-bytes-per-line))
  1007.       (y 0 (index1+ y)))
  1008.      ((index>= y height))
  1009.       (declare (type array-index start y))
  1010.       (do* ((end (index+ start (index* width 2)))
  1011.         (i start (index+ i 2))
  1012.         (x 0 (index1+ x)))
  1013.        ((index>= i end))
  1014.     (declare (type array-index end i x))
  1015.     (setf (aref array y x)
  1016.           (read-image-assemble-bytes
  1017.         (aref buffer-bbuf (index+ i 0))
  1018.         (aref buffer-bbuf (index+ i 1))))))))
  1019.  
  1020. (defun read-pixarray-24 (buffer-bbuf index array x y width height 
  1021.              padded-bytes-per-line bits-per-pixel)
  1022.   (declare (type buffer-bytes buffer-bbuf)
  1023.        (type pixarray-24 array)
  1024.        (type card16 width height)
  1025.        (type array-index index padded-bytes-per-line)
  1026.        (type (member 1 4 8 16 24 32) bits-per-pixel)
  1027.        (ignore bits-per-pixel))
  1028.   #.(declare-buffun)
  1029.   (with-vector (buffer-bbuf buffer-bytes)
  1030.     (do* ((start (index+ index
  1031.              (index* y padded-bytes-per-line)
  1032.              (index* x 3))
  1033.          (index+ start padded-bytes-per-line))
  1034.       (y 0 (index1+ y)))
  1035.      ((index>= y height))
  1036.       (declare (type array-index start y))
  1037.       (do* ((end (index+ start (index* width 3)))
  1038.         (i start (index+ i 3))
  1039.         (x 0 (index1+ x)))
  1040.        ((index>= i end))
  1041.     (declare (type array-index end i x))
  1042.     (setf (aref array y x)
  1043.           (read-image-assemble-bytes
  1044.         (aref buffer-bbuf (index+ i 0))
  1045.         (aref buffer-bbuf (index+ i 1))
  1046.         (aref buffer-bbuf (index+ i 2))))))))
  1047.  
  1048. (defun read-pixarray-32 (buffer-bbuf index array x y width height 
  1049.              padded-bytes-per-line bits-per-pixel)
  1050.   (declare (type buffer-bytes buffer-bbuf)
  1051.        (type pixarray-32 array)
  1052.        (type card16 width height)
  1053.        (type array-index index padded-bytes-per-line)
  1054.        (type (member 1 4 8 16 24 32) bits-per-pixel)
  1055.        (ignore bits-per-pixel))
  1056.   #.(declare-buffun)
  1057.   (with-vector (buffer-bbuf buffer-bytes)
  1058.     (do* ((start (index+ index
  1059.              (index* y padded-bytes-per-line)
  1060.              (index* x 4))
  1061.          (index+ start padded-bytes-per-line))
  1062.       (y 0 (index1+ y)))
  1063.      ((index>= y height))
  1064.       (declare (type array-index start y))
  1065.       (do* ((end (index+ start (index* width 4)))
  1066.         (i start (index+ i 4))
  1067.         (x 0 (index1+ x)))
  1068.        ((index>= i end))
  1069.     (declare (type array-index end i x))
  1070.     (setf (aref array y x)
  1071.           (read-image-assemble-bytes
  1072.         (aref buffer-bbuf (index+ i 0))
  1073.         (aref buffer-bbuf (index+ i 1))
  1074.         (aref buffer-bbuf (index+ i 2))
  1075.         (aref buffer-bbuf (index+ i 3))))))))
  1076.  
  1077. (defun read-pixarray-internal
  1078.        (bbuf boffset pixarray x y width height padded-bytes-per-line
  1079.     bits-per-pixel read-pixarray-function
  1080.     from-unit from-byte-lsb-first-p from-bit-lsb-first-p
  1081.     to-unit to-byte-lsb-first-p to-bit-lsb-first-p)
  1082.   (declare (type buffer-bytes bbuf)
  1083.        (type array-index boffset padded-bytes-per-line)
  1084.        (type pixarray pixarray)
  1085.        (type card16 x y width height)
  1086.        (type (member 1 4 8 16 24 32) bits-per-pixel)
  1087.        (type function read-pixarray-function)
  1088.        (type (member 8 16 32) from-unit to-unit)
  1089.        (type boolean from-byte-lsb-first-p from-bit-lsb-first-p
  1090.          to-byte-lsb-first-p to-bit-lsb-first-p))
  1091.   (multiple-value-bind (image-swap-function image-swap-lsb-first-p)
  1092.       (image-swap-function
  1093.     bits-per-pixel
  1094.     from-unit from-byte-lsb-first-p from-bit-lsb-first-p
  1095.     to-unit to-byte-lsb-first-p to-bit-lsb-first-p)
  1096.     (if (eq image-swap-function 'image-noswap)
  1097.     (funcall
  1098.       read-pixarray-function
  1099.       bbuf boffset pixarray x y width height padded-bytes-per-line
  1100.       bits-per-pixel)
  1101.       (with-image-data-buffer (buf (index* height padded-bytes-per-line))
  1102.     (funcall
  1103.       (symbol-function image-swap-function) bbuf buf
  1104.       (index+ boffset (index* y padded-bytes-per-line)) 0
  1105.       (index-ceiling (index* (index+ x width) bits-per-pixel) 8)
  1106.       padded-bytes-per-line padded-bytes-per-line height
  1107.       image-swap-lsb-first-p)
  1108.     (funcall
  1109.       read-pixarray-function 
  1110.       buf 0 pixarray x 0 width height padded-bytes-per-line
  1111.       bits-per-pixel)))))
  1112.  
  1113. (defun read-pixarray
  1114.        (bbuf boffset pixarray x y width height padded-bytes-per-line
  1115.     bits-per-pixel unit byte-lsb-first-p bit-lsb-first-p)
  1116.   (declare (type buffer-bytes bbuf)
  1117.        (type array-index boffset padded-bytes-per-line)
  1118.        (type pixarray pixarray)
  1119.        (type card16 x y width height)
  1120.        (type (member 1 4 8 16 24 32) bits-per-pixel)
  1121.        (type (member 8 16 32) unit)
  1122.        (type boolean byte-lsb-first-p bit-lsb-first-p))
  1123.   (unless (fast-read-pixarray
  1124.         bbuf boffset pixarray x y width height padded-bytes-per-line
  1125.         bits-per-pixel unit byte-lsb-first-p bit-lsb-first-p)
  1126.     (read-pixarray-internal
  1127.       bbuf boffset pixarray x y width height padded-bytes-per-line
  1128.       bits-per-pixel 
  1129.       (ecase bits-per-pixel
  1130.     ( 1 #'read-pixarray-1 )
  1131.     ( 4 #'read-pixarray-4 )
  1132.     ( 8 #'read-pixarray-8 )
  1133.     (16 #'read-pixarray-16)
  1134.     (24 #'read-pixarray-24)
  1135.     (32 #'read-pixarray-32))
  1136.       unit byte-lsb-first-p bit-lsb-first-p
  1137.       *image-unit* *image-byte-lsb-first-p* *image-bit-lsb-first-p*)))
  1138.  
  1139. (defun read-xy-format-image-x
  1140.        (buffer-bbuf index length data width height depth
  1141.     padded-bytes-per-line padded-bytes-per-plane
  1142.     unit byte-lsb-first-p bit-lsb-first-p pad)
  1143.   (declare (type buffer-bytes buffer-bbuf)
  1144.        (type card16 width height)
  1145.        (type array-index index length padded-bytes-per-line
  1146.          padded-bytes-per-plane)
  1147.        (type image-depth depth)
  1148.        (type (member 8 16 32) unit pad)
  1149.        (type boolean byte-lsb-first-p bit-lsb-first-p)
  1150.        (values image-x))
  1151.   (assert (index<= (index* depth padded-bytes-per-plane) length))
  1152.   (let* ((bytes-per-line (index-ceiling width 8))
  1153.      (data-length (index* padded-bytes-per-plane depth)))
  1154.     (declare (type array-index bytes-per-line data-length))
  1155.     (cond (data
  1156.        (check-type data buffer-bytes)
  1157.        (assert (index>= (length data) data-length)))
  1158.       (t
  1159.        (setq data (make-array data-length :element-type 'card8))))
  1160.     (do ((plane 0 (index1+ plane)))
  1161.     ((index>= plane depth))
  1162.       (declare (type image-depth plane))
  1163.       (image-noswap
  1164.     buffer-bbuf data
  1165.     (index+ index (index* plane padded-bytes-per-plane))
  1166.     (index* plane padded-bytes-per-plane)
  1167.     bytes-per-line padded-bytes-per-line padded-bytes-per-line
  1168.     height byte-lsb-first-p))
  1169.     (create-image 
  1170.       :width width :height height :depth depth :data data
  1171.       :bits-per-pixel 1 :format :xy-pixmap
  1172.       :bytes-per-line padded-bytes-per-line
  1173.       :unit unit :pad pad
  1174.       :byte-lsb-first-p byte-lsb-first-p :bit-lsb-first-p bit-lsb-first-p)))
  1175.  
  1176. (defun read-z-format-image-x
  1177.        (buffer-bbuf index length data width height depth
  1178.     padded-bytes-per-line 
  1179.     unit byte-lsb-first-p bit-lsb-first-p pad bits-per-pixel)
  1180.   (declare (type buffer-bytes buffer-bbuf)
  1181.        (type card16 width height)
  1182.        (type array-index index length padded-bytes-per-line)
  1183.        (type image-depth depth)
  1184.        (type (member 8 16 32) unit pad)
  1185.        (type boolean byte-lsb-first-p bit-lsb-first-p)
  1186.        (type (member 1 4 8 16 24 32) bits-per-pixel)
  1187.        (values image-x))
  1188.   (assert (index<= (index* height padded-bytes-per-line) length))
  1189.   (let ((bytes-per-line (index-ceiling (index* width bits-per-pixel) 8))
  1190.     (data-length (index* padded-bytes-per-line height)))
  1191.     (declare (type array-index bytes-per-line data-length))
  1192.     (cond (data
  1193.        (check-type data buffer-bytes)
  1194.        (assert (index>= (length data) data-length)))
  1195.       (t
  1196.        (setq data (make-array data-length :element-type 'card8))))
  1197.     (image-noswap
  1198.       buffer-bbuf data index 0 bytes-per-line padded-bytes-per-line
  1199.       padded-bytes-per-line height byte-lsb-first-p)
  1200.     (create-image 
  1201.       :width width :height height :depth depth :data data
  1202.       :bits-per-pixel bits-per-pixel :format :z-pixmap
  1203.       :bytes-per-line padded-bytes-per-line
  1204.       :unit unit :pad pad
  1205.       :byte-lsb-first-p byte-lsb-first-p :bit-lsb-first-p bit-lsb-first-p)))
  1206.  
  1207. (defun read-image-xy (bbuf index length data x y width height depth
  1208.               padded-bytes-per-line padded-bytes-per-plane
  1209.               unit byte-lsb-first-p bit-lsb-first-p)
  1210.   (declare (type buffer-bytes bbuf)
  1211.        (type card16 x y width height)
  1212.        (type array-index index length padded-bytes-per-line
  1213.          padded-bytes-per-plane)
  1214.        (type image-depth depth)
  1215.        (type (member 8 16 32) unit)
  1216.        (type boolean byte-lsb-first-p bit-lsb-first-p)
  1217.        (values image-xy))
  1218.   (check-type data list)
  1219.   (multiple-value-bind (dimensions element-type)
  1220.       (if data
  1221.       (values (array-dimensions (first data))
  1222.           (array-element-type (first data)))
  1223.     (values (list height
  1224.               (index* (index-ceiling width *image-pad*) *image-pad*))
  1225.         'pixarray-1-element-type))
  1226.     (do* ((arrays data)
  1227.       (result nil)
  1228.       (limit (index+ length index))
  1229.       (plane 0 (1+ plane))
  1230.       (index index (index+ index padded-bytes-per-plane)))
  1231.      ((or (>= plane depth)
  1232.           (index> (index+ index padded-bytes-per-plane) limit))
  1233.       (setq data (nreverse result) depth (length data)))
  1234.       (declare (type array-index limit index)
  1235.            (type image-depth plane)
  1236.            (type list arrays result))
  1237.       (let ((array (or (pop arrays)
  1238.                (make-array dimensions :element-type element-type))))
  1239.     (declare (type pixarray-1 array))
  1240.     (push array result)
  1241.     (read-pixarray
  1242.       bbuf index array x y width height padded-bytes-per-line 1
  1243.       unit byte-lsb-first-p bit-lsb-first-p)))
  1244.     (create-image 
  1245.       :width width :height height :depth depth :data data)))
  1246.  
  1247. (defun read-image-z (bbuf index length data x y width height depth
  1248.              padded-bytes-per-line bits-per-pixel
  1249.              unit byte-lsb-first-p bit-lsb-first-p)
  1250.   (declare (type buffer-bytes bbuf)
  1251.        (type card16 x y width height)
  1252.        (type array-index index length padded-bytes-per-line)
  1253.        (type image-depth depth)
  1254.        (type (member 1 4 8 16 24 32) bits-per-pixel)
  1255.        (type (member 8 16 32) unit)
  1256.        (type boolean byte-lsb-first-p bit-lsb-first-p)
  1257.        (values image-z))
  1258.   (assert (index<= (index* (index+ y height) padded-bytes-per-line) length))
  1259.   (let* ((image-bits-per-line (index* width bits-per-pixel))
  1260.      (image-pixels-per-line
  1261.        (index-ceiling
  1262.          (index* (index-ceiling image-bits-per-line *image-pad*)
  1263.              *image-pad*)
  1264.          bits-per-pixel)))
  1265.     (declare (type array-index image-bits-per-line image-pixels-per-line))
  1266.     (unless data
  1267.       (setq data
  1268.         (make-array
  1269.           (list height image-pixels-per-line)
  1270.           :element-type (ecase bits-per-pixel
  1271.                   (1  'pixarray-1-element-type)
  1272.                   (4  'pixarray-4-element-type)
  1273.                   (8  'pixarray-8-element-type)
  1274.                   (16 'pixarray-16-element-type)
  1275.                   (24 'pixarray-24-element-type)
  1276.                   (32 'pixarray-32-element-type)))))
  1277.     (read-pixarray
  1278.       bbuf index data x y width height padded-bytes-per-line bits-per-pixel
  1279.       unit byte-lsb-first-p bit-lsb-first-p)
  1280.     (create-image 
  1281.       :width width :height height :depth depth :data data
  1282.       :bits-per-pixel bits-per-pixel)))
  1283.  
  1284. (defun get-image (drawable &key
  1285.           data
  1286.           (x (required-arg x))
  1287.           (y (required-arg y))
  1288.           (width (required-arg width))
  1289.           (height (required-arg height))
  1290.           plane-mask format result-type)
  1291.   (declare (type drawable drawable)
  1292.        (type (or buffer-bytes list pixarray) data)
  1293.        (type int16 x y) ;; required
  1294.        (type card16 width height) ;; required
  1295.        (type (or null pixel) plane-mask)
  1296.        (type (or null (member :xy-pixmap :z-pixmap)) format)
  1297.        (type (or null (member image-xy image-x image-z)) result-type)
  1298.        (values image visual-info))
  1299.   (unless result-type
  1300.     (setq result-type (ecase format
  1301.             (:xy-pixmap 'image-xy)
  1302.             (:z-pixmap 'image-z)
  1303.             ((nil) 'image-x))))
  1304.   (unless format
  1305.     (setq format (case result-type
  1306.            (image-xy :xy-pixmap)
  1307.            ((image-z image-x) :z-pixmap))))
  1308.   (unless (ecase result-type
  1309.         (image-xy (eq format :xy-pixmap))
  1310.         (image-z (eq format :z-pixmap))
  1311.         (image-x t))
  1312.     (error "Result-type ~s is incompatable with format ~s"
  1313.        result-type format))
  1314.   (unless plane-mask (setq plane-mask #xffffffff))
  1315.   (let ((display (drawable-display drawable)))
  1316.     (with-buffer-request-and-reply (display *x-getimage* nil :sizes (8 32))
  1317.      (((data (member error :xy-pixmap :z-pixmap)) format)
  1318.       (drawable drawable)
  1319.       (int16 x y)
  1320.       (card16 width height)
  1321.       (card32 plane-mask))
  1322.       (let* ((depth (card8-get 1))
  1323.          (length (index* 4 (card32-get 4)))
  1324.          (visual-info (visual-info display (resource-id-get 8)))
  1325.          (bitmap-format (display-bitmap-format display))
  1326.          (unit (bitmap-format-unit bitmap-format))
  1327.          (byte-lsb-first-p (display-image-lsb-first-p display))
  1328.          (bit-lsb-first-p  (bitmap-format-lsb-first-p bitmap-format)))
  1329.     (declare (type image-depth depth)
  1330.          (type array-index length)
  1331.          (type (or null visual-info) visual-info)
  1332.          (type bitmap-format bitmap-format)
  1333.          (type (member 8 16 32) unit)
  1334.          (type boolean byte-lsb-first-p bit-lsb-first-p))
  1335.     (multiple-value-bind (pad bits-per-pixel)
  1336.         (ecase format
  1337.           (:xy-pixmap
  1338.         (values (bitmap-format-pad bitmap-format) 1))
  1339.           (:z-pixmap
  1340.         (if (= depth 1)
  1341.             (values (bitmap-format-pad bitmap-format) 1)
  1342.           (let ((pixmap-format
  1343.               (find depth (display-pixmap-formats display)
  1344.                 :key #'pixmap-format-depth)))
  1345.             (declare (type pixmap-format pixmap-format))
  1346.             (values (pixmap-format-scanline-pad pixmap-format)
  1347.                 (pixmap-format-bits-per-pixel pixmap-format))))))
  1348.       (declare (type (member 8 16 32) pad)
  1349.            (type (member 1 4 8 16 24 32) bits-per-pixel))
  1350.       (let* ((bits-per-line (index* bits-per-pixel width))
  1351.          (padded-bits-per-line
  1352.            (index* (index-ceiling bits-per-line pad) pad))
  1353.          (padded-bytes-per-line
  1354.            (index-ceiling padded-bits-per-line 8))
  1355.          (padded-bytes-per-plane
  1356.            (index* padded-bytes-per-line height))
  1357.          (image
  1358.            (ecase result-type
  1359.              (image-x
  1360.                (ecase format
  1361.              (:xy-pixmap
  1362.                (read-xy-format-image-x
  1363.                  buffer-bbuf *replysize* length data
  1364.                  width height depth
  1365.                  padded-bytes-per-line padded-bytes-per-plane
  1366.                  unit byte-lsb-first-p bit-lsb-first-p
  1367.                  pad))
  1368.              (:z-pixmap
  1369.                (read-z-format-image-x
  1370.                  buffer-bbuf *replysize* length data
  1371.                  width height depth
  1372.                  padded-bytes-per-line
  1373.                  unit byte-lsb-first-p bit-lsb-first-p
  1374.                  pad bits-per-pixel))))
  1375.              (image-xy
  1376.                (read-image-xy
  1377.              buffer-bbuf *replysize* length data
  1378.              0 0 width height depth
  1379.              padded-bytes-per-line padded-bytes-per-plane
  1380.              unit byte-lsb-first-p bit-lsb-first-p))
  1381.              (image-z
  1382.                (read-image-z
  1383.              buffer-bbuf *replysize* length data
  1384.              0 0 width height depth padded-bytes-per-line
  1385.              bits-per-pixel 
  1386.              unit byte-lsb-first-p bit-lsb-first-p)))))
  1387.         (declare (type image image)
  1388.              (type array-index bits-per-line 
  1389.                padded-bits-per-line padded-bytes-per-line))
  1390.         (when visual-info
  1391.           (unless (zerop (visual-info-red-mask visual-info))
  1392.         (setf (image-red-mask image)
  1393.               (visual-info-red-mask visual-info)))
  1394.           (unless (zerop (visual-info-green-mask visual-info))
  1395.         (setf (image-green-mask image)
  1396.               (visual-info-green-mask visual-info)))
  1397.           (unless (zerop (visual-info-blue-mask visual-info))
  1398.         (setf (image-blue-mask image)
  1399.               (visual-info-blue-mask visual-info))))
  1400.         (values image visual-info)))))))
  1401.  
  1402.  
  1403. ;;;-----------------------------------------------------------------------------
  1404. ;;; PUT-IMAGE
  1405.  
  1406. (defun write-pixarray-1 (buffer-bbuf index array x y width height
  1407.              padded-bytes-per-line bits-per-pixel)
  1408.   (declare (type buffer-bytes buffer-bbuf)
  1409.        (type pixarray-1 array)
  1410.        (type card16 x y width height)
  1411.        (type array-index index padded-bytes-per-line)
  1412.        (type (member 1 4 8 16 24 32) bits-per-pixel)
  1413.        (ignore bits-per-pixel))
  1414.   #.(declare-buffun)
  1415.   (with-vector (buffer-bbuf buffer-bytes)
  1416.     (do* ((h 0 (index1+ h))
  1417.       (y y (index1+ y))
  1418.       (right-bits (index-mod width 8))
  1419.       (middle-bits (index- width right-bits))
  1420.       (middle-bytes (index-ceiling middle-bits 8))
  1421.       (start index (index+ start padded-bytes-per-line)))
  1422.      ((index>= h height))
  1423.       (declare (type array-index h y right-bits middle-bits
  1424.              middle-bytes start))
  1425.       (do* ((end (index+ start middle-bytes))
  1426.         (i start (index1+ i))
  1427.         (start-x x)
  1428.         (x start-x (index+ x 8)))
  1429.        ((index>= i end)
  1430.         (unless (index-zerop right-bits)
  1431.           (let ((x (index+ start-x middle-bits)))
  1432.         (declare (type array-index x))
  1433.         (setf (aref buffer-bbuf end)
  1434.               (write-image-assemble-bytes
  1435.             (aref array y (index+ x 0))
  1436.             (if (index> right-bits 1)
  1437.                 (aref array y (index+ x 1))
  1438.               0)
  1439.             (if (index> right-bits 2)
  1440.                 (aref array y (index+ x 2))
  1441.               0)
  1442.             (if (index> right-bits 3)
  1443.                 (aref array y (index+ x 3))
  1444.               0)
  1445.             (if (index> right-bits 4)
  1446.                 (aref array y (index+ x 4))
  1447.               0)
  1448.             (if (index> right-bits 5)
  1449.                 (aref array y (index+ x 5))
  1450.               0)
  1451.             (if (index> right-bits 6)
  1452.                 (aref array y (index+ x 6))
  1453.               0)
  1454.             0)))))
  1455.     (declare (type array-index end i start-x x))
  1456.     (setf (aref buffer-bbuf i)
  1457.           (write-image-assemble-bytes
  1458.         (aref array y (index+ x 0))
  1459.         (aref array y (index+ x 1))
  1460.         (aref array y (index+ x 2))
  1461.         (aref array y (index+ x 3))
  1462.         (aref array y (index+ x 4))
  1463.         (aref array y (index+ x 5))
  1464.         (aref array y (index+ x 6))
  1465.         (aref array y (index+ x 7))))))))
  1466.  
  1467. (defun write-pixarray-4 (buffer-bbuf index array x y width height
  1468.              padded-bytes-per-line bits-per-pixel)
  1469.   (declare (type buffer-bytes buffer-bbuf)
  1470.        (type pixarray-4 array)
  1471.        (type int16 x y)
  1472.        (type card16 width height)
  1473.        (type array-index index padded-bytes-per-line)
  1474.        (type (member 1 4 8 16 24 32) bits-per-pixel)
  1475.        (ignore bits-per-pixel))
  1476.   #.(declare-buffun)
  1477.   (with-vector (buffer-bbuf buffer-bytes)
  1478.     (do* ((h 0 (index1+ h))
  1479.       (y y (index1+ y))
  1480.       (right-nibbles (index-mod width 2))
  1481.       (middle-nibbles (index- width right-nibbles))
  1482.       (middle-bytes (index-ceiling middle-nibbles 2))
  1483.       (start index (index+ start padded-bytes-per-line)))
  1484.      ((index>= h height))
  1485.       (declare (type array-index h y right-nibbles middle-nibbles
  1486.              middle-bytes start))
  1487.       (do* ((end (index+ start middle-bytes))
  1488.         (i start (index1+ i))
  1489.         (start-x x)
  1490.         (x start-x (index+ x 2)))
  1491.        ((index>= i end)
  1492.         (unless (index-zerop right-nibbles)
  1493.           (setf (aref buffer-bbuf end)
  1494.             (write-image-assemble-bytes
  1495.               (aref array y (index+ start-x middle-nibbles))
  1496.               0))))
  1497.     (declare (type array-index end i start-x x))
  1498.     (setf (aref buffer-bbuf i)
  1499.           (write-image-assemble-bytes
  1500.         (aref array y (index+ x 0))
  1501.         (aref array y (index+ x 1))))))))
  1502.  
  1503. (defun write-pixarray-8 (buffer-bbuf index array x y width height
  1504.              padded-bytes-per-line bits-per-pixel)
  1505.   (declare (type buffer-bytes buffer-bbuf)
  1506.        (type pixarray-8 array)
  1507.        (type int16 x y)
  1508.        (type card16 width height)
  1509.        (type array-index index padded-bytes-per-line)
  1510.        (type (member 1 4 8 16 24 32) bits-per-pixel)
  1511.        (ignore bits-per-pixel))
  1512.   #.(declare-buffun)
  1513.   (with-vector (buffer-bbuf buffer-bytes)
  1514.     (do* ((h 0 (index1+ h))
  1515.       (y y (index1+ y))
  1516.       (start index (index+ start padded-bytes-per-line)))
  1517.      ((index>= h height))
  1518.       (declare (type array-index h y start))
  1519.       (do* ((end (index+ start width))
  1520.         (i start (index1+ i))
  1521.         (x x (index1+ x)))
  1522.        ((index>= i end))
  1523.     (declare (type array-index end i x))
  1524.     (setf (aref buffer-bbuf i) (the card8 (aref array y x)))))))
  1525.  
  1526. (defun write-pixarray-16 (buffer-bbuf index array x y width height
  1527.               padded-bytes-per-line bits-per-pixel)
  1528.   (declare (type buffer-bytes buffer-bbuf)
  1529.        (type pixarray-16 array)
  1530.        (type int16 x y)
  1531.        (type card16 width height)
  1532.        (type array-index index padded-bytes-per-line)
  1533.        (type (member 1 4 8 16 24 32) bits-per-pixel)
  1534.        (ignore bits-per-pixel))
  1535.   #.(declare-buffun)
  1536.   (with-vector (buffer-bbuf buffer-bytes)
  1537.     (do* ((h 0 (index1+ h))
  1538.       (y y (index1+ y))
  1539.       (start index (index+ start padded-bytes-per-line)))
  1540.      ((index>= h height))
  1541.       (declare (type array-index h y start))
  1542.       (do* ((end (index+ start (index* width 2)))
  1543.         (i start (index+ i 2))
  1544.         (x x (index1+ x)))
  1545.        ((index>= i end))
  1546.     (declare (type array-index end i x))
  1547.     (let ((pixel (aref array y x)))
  1548.       (declare (type pixarray-16-element-type pixel))
  1549.       (setf (aref buffer-bbuf (index+ i 0))
  1550.         (write-image-load-byte 0 pixel 16))
  1551.       (setf (aref buffer-bbuf (index+ i 1))
  1552.         (write-image-load-byte 8 pixel 16)))))))
  1553.  
  1554. (defun write-pixarray-24 (buffer-bbuf index array x y width height
  1555.               padded-bytes-per-line bits-per-pixel)
  1556.   (declare (type buffer-bytes buffer-bbuf)
  1557.        (type pixarray-24 array)
  1558.        (type int16 x y)
  1559.        (type card16 width height)
  1560.        (type array-index index padded-bytes-per-line)
  1561.        (type (member 1 4 8 16 24 32) bits-per-pixel)
  1562.        (ignore bits-per-pixel))
  1563.   #.(declare-buffun)
  1564.   (with-vector (buffer-bbuf buffer-bytes)
  1565.     (do* ((h 0 (index1+ h))
  1566.       (y y (index1+ y))
  1567.       (start index (index+ start padded-bytes-per-line)))
  1568.      ((index>= h height))
  1569.       (declare (type array-index y start))
  1570.       (do* ((end (index+ start (index* width 3)))
  1571.         (i start (index+ i 3))
  1572.         (x x (index1+ x)))
  1573.        ((index>= i end))
  1574.     (declare (type array-index end i x))
  1575.     (let ((pixel (aref array y x)))
  1576.       (declare (type pixarray-24-element-type pixel))
  1577.       (setf (aref buffer-bbuf (index+ i 0))
  1578.         (write-image-load-byte 0 pixel 24))
  1579.       (setf (aref buffer-bbuf (index+ i 1))
  1580.         (write-image-load-byte 8 pixel 24))
  1581.       (setf (aref buffer-bbuf (index+ i 2))
  1582.         (write-image-load-byte 16 pixel 24)))))))
  1583.  
  1584. (defun write-pixarray-32 (buffer-bbuf index array x y width height
  1585.               padded-bytes-per-line bits-per-pixel)
  1586.   (declare (type buffer-bytes buffer-bbuf)
  1587.        (type pixarray-32 array)
  1588.        (type int16 x y)
  1589.        (type card16 width height)
  1590.        (type array-index index padded-bytes-per-line)
  1591.        (type (member 1 4 8 16 24 32) bits-per-pixel)
  1592.        (ignore bits-per-pixel))
  1593.   #.(declare-buffun)
  1594.   (with-vector (buffer-bbuf buffer-bytes)
  1595.     (do* ((h 0 (index1+ h))
  1596.       (y y (index1+ y))
  1597.       (start index (index+ start padded-bytes-per-line)))
  1598.      ((index>= h height))
  1599.       (declare (type array-index h y start))
  1600.       (do* ((end (index+ start (index* width 4)))
  1601.         (i start (index+ i 4))
  1602.         (x x (index1+ x)))
  1603.        ((index>= i end))
  1604.     (declare (type array-index end i x))
  1605.     (let ((pixel (aref array y x)))
  1606.       (declare (type pixarray-32-element-type pixel))
  1607.       (setf (aref buffer-bbuf (index+ i 0))
  1608.         (write-image-load-byte 0 pixel 32))
  1609.       (setf (aref buffer-bbuf (index+ i 1))
  1610.         (write-image-load-byte 8 pixel 32))
  1611.       (setf (aref buffer-bbuf (index+ i 2))
  1612.         (write-image-load-byte 16 pixel 32))
  1613.       (setf (aref buffer-bbuf (index+ i 2))
  1614.         (write-image-load-byte 24 pixel 32)))))))
  1615.  
  1616. (defun write-pixarray-internal
  1617.        (bbuf boffset pixarray x y width height padded-bytes-per-line
  1618.     bits-per-pixel write-pixarray-function
  1619.     from-unit from-byte-lsb-first-p from-bit-lsb-first-p
  1620.     to-unit to-byte-lsb-first-p to-bit-lsb-first-p)
  1621.   (declare (type buffer-bytes bbuf)
  1622.        (type pixarray pixarray)
  1623.        (type card16 x y width height)
  1624.        (type array-index boffset padded-bytes-per-line)
  1625.        (type (member 1 4 8 16 24 32) bits-per-pixel)
  1626.        (type function write-pixarray-function)
  1627.        (type (member 8 16 32) from-unit to-unit)
  1628.        (type boolean from-byte-lsb-first-p from-bit-lsb-first-p
  1629.          to-byte-lsb-first-p to-bit-lsb-first-p))
  1630.   (multiple-value-bind (image-swap-function image-swap-lsb-first-p)
  1631.       (image-swap-function
  1632.     bits-per-pixel
  1633.     from-unit from-byte-lsb-first-p from-bit-lsb-first-p
  1634.     to-unit to-byte-lsb-first-p to-bit-lsb-first-p)
  1635.     (declare (type symbol image-swap-function)
  1636.          (type boolean image-swap-lsb-first-p))
  1637.     (if (eq image-swap-function 'image-noswap)
  1638.     (funcall
  1639.       write-pixarray-function
  1640.       bbuf boffset pixarray x y width height padded-bytes-per-line
  1641.       bits-per-pixel)
  1642.       (with-image-data-buffer (buf (index* height padded-bytes-per-line))
  1643.     (funcall
  1644.       write-pixarray-function 
  1645.       buf 0 pixarray x y width height padded-bytes-per-line
  1646.       bits-per-pixel)
  1647.     (funcall
  1648.       (symbol-function image-swap-function) buf bbuf 0 boffset
  1649.       (index-ceiling (index* width bits-per-pixel) 8)
  1650.       padded-bytes-per-line padded-bytes-per-line height
  1651.       image-swap-lsb-first-p)))))
  1652.  
  1653. (defun write-pixarray
  1654.        (bbuf boffset pixarray x y width height padded-bytes-per-line
  1655.     bits-per-pixel unit byte-lsb-first-p bit-lsb-first-p)
  1656.   (declare (type buffer-bytes bbuf)
  1657.        (type pixarray pixarray)
  1658.        (type card16 x y width height)
  1659.        (type array-index boffset padded-bytes-per-line)
  1660.        (type (member 1 4 8 16 24 32) bits-per-pixel)
  1661.        (type (member 8 16 32) unit)
  1662.        (type boolean byte-lsb-first-p bit-lsb-first-p))
  1663.   (unless (fast-write-pixarray
  1664.         bbuf boffset pixarray x y width height padded-bytes-per-line
  1665.         bits-per-pixel unit byte-lsb-first-p bit-lsb-first-p)
  1666.     (write-pixarray-internal
  1667.       bbuf boffset pixarray x y width height padded-bytes-per-line
  1668.       bits-per-pixel
  1669.       (ecase bits-per-pixel
  1670.     ( 1 #'write-pixarray-1 )
  1671.     ( 4 #'write-pixarray-4 )
  1672.     ( 8 #'write-pixarray-8 )
  1673.     (16 #'write-pixarray-16)
  1674.     (24 #'write-pixarray-24)
  1675.     (32 #'write-pixarray-32))
  1676.       *image-unit* *image-byte-lsb-first-p* *image-bit-lsb-first-p*
  1677.       unit byte-lsb-first-p bit-lsb-first-p)))
  1678.  
  1679. (defun write-xy-format-image-x-data
  1680.        (data obuf data-start obuf-start x y width height
  1681.     from-padded-bytes-per-line to-padded-bytes-per-line
  1682.     from-bitmap-unit from-byte-lsb-first-p from-bit-lsb-first-p
  1683.     to-bitmap-unit to-byte-lsb-first-p to-bit-lsb-first-p)
  1684.   (declare (type buffer-bytes data obuf)
  1685.        (type array-index data-start obuf-start
  1686.          from-padded-bytes-per-line to-padded-bytes-per-line)
  1687.        (type card16 x y width height)
  1688.        (type (member 8 16 32) from-bitmap-unit to-bitmap-unit)
  1689.        (type boolean from-byte-lsb-first-p from-bit-lsb-first-p
  1690.          to-byte-lsb-first-p to-bit-lsb-first-p))
  1691.   (assert (index-zerop (index-mod x 8)))
  1692.   (multiple-value-bind (image-swap-function image-swap-lsb-first-p)
  1693.       (image-swap-function
  1694.     1
  1695.     from-bitmap-unit from-byte-lsb-first-p from-bit-lsb-first-p
  1696.     to-bitmap-unit to-byte-lsb-first-p to-bit-lsb-first-p)
  1697.     (declare (type symbol image-swap-function)
  1698.          (type boolean image-swap-lsb-first-p))
  1699.     (let ((x-mod-unit (index-mod x from-bitmap-unit)))
  1700.       (declare (type card16 x-mod-unit))
  1701.       (if (and (index-plusp x-mod-unit)
  1702.            (not (eq from-byte-lsb-first-p from-bit-lsb-first-p)))
  1703.       (let* ((temp-width (index+ width x-mod-unit))
  1704.          (temp-bytes-per-line (index-ceiling temp-width 8))
  1705.          (temp-padded-bits-per-line
  1706.            (index* (index-ceiling temp-width from-bitmap-unit)
  1707.                from-bitmap-unit))
  1708.          (temp-padded-bytes-per-line
  1709.            (index-ceiling temp-padded-bits-per-line 8)))
  1710.         (declare (type card16 temp-width temp-bytes-per-line
  1711.                temp-padded-bits-per-line temp-padded-bytes-per-line))
  1712.         (with-image-data-buffer
  1713.          (buf (index* height temp-padded-bytes-per-line))
  1714.           (funcall
  1715.         (symbol-function image-swap-function) data buf
  1716.         (index+ data-start
  1717.             (index* y from-padded-bytes-per-line)
  1718.             (index-floor (index- x x-mod-unit) 8))
  1719.         0 temp-bytes-per-line from-padded-bytes-per-line
  1720.         temp-padded-bytes-per-line height image-swap-lsb-first-p)
  1721.           (write-xy-format-image-x-data
  1722.         buf obuf 0 obuf-start x-mod-unit 0 width height
  1723.         temp-padded-bytes-per-line to-padded-bytes-per-line
  1724.         from-bitmap-unit to-byte-lsb-first-p to-byte-lsb-first-p
  1725.         to-bitmap-unit to-byte-lsb-first-p to-bit-lsb-first-p)))
  1726.     (funcall
  1727.       (symbol-function image-swap-function) data obuf 
  1728.       (index+ data-start
  1729.           (index* y from-padded-bytes-per-line)
  1730.           (index-floor x 8))
  1731.       obuf-start (index-ceiling width 8) from-padded-bytes-per-line
  1732.       to-padded-bytes-per-line height image-swap-lsb-first-p)))))
  1733.  
  1734. (defun write-xy-format-image-x
  1735.        (display image src-x src-y width height
  1736.     padded-bytes-per-line
  1737.     unit byte-lsb-first-p bit-lsb-first-p)
  1738.   (declare (type display display)
  1739.        (type image-x image)
  1740.        (type int16 src-x src-y)
  1741.        (type card16 width height)
  1742.        (type array-index padded-bytes-per-line)
  1743.        (type (member 8 16 32) unit)
  1744.        (type boolean byte-lsb-first-p bit-lsb-first-p))
  1745.   (dotimes (plane (image-depth image))
  1746.     (let ((data-start
  1747.         (index* (index* plane (image-height image))
  1748.             (image-x-bytes-per-line image)))
  1749.       (src-y src-y)
  1750.       (height height))
  1751.       (declare (type int16 src-y)
  1752.            (type card16 height))
  1753.       (loop 
  1754.     (when (index-zerop height) (return))
  1755.     (let ((nlines
  1756.         (index-min (index-floor (index- (buffer-size display)
  1757.                         (buffer-boffset display))
  1758.                     padded-bytes-per-line)
  1759.                height)))
  1760.       (declare (type array-index nlines))
  1761.       (when (index-plusp nlines)
  1762.         (write-xy-format-image-x-data
  1763.           (image-x-data image) (buffer-obuf8 display)
  1764.           data-start (buffer-boffset display)
  1765.           src-x src-y width nlines 
  1766.           (image-x-bytes-per-line image) padded-bytes-per-line
  1767.           (image-x-unit image) (image-x-byte-lsb-first-p image)
  1768.           (image-x-bit-lsb-first-p image)
  1769.           unit byte-lsb-first-p bit-lsb-first-p)
  1770.         (index-incf (buffer-boffset display)
  1771.             (index* nlines padded-bytes-per-line))
  1772.         (index-incf src-y nlines)
  1773.         (when (index-zerop (index-decf height nlines)) (return))))
  1774.     (buffer-flush display)))))
  1775.  
  1776. (defun write-z-format-image-x-data
  1777.        (data obuf data-start obuf-start x y width height
  1778.     from-padded-bytes-per-line to-padded-bytes-per-line
  1779.     bits-per-pixel
  1780.     from-bitmap-unit from-byte-lsb-first-p from-bit-lsb-first-p
  1781.     to-bitmap-unit to-byte-lsb-first-p to-bit-lsb-first-p)
  1782.   (declare (type buffer-bytes data obuf)
  1783.        (type array-index data-start obuf-start
  1784.          from-padded-bytes-per-line to-padded-bytes-per-line)
  1785.        (type card16 x y width height)
  1786.        (type (member 1 4 8 16 24 32) bits-per-pixel)
  1787.        (type (member 8 16 32) from-bitmap-unit to-bitmap-unit)
  1788.        (type boolean from-byte-lsb-first-p from-bit-lsb-first-p
  1789.          to-byte-lsb-first-p to-bit-lsb-first-p))
  1790.   (if (index= bits-per-pixel 1)
  1791.       (write-xy-format-image-x-data
  1792.     data obuf data-start obuf-start x y width height
  1793.     from-padded-bytes-per-line to-padded-bytes-per-line
  1794.     from-bitmap-unit from-byte-lsb-first-p from-bit-lsb-first-p
  1795.     to-bitmap-unit to-byte-lsb-first-p to-bit-lsb-first-p)
  1796.     (let ((srcoff
  1797.         (index+ data-start
  1798.             (index* y from-padded-bytes-per-line)
  1799.             (index-floor (index* x bits-per-pixel) 8)))
  1800.       (srclen (index-ceiling (index* width bits-per-pixel) 8)))
  1801.       (declare (type array-index srcoff srclen))
  1802.       (if (and (index= bits-per-pixel 4) (index-oddp x))
  1803.       (with-image-data-buffer (buf (index* height to-padded-bytes-per-line))
  1804.         (image-swap-nibbles-left
  1805.           data buf srcoff 0 srclen
  1806.           from-padded-bytes-per-line to-padded-bytes-per-line height nil)
  1807.         (write-z-format-image-x-data
  1808.           buf obuf 0 obuf-start 0 0 width height
  1809.           to-padded-bytes-per-line to-padded-bytes-per-line
  1810.           bits-per-pixel
  1811.           from-bitmap-unit from-byte-lsb-first-p from-bit-lsb-first-p
  1812.           to-bitmap-unit to-byte-lsb-first-p to-bit-lsb-first-p))
  1813.     (multiple-value-bind (image-swap-function image-swap-lsb-first-p)
  1814.         (image-swap-function
  1815.           bits-per-pixel
  1816.           from-bitmap-unit from-byte-lsb-first-p from-bit-lsb-first-p
  1817.           to-bitmap-unit to-byte-lsb-first-p to-bit-lsb-first-p)
  1818.       (declare (type symbol image-swap-function)
  1819.            (type boolean image-swap-lsb-first-p))
  1820.       (funcall
  1821.         (symbol-function image-swap-function) data obuf srcoff obuf-start
  1822.         srclen from-padded-bytes-per-line to-padded-bytes-per-line height
  1823.         image-swap-lsb-first-p))))))
  1824.  
  1825. (defun write-z-format-image-x (display image src-x src-y width height
  1826.                    padded-bytes-per-line
  1827.                    unit byte-lsb-first-p bit-lsb-first-p)
  1828.   (declare (type display display)
  1829.        (type image-x image)
  1830.        (type int16 src-x src-y)
  1831.        (type card16 width height)
  1832.        (type array-index padded-bytes-per-line)
  1833.        (type boolean byte-lsb-first-p bit-lsb-first-p))
  1834.   (loop 
  1835.     (when (index-zerop height) (return))
  1836.     (let ((nlines
  1837.         (index-min (index-floor (index- (buffer-size display)
  1838.                         (buffer-boffset display))
  1839.                     padded-bytes-per-line)
  1840.                height)))
  1841.       (declare (type array-index nlines))
  1842.       (when (index-plusp nlines)
  1843.     (write-z-format-image-x-data 
  1844.       (image-x-data image) (buffer-obuf8 display) 0 (buffer-boffset display)
  1845.       src-x src-y width nlines
  1846.       (image-x-bytes-per-line image) padded-bytes-per-line
  1847.       (image-x-bits-per-pixel image)
  1848.       (image-x-unit image) (image-x-byte-lsb-first-p image)
  1849.       (image-x-bit-lsb-first-p image)
  1850.       unit byte-lsb-first-p bit-lsb-first-p)
  1851.     (index-incf (buffer-boffset display)
  1852.             (index* nlines padded-bytes-per-line))
  1853.     (index-incf src-y nlines)
  1854.     (when (index-zerop (index-decf height nlines)) (return))))
  1855.     (buffer-flush display)))
  1856.  
  1857. (defun write-image-xy (display image src-x src-y width height
  1858.                padded-bytes-per-line
  1859.                unit byte-lsb-first-p bit-lsb-first-p)
  1860.   (declare (type display display)
  1861.        (type image-xy image)
  1862.        (type array-index padded-bytes-per-line)
  1863.        (type int16 src-x src-y)
  1864.        (type card16 width height)
  1865.        (type (member 8 16 32) unit)
  1866.        (type boolean byte-lsb-first-p bit-lsb-first-p))
  1867.   (dolist (bitmap (image-xy-bitmap-list image))
  1868.     (declare (type pixarray-1 bitmap))
  1869.     (let ((src-y src-y)
  1870.       (height height))
  1871.       (declare (type int16 src-y)
  1872.            (type card16 height))
  1873.       (loop 
  1874.     (let ((nlines
  1875.         (index-min (index-floor (index- (buffer-size display)
  1876.                         (buffer-boffset display))
  1877.                     padded-bytes-per-line)
  1878.                height)))
  1879.       (declare (type array-index nlines))
  1880.       (when (index-plusp nlines)
  1881.         (write-pixarray 
  1882.           (buffer-obuf8 display) (buffer-boffset display)
  1883.           bitmap src-x src-y width nlines
  1884.           padded-bytes-per-line 1
  1885.           unit byte-lsb-first-p bit-lsb-first-p)
  1886.         (index-incf (buffer-boffset display)
  1887.             (index* nlines padded-bytes-per-line))
  1888.         (index-incf src-y nlines)
  1889.         (when (index-zerop (index-decf height nlines)) (return))))
  1890.     (buffer-flush display)))))
  1891.  
  1892. (defun write-image-z (display image src-x src-y width height
  1893.               padded-bytes-per-line
  1894.               unit byte-lsb-first-p bit-lsb-first-p)
  1895.   (declare (type display display)
  1896.        (type image-z image)
  1897.        (type array-index padded-bytes-per-line)
  1898.        (type int16 src-x src-y)
  1899.        (type card16 width height)
  1900.        (type (member 8 16 32) unit)
  1901.        (type boolean byte-lsb-first-p bit-lsb-first-p))
  1902.   (loop 
  1903.     (let ((bits-per-pixel (image-z-bits-per-pixel image))
  1904.       (nlines
  1905.         (index-min (index-floor (index- (buffer-size display)
  1906.                         (buffer-boffset display))
  1907.                     padded-bytes-per-line)
  1908.                height)))
  1909.       (declare (type (member 1 4 8 16 24 32) bits-per-pixel)
  1910.            (type array-index nlines))
  1911.       (when (index-plusp nlines)
  1912.     (write-pixarray
  1913.       (buffer-obuf8 display) (buffer-boffset display)
  1914.       (image-z-pixarray image) src-x src-y width nlines
  1915.       padded-bytes-per-line bits-per-pixel
  1916.       unit byte-lsb-first-p bit-lsb-first-p)
  1917.     (index-incf (buffer-boffset display)
  1918.             (index* nlines padded-bytes-per-line))
  1919.     (index-incf src-y nlines)
  1920.     (when (index-zerop (index-decf height nlines)) (return))))
  1921.     (buffer-flush display)))
  1922.  
  1923. ;;; Note:    The only difference between a format of :bitmap and :xy-pixmap
  1924. ;;;        of depth 1 is that when sending a :bitmap format the foreground 
  1925. ;;;        and background in the gcontext are used.
  1926.  
  1927. (defun put-image (drawable gcontext image &key
  1928.           (src-x 0) (src-y 0)        ;Position within image
  1929.           (x (required-arg x))        ;Position within drawable
  1930.           (y (required-arg y))
  1931.           width height
  1932.           bitmap-p)
  1933.   ;; Copy an image into a drawable.
  1934.   ;; WIDTH and HEIGHT default from IMAGE.
  1935.   ;; When BITMAP-P, force format to be :bitmap when depth=1.
  1936.   ;; This causes gcontext to supply foreground & background pixels.
  1937.   (declare (type drawable drawable)
  1938.        (type gcontext gcontext)
  1939.        (type image image)
  1940.        (type int16 x y) ;; required
  1941.        (type int16 src-x src-y)
  1942.        (type (or null card16) width height)
  1943.        (type boolean bitmap-p))
  1944.   (let* ((format
  1945.        (etypecase image
  1946.          (image-x (image-x-format (the image-x image)))
  1947.          (image-xy :xy-pixmap)
  1948.          (image-z :z-pixmap)))
  1949.      (src-x
  1950.        (if (image-x-p image)
  1951.            (index+ src-x (image-x-left-pad (the image-x image)))
  1952.          src-x))
  1953.      (image-width (image-width image))
  1954.      (image-height (image-height image))
  1955.      (width (min (or width image-width) (index- image-width src-x)))
  1956.      (height (min (or height image-height) (index- image-height src-y)))
  1957.      (depth (image-depth image))
  1958.      (display (drawable-display drawable))
  1959.      (bitmap-format (display-bitmap-format display))
  1960.      (unit (bitmap-format-unit bitmap-format))
  1961.      (byte-lsb-first-p (display-image-lsb-first-p display))
  1962.      (bit-lsb-first-p  (bitmap-format-lsb-first-p bitmap-format)))
  1963.     (declare (type (member :bitmap :xy-pixmap :z-pixmap) format)
  1964.          (type card16 src-x image-width image-height width height)
  1965.          (type image-depth depth)
  1966.          (type display display)
  1967.          (type bitmap-format bitmap-format)
  1968.          (type (member 8 16 32) unit)
  1969.          (type boolean byte-lsb-first-p bit-lsb-first-p))
  1970.     (when (and bitmap-p (not (index= depth 1)))
  1971.       (error "Bitmaps must have depth 1"))
  1972.     (unless (index<= 0 src-x (index1- (image-width image)))
  1973.       (error "src-x not inside image"))
  1974.     (unless (index<= 0 src-y (index1- (image-height image)))
  1975.       (error "src-y not inside image"))
  1976.     (when (and (index> width 0) (index> height 0))
  1977.       (multiple-value-bind (pad bits-per-pixel)
  1978.       (ecase format
  1979.         ((:bitmap :xy-pixmap)
  1980.           (values (bitmap-format-pad bitmap-format) 1))
  1981.         (:z-pixmap
  1982.           (if (= depth 1) 
  1983.           (values (bitmap-format-pad bitmap-format) 1)
  1984.         (let ((pixmap-format
  1985.             (find depth (display-pixmap-formats display)
  1986.                   :key #'pixmap-format-depth)))
  1987.           (declare (type (or null pixmap-format) pixmap-format))
  1988.           (if (null pixmap-format)
  1989.               (error "The depth of the image ~s does not match any server pixmap format." image))
  1990.           (if (not (= (typecase image
  1991.                 (image-z (image-z-bits-per-pixel image))
  1992.                 (image-x (image-x-bits-per-pixel image)))
  1993.                   (pixmap-format-bits-per-pixel pixmap-format)))
  1994.               ;; We could try to use the "/* XXX slow, but works */"
  1995.               ;; code in XPutImage from X11R4 here.  However, that
  1996.               ;; would require considerable support code
  1997.               ;; (see XImUtil.c, etc).
  1998.               (error "The bits-per-pixel of the image ~s does not match any server pixmap format." image))
  1999.           (values (pixmap-format-scanline-pad pixmap-format)
  2000.               (pixmap-format-bits-per-pixel pixmap-format))))))
  2001.     (declare (type (member 8 16 32) pad)
  2002.          (type (member 1 4 8 16 24 32) bits-per-pixel))
  2003.     (let* ((left-pad
  2004.          (if (or (eq format :xy-pixmap) (= depth 1))
  2005.              (index-mod src-x (index-min pad *image-pad*))
  2006.            0))
  2007.            (left-padded-src-x (index- src-x left-pad))
  2008.            (left-padded-width (index+ width left-pad))
  2009.            (bits-per-line (index* left-padded-width bits-per-pixel))
  2010.            (padded-bits-per-line
  2011.          (index* (index-ceiling bits-per-line pad) pad))
  2012.            (padded-bytes-per-line (index-ceiling padded-bits-per-line 8))
  2013.            (request-bytes-per-line
  2014.          (ecase format
  2015.            ((:bitmap :xy-pixmap) (index* padded-bytes-per-line depth))
  2016.            (:z-pixmap padded-bytes-per-line)))
  2017.            (max-bytes-per-request
  2018.          (index* (index- (display-max-request-length display) 6) 4))
  2019.            (max-request-height
  2020.          (floor max-bytes-per-request request-bytes-per-line)))
  2021.       (declare (type card8 left-pad)
  2022.            (type int16 left-padded-src-x)
  2023.            (type card16 left-padded-width)
  2024.            (type array-index bits-per-line padded-bits-per-line
  2025.              padded-bytes-per-line request-bytes-per-line
  2026.              max-bytes-per-request max-request-height))
  2027.       ;; Be sure that a scanline can fit in a request
  2028.       (when (index-zerop max-request-height)
  2029.         (error "Can't even fit one image scanline in a request"))
  2030.       ;; Be sure a scanline can fit in a buffer
  2031.       (buffer-ensure-size display padded-bytes-per-line)
  2032.       ;; Send the image in multiple requests to avoid exceeding the
  2033.       ;; request limit
  2034.       (do* ((request-src-y src-y (index+ request-src-y request-height))
  2035.         (request-y y (index+ request-y request-height))
  2036.         (height-remaining
  2037.           height (index- height-remaining request-height))
  2038.         (request-height
  2039.           (index-min height-remaining max-request-height)
  2040.           (index-min height-remaining max-request-height)))
  2041.            ((index<= height-remaining 0))
  2042.         (declare (type array-index request-src-y height-remaining
  2043.                request-height))
  2044.         (let* ((request-bytes (index* request-bytes-per-line request-height))
  2045.            (request-words (index-ceiling request-bytes 4))
  2046.            (request-length (index+ request-words 6)))
  2047.           (declare (type array-index request-bytes)
  2048.                (type card16 request-words request-length))
  2049.           (with-buffer-request (display *x-putimage* :gc-force gcontext)
  2050.         ((data (member :bitmap :xy-pixmap :z-pixmap))
  2051.          (cond ((or (eq format :bitmap) bitmap-p) :bitmap)
  2052.                ((plusp left-pad) :xy-pixmap)
  2053.                (t format)))
  2054.         (drawable drawable)
  2055.         (gcontext gcontext)
  2056.         (card16 width request-height)
  2057.         (int16 x request-y)
  2058.         (card8 left-pad depth)
  2059.         (pad16 nil)
  2060.         (progn 
  2061.           (length-put 2 request-length)
  2062.           (setf (buffer-boffset display) (advance-buffer-offset 24))
  2063.           (etypecase image
  2064.             (image-x
  2065.               (ecase (image-x-format (the image-x image))
  2066.             ((:bitmap :xy-pixmap)
  2067.               (write-xy-format-image-x
  2068.                 display image left-padded-src-x request-src-y
  2069.                 left-padded-width request-height
  2070.                 padded-bytes-per-line
  2071.                 unit byte-lsb-first-p bit-lsb-first-p))
  2072.             (:z-pixmap
  2073.               (write-z-format-image-x
  2074.                 display image left-padded-src-x request-src-y
  2075.                 left-padded-width request-height
  2076.                 padded-bytes-per-line
  2077.                 unit byte-lsb-first-p bit-lsb-first-p))))
  2078.             (image-xy
  2079.               (write-image-xy
  2080.             display image left-padded-src-x request-src-y
  2081.             left-padded-width request-height
  2082.             padded-bytes-per-line
  2083.             unit byte-lsb-first-p bit-lsb-first-p))
  2084.             (image-z
  2085.               (write-image-z
  2086.             display image left-padded-src-x request-src-y
  2087.             left-padded-width request-height
  2088.             padded-bytes-per-line
  2089.             unit byte-lsb-first-p bit-lsb-first-p)))
  2090.           ;; Be sure the request is padded to a multiple of 4 bytes
  2091.           (buffer-pad-request display (index- (index* request-words 4) request-bytes))
  2092.           )))))))))
  2093.  
  2094. ;;;-----------------------------------------------------------------------------
  2095. ;;; COPY-IMAGE
  2096.  
  2097. (defun xy-format-image-x->image-x (image x y width height)
  2098.   (declare (type image-x image)
  2099.        (type card16 x y width height)
  2100.        (values image-x))
  2101.   (let* ((padded-x (index+ x (image-x-left-pad image)))
  2102.      (left-pad (index-mod padded-x 8))
  2103.      (x (index- padded-x left-pad))
  2104.      (unit (image-x-unit image))
  2105.      (byte-lsb-first-p (image-x-byte-lsb-first-p image))
  2106.      (bit-lsb-first-p (image-x-bit-lsb-first-p image))
  2107.      (pad (image-x-pad image))
  2108.      (padded-width
  2109.        (index* (index-ceiling (index+ width left-pad) pad) pad))
  2110.      (padded-bytes-per-line (index-ceiling padded-width 8))
  2111.      (padded-bytes-per-plane (index* padded-bytes-per-line height))
  2112.      (length (index* padded-bytes-per-plane (image-depth image)))
  2113.      (obuf (make-array length :element-type 'card8)))
  2114.     (declare (type card16 x)
  2115.          (type card8 left-pad)
  2116.          (type (member 8 16 32) unit pad)
  2117.          (type array-index padded-width padded-bytes-per-line
  2118.            padded-bytes-per-plane length)
  2119.          (type buffer-bytes obuf))
  2120.     (dotimes (plane (image-depth image))
  2121.       (let ((data-start
  2122.           (index* (image-x-bytes-per-line image)
  2123.               (image-height image)
  2124.               plane))
  2125.         (obuf-start
  2126.           (index* padded-bytes-per-plane
  2127.               plane)))
  2128.     (declare (type array-index data-start obuf-start))
  2129.     (write-xy-format-image-x-data
  2130.       (image-x-data image) obuf data-start obuf-start
  2131.       x y width height 
  2132.       (image-x-bytes-per-line image) padded-bytes-per-line
  2133.       unit byte-lsb-first-p bit-lsb-first-p
  2134.       unit byte-lsb-first-p bit-lsb-first-p)))
  2135.     (create-image
  2136.       :width width :height height :depth (image-depth image)
  2137.       :data obuf :format (image-x-format image) :bits-per-pixel 1
  2138.       :bytes-per-line padded-bytes-per-line
  2139.       :unit unit :pad pad :left-pad left-pad
  2140.       :byte-lsb-first-p byte-lsb-first-p :bit-lsb-first-p bit-lsb-first-p)))
  2141.  
  2142. (defun z-format-image-x->image-x (image x y width height)
  2143.   (declare (type image-x image)
  2144.        (type card16 x y width height)
  2145.        (values image-x))
  2146.   (let* ((padded-x (index+ x (image-x-left-pad image)))
  2147.      (left-pad
  2148.        (if (index= (image-depth image) 1)
  2149.            (index-mod padded-x 8)
  2150.          0))
  2151.      (x (index- padded-x left-pad))
  2152.      (bits-per-pixel (image-x-bits-per-pixel image))
  2153.      (unit (image-x-unit image))
  2154.      (byte-lsb-first-p (image-x-byte-lsb-first-p image))
  2155.      (bit-lsb-first-p (image-x-bit-lsb-first-p image))
  2156.      (pad (image-x-pad image))
  2157.      (bits-per-line (index* (index+ width left-pad) bits-per-pixel))
  2158.      (padded-bits-per-line (index* (index-ceiling bits-per-line pad) pad))
  2159.      (padded-bytes-per-line (index-ceiling padded-bits-per-line 8))
  2160.      (padded-bytes-per-plane (index* padded-bytes-per-line height))
  2161.      (length (index* padded-bytes-per-plane (image-depth image)))
  2162.      (obuf (make-array length :element-type 'card8)))
  2163.     (declare (type card16 x)
  2164.          (type card8 left-pad)
  2165.          (type (member 8 16 32) unit pad)
  2166.          (type array-index bits-per-pixel padded-bytes-per-line
  2167.            padded-bytes-per-plane length)
  2168.          (type buffer-bytes obuf))
  2169.     (write-z-format-image-x-data
  2170.       (image-x-data image) obuf 0 0
  2171.       x y width height 
  2172.       (image-x-bytes-per-line image) padded-bytes-per-line
  2173.       bits-per-pixel
  2174.       unit byte-lsb-first-p bit-lsb-first-p
  2175.       unit byte-lsb-first-p bit-lsb-first-p)
  2176.     (create-image
  2177.       :width width :height height :depth (image-depth image)
  2178.       :data obuf :format :z-pixmap :bits-per-pixel bits-per-pixel
  2179.       :bytes-per-line padded-bytes-per-line
  2180.       :unit unit :pad pad :left-pad left-pad
  2181.       :byte-lsb-first-p byte-lsb-first-p :bit-lsb-first-p bit-lsb-first-p)))
  2182.  
  2183. (defun image-x->image-x  (image x y width height)
  2184.   (declare (type image-x image)
  2185.        (type card16 x y width height)
  2186.        (values image-x))
  2187.   (ecase (image-x-format image)
  2188.     ((:bitmap :xy-pixmap)
  2189.       (xy-format-image-x->image-x image x y width height))
  2190.     (:z-pixmap
  2191.       (z-format-image-x->image-x image x y width height))))
  2192.  
  2193. (defun image-x->image-xy (image x y width height)
  2194.   (declare (type image-x image)
  2195.        (type card16 x y width height)
  2196.        (values image-xy))
  2197.   (unless (or (eq (image-x-format image) :bitmap)
  2198.           (eq (image-x-format image) :xy-pixmap)
  2199.           (and (eq (image-x-format image) :z-pixmap)
  2200.            (index= (image-depth image) 1)))
  2201.     (error "Format conversion from ~S to ~S not supported"
  2202.        (image-x-format image) :xy-pixmap))
  2203.   (read-image-xy
  2204.     (image-x-data image) 0 (length (image-x-data image)) nil
  2205.     (index+ x (image-x-left-pad image)) y width height
  2206.     (image-depth image) (image-x-bytes-per-line image)
  2207.     (index* (image-x-bytes-per-line image) (image-height image))
  2208.     (image-x-unit image) (image-x-byte-lsb-first-p image)
  2209.     (image-x-bit-lsb-first-p image)))
  2210.  
  2211. (defun image-x->image-z  (image x y width height)
  2212.   (declare (type image-x image)
  2213.        (type card16 x y width height)
  2214.        (values image-z))
  2215.   (unless (or (eq (image-x-format image) :z-pixmap)
  2216.           (eq (image-x-format image) :bitmap)
  2217.           (and (eq (image-x-format image) :xy-pixmap)
  2218.            (index= (image-depth image) 1)))
  2219.     (error "Format conversion from ~S to ~S not supported"
  2220.        (image-x-format image) :z-pixmap))
  2221.   (read-image-z
  2222.     (image-x-data image) 0 (length (image-x-data image)) nil
  2223.     (index+ x (image-x-left-pad image)) y width height
  2224.     (image-depth image) (image-x-bytes-per-line image)
  2225.     (image-x-bits-per-pixel image)
  2226.     (image-x-unit image) (image-x-byte-lsb-first-p image)
  2227.     (image-x-bit-lsb-first-p image)))
  2228.  
  2229. (defun copy-pixarray (array x y width height bits-per-pixel)
  2230.   (declare (type pixarray array)
  2231.        (type card16 x y width height)
  2232.        (type (member 1 4 8 16 24 32) bits-per-pixel))
  2233.   (let* ((bits-per-line (index* bits-per-pixel width))
  2234.      (padded-bits-per-line
  2235.        (index* (index-ceiling bits-per-line *image-pad*) *image-pad*))
  2236.      (padded-width (index-ceiling padded-bits-per-line bits-per-pixel))
  2237.      (copy (make-array (list height padded-width)
  2238.                :element-type (array-element-type array))))
  2239.     (declare (type array-index bits-per-line padded-bits-per-line padded-width)
  2240.          (type pixarray copy))
  2241.     #.(declare-buffun)
  2242.     (unless (fast-copy-pixarray array copy x y width height bits-per-pixel)
  2243.       (macrolet
  2244.     ((copy (array-type element-type)
  2245.        `(let ((array array)
  2246.           (copy copy))
  2247.           (declare (type ,array-type array copy))
  2248.           (do* ((dst-y 0 (index1+ dst-y))
  2249.             (src-y y (index1+ src-y)))
  2250.            ((index>= dst-y height))
  2251.         (declare (type card16 dst-y src-y))
  2252.         (do* ((dst-x 0 (index1+ dst-x))
  2253.               (src-x x (index1+ src-x)))
  2254.              ((index>= dst-x width))
  2255.           (declare (type card16 dst-x src-x))
  2256.           (setf (aref copy dst-y dst-x)
  2257.             (the ,element-type
  2258.                  (aref array src-y src-x))))))))
  2259.     (ecase bits-per-pixel
  2260.       (1  (copy pixarray-1  pixarray-1-element-type))
  2261.       (4  (copy pixarray-4  pixarray-4-element-type))
  2262.       (8  (copy pixarray-8  pixarray-8-element-type))
  2263.       (16 (copy pixarray-16 pixarray-16-element-type))
  2264.       (24 (copy pixarray-24 pixarray-24-element-type))
  2265.       (32 (copy pixarray-32 pixarray-32-element-type)))))
  2266.     copy))
  2267.  
  2268. (defun image-xy->image-x (image x y width height)
  2269.   (declare (type image-xy image)
  2270.        (type card16 x y width height)
  2271.        (values image-x))
  2272.   (let* ((padded-bits-per-line
  2273.        (index* (index-ceiling width *image-pad*) *image-pad*))
  2274.      (padded-bytes-per-line (index-ceiling padded-bits-per-line 8))
  2275.      (padded-bytes-per-plane (index* padded-bytes-per-line height))
  2276.      (bytes-total (index* padded-bytes-per-plane (image-depth image)))
  2277.      (data (make-array bytes-total :element-type 'card8)))
  2278.     (declare (type array-index padded-bits-per-line padded-bytes-per-line
  2279.            padded-bytes-per-plane bytes-total)
  2280.          (type buffer-bytes data))
  2281.     (let ((index 0))
  2282.       (declare (type array-index index))
  2283.       (dolist (bitmap (image-xy-bitmap-list image))
  2284.     (declare (type pixarray-1 bitmap))
  2285.     (write-pixarray
  2286.       data index bitmap x y width height padded-bytes-per-line 1
  2287.       *image-unit* *image-byte-lsb-first-p* *image-bit-lsb-first-p*)
  2288.     (index-incf index padded-bytes-per-plane)))
  2289.     (create-image
  2290.       :width width :height height :depth (image-depth image)
  2291.       :data data :format :xy-pixmap :bits-per-pixel 1
  2292.       :bytes-per-line padded-bytes-per-line
  2293.       :unit *image-unit* :pad *image-pad*
  2294.       :byte-lsb-first-p *image-byte-lsb-first-p*
  2295.       :bit-lsb-first-p *image-bit-lsb-first-p*)))
  2296.  
  2297. (defun image-xy->image-xy (image x y width height)
  2298.   (declare (type image-xy image)
  2299.        (type card16 x y width height)
  2300.        (values image-xy))
  2301.   (create-image
  2302.     :width width :height height :depth (image-depth image)
  2303.     :data (mapcar
  2304.         #'(lambda (array)
  2305.         (declare (type pixarray-1 array))
  2306.         (copy-pixarray array x y width height 1))
  2307.         (image-xy-bitmap-list image))))
  2308.  
  2309. (defun image-xy->image-z (image x y width height)
  2310.   (declare (type image-z image)
  2311.        (type card16 x y width height)
  2312.        (ignore image x y width height))
  2313.   (error "Format conversion from ~S to ~S not supported"
  2314.      :xy-pixmap :z-pixmap))
  2315.  
  2316. (defun image-z->image-x (image x y width height)
  2317.   (declare (type image-z image)
  2318.        (type card16 x y width height)
  2319.        (values image-x))
  2320.   (let* ((bits-per-line (index* width (image-z-bits-per-pixel image)))
  2321.      (padded-bits-per-line
  2322.        (index* (index-ceiling bits-per-line *image-pad*) *image-pad*))
  2323.      (padded-bytes-per-line (index-ceiling padded-bits-per-line 8))
  2324.      (bytes-total
  2325.        (index* padded-bytes-per-line height (image-depth image)))
  2326.      (data (make-array bytes-total :element-type 'card8))
  2327.      (bits-per-pixel (image-z-bits-per-pixel image)))
  2328.     (declare (type array-index bits-per-line padded-bits-per-line
  2329.            padded-bytes-per-line bytes-total)
  2330.          (type buffer-bytes data)
  2331.          (type (member 1 4 8 16 24 32) bits-per-pixel))
  2332.     (write-pixarray
  2333.       data 0 (image-z-pixarray image) x y width height padded-bytes-per-line 
  2334.       (image-z-bits-per-pixel image)
  2335.       *image-unit* *image-byte-lsb-first-p* *image-bit-lsb-first-p*)
  2336.     (create-image
  2337.       :width width :height height :depth (image-depth image)
  2338.       :data data :format :z-pixmap
  2339.       :bits-per-pixel bits-per-pixel
  2340.       :bytes-per-line padded-bytes-per-line
  2341.       :unit *image-unit* :pad *image-pad*
  2342.       :byte-lsb-first-p *image-byte-lsb-first-p*
  2343.       :bit-lsb-first-p *image-bit-lsb-first-p*)))
  2344.  
  2345. (defun image-z->image-xy (image x y width height)
  2346.   (declare (type image-z image)
  2347.        (type card16 x y width height)
  2348.        (ignore image x y width height))
  2349.   (error "Format conversion from ~S to ~S not supported"
  2350.      :z-pixmap :xy-pixmap))
  2351.  
  2352. (defun image-z->image-z (image x y width height)
  2353.   (declare (type image-z image)
  2354.        (type card16 x y width height)
  2355.        (values image-z))
  2356.   (create-image
  2357.     :width width :height height :depth (image-depth image)
  2358.     :data (copy-pixarray
  2359.         (image-z-pixarray image) x y width height
  2360.         (image-z-bits-per-pixel image))))
  2361.  
  2362. (defun copy-image (image &key (x 0) (y 0) width height result-type)
  2363.   ;; Copy with optional sub-imaging and format conversion.
  2364.   ;; result-type defaults to (type-of image)
  2365.   (declare (type image image)
  2366.        (type card16 x y)
  2367.        (type (or null card16) width height) ;; Default from image
  2368.        (type (or null (member image-x image-xy image-z)) result-type))
  2369.   (declare (values image))
  2370.   (let* ((image-width (image-width image))
  2371.      (image-height (image-height image))
  2372.      (width (or width image-width))
  2373.      (height (or height image-height)))
  2374.     (declare (type card16 image-width image-height width height))
  2375.     (unless (index<= 0 x (index1- image-width)) (error "x not inside image"))
  2376.     (unless (index<= 0 y (index1- image-height)) (error "y not inside image"))
  2377.     (setq width (index-min width (index-max (index- image-width x) 0)))
  2378.     (setq height (index-min height (index-max (index- image-height y) 0)))
  2379.     (let ((copy
  2380.         (etypecase image
  2381.           (image-x
  2382.         (ecase result-type
  2383.           ((nil image-x) (image-x->image-x image x y width height))
  2384.           (image-xy (image-x->image-xy image x y width height))
  2385.           (image-z  (image-x->image-z  image x y width height))))
  2386.           (image-xy
  2387.         (ecase result-type
  2388.           (image-x (image-xy->image-x image x y width height))
  2389.           ((nil image-xy) (image-xy->image-xy image x y width height))
  2390.           (image-z  (image-xy->image-z image x y width height))))
  2391.           (image-z 
  2392.         (ecase result-type
  2393.           (image-x (image-z->image-x image x y width height))
  2394.           (image-xy  (image-z->image-xy image x y width height))
  2395.           ((nil image-z) (image-z->image-z image x y width height)))))))
  2396.       (declare (type image copy))
  2397.       (setf (image-plist copy) (copy-list (image-plist image)))
  2398.       (when (and (image-x-hot image) (not (index-zerop x)))
  2399.     (setf (image-x-hot copy) (index- (image-x-hot image) x)))
  2400.       (when (and (image-y-hot image) (not (index-zerop y)))
  2401.     (setf (image-y-hot copy) (index- (image-y-hot image) y)))
  2402.       copy)))
  2403.  
  2404.  
  2405. ;;;-----------------------------------------------------------------------------
  2406. ;;; Image I/O functions
  2407.  
  2408.  
  2409. (defun read-bitmap-file (pathname)
  2410.   ;; Creates an image from a C include file in standard X11 format
  2411.   (declare (type (or pathname string stream) pathname))
  2412.   (declare (values image))
  2413.   (with-open-file (fstream pathname :direction :input)
  2414.     (let ((line "")
  2415.       (properties nil)
  2416.       (name nil)
  2417.       (name-end nil))
  2418.       (declare (type string line)
  2419.            (type stringable name)
  2420.            (type list properties))
  2421.       ;; Get properties
  2422.       (loop
  2423.     (setq line (read-line fstream))
  2424.     (unless (char= (aref line 0) #\#) (return))
  2425.     (flet ((read-keyword (line start end)
  2426.          (kintern
  2427.            (substitute
  2428.              #\- #\_
  2429.              (#-excl string-upcase
  2430.               #+excl correct-case
  2431.               (subseq line start end))
  2432.              :test #'char=))))
  2433.       (when (null name)
  2434.         (setq name-end (position #\_ line :test #'char= :from-end t)
  2435.           name (read-keyword line 8 name-end))
  2436.         (unless (eq name :image)
  2437.           (setf (getf properties :name) name)))
  2438.       (let* ((ind-start (index1+ name-end))
  2439.          (ind-end (position #\Space line :test #'char=
  2440.                     :start ind-start))
  2441.          (ind (read-keyword line ind-start ind-end))
  2442.          (val-start (index1+ ind-end))
  2443.          (val (parse-integer line :start val-start)))
  2444.         (setf (getf properties ind) val))))
  2445.       ;; Calculate sizes
  2446.       (multiple-value-bind (width height depth left-pad)
  2447.       (flet ((extract-property (ind &rest default)
  2448.            (prog1 (apply #'getf properties ind default)
  2449.               (remf properties ind))))
  2450.         (values (extract-property :width)
  2451.             (extract-property :height)
  2452.             (extract-property :depth 1)
  2453.             (extract-property :left-pad 0)))
  2454.     (declare (type (or null card16) width height)
  2455.          (type image-depth depth)
  2456.          (type card8 left-pad))
  2457.     (unless (and width height) (error "Not a BITMAP file"))
  2458.     (let* ((bits-per-pixel
  2459.          (cond ((index> depth 24) 32)
  2460.                ((index> depth 16) 24)
  2461.                ((index> depth 8)  16)
  2462.                ((index> depth 4)   8)
  2463.                ((index> depth 1)   4)
  2464.                (t                  1)))
  2465.            (bits-per-line (index* width bits-per-pixel))
  2466.            (bytes-per-line (index-ceiling bits-per-line 8))
  2467.            (padded-bits-per-line
  2468.          (index* (index-ceiling bits-per-line 32) 32))
  2469.            (padded-bytes-per-line
  2470.          (index-ceiling padded-bits-per-line 8))
  2471.            (data (make-array (* padded-bytes-per-line height)
  2472.                  :element-type 'card8))
  2473.            (line-base 0)
  2474.            (byte 0))
  2475.       (declare (type array-index bits-per-line bytes-per-line
  2476.              padded-bits-per-line padded-bytes-per-line
  2477.              line-base byte)
  2478.            (type buffer-bytes data))
  2479.       (with-vector (data buffer-bytes)
  2480.         (flet ((parse-hex (char)
  2481.              (second
  2482.                (assoc char
  2483.                   '((#\0  0) (#\1  1) (#\2  2) (#\3  3)
  2484.                 (#\4  4) (#\5  5) (#\6  6) (#\7  7)
  2485.                 (#\8  8) (#\9  9) (#\a 10) (#\b 11)
  2486.                 (#\c 12) (#\d 13) (#\e 14) (#\f 15))
  2487.                   :test #'char-equal))))
  2488.           (declare (inline parse-hex))
  2489.           ;; Read data
  2490.           ;; Note: using read-line instead of read-char would be 20% faster,
  2491.           ;;       but would cons a lot of garbage...
  2492.           (dotimes (i height)
  2493.         (dotimes (j bytes-per-line)
  2494.           (loop (when (eql (read-char fstream) #\x) (return)))
  2495.           (setf (aref data (index+ line-base byte))
  2496.             (index+ (index-ash (parse-hex (read-char fstream)) 4)
  2497.                 (parse-hex (read-char fstream))))
  2498.           (incf byte))
  2499.         (setq byte 0
  2500.               line-base (index+ line-base padded-bytes-per-line)))))
  2501.       ;; Compensate for left-pad in width and x-hot
  2502.       (index-decf width left-pad)
  2503.       (when (getf properties :x-hot)
  2504.         (index-decf (getf properties :x-hot) left-pad))
  2505.       (create-image
  2506.         :width width :height height
  2507.         :depth depth :bits-per-pixel bits-per-pixel
  2508.         :data data :plist properties :format :z-pixmap
  2509.         :bytes-per-line padded-bytes-per-line
  2510.         :unit 32 :pad 32 :left-pad left-pad
  2511.         :byte-lsb-first-p t :bit-lsb-first-p t))))))
  2512.  
  2513. (defun write-bitmap-file (pathname image &optional name)
  2514.   ;; Writes an image to a C include file in standard X11 format
  2515.   ;; NAME argument used for variable prefixes.  Defaults to "image"
  2516.   (declare (type (or pathname string stream) pathname)
  2517.        (type image image)
  2518.        (type (or null stringable) name))
  2519.   (unless (typep image 'image-x)
  2520.     (setq image (copy-image image :result-type 'image-x)))
  2521.   (let* ((plist (image-plist image))
  2522.      (name (or name (image-name image) 'image))
  2523.      (left-pad (image-x-left-pad image))
  2524.      (width (index+ (image-width image) left-pad))
  2525.      (height (image-height image))
  2526.      (depth
  2527.        (if (eq (image-x-format image) :z-pixmap)
  2528.            (image-depth image)
  2529.          1))
  2530.      (bits-per-pixel (image-x-bits-per-pixel image))
  2531.      (bits-per-line (index* width bits-per-pixel))
  2532.      (bytes-per-line (index-ceiling bits-per-line 8))
  2533.      (last (index* bytes-per-line height))
  2534.      (count 0))
  2535.     (declare (type list plist)
  2536.          (type stringable name)
  2537.          (type card8 left-pad)
  2538.          (type card16 width height)
  2539.          (type (member 1 4 8 16 24 32) bits-per-pixel)
  2540.          (type image-depth depth)
  2541.          (type array-index bits-per-line bytes-per-line count last))
  2542.     ;; Move x-hot by left-pad, if there is an x-hot, so image readers that
  2543.     ;; don't know about left pad get the hot spot in the right place.  We have
  2544.     ;; already increased width by left-pad.
  2545.     (when (getf plist :x-hot)
  2546.       (setq plist (copy-list plist))
  2547.       (index-incf (getf plist :x-hot) left-pad))
  2548.     (with-image-data-buffer (data last)
  2549.       (multiple-value-bind (image-swap-function image-swap-lsb-first-p)
  2550.       (image-swap-function
  2551.         bits-per-pixel
  2552.         (image-x-unit image) (image-x-byte-lsb-first-p image)
  2553.         (image-x-bit-lsb-first-p image) 32 t t)
  2554.     (declare (type symbol image-swap-function)
  2555.          (type boolean image-swap-lsb-first-p))
  2556.     (funcall
  2557.       (symbol-function image-swap-function) (image-x-data image)
  2558.       data 0 0 bytes-per-line (image-x-bytes-per-line image)
  2559.       bytes-per-line height image-swap-lsb-first-p))
  2560.       (with-vector (data buffer-bytes)
  2561.     (setq name (string-downcase (string name)))
  2562.     (with-open-file (fstream pathname :direction :output)
  2563.       (format fstream "#define ~a_width ~d~%" name width)
  2564.       (format fstream "#define ~a_height ~d~%" name height)
  2565.       (unless (= depth 1)
  2566.         (format fstream "#define ~a_depth ~d~%" name depth))
  2567.       (unless (zerop left-pad)
  2568.         (format fstream "#define ~a_left_pad ~d~%" name left-pad))
  2569.       (do ((prop plist (cddr prop)))
  2570.           ((endp prop))
  2571.         (when (and (not (member (car prop) '(:width :height)))
  2572.                (numberp (cadr prop)))
  2573.           (format fstream "#define ~a_~a ~d~%"
  2574.               name
  2575.               (substitute
  2576.             #\_ #\- (string-downcase (string (car prop)))
  2577.             :test #'char=)
  2578.               (cadr prop))))
  2579.       (format fstream "static char ~a_bits[] = {" name)
  2580.       (dotimes (i height)
  2581.         (dotimes (j bytes-per-line)
  2582.           (when (zerop (index-mod count 15))
  2583.         (terpri fstream)
  2584.         (write-char #\space fstream))
  2585.           (write-string "0x" fstream)
  2586.           ;; Faster than (format fstream "0x~2,'0x," byte)
  2587.           (let ((byte (aref data count))
  2588.             (translate "0123456789abcdef"))
  2589.         (declare (type card8 byte))
  2590.         (write-char (char translate (ldb (byte 4 4) byte)) fstream)
  2591.         (write-char (char translate (ldb (byte 4 0) byte)) fstream))
  2592.           (index-incf count)
  2593.           (unless (index= count last)
  2594.         (write-char #\, fstream))))
  2595.       (format fstream "};~%" fstream))))))
  2596.  
  2597. (defun bitmap-image (&optional plist &rest patterns)
  2598.   ;; Create an image containg pattern
  2599.   ;; PATTERNS are bit-vector constants (e.g. #*10101)
  2600.   ;; If the first parameter is a list, its used as the image property-list.
  2601.   (declare (type (or list bit-vector) plist)
  2602.        (type list patterns)) ;; list of bitvector
  2603.   (declare (values image))
  2604.   (unless (listp plist)
  2605.     (push plist patterns)
  2606.     (setq plist nil))
  2607.   (let* ((width (length (first patterns)))
  2608.      (height (length patterns))
  2609.      (bitarray (make-array (list height width) :element-type 'bit))
  2610.      (row 0))
  2611.     (declare (type card16 width height row)
  2612.          (type pixarray-1 bitarray))
  2613.     (dolist (pattern patterns)
  2614.       (declare (type simple-bit-vector pattern))
  2615.       (dotimes (col width)
  2616.     (declare (type card16 col))
  2617.     (setf (aref bitarray row col) (the bit (aref pattern col))))
  2618.       (incf row))
  2619.     (create-image :width width :height height :plist plist :data bitarray)))
  2620.  
  2621. (defun image-pixmap (drawable image &key gcontext width height depth)
  2622.   ;; Create a pixmap containing IMAGE. Size defaults from the image.
  2623.   ;; DEPTH is the pixmap depth.
  2624.   ;; GCONTEXT is used for putting the image into the pixmap.
  2625.   ;; If none is supplied, then one is created, used then freed.
  2626.   (declare (type drawable drawable)
  2627.        (type image image)
  2628.        (type (or null gcontext) gcontext)
  2629.        (type (or null card16) width height)
  2630.        (type (or null card8) depth))
  2631.   (declare (values pixmap))
  2632.   (let* ((image-width (image-width image))
  2633.      (image-height (image-height image))
  2634.      (image-depth (image-depth image))
  2635.      (width (or width image-width))
  2636.      (height (or height image-height))
  2637.      (depth (or depth image-depth))
  2638.      (pixmap (create-pixmap :drawable drawable
  2639.                    :width width
  2640.                    :height height
  2641.                    :depth depth))
  2642.      (gc (or gcontext (create-gcontext
  2643.                 :drawable pixmap
  2644.                 :foreground 1
  2645.                 :background 0))))
  2646.     (unless (= depth image-depth)
  2647.       (if (= image-depth 1)
  2648.       (unless gcontext (xlib::required-arg gcontext))
  2649.     (error "Pixmap depth ~d incompatable with image depth ~d"
  2650.            depth image-depth)))           
  2651.     (put-image pixmap gc image :x 0 :y 0 :bitmap-p (and (= image-depth 1) gcontext))
  2652.     ;; Tile when image-width is less than the pixmap width, or
  2653.     ;; the image-height is less than the pixmap height.
  2654.     ;; ??? Would it be better to create a temporary pixmap and 
  2655.     ;; ??? let the server do the tileing?
  2656.     (do ((x image-width (+ x image-width)))
  2657.     ((>= x width))
  2658.       (copy-area pixmap gc 0 0 image-width image-height pixmap x 0)
  2659.       (incf image-width image-width))
  2660.     (do ((y image-height (+ y image-height)))
  2661.     ((>= y height))
  2662.       (copy-area pixmap gc 0 0 image-width image-height pixmap 0 y)
  2663.       (incf image-height image-height))
  2664.     (unless gcontext (free-gcontext gc))
  2665.     pixmap))
  2666.  
  2667.