~ubuntu-branches/ubuntu/intrepid/ecl/intrepid

« back to all changes in this revision

Viewing changes to src/clx/image.lisp

  • Committer: Bazaar Package Importer
  • Author(s): Peter Van Eynde
  • Date: 2006-05-17 02:46:26 UTC
  • Revision ID: james.westby@ubuntu.com-20060517024626-lljr08ftv9g9vefl
Tags: upstream-0.9h-20060510
ImportĀ upstreamĀ versionĀ 0.9h-20060510

Show diffs side-by-side

added added

removed removed

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