我正在用C语言编写OSX,在32位模式下运行在64位机器上。我正在使用GCC编译386。项目很大;我没有看到编译器的任何奇怪行为(可能直到现在。)应用程序是多线程的,并且此代码应该是,但此时正在运行单线程。我正在使用位置无关的clib进行编译,并在线程化时使用posix线程。如果我做线程,那么这段代码btw的行为完全相同。
以下是以最简单的形式演示问题的简化程序。基本上,我将这里的16位图像通道从一组三个RGB通道(mr,mg,mb)移动到另一组完全相同大小的3个RGB通道(lr,lg,lb)。片段,因为我即将转储它,完美地工作:
void lrip_me( unsigned short *mr, // RIP from source image
unsigned short *mg,
unsigned short *mb,
unsigned short *lr, // into RGB layer
unsigned short *lg,
unsigned short *lb,
struct layer *lay,
long start,long finish)
{
long xw,yw;
long xf,yf;
long x,y;
unsigned long offset;
xw = lay->parent->x;
yw = lay->parent->y;
xf = xw - 1;
yf = yw - 1;
for (y=start; y<finish; y++)
{
for (x=0; x<xw; x++)
{
offset = (y * xw) + x;
if (x==0 || x==xf || y==0 || y==yf) // then on edge
{
lr[offset] = mr[offset];
lg[offset] = mg[offset];
lb[offset] = mb[offset];
}
else
{
lr[offset] = mr[offset];
lg[offset] = mg[offset];
lb[offset] = mb[offset];
}
}
}
}
如您所见,图像边缘和边缘内部的动作是相同的;我只是移动数据。这是有效的 - 它的输出是lr,lg和lb通道中的图像。
BUT。如果,在else子句中,我将行更改为read ...
lr[offset] = mr[offset-xw];
lg[offset] = mg[offset-xw];
lb[offset] = mb[offset-xw];
...您希望图像内部移动一条扫描线,因为数据提取将来自完整扫描线的距离,但会转移到未移位的目标位置。相反,输出看起来完全随机。就像短裤被装在错误的边界上,或许是从其他地方。这也是做同样的事情......
lr[offset] = mr[offset-1];
lg[offset] = mg[offset-1];
lb[offset] = mb[offset-1];
...在那里,我希望图像水平移动一个像素。不。相同的结果 - 最纯粹的哈希。
我尝试过更改为指针数学而不是数组// *(mr + offset-1)//并获得完全相同的结果。我已经在库中和objc环境中编译了它。我试过使用偶数偏移,认为编译器可能对数据的大小感到困惑。我每次都得到相同的结果。偏移值可以按原样使用,但只能按原样使用。它不能在括号内修改,而且,它不能在括号外修改,只是被视为长。
我不知道这里发生了什么。如果有人能帮助我了解它是什么,我一定会很感激。
一点背景;这是一个RIP(去除孤立的像素)操作,或者至少,如果我可以得到循环当前正在查看的那个周围的8个像素。这就是边缘被区别对待的原因;我不想在边缘上运行8像素的外观,只在其中我将始终拥有所有8个内容:
ooo
oxo
ooo
在这个测试用例中,我删除了所有的RIP代码,因为它增加了很多复杂性并且没有解决问题。这简直就是(哈!)一个数组和指针偏移看起来不合理的情况。