0

我有一个图像数据的二进制文件,其中每个像素正好是 4 位。图像数据布局如下:

有 N 个图像,其中第一个图像是 1x1,第二个图像是 2x2,第三个是 4x4,依此类推(如果您想知道它们是 mipmaps)。

给定一个指向数据缓冲区开始的指针,我想跳到最大的图像。

现在我知道我想跳过多少字节,但是开头有一个烦人的 1x1 图像,它是 4 位。无论如何,我都不知道要逐位递增指针。

我怎样才能成功地检索数据而一切都被关闭 4 位?

4

2 回答 2

4

假设您可以更改文件格式,您可以执行以下任一操作:

  • 为 1x1 图像添加填充
  • 以相反的顺序存储图像(实际上与上面相同,但不适用于 mip-map,因为您不一定知道将拥有多少张图像)

如果您无法更改格式,您有以下选择:

  • 转换数据
  • 接受缓冲区偏移半个字节并相应地使用它

你说:

我怎样才能成功地检索数据而一切都被关闭 4 位?

所以这意味着你需要转换。当您以字节为单位计算偏移量时,您会发现第一个包含前一个图像的半个字节。所以在紧要关头,你可以像这样洗牌:

for( i = start; i < end; i++ ) {
    p[i] = (p[i] << 4) | (p[i+1] >> 4);
}

假设第一个像素是 4-7 位,第二个像素是 0-3 位,依此类推……如果反过来,只需反转这两个移位。

于 2013-02-14T22:28:51.143 回答
0
// this assumes pixels points to bytes(unsigned chars)
index = ?;// your index to the pixel

byte_t b = pixels[index / 2];
if (index % 2) pixel = b >> 4;
else pixel = b & 15; 

// Or you can use
byte_t b = pixels[index >> 1];
if (index & 1) pixel = b >> 4;
else pixel = b & 15; 

无论哪种方式,只需计算文件的逻辑索引。除以二会将您带到像素所在字节的开头。然后只需读取正确的一半字节。

所以做一个函数

byte_t GetMyPixel(unsigned char* pixels, unsigned index) {
  byte_t b = pixels[index >> 1];
  byte_t pixel;
  if (index & 1) pixel = b >> 4;
  else pixel = b & 15; 
  return pixel; 
} 

读取第一张图片。

Image1x1 = GetMyPixel(pixels,0);



Image2x2_1 = GetMyPixel(pixels,1);// Top left pixel of second image
Image2x2_2 = GetMyPixel(pixels,2);// Top Right pixel of second image
Image2x2_3 = GetMyPixel(pixels,3);// Bottom left pixel of second image
... etc

所以这是解决问题的一种方法。您可能需要考虑您正在使用的字节序,所以如果它看起来错误,那么切换像素读取的逻辑......

byte_t GetMyPixel(unsigned char* pixels, unsigned index) {
  byte_t b = pixels[index >> 1];
  byte_t pixel;
  #if OTHER_ENDIAN
  if (index & 1) pixel = b >> 4;
  else pixel = b & 15; 
  #else
  if (index & 1) pixel = b & 15;
  else pixel = b >> 4; 
  #endif
  return pixel; 
} 
于 2013-02-15T00:38:42.427 回答