Imagination PowerVR SDK Blog

PVRTexLib 4.2 - Transcoding to PVRTC v1 Failing


#1

I cannot get the PVRTexLib v4.2 to transcode to ePVRTPF_PVRTCI_2bpp_RGBA or ePVRTPF_PVRTCI_4bpp_RGBA formats but am able to do just about any other format with the exact same input and output.



I’d understand if no PVRTC was working but ePVRTPF_PVRTCII_2bpp and ePVRTPF_PVRTCII_4bpp are working without failure at all just the v1 formats.



With my code sample below is there something I’m potentially doing that isn’t supported in PVRTC v1 that is in the other formats or is it a bug in the encoder?



Any tips appreciated:



Objective-C++:


  • (NSData *)encodePixelDataToPVRFileData:(NSData *)pData

    height:(NSUInteger)pHeight

    width:(NSUInteger)pWidth

    fromPixelFormat:(NSString *)pFromPixelFormat

    toPixelFormat:(NSString *)pToPixelFormat

    alphaPremultiplied:(signed char)pAlphaPremultiplied

    allowDithering:(signed char)pAllowDithering {



    // get pixel types

    PixelType inPixelType = [self _pixelTypeFromPixelFormat:pFromPixelFormat];

    PixelType outPixelType = [self _pixelTypeFromPixelFormat:pToPixelFormat];



    // setup data structures

    CPVRTextureHeader inTextureHeader(inPixelType.PixelTypeID, (uint32_t)pHeight, (uint32_t)pWidth);

    inTextureHeader.setIsPreMultiplied(pAlphaPremultiplied);

    CPVRTexture texture(inTextureHeader, pData.bytes);



    // encode

    if(Transcode(texture, outPixelType, ePVRTVarTypeUnsignedByteNorm, ePVRTCSpacelRGB, ePVRTCBest, pAllowDithering)) {



    NSMutableData *data = [NSMutableData data];



    size_t fileHeaderLength = PVRTEX3_HEADERSIZE;

    PVRTextureHeaderV3 fileHeader = texture.getHeader().getFileHeader();

    [data appendBytes:&fileHeader length:fileHeaderLength];



    size_t fileDataLength = texture.getDataSize();

    void *fileData = texture.getDataPtr();

    [data appendBytes:fileData length:fileDataLength];



    return data;

    }



    return nil;

    }
  • (PixelType)_pixelTypeFromPixelFormat:(NSString *)pPixelFormat {

    if([pPixelFormat isEqualToString:@“pvrtc2bpp”]) {

    return PixelType(ePVRTPF_PVRTCI_2bpp_RGBA);

    } else if([pPixelFormat isEqualToString:@“pvrtc4bpp”]) {

    return PixelType(ePVRTPF_PVRTCI_4bpp_RGBA);

    } else if([pPixelFormat isEqualToString:@“pvrtcii2bpp”]) {

    return PixelType(ePVRTPF_PVRTCII_2bpp);

    } else if([pPixelFormat isEqualToString:@“pvrtcii4bpp”]) {

    return PixelType(ePVRTPF_PVRTCII_4bpp);

    } else {

    const char *chars = [pPixelFormat UTF8String];

    uint8 pf[8];

    for(NSInteger i = 0; i < pPixelFormat.length; ++i) {

    switch(chars) {

    case ‘r’ :

    case ‘g’ :

    case ‘b’ :

    case ‘a’ :

    pf = chars;

    break;

    case ‘0’ :

    pf = 0;

    break;

    case ‘1’ :

    pf = 1;

    break;

    case ‘2’ :

    pf = 2;

    break;

    case ‘3’ :

    pf = 3;

    break;

    case ‘4’ :

    pf = 4;

    break;

    case ‘5’ :

    pf = 5;

    break;

    case ‘6’ :

    pf = 6;

    break;

    case ‘7’ :

    pf = 7;

    break;

    case ‘8’ :

    pf = 8;

    break;

    }

    }

    return PixelType(pf[0], pf[1], pf[2], pf[3], pf[4], pf[5], pf[6], pf[7]);

    }

    }


#2

Hi Robert,



There’s nothing obvious from your code that you could be doing which would cause a failure. The only thing I can think of, which I can’t tell from your code, is perhaps if you’re using non-power of two width/height?



PVRTC1 only supports dimensions that are powers of two, any other sizes will fail. Also it’s worth noting that some PowerVR devices only support square PVRTC1 as well, which is due to how the original specification was written - though compression will succeed.



Regards,

Tobias


#3

Hey Tobias,



Yup that would be exactly what it was thanks for the reply… stupid moment.



-Robert