boost :: gil指向bgr8_view_t对象的指针

时间:2012-02-04 11:54:37

标签: c++ boost boost-gil

我想编写一个在BGR中转换BGRA的函数。 void convertBGRAViewtoBGRView( const boost::gil::bgra8_view_t &src, boost::gil::bgr8_view_t dst ) 如果我这样写:

size_t numPixels = src.width() * src.height();
boost::gil::bgra8_view_t::iterator it = src.begin();
boost::gil::bgr8_view_t::iterator itD = dst.begin();
for( int i = 0; i < numPixels; ++i ){

    boost::gil::bgra8_pixel_t pixe(it[0]);
    *it++;
    boost::gil::bgr8_pixel_t pix(pixe[0],pixe[1],pixe[2]);

    *itD++ = pix;        
}

它有效,但速度很慢。所以我想使用NEON指令,因此我需要一个指针(例如UInt8 *)或(UInt32 *)。 我试过这样的话:

UInt32 *temp = (UInt32*)&src(0,0);
for( int i = 0; i < numPixels; ++i ){        
    boost::gil::bgr8_pixel_t pixk( (( *temp) & 0xff), ( (*temp>>8) & 0xff), ((*temp >> 16 )& 0xff));
    *itD++ = pixk;
    temp += 1;
}

这或多或少有效,但生成的图像不正确。我认为可能是对齐问题。有谁知道如何让它工作? 该解决方案比使用迭代器的解决方案快约3倍。

更新: 我检查了调试器: src的宽度为480x360,直到i == 259,一切都是正确的,但是后面的迭代器和指针的解决方案是不同的。

感谢。

2 个答案:

答案 0 :(得分:2)

在根据你的答案进行一些计算之后,我发现360*4可以被任何高达32的东西分割,而360*4+8*4甚至可以被64分割。所以我猜错误的原因是在您的情况下,GIL尝试将图像行对齐为64字节边界,因此不会连续存储它们。

因此,总是建议使用通用迭代器接口而不是直接弄乱原始内存,否则你必须完全确定任何这样的对齐约定(但也许它们是完全标准化的,可以在某处读取文件)。

答案 1 :(得分:0)

好的我找到了如何解决它,但仍然不知道原因:) 这适用于我的情况下宽度为360的图像。

UInt32 *temp = (UInt32*)&src(0,0);
for( int i = 0; i < numPixels; ++i ){   
  if( i%360==0 && i!=0 ){
    temp += 8;
  }
  boost::gil::bgr8_pixel_t pixk( (( *temp) & 0xff), ( (*temp>>8) & 0xff), ((*temp >> 16 )& 0xff));
  *itD++ = pixk;
  temp += 1;
}

在iOS平台上使用这个更好:

UInt8 *temp = (UInt8*)&src(0,0);
for( int i = 0; i < numPixels; ++i ){   
  if( i%360==0 && i!=0 ){
    temp += 8*4;
  }
  boost::gil::bgr8_pixel_t pixk( *temp, *(temp+1), *(temp+2));
  *itD++ = pixk;
  temp += 4;
}

摆脱其他迭代器可以进一步提高速度(在iOS上测试)。