From Friday, April 19th (11:00 PM CDT) through Saturday, April 20th (2:00 PM CDT), 2024, ni.com will undergo system upgrades that may result in temporary service interruption.

We appreciate your patience as we improve our online experience.

LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

PNG Writing on Odd Targets and Compression

So yesterday I posted over on the idea exchange a change I wanted to the LV Image Data to PNG.  That function takes a LabVIEW image and turns it into a PNG stream.  Useful in cases where you want to do something like send the image of a front panel into a web page.  You get the image of the front panel or control, turn it into a PNG, and send it.  The problem with this function is it doesn't compress the PNG at all.  That was a simple fix, but then I learned that this function doesn't work on various targets.  No big deal I'll just write my own LV Image Data to PNG function.  Well my first odd target to test on was a Raspberry Pi.  Here the Write PNG File, also doesn't work.  The main contents of a PNG is a compressed 24 bit image.  So using the built in LabVIEW functions I zipped the image, and put it in the PNG.  This works (with a minor UI bug) but not all PNG viewers like this compression type of PKZip and instead want zlib.  OpenG has a zlib wrapper but is compiled for x86 processor architecture.  Whatever I can just use the built in functions of the OS...except LINX in LabVIEW is in a sandbox and you need an extra step to SSH into itself, from itself there by allowing you to use this function.  But if you do these steps then the pigz method should work.  Otherwise the PKZip method should work if your viewer supports it.

 

I say all this so others might learn from me, and so that if I ever pick this up again I can remember what I did.  Attached is a zip with some VIs in it.  The Test Save PNG will attempt to save the image of a control using some of these various methods.  The default of Platform Dependent uses a compressed function that is built around what NI was doing, and on Linux tries pigz, then PKZip if that fails.

Message 1 of 7
(3,370 Views)

Hi!

 

Looks like you are very familiar with this function.

Could you explain this strange behavior ?

 

I'm unable to understand why this function is working so slow. Your "file_io" variant is much faster (up to 10 times!) than default "memory_io" function.

 

(Initially I've asked this in beta forum, but now 2020CE is released.)

0 Kudos
Message 2 of 7
(3,220 Views)

Yeah I saw your post on the beta forums, and honestly I was just waiting for someone else to chime in, I don't really have anything to add.  I also only have 2018 on this development machine at the moment so I can't open your code.  There is definitely something funky going on with these functions.  I feel like we would benefit from NI giving these functions, and probably any PNG file or conversion related features, a review.  Their support on various targets seems spotty at best.  I also suspect that the Read/Write PNG VIs are just a single call library node to something hidden.

 

EDIT: Okay the write function is a little more than a single call library node, but the core of it is the LVImageDataToPNG function call.

0 Kudos
Message 3 of 7
(3,195 Views)

One thing that is funky with the Call Library Function Node is the "auto sized array". You can make the CLFN set the size of arrays\strings automatically, based on another input.

 

That function doesn't always work properly. I noticed (coincidentally with an inflate function in zlib) that the CLFN returns old values if this trick is used when it's in a reentrant VI.

 

There might be related performance penalties. If there are problems with the memory allocation, there might be problems with deallocating the memory.

 

 

0 Kudos
Message 4 of 7
(3,169 Views)

Hi As_ks,

I filed a bug to investigate the behavior you described here and on the beta forums. I took a look at it and am not sure why it's this way. This behavior has been around for quite some time, so I agree with Hooovahh that these functions are worth taking a look at. The bug number is 1057184.

I know that's not a satisfactory answer to why, but at least you are aware it's on our radar. 

ZK
Technical Support Engineer | NI | Not actually retired but I don't know how to change that
0 Kudos
Message 5 of 7
(3,100 Views)

libz.so is definitely available in the chroot environment under the /lib directory of the Raspberry Pi and I would be surprised if the BeagleBoneBlack is different as it is also a Debian derived Linux system (even its Android based OS variant is in essence a Linux kernel too). It is so wide used in many different Unix OS tools that I would be surprised if it is not present out of the box with every single Linux based OS out there. The kernel itself is often compressed with it and one of the first tasks of the bootloader after initializing the hardware to a known state so it can access the boot partition is to grab it and unpack it.

 

If it is only about using the inflate() and or deflate() functions that would be definitely an easy task to do on every Unix based environment that LabVIEW possibly can run on.

 

The OpenG ZLIB library that you can get from the OpenG VIPM repository is indeed only available for x86 based Windows and Linux desktop targets. The Beta version I posted last year over on LAVA is however also for all the NI realtime targets. There isn't a specific Raspberry Pi version yet! But as I'm currently busy with the Raspberry Pi for Michael Avoliatis, I plan to fix that together with quite a few other improvements in that library.

 

wiebe@CARYA wrote:

One thing that is funky with the Call Library Function Node is the "auto sized array". You can make the CLFN set the size of arrays\strings automatically, based on another input.

 

That function doesn't always work properly. I noticed (coincidentally with an inflate function in zlib) that the CLFN returns old values if this trick is used when it's in a reentrant VI.

I would be interested to learn more about that. Do you have an example that reliably can show this? I was just about to give up my resistence to use that feature in my own libraries as I found the thought to explicitly initialize buffers always more convincing and then you post something like this!!!! 😀

Rolf Kalbermatter
My Blog
Message 6 of 7
(3,085 Views)

@rolfk wrote:

 

wiebe@CARYA wrote:

One thing that is funky with the Call Library Function Node is the "auto sized array". You can make the CLFN set the size of arrays\strings automatically, based on another input.

 

That function doesn't always work properly. I noticed (coincidentally with an inflate function in zlib) that the CLFN returns old values if this trick is used when it's in a reentrant VI.

I would be interested to learn more about that. Do you have an example that reliably can show this? I was just about to give up my resistence to use that feature in my own libraries as I found the thought to explicitly initialize buffers always more convincing and then you post something like this!!!! 😀


It was quite reproducible, but only in (fast?) loops. I have changed the function, but the base is still the same. And I use the original zlib, not the LVzlib (again, basically the same).

 

I think I saw it in other dlls\functions.

 

It was in LV13, I'll try LV18 as well. EDIT I started this in LV7.1, so it might even date back to then.

 

I'll see if I can make a small test.

 

EDIT: Apparently it was either too obscure to easily reproduce, or <LV13. I deflate in my PDF generation, and report generation probably happened in some clone. It was 100% clear the auto-length-allocation was the problem. Parts of the PDF where not there, others where drawn twice. Changing the dll fixed it. Changing it back and forth turned it on and off.

 

It could also be related to the destination of the output. LabVIEW seemed to try to reuse the same location, a bit too lazy. This could be similar to not using the "mark as modifier" when it's needed.

0 Kudos
Message 7 of 7
(3,076 Views)