1

jmorecfg.h

#define PACK_TWO_PIXELS(l,r)   ((r<<16) | l)
#define PACK_NEED_ALIGNMENT(ptr) (((int)(ptr))&3)
#define WRITE_TWO_PIXELS(addr, pixels) do {     \
         ((INT16*)(addr))[0] = (pixels);        \
         ((INT16*)(addr))[1] = (pixels)>>16;    \
    } while(0)
#define WRITE_TWO_ALIGNED_PIXELS(addr, pixels)  ((*(INT32*)(addr)) = pixels

有人可以解释 WRITE_TWO_PIXELS 和 WRITE_TWO_ALIGNED_PIXELS 之间的区别吗?如果像素是分配uint32_t和addr & 3 == 0的堆栈,它们不应该是等价的吗?

谢谢。

4

2 回答 2

2

在这两个宏中,唯一重要的对齐是addr. 正如问题中所写,如果addr是 32 位对齐的(意味着它的低两位为零),它们是等效的,但前提是目标架构也是小端的。

在大端机器上,pixels必须写入(INT16*)(addr))[0]的高 16 位和低 16 位以(INT16*)(addr))[1]使它们相等。

在不检查我的 libjpeg 源代码副本的情况下,我猜这些定义要么预计会作为移植库的一部分而被修改,要么它们已经受到字节顺序声明的保护。

如果addr不是 32 位对齐的,那么WRITE_TWO_ALIGNED_PIXELS宏可能会导致在不允许未对齐访问的架构上引发异常。当然在某些情况下,未对齐访问是允许的,但比两个较小的对齐访问要昂贵得多,并且在其他一些架构上,未对齐访问很难与对齐访问区分开来。

这两个宏的存在是为了提醒库的作者​​考虑对齐,并标准化处理未对齐访问的方法,以便在构建无关紧要的平台时对其进行优化。

于 2010-09-23T20:40:22.467 回答
2

WRITE_TWO_PIXELS并且WRITE_TWO_ALIGNED_PIXELS等效于小端机器,但不适用于大端架构。

[示例编辑:感谢史蒂夫杰索普]

让,像素= 0x0A0B0C0D

对于大端机器,WRITE_TWO_PIXELS工作如下:

---------------------
| 0B | 0A | 0D | 0C |
---------------------
  3    2    1    0          <--- addr

whereWRITE_TWO_ALIGNED_PIXELS会写如下:

---------------------
| 0D | 0C | 0B | 0A |
---------------------
  3    2    1    0          <--- addr
于 2010-09-23T20:44:33.333 回答