2010-06-29 114 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文件中。

希望有所幫助。