[GIL] trying to clean up a small block of adhoc code

Hi, I've found a small block of adhoc image manipulation code written by someone in my current project. std::vector<float> pBuffer( 1024*1024 ); GenerateNoise( pBuffer, 1024, 1024 ) int n = 0; for(int y=0; y<1024; y++) { for(int x=0; x<1024; x++) { int xcopy = x, ycopy = y; if(x > 511) xcopy = 511 - CMath::Abs(512 - xcopy); if(y > 511) ycopy = 511 - CMath::Abs(512 - ycopy); pBuffer[n] = pBuffer[ycopy*1024 + xcopy]; n++; } } This takes the upper left corner and copies it to the upper right flipped horizontally, lower left flipper vertically, and lower right flipped horizontally and vertically. The code is poorly written but instead of trying to clean it up myself I thought this would be a good opportunity to learn to use gil. I think to get started I first need to create a gil image view from the raw data. Is this right? I looked at the image view from raw data function in the doxygen documentation but I don't see any for 1 channel data image data. Am I missing something? Thanks, Michael Marcin

Michael, here is my version of your algorithm. Please have a look: std::vector<float> buffer( 1024 * 1024 ); //GenerateNoise( pBuffer, 1024, 1024 ) gray32f_view_t src = interleaved_view( 1024, 1024 , (gray32f_pixel_t*) &buffer.front() , 1024 * 4 // bytes per scanline ); for( int y = 0; y < src.height(); ++y ) { gray32f_view_t::x_iterator src_it = src.row_begin( y ); float ycopy = y; if(y > 511) { ycopy = 511 - std::abs( 512.f - ycopy ); } for( int x = 0; x < src.width(); ++x ) { float xcopy = x; if(x > 511) { xcopy = 511 - std::abs( 512.f - xcopy ); } src_it[x] = src[xcopy][ycopy]; } } I haven't really tested it, though. Most of the code you find in the gil tutorial: http://stlab.adobe.com/gil/html/giltutorial.html Christian On Mon, Jun 16, 2008 at 11:59 AM, Michael Marcin <mike.marcin@gmail.com> wrote:
Hi,
I've found a small block of adhoc image manipulation code written by someone in my current project.
std::vector<float> pBuffer( 1024*1024 ); GenerateNoise( pBuffer, 1024, 1024 ) int n = 0; for(int y=0; y<1024; y++) { for(int x=0; x<1024; x++) { int xcopy = x, ycopy = y; if(x > 511) xcopy = 511 - CMath::Abs(512 - xcopy); if(y > 511) ycopy = 511 - CMath::Abs(512 - ycopy); pBuffer[n] = pBuffer[ycopy*1024 + xcopy]; n++; } }
This takes the upper left corner and copies it to the upper right flipped horizontally, lower left flipper vertically, and lower right flipped horizontally and vertically.
The code is poorly written but instead of trying to clean it up myself I thought this would be a good opportunity to learn to use gil.
I think to get started I first need to create a gil image view from the raw data. Is this right?
I looked at the image view from raw data function in the doxygen documentation but I don't see any for 1 channel data image data. Am I missing something?
Thanks,
Michael Marcin
_______________________________________________ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost

Ok so should this function? gray32f_view_t noise = interleaved_view( width, height , (gray32f_pixel_t*) &pBuffer[0] , width * sizeof(float) // bytes per scanline ); gray32f_view_t src = subimage_view(noise,0,0,half_width,half_height); copy_pixels( flipped_left_right_view(src), subimage_view(noise,half_width,0,half_width,half_height) ); copy_pixels( flipped_up_down_view(src), subimage_view(noise,0,half_height,half_width,half_height) ); copy_pixels( transposed_view(src), subimage_view(noise,half_width,half_height,half_width,half_height) ); Christian Henning wrote:
Michael,
here is my version of your algorithm. Please have a look:
std::vector<float> buffer( 1024 * 1024 ); //GenerateNoise( pBuffer, 1024, 1024 )
gray32f_view_t src = interleaved_view( 1024, 1024 , (gray32f_pixel_t*) &buffer.front() , 1024 * 4 // bytes per scanline );
for( int y = 0; y < src.height(); ++y ) { gray32f_view_t::x_iterator src_it = src.row_begin( y );
float ycopy = y; if(y > 511) { ycopy = 511 - std::abs( 512.f - ycopy ); }
for( int x = 0; x < src.width(); ++x ) { float xcopy = x;
if(x > 511) { xcopy = 511 - std::abs( 512.f - xcopy ); }
src_it[x] = src[xcopy][ycopy]; } }

Michael, Here is a version of the algorithm that makes use of view transformations: template <typename View> void reflect_quadrants(const View& src) { typedef typename View::point_t point_t; point_t q_dims = ifloor(src.dimensions()/2); point_t mid = iceil (src.dimensions()/2); View q1 = subimage_view(src,point_t(0,0),q_dims); View q2 = subimage_view(src,point_t(mid.x,0),q_dims); View q3 = subimage_view(src,point_t(0,mid.y),q_dims); View q4 = subimage_view(src,mid,q_dims); copy_pixels(flipped_left_right_view(q1), q2); copy_pixels(flipped_up_down_view(q1), q3); copy_pixels(flipped_up_down_view(flipped_left_right_view(q1)), q4); } std::vector<float> buffer( 1024 * 1024 ); GenerateNoise( pBuffer, 1024, 1024 ) gray32f_view_t src = interleaved_view( 1024, 1024 , (gray32f_pixel_t*) &buffer.front() , 1024 * 4 // bytes per scanline ); reflect_quadrants(src); ______ reflect_quadrants should work for images of any number of channels, dimensions, interleaved/planar, non-byte-aligned, synthetic, etc. Lubomir

Lubomir Bourdev wrote:
Michael,
Here is a version of the algorithm that makes use of view transformations:
<snip>
reflect_quadrants should work for images of any number of channels, dimensions, interleaved/planar, non-byte-aligned, synthetic, etc.
This makes a lot of sense and is certainly easier to read than what was there before. The only thing that feels strange is using interleaved_view when I actually don't have interleaved data which is where I got caught up. Thanks, Michael Marcin

Michael Marcin wrote:
The only thing that feels strange is using interleaved_view when I actually don't have interleaved data which is where I got caught up.
Interleaved vs. planar only makes sense if you have more than one channel. A single-channel image can be treated as interleaved or planar. GIL happens to define it as interleaved, which avoids some unnecessary code. Lubomir
participants (3)
-
Christian Henning
-
Lubomir Bourdev
-
Michael Marcin