我有一个图像数据的二进制文件,其中每个像素正好是 4 位。图像数据布局如下:
有 N 个图像,其中第一个图像是 1x1,第二个图像是 2x2,第三个是 4x4,依此类推(如果您想知道它们是 mipmaps)。
给定一个指向数据缓冲区开始的指针,我想跳到最大的图像。
现在我知道我想跳过多少字节,但是开头有一个烦人的 1x1 图像,它是 4 位。无论如何,我都不知道要逐位递增指针。
我怎样才能成功地检索数据而一切都被关闭 4 位?
我有一个图像数据的二进制文件,其中每个像素正好是 4 位。图像数据布局如下:
有 N 个图像,其中第一个图像是 1x1,第二个图像是 2x2,第三个是 4x4,依此类推(如果您想知道它们是 mipmaps)。
给定一个指向数据缓冲区开始的指针,我想跳到最大的图像。
现在我知道我想跳过多少字节,但是开头有一个烦人的 1x1 图像,它是 4 位。无论如何,我都不知道要逐位递增指针。
我怎样才能成功地检索数据而一切都被关闭 4 位?
假设您可以更改文件格式,您可以执行以下任一操作:
如果您无法更改格式,您有以下选择:
你说:
我怎样才能成功地检索数据而一切都被关闭 4 位?
所以这意味着你需要转换。当您以字节为单位计算偏移量时,您会发现第一个包含前一个图像的半个字节。所以在紧要关头,你可以像这样洗牌:
for( i = start; i < end; i++ ) {
p[i] = (p[i] << 4) | (p[i+1] >> 4);
}
假设第一个像素是 4-7 位,第二个像素是 0-3 位,依此类推……如果反过来,只需反转这两个移位。
// 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;
}