Calling QImage(const uchar *,int,int,QImage::Format)

45 views
Skip to first unread message

Mark Cox

unread,
Aug 8, 2012, 6:59:27 AM8/8/12
to eql-...@googlegroups.com
G'day,

How do you pass a const uchar * to the above constructor?

Thanks
Mark

Polos Ruetz

unread,
Aug 8, 2012, 8:27:38 AM8/8/12
to eql-...@googlegroups.com
2012/8/8, Mark Cox <mark...@gmail.com>:
> How do you pass a const uchar * to the above constructor?

I didn't implement the "uchar*" type, so it should not be listed in
the EQL docu (I will correct this).

Since QByteArray is implemented as a primitive type (a Lisp vector of
octets), you could use the "loadFromData(QByteArray,const char*)"
method from QImage instead.

Or do you have some embedded C code, and you already have the data as
"const uchar *"?
If you want to suggest me a solution, I will implement it.

Paul

Mark Cox

unread,
Aug 8, 2012, 5:48:24 PM8/8/12
to eql-...@googlegroups.com
Hi Paul,

I don't have embedded C code, but I want to work directly with raw pixel data as an array. Thus, I would like to be able to do something like this

(let* ((indexed8-image-data (make-array '(30 30) :initial-element 0))
       (qimage              (make-qimage indexed8-image-data 30 30 |QImage.Format_Indexed8|)))
  (qfun some-object "setImage" qimage))


I don't mind if INDEXED8-IMAGE-DATA needs to have :ELEMENT-TYPE '(unsigned-byte 8) and/or that it has to be a SIMPLE-ARRAY of rank 1.

I think requiring a (SIMPLE-ARRAY (UNSIGNED-BYTE 8) (*)) would be the easiest solution as QImage can handle different pixel encoding strategies (see [1]). This way, MAKE-QIMAGE would only need to check that the length of the array matches the width, height and QImage::Format parameter. 

ECL seems to do a good job at handling displaced arrays. This should provide an easy way of handling the formats Format_Indexed8 and Format_ARGB32 as multidimensional arrays. For example

> (type-of (make-array 900
                       :element-type '(unsigned-byte 8)
                       :displaced-to (make-array '(30 30) :element-type '(unsigned-byte 8))))

(VECTOR EXT:BYTE8 900)


So I would suggest something like this.

;; %make-qimage/dangerous is an embedded C function that requires a (SIMPLE-ARRAY (UNSIGNED-BYTE 8) (*))
(defun %make-qimage/dangerous (vector width height format))

(defun %make-qimage (vector width height format)
  (check-type vector (vector (unsigned-byte 8) *))
  (assert (= (length vector)
             (* width height (ecase format
                                ;; all format types
                                ))))
  (%make-qimage/dangerous vector width height format))

(defun make-qimage (array width height format)
  (assert (equal '(unsigned-byte 8) (array-element-type array)))
  (let ((vector (convert-array-if-necessary array)))
    (%make-qimage vector width height format)))

I can do all of this if you want, just let me know where you want the C function and the lisp code to go, then I will send you a patch.

Polos Ruetz

unread,
Aug 9, 2012, 5:02:26 AM8/9/12
to eql-...@googlegroups.com
2012/8/8, Mark Cox <mark...@gmail.com>:
> ...
> I can do all of this if you want, just let me know where you want the C
> function and the lisp code to go, then I will send you a patch.

thanks, looks nice!

So could you please insert the C code at the end of file
"src/ecl_fun.cpp", and put the Lisp code in
"src/lisp/special-extensions.lisp" (this way it will be easy to add
the working version to "make-eql-lib.lisp").

I already added a dummy function (see new version from git), so you can try:

(eql::make-qimage/dangerous) ; returns #<QImage 0x0>

Paul
Reply all
Reply to author
Forward
0 new messages