PNG image decoder on Windows CE, Windows Embedded Compact 7, Windows Embedded Compact 2013
Posted on December 12, 2014
A lot of people are asking for help regarding PNG image decoding on
- Windows CE
- Windows Embedded Compact 7
- Windows Embedded Compact 2013
so let’s shed some light into this topic.
Windows CE and Windows Embedded Compact 7
The presence of PNG image decoder in these OSes depends on the presence of SYSGEN_IMAGING_PNG_DECODE variable during the build of OS image.
If you do not include SYSGEN_IMAGING_PNG_DECODE variable, the PNG image decoder will not be installed into the OS. However, the OS will still be able to draw a PNG image, but the transparent pixels will be ignored and they will (most of the time) be substituted with black color. Since we have not found a reliable mechanism to detect whether PNG decoder is in the OS or not (the controls work in both cases, however in case that PNG decoder is absent, the images are rendered incorrectly, but no error/exception is thrown), you have to tell Bee Mobile controls whether to use the built-in PNG image decoder or not. We’ll call the built-in PNG image decoder ‘Imaging API‘. You do this by executing the following code:
BeeMobile.Common.Environment.WinCESettings.UsePngLibrary = true;
If you set the static UsePngLibrary property to true, you’re telling all Bee Mobile controls NOT TO use Imaging API, but to use Bee Mobile PNG image decoder instead which we’ll call LibPNG from now on. Make sure to assign the UsePngLibrary property before you initialize any Bee Mobile control(s). If you do not assign any value to it, it will keep its default value which is false. That means that Imaging API is used by default.
LibPNG is implemented in these 3 files:
You will find these files in iPack installation folder which by default is:
c:\Program Files (x86)\Bee Mobile\iPack\WinCE
Since these file are not managed code written assemblies, but they are native code written libraries, you will have to browse into corresponding sub-folder based on the processor architecture of your device:
- ARMV4I – the most used
- ARM4 for WM2003SE – old Pocket PC 2003 devices
Which PNG decoder should I use ?
So if you’re working on Windows CE or Windows Embedded Compact 7 you have two different PNG decoders to choose from. Imaging API is the default one and it is a tiny bit faster than LibPNG. On the other hand it is not always present and it may be buggy at times. Some customers complain that when they try to draw a PNG file they receive this exception:
An unhandled exception of type 'System.Runtime.
InteropServices.COMException' occurred in BeeMobile.Common.CF35.dll Additional information: 0x80004005
If this is your case, don’t use Imaging API, use Lib PNG instead.
Knowing which decoder is being used
The entire PNG drawing algorithm is quite complex and it consists of managed code part and unmanaged code part. The managed code part is implemented in PngImage class found in BeeMobile.Common namespace in BeeMobile.Common.CF35 assembly. The managed code part also contains a mechanism which detects what PNG decoders are available on your device and chooses one based on a few criteria (the criteria are also encoded in PngImage class). You can take a look into PngImage.PngDecoderType property (which is a public and static property) at any time to see what decoder is currently chosen. This property can have any of these 4 values:
- WIC – used only on .NET Compact Framework 3.9 on Windows Embedded Compact 2013 OS.
- LibPNG – this is the Bee Mobile PNG image decoder.
- ImagingApi – that’s the PNG decoder built-in your OS.
- None – this means that PngImage class failed to load any PNG image decoder. If this happens, it will not draw any PNG image(s) and calling the Draw method of PngImage class will result in exception.
I already mentioned that if you set
WinCESettings.UsePngLibrary = true;
you’re explicitly telling Bee Mobile PngImage to use LibPNG. However if for any reason PngImage fails loading LibPNG (despite of this setting) AND it finds out that ImagingApi is present, it will revert back to ImagingApi. The reason for not finding LibPNG could be that you did not upload the necessary files to your device or that even though you uploaded them, they are designed for different processor architecture.
Windows Embedded Compact 2013
This OS supports .NET Compact Framework v. 3.9. If you run iPack controls on this OS they will use another PNG image decoder – WIC. WIC is an abbreviation for Windows Imaging Component and it is actually a PNG image decoder (plus some other functionality). However, it written in native code and designed to be used by applications written in native code so we created a managed code wrapper around it to be able to use it in the managed environment of .NET Compact Framework v. 3.9. All the magic happens under the hood, so the only thing you have to do it instantiate the PngImage class (or use any iPack control that draws PNG images) and enjoy. If you inspect
property, you will find out that it’s set to WIC.