From: Alan Crowe
Subject: CLX - size limits in xlib:put-raw-image
Date: 
Message-ID: <861xp416lu.fsf@cawtech.freeserve.co.uk>
I've nearly got put-raw-image working on my hardware, using
true colour and 24 bits per pixel

If the number of columns is a multiple of 4 there is no
problem. Otherwise the number of bytes in each line has to
be rounded up to a multiple of four.

That was working nicely, and I was trying out various size
images, when I started getting length errors again.

With 281 rows, I could have up to 310 columns of pixels, but
311 would give me a length error.

Asynchronous LENGTH-ERROR in request 274 (last request was
273)  Code 6.0 [ChangeSaveSet]

The X server seems to expecting fewer bytes than it
receives, so the extra get interpretted as command codes.

169x512 works
      (make-instance 'raw-image
		     :picture (random-pic 169 512)))

170x512 doesn't
      (make-instance 'raw-image
		     :picture (random-pic 170 512)))
Asynchronous LENGTH-ERROR in current request  Code 72.0
      [PutImage]

There seems to be some kind of size limit around 2^18,
that is 3 (for three bytes per pixel) x 170 x 512 is 2^18ish.

I've fallen behind with administering my system, still using
CMUCL 18d, instead of 18e, and FreeBSD 4.1, and XFree86
3.3.6, so I could stop writing software and try to get
everything up to date.

However, the size limit I've hit will cripple any real
application, so I cannot image that it was accidently
present even in early releases. So perhaps I'm
misunderstanding things and shouldn't be expecting this to
work anyway.

Here is my code, though I cannot begin to imagine how it
could be creating a length limitation.

I've got a class to wrap up the grungy details of raw
images.

(defclass raw-image()
  ((width :accessor width :initarg :width)
   (height :accessor height :initarg :height)
   (rgb-bytes :accessor rgb-bytes)
   (line-length :reader line-length)))

So my code to call xlib:put-raw-image looks like this:

(defmethod draw (window grackon (image raw-image) x y)
  ;(format t "Drawing at ~A~%" time)
  ;(describe (xlib:display-bitmap-format
  ;  (xlib:window-display window)))
  (xlib:clear-area window)
  (xlib:put-raw-image window grackon (rgb-bytes image)
		      :depth 24
		      :x x
		      :y y
		      :width (width image)
		      :height (height image)
		      :left-pad 0
		      :format :z-pixmap))

You'll notice that this is no `picture' slot in my raw-image
class, so what's up with 

(make-instance 'raw-image
		     :picture (random-pic 170 512))) ?

I got carried away and customized make-instance by adding an
:after method to one of the methods that make-instance uses.

(defmethod initialize-instance :after ((i raw-image)
				       &key (picture nil picture-supplied))
  (when picture-supplied
    (setf (height i) (first (array-dimensions picture))
	  (width i)(second (array-dimensions picture))))
  (setf (slot-value i 'line-length)
	(* 4 (ceiling (* 3 (width i)) 4)) ; <--- key bit of
                  ;; code that rounds up line lengths
                  ;; so lots more work to be done
                  ;; to write proper portable code
                  ;; that asks the Xserver about its 
                  ;; requirements.
	(rgb-bytes i)
	(make-array (* (height i)(line-length i))
		    :element-type '(unsigned-byte 8)))
  (when picture-supplied
    (loop for col below (width i) do
	  (loop for row below (height i) do
		(let ((index (+ (* 3 col)(* row (line-length i)))))
		  (typecase picture
			    ((array * (* * *))
			     (dotimes (pixel 3)
				      (setf (aref (rgb-bytes i)(+ index pixel))
					    (aref picture row col pixel))))
			    ((array * (* *))
			     (error "2D code not written yet."))))))))

Things seemed to be going quite well, then suddenly -wallop-
a size limit. All help greatfully received.

Alan Crowe
Edinbugh
Scotland