Beispiel #1
0
	void MorphErode::erodeU16( Image& dst, const Image& src, size_t radius ) const
	{
		size_t step = radius * 2 + 1;
		size_t curbuf;
		size_t w = src.width();
		size_t h = src.height();
		SIMD* simd = SIMD::instance();
		size_t bstride = Math::pad( w, 8 );
		uint16_t** buf;
		size_t i;

		IMapScoped<uint16_t> mapdst( dst );
		IMapScoped<const uint16_t> mapsrc( src );

		/* allocate and fill buffer */
		ScopedBuffer<uint16_t,true> bufmem( bstride * step );
		ScopedBuffer<uint16_t*,true> bufptr( step );

		buf = bufptr.ptr();
		buf[ 0 ] = bufmem.ptr();
		for( i = 0; i < step; i++ ) {
			if( i != 0 )
				buf[ i ] = buf[ i - 1 ] + bstride;
			simd->erodeSpanU16( buf[ i ], mapsrc.ptr(), w, radius );
			mapsrc++;
		}

		/* upper border */
		simd->MinValueVertU16( mapdst.ptr(), ( const uint16_t** ) buf, radius + 1, w );
		for( i = 1; i < radius; i++ ) {
			uint16_t* prev = mapdst.ptr();
			mapdst++;
			simd->MinValueU16( mapdst.ptr(), ( const uint16_t* ) prev, ( const uint16_t* ) buf[ radius + 1 + i ], w );
		}
		mapdst++;

		/* center */
		curbuf = 0;
		i = h - 2 * radius - 1;
		simd->MinValueVertU16( mapdst.ptr(), ( const uint16_t** ) buf, step, w );
		mapdst++;
		while( i-- ) {
			simd->erodeSpanU16( buf[ curbuf ], mapsrc.ptr(), w, radius );
			curbuf = ( curbuf + 1 ) % step;
			simd->MinValueVertU16( mapdst.ptr(), ( const uint16_t** ) buf, step, w );
			mapdst++;
			mapsrc++;
		}

		/* lower border */
		/* reorder buffer */
		ScopedBuffer<uint16_t*,true> bufptr2( step );
		uint16_t** buf2 = bufptr2.ptr();
		for( i = 0; i < step; i++ )
			buf2[ i ] = buf[ ( curbuf + i ) % step ];

		for( i = 1; i <= radius; i++ ) {
			simd->MinValueVertU16( mapdst.ptr(), ( const uint16_t** ) ( buf2 + i ), step - i, w );
			mapdst++;
		}
	}