24 位 RGB 位图中的填充
有人可以向我解释为什么在 24 位 RGB 位图文件中我必须添加一个填充,其大小取决于图像的宽度吗?做什么的 ?
我的意思是我必须将此代码添加到我的程序中(用 C 语言):
if( read % 4 != 0 ) {
read = 4 - (read%4);
printf( "Padding: %d bytes\n", read );
fread( pixel, read, 1, inFile );
}
could somebody explain to me why in 24-bit rgb bitmap file I have to add a padding which size depends on width of image ? What for ?
I mean I must add this code to my program (in C):
if( read % 4 != 0 ) {
read = 4 - (read%4);
printf( "Padding: %d bytes\n", read );
fread( pixel, read, 1, inFile );
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
因为 24 位是奇数字节 (3),并且由于多种原因,所有图像行都需要从 4 字节的倍数地址开始。
Because 24 bits is an odd number of bytes (3) and for a variety of reasons all the image rows are required to start at an address which is a multiple of 4 bytes.
根据 Wikipedia,位图文件格式指定:
关于 Data Structure Padding 的维基百科文章也是一篇有趣的文章,它解释了填充在计算机科学中普遍使用的原因。
According to Wikipedia, the bitmap file format specifies that:
The wikipedia article on Data Structure Padding is also an interesting read that explains the reasons that paddings are generally used in computer science.
我认为这是设计决策,旨在对齐更好的内存模式,同时不浪费那么多空间(对于 319px 宽的图像,您将浪费 3 个字节或 0.25%)
想象一下您需要直接访问一些奇数行。您可以通过执行以下操作来访问第 n 行的前 4 个像素:
请注意,如果 n 和 width 是奇数(并且 bmp 是偶数), startRow 将会很奇怪。
现在,如果您尝试进行以下加速:
您会遇到很多问题。在最好的情况下(即英特尔CPU),自 startRow 以来,a、b 和 c 的每个负载都需要分成两个负载不能被 4 整除。在最坏的情况下(例如 sun sparc),您的程序将因“总线错误”而崩溃。
在较新的设计中,通常强制行至少与 L1 缓存行大小对齐(intel 上为 64 字节,nvidia gpus 上为 128 字节)。
I presume this was design decision to align for better memory patterns while not wasting that much space (for 319px wide image you would waste 3 bytes or 0.25%)
Imagine you need to access some odd row directly. You could access first 4 pixels of n-th row by doing:
Note that if n and width are odd (and bmp is even), startRow is going to be odd.
Now if you tried to do following speedup:
You'd run into lots of problems. In best case scenario (that is intel cpu) your every load of a, b and c would need to be broken into two loads since startRow is not divisible by 4. In worst case scenario (eg. sun sparc) your program would crash with "bus error".
In newer designs it is common to force rows to be aligned to at least L1 cache line size (64 bytes on intel or 128 bytes on nvidia gpus).
简短版本
因为 bmp 文件格式指定行必须完全适合 32 位“存储单元”。由于像素为 24 位,因此某些像素组合无法完美地位于 32 位“单元”中。在这种情况下,单元格被“填充”到完整的 32 位。
每字节 8 位 ∴
单元:32位=4字节∴
像素:24bits = 3bytes
长版本
-wiki: Word_(computer_architecture)
计算机系统基本上都有一个首选的“字长”(尽管现在不那么重要)。标准数据单元允许对计算机系统的架构进行各种优化(想想集装箱为航运业所做的事情)。有一个 32 位标准,称为 DWORD 又名双字(I猜测) - 这就是典型的位图图像的优化目标。
因此,如果每个像素有 24 位,则会出现各种“文字像素”行长度,无法很好地适应 32 位。所以在这种情况下,请将其填充掉。
注意:今天,您可能使用的是 64 位字长的计算机。检查您的处理器。
Short version
Because the bmp file format specifies rows must perfectly fit in a 32bits "memory cells". Because pixels are 24bits, some combinations of pixels will not perfect sit in 32bit "cells". In this case, the cell is "padded up to" the full 32bits.
8bits per byte ∴
cell: 32bit = 4bytes ∴
pixel: 24bits = 3bytes
Long version
-wiki: Word_(computer_architecture)
Computer systems basically have a preferred "word length" (though not so important these days). A standard data unit allows all sorts of optimisations in the architecture of the computer system (think what shipping containers did for the shipping industry). There is a 32 bit standard called DWORD aka Double word (I guess) - and thats what typical bitmap images are optimised for.
So if you have 24bits per pixel, there will be various "literal pixels" row lengths that will not fit nicely into the 32bits. So in that case, pad it out.
Note: today, you are probably using a computer with a 64bit word size. Check your processor.
每行末尾是否有填充取决于格式。
对于 3 x 8 位通道图像来说确实没有太多理由,因为 I/O 无论如何都是面向字节的。对于像素压缩到小于一个字节(例如 1 位/像素)的图像,填充非常有用,这样每行都以字节偏移量开始。
It depends on the format whether or not there is padding at the end of each row.
There really isn't much reason for it for 3 x 8 bit channel images since I/O is byte oriented anyway. For images with pixels packed into less than a byte (1 bit / pixel for example), padding is useful so that each row starts at a byte offset.