Reading PVRTC image color information for each pixel
How do I read the image color information for each pixel of PVRTC image?
Here is my code extracting the integer arrays
NSData *data = [[NSData alloc] initWithContentsOfFile:path];
NSMutableArray *_imageData = [[NSMutableArray alloc] initWithCapacity:10];
BOOL success = FALSE;
PVRTexHeader *header = NULL;
uint32_t flags, pvrTag;
uint32_t dataLength = 0, dataOffset = 0, dataSize = 0;
uint32_t blockSize = 0, widthBlocks = 0, heightBlocks = 0;
uint32_t width = 0, height = 0, bpp = 4;
uint8_t *bytes = NULL;
uint32_t formatFlags;
header = (PVRTexHeader *)[data bytes];
pvrTag = CFSwapInt32LittleToHost(header->pvrTag);
if (gPVRTexIdentifier[0] != ((pvrTag >> 0) & 0xff) ||
gPVRTexIdentifier[1] != ((pvrTag >> 8) & 0xff) ||
gPVRTexIdentifier[2] != ((pvrTag >> 16) & 0xff) ||
gPVRTexIdentifier[3] != ((pvrTag >> 24) & 0xff))
{
return FALSE;
}
flags = CFSwapInt32LittleToHost(header->flags);
formatFlags = flags & PVR_TEXTURE_FLAG_TYPE_MASK;
if (formatFlags == kPVRTextureFlagTypePVRTC_4 || formatFlags == kPVRTextureFlagTypePVRTC_2)
{
[_imageData removeAllObjects];
if (formatFlags == kPVRTextureFlagTypePVRTC_4)
_internalFormat = GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG;
else if (formatFlags == kPVRTextureFlagTypePVRTC_2)
_internalFormat = GL_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG;
_width = width = CFSwapInt32LittleToHost(header->width);
_height = height = CFSwapInt32LittleToHost(header->height);
if (CFSwapInt32LittleToHost(header->bitmaskAlpha))
_hasAlpha = TRUE;
else
_hasAlpha = FALSE;
dataLength = CFSwapInt32LittleToHost(header->dataLength);
bytes = ((uint8_t *)[data bytes]) + sizeof(PVRTexHeader);
// Calculate the data size for each texture level and respect the minimum number of blocks
while (dataOffset < dataLength)
{
if (formatFlags == kPVRTextureFlagTypePVRTC_4)
{
blockSize = 4 * 4; // Pixel by pixel block size for 4bpp
widthBlocks = width / 4;
heightBlocks = height / 4;
bpp = 4;
}
else
{
blockSize = 8 * 4; // Pixel by pixel block size for 2bpp
widthBlocks = width / 8;
heightBlocks = height / 4;
bpp = 2;
}
// Clamp to minimum number of blocks
if (widthBlocks < 2)
widthBlocks = 2;
if (heightBlocks < 2)
heightBlocks = 2;
dataSize = widthBlocks * heightBlocks * ((blockSize * bpp) / 8);
[_imageData addObject:[NSData dataWithBytes:bytes+dataOffset length:dataSize]];
for (int i=0; i < mipmapCount; i++)
{
NSLog(@"width:%d, height:%d",width,height);
data = [[NSData alloc] i开发者_开发知识库nitWithData:[_imageData objectAtIndex:i]];
NSLog(@"data length:%d",[data length]);
//extracted 20 sample data, but all u could see are large integer number for(int i = 0; i < 20; i++){ NSLog(@"data[%d]:%d",i,data[i]); }
PVRTC is a 4x4 (or 8x4) texel, block-based compression system that takes into account surrounding blocks to represent two low frequency images with which higher frequency modulation data is combined in order to produce the actual texel output. A better explanation is available here:
http://web.onetel.net.uk/~simonnihal/assorted3d/fenney03texcomp.pdf
So the values you're extracting are actually parts of the encoded blocks and these need to be decoded correctly in order to get sensible values.
There are two ways to get to the colour information: decode/decompress the PVR texture information using a software decompressor or render the texture using a POWERVR graphics core and then read the result back. I'll only discuss the first option here.
It's rather tricky to assemble a decompressor from only the information there, but fortunately there's C++ decompression source code in the POWERVR SDK which you can get here - download one of the iPhone SDKs for instance:
http://www.imgtec.com/powervr/insider/powervr-sdk.asp
It's in the Tools/PVRTDecompress.cpp file.
Hope that helps.
精彩评论