PVRTexLib in C# (with C++ tests)


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:

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;
    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,

© Imagination Technologies Limited. All rights reserved.
Privacy PolicyTerms & ConditionsTrademarksCookies