PVRTexLib in C# (with C++ tests)

Hello,

EDIT: To be sure my C# code or native communication isn’t at fault, I created a C++ project and linked the PVRTexLib there as well, and conducted the same scenarios as described below. I also get the same behaviour and issues with my C++ application. There this problem does not exist due to C# or its native communication currently.
EDIT 2: I also used the Set methods for the PVRHeader, which don’t seem to set the values, since they still return 0 or null.

for my current C# project I wanted to include the PVRTexLib, since I have to transcode raw pixel data from one encoding to another. For that I load the native dll of PVRTexLib (its newest release) and via DllImport attributes I access the exported methods, viewable from the PVRTexLib.hpp.

I now have the problem, that for some reason the library will not return the same pointer to the texture header when I request it from a created texture. Here is what I do to check that

var pvrHeaderPtr = PVRTexLib_CreateTextureHeader(createParams);
var dataHandle = GCHandle.Alloc(data, GCHandleType.Pinned);
var pvrTexturePtr = PVRTexLib_CreateTexture(pvrHeaderPtr, dataHandle.AddrOfPinnedObject());
var headerPtr = PVRTexLib_GetTextureHeader(pvrTexture);

If I compare pvrHeaderPtr with headerPtr, then they are not equal. However both seem to work fine, as I can request valid information from both of them. Is the header copied when creating a texture?

A second problem is, that I do not get ifnormation back on the data pointer or the data size from a header. Requesting the information from the header will return 0 or a null ptr (which as per documentation indicates an error). However, I can not deduce what I do wrong. The smallest test I could conduct that reproduces the issue is the following:

var pvrHeaderPtr = PVRTexLib_CreateTextureHeader(createParams);
var dataSize = PVRTexLib_GetTextureDataSize(pvrHeaderPtr, -1, true, true);

The variable dataSize is now zero. Even though the given values in the Params struct are valid and should produce something > 0.

My current test file has the following specifications, that I write into the CreateParams struct like this:

var createParams = new PVRCreateParams
{
    width = (int)4,
    height = (int)4,
    depth = (int)1,
    pixelFormat = (ulong)2,  // this is PVRTLPF_PVRTCI_4bpp_RGB, as per PVRTexLibPixelFormat enum
    colorSpace = (int)0,  // this is PVRTLCS_Linear, as per PVRTexLibColourSpace enum
    channelType = (int)2,  // this is PVRTLVT_UnsignedByte, as per PVRTexLibVariableType enum
    preMultiplied = false
};

This is my PVRCreateParams struct:

[StructLayout(LayoutKind.Sequential)]
class PVRCreateParams
{
    public ulong pixelFormat;
    public uint width;
    public uint height;
    public uint depth;
    public uint numMipMaps;
    public uint numArrayMembers;
    public uint numFaces;
    public int colorSpace;
    public int channelType;
    [MarshalAs(UnmanagedType.Bool)]
    public bool preMultiplied;
}

Can someone help me solve the 2 problems above?

I found the solutions to both of my problems after hours of thinking about what could be wrong and reverse engineering the library. I have to set numMipMaps, numFaces, and numArrayMembers to non-zero values each.

If either of the booleans in the GetDataSize method is true, the result will be 0 if numArrayMember or numFaces is 0. Its result will also be 0 if a mip level is given that is >= than numMipMaps.

Given the non-zero condition from above, it also applies to getting the texture data pointer. If any of the 4 values in GetTextureDataPtr is >= the number given given by the header, the method will return a null pointer. ZSlice depends on numMipMaps here.

Hi onepiecefreak,

Glad to know you managed to solve your questions, please don’t hesitate to ask if you have more questions.

Best regards,
Alejandro