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

时间:2010-06-29 07:51:15

标签: objective-c iphone

如何读取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; i&lt; 20; i ++){                的NSLog(@ “数据[%d]:%d”,I,数据[I]);                  }

1 个答案:

答案 0 :(得分: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文件中。

希望有所帮助。

相关问题