which filter for encoding a png interlaced using windows imaging components (wic) with the c# wrapper?

1

I'm trying to encode an image as an interlaced png using WIC. I can save the image as png without any problems and set the interlaced mode. But if i try to set a filtermode (any filter), i get the following error:

[System.Runtime.InteropServices.COMException] = {"The bitmap property type is unexpected.   (Exception from HRESULT: 0x88982F8E)"}

Do i set the value of the property bag in a wrong way? This is the code, the exception is thrown at propBag.Write.

[...]
var arg = new IPropertyBag2[1];
encoder.CreateNewFrame(out outputFrame, arg);
var propBag = arg[0];
var propertyBagOptions = new PROPBAG2[2];

propertyBagOptions[0].pstrName = "InterlaceOption";
propertyBagOptions[1].pstrName = "FilterOption";
propBag.Write(2, propertyBagOption1, new object[] { true, WICPngFilterOption.WICPngFilterAdaptive});
[...]

Thanks for Help, Stephanie

c#
wic
asked on Stack Overflow May 28, 2014 by Stephanie

1 Answer

0

I believe this is because the FilterOption property needs to be an Unsigned Byte:

| Property Name |VARTYPE|Value Range       | Default Value          | 
|---------------|-------|------------------|------------------------|
|InterlaceOption|VT_BOOL|TRUE/FALSE        |FALSE                   |
|FilterOption   |VT_UI1 |WICPngFilterOption|WICPngFilterUnspecified |

The underlying Write method is marked to marshall the Value as a VARIANT (i.e. UnmanagedType.Struct), which is correct:

void Write(
   uint cProperties, 
   [MarshalAs(UnmanagedType.LPArray)] PROPBAG2[] pPropBag, 
   [MarshalAs(UnmanagedType.Struct)] ref object pvarValue
);

I'm not going to test it; because i can't, but i think the fix is to cast your PNG filter option to the C# equivalent of an unsigned byte byte.

propBag.Write(
   1, 
   propertyBagOption, 
   UInt8(WICPngFilterOption.WICPngFilterAdaptive));

The reason i think this is because from my native code, i was giving the property value as a variant. But the variant was actually a signed 32-bit (aka Int32). This caused the error:

0x88982F8E

When you look at WinCodec.h (which is the native code that .NET imaging is using), it corresponds to error:

  WINCODEC_ERR_PROPERTYUNEXPECTEDTYPE = HRESULT($88982f8E);

I has to make sure to force the variant to contain a VT_UI1:

propertyBagHelper.Write('FilterOption', VarAsType(WICPngFilterAdaptive, VT_UI1));

Then it succeeded.

This is all great from native code, when you know what's going on. The .NET/CLR/C# wrapper world loves to obfuscate everything; so you don't really know what the parameters contain when you pass them.

Note: Any code released into public domain. No attribution required.

answered on Stack Overflow Jun 14, 2014 by Ian Boyd • edited Jan 15, 2016 by Ian Boyd

User contributions licensed under CC BY-SA 3.0