2010-06-29 78 views
1

如何读取PVRTC图像的每个像素的图像颜色信息?读取每个像素的PVRTC图像颜色信息

这是我的代码中提取整数数组

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] initWithData:[_imageData objectAtIndex:i]]; 
       NSLog(@"data length:%d",[data length]); 

//提取20的样本数据,但所有ü可以看到的是大的整数数目 的for(int i = 0;我< 20;我++){ NSLog(@“data [%d]:%d”,i,data [i]); }

回答

1

PVRTC是一种基于块的4x4(或8x4)压缩系统,它考虑了周围的块以表示两个低频图像,为了生成实际的纹理输出,将高频调制数据与其结合。一个更好的解释,请访问:

http://web.onetel.net.uk/~simonnihal/assorted3d/fenney03texcomp.pdf

所以你提取值实际上编码块的部分而这些都需要进行,以获得合理的值正确解码。

有两种方法可以获取颜色信息:使用软件解压缩器对PVR纹理信息进行解码/解压缩或使用POWERVR图形核心渲染纹理,然后读取结果。我只会在这里讨论第一个选项。

这是相当棘手仅从信息组装解压缩在那里,幸好有一个在POWERVR SDK,你可以在这里C++解压缩源代码 - 下载iPhone的SDK的一个实例:

http://www.imgtec.com/powervr/insider/powervr-sdk.asp

它位于Tools/PVRTDecompress.cpp文件中。

希望有所帮助。