二进制文件位操作
binary file bit manipuation
我有一个图像数据的二进制文件,其中每个像素正好是4位。图像数据布局如下:
有N个图像,其中第一个图像是1x1,第二个图像是2x2,第三个图像是4x4,依此类推(如果你想知道的话,它们是mipmap)。
给定一个指向数据缓冲区开始的指针,我想跳到最大的图像。
现在我知道我想跳过多少字节,但在开始时有一个烦人的1x1图像,它是4位。无论如何,我都不知道要逐位递增指针。
如何在所有数据都不偏离4位的情况下成功检索数据?
假设您可以更改文件格式,则可以执行以下操作之一:
- 为1x1图像添加填充
- 以相反的顺序存储图像(实际上与上面相同,但对于mip贴图来说并不理想,因为你不一定知道你会有多少图像)
如果你不能改变你的格式,你可以选择:
- 转换数据
- 接受缓冲区偏移了半个字节,并相应地使用它
你说:
如何在不关闭所有内容的情况下成功检索数据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;
无论哪种方式,都只需计算文件的逻辑索引。除以2,你就可以到达像素所在的字节的开头。然后只读取正确的半个字节。
所以做一个函数
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;
}
相关文章:
- 如何使用位字段将数据从二进制文件复制到结构中?
- 将位字符串转储到二进制文件的最佳方法是什么
- C++二进制文件 I/O 操作速度变慢.数据库如何处理二进制文件?
- 自定义二进制文件在 C++ 中触发故障位
- 在 64 位 Linux armv8 计算机上编译 32 位二进制文件时遇到问题
- 无法在 64 位 Debian 上运行 32 位二进制文件
- 如何将位域写入二进制文件
- 如何将大型二进制文件(10000k 位)转换为基数 3 或基数 31?
- 如何在我的进程中运行的二进制文件中注册操作和内核
- 读取 64 位整数二进制文件
- 了解C++位操作中的二进制转换实现
- 64位C++二进制文件消耗巨大的内存,即使二进制文件的大小也是巨大的
- 32位应用程序链接到System32二进制文件,而不是SysWOW64
- C++正在将位集写入二进制文件
- 从二进制文件 c++ 读取 16 位整数
- 获取二进制文件的最后 n 位
- 如何仅将 16 位分配给二进制文件中的任何整数,而不是C++中的正常 32 位
- 将操作码添加到现有二进制文件所需的内容
- bash:即使二进制和Linux是64位的,也无法执行二进制文件:Exec格式错误
- 二进制文件位操作