[Pharo-Users] FFI question. How read external byte* to image Form?

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
1 message Options
Reply | Threaded
Open this post in threaded view
|

[Pharo-Users] FFI question. How read external byte* to image Form?

Denis Kudriashov
Hello.

My application works extensively with png images. So Image based PNGReadWriter speed not enough for me.
I have C library dll which has function "byte* readPNG(filename)". It returns buffer (pointer address) with same structure as Form Bitmap has.

I use FFI to call this function. And I have very naive converter of returned buffer to Form:

buffer := self primReadImageBytesFrom: imagePath.
buffer getHandle asInteger == 0 ifTrue: [self error: 'bad image: ', imagePath ].  
   
form := Form extent: width @ height depth: 32.
   
x:= 0. y:=0.
[y <=  height ] whileTrue: [
x :=0.
[x <= width] whileTrue: [

    offset  := x * 4 + (y * width * 4) + 1 + 8.
    value := buffer getHandle integerAt: offset size: 4 signed: false.    
    form pixelValueAt: x@y put: value.
    x := x + 1.
].
y := y + 1.
].
^form

It's work and it is improve that buffer format similar to Form bits format. But such algorithm very slow.
So my question is: How efficiently convert external byte array from FFI call to internal ByteArray (Bitmap, Form).

I know about BitBlt class and

    blt := (BitBlt current
                toForm: f)
                sourceForm: source.
    blt combinationRule: Form over. "store"
    blt sourceX: 0;
         sourceY: 0;
         height: height;
         width: width.
    blt destX: 0;
         destY: 0.
    blt copyBits.

And it works very fast. I try create source Form by

source := Form extent: width@height depth: 32.
source bits: buffer getHandle

But BitBlt raise error for such form. #copyBits primitive failed and method execution continue with attempt to unhibernate given forms.

Any ideas?