2

我想写一个在 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 一切都是正确的,但之后迭代器和指针的解决方案是不同的。

谢谢。

4

2 回答 2

2

After some computation based on your answer, I found out that 360*4 is dividable by anything up to 32, whereas 360*4+8*4 is even dividable by 64. So I guess the reason for the error is that GIL in your case tries to align image rows at 64 byte boundaries and therefore doesn't store them contiguously.

Because of this it is always advised to use the generic iterator interface instead of messing with the raw memory directly, otherwise you have to be completely sure about any such alignment conventions (but maybe they are perfectly standardized and can be read somewhere in the documentation).

于 2012-02-06T14:22:58.900 回答
0

OK I found how to fix it, but still don't know the reason :) This works for images with width 360 in my case.

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;
}

It is even better to use this one for the iOS platform:

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;
}

Getting rid of the other iterator further improves speed (tested on iOS).

于 2012-02-06T11:45:51.870 回答