Axiom.Media.LinearResampler.Scale C# (CSharp) Method

Scale() public method

public Scale ( PixelBox src, PixelBox dst ) : void
src PixelBox
dst PixelBox
return void
		public void Scale( PixelBox src, PixelBox dst )
		{
			int srcelemsize = PixelUtil.GetNumElemBytes( src.Format );
			int dstelemsize = PixelUtil.GetNumElemBytes( dst.Format );

			int dstOffset = 0;

			// sx_48,sy_48,sz_48 represent current position in source
			// using 16/48-bit fixed precision, incremented by steps
			UInt64 stepx = ( (UInt64)src.Width << 48 ) / (UInt64)dst.Width;
			UInt64 stepy = ( (UInt64)src.Height << 48 ) / (UInt64)dst.Height;
			UInt64 stepz = ( (UInt64)src.Depth << 48 ) / (UInt64)dst.Depth;
			// temp is 16/16 bit fixed precision, used to adjust a source
			// coordinate (x, y, or z) backwards by half a pixel so that the
			// integer bits represent the first sample (eg, sx1) and the
			// fractional bits are the blend weight of the second sample
			uint temp;
			// note: ((stepz>>1) - 1) is an extra half-step increment to adjust
			// for the center of the destination pixel, not the top-left corner
			UInt64 sz_48 = ( stepz >> 1 ) - 1;
			for ( int z = dst.Front; z < dst.Back; z++, sz_48 += stepz )
			{
				temp = (uint)( sz_48 >> 32 );
				temp = ( temp > 0x8000 ) ? temp - 0x8000 : 0;
				int sz1 = (int)( temp >> 16 );
				int sz2 = System.Math.Min( sz1 + 1, src.Depth - 1 );
				float szf = ( temp & 0xFFFF ) / 65536f;

				UInt64 sy_48 = ( stepy >> 1 ) - 1;
				for ( int y = dst.Top; y < dst.Bottom; y++, sy_48 += stepy )
				{
					temp = (uint)( sy_48 >> 32 );
					temp = ( temp > 0x8000 ) ? temp - 0x8000 : 0;
					int sy1 = (int)( temp >> 16 ); // src x #1
					int sy2 = System.Math.Min( sy1 + 1, src.Height - 1 ); // src x #2
					float syf = ( temp & 0xFFFF ) / 65536f; // weight of #2

					UInt64 sx_48 = ( stepx >> 1 ) - 1;
					for ( int x = dst.Left; x < dst.Right; x++, sx_48 += stepx )
					{
						temp = (uint)( sy_48 >> 32 );
						temp = ( temp > 0x8000 ) ? temp - 0x8000 : 0;
						int sx1 = (int)( temp >> 16 ); // src x #1
						int sx2 = System.Math.Min( sx1 + 1, src.Width - 1 ); // src x #2
						float sxf = ( temp & 0xFFFF ) / 65536f; // weight of #2
						ColorEx x1y1z1 = ColorEx.White, x2y1z1 = ColorEx.White, x1y2z1 = ColorEx.White, x2y2z1 = ColorEx.White;
						ColorEx x1y1z2 = ColorEx.White, x2y1z2 = ColorEx.White, x1y2z2 = ColorEx.White, x2y2z2 = ColorEx.White;
						Unpack( ref x1y1z1, sx1, sy1, sz1, src.Format, src.Data, src, srcelemsize );
						Unpack( ref x2y1z1, sx2, sy1, sz1, src.Format, src.Data, src, srcelemsize );
						Unpack( ref x1y2z1, sx1, sy2, sz1, src.Format, src.Data, src, srcelemsize );
						Unpack( ref x2y2z1, sx2, sy2, sz1, src.Format, src.Data, src, srcelemsize );
						Unpack( ref x1y1z2, sx1, sy1, sz2, src.Format, src.Data, src, srcelemsize );
						Unpack( ref x2y1z2, sx2, sy1, sz2, src.Format, src.Data, src, srcelemsize );
						Unpack( ref x1y2z2, sx1, sy2, sz2, src.Format, src.Data, src, srcelemsize );
						Unpack( ref x2y2z2, sx2, sy2, sz2, src.Format, src.Data, src, srcelemsize );

						ColorEx accum =
							x1y1z1 * ( ( 1.0f - sxf ) * ( 1.0f - syf ) * ( 1.0f - szf ) ) +
							x2y1z1 * ( sxf * ( 1.0f - syf ) * ( 1.0f - szf ) ) +
							x1y2z1 * ( ( 1.0f - sxf ) * syf * ( 1.0f - szf ) ) +
							x2y2z1 * ( sxf * syf * ( 1.0f - szf ) ) +
							x1y1z2 * ( ( 1.0f - sxf ) * ( 1.0f - syf ) * szf ) +
							x2y1z2 * ( sxf * ( 1.0f - syf ) * szf ) +
							x1y2z2 * ( ( 1.0f - sxf ) * syf * szf ) +
							x2y2z2 * ( sxf * syf * szf );

						PixelConverter.PackColor( accum, dst.Format, new IntPtr( dst.Data.ToInt32() + dstOffset ) );
						dstOffset += dstelemsize;
					}
					dstOffset += dstelemsize * dst.RowSkip;
				}
				dstOffset += dstelemsize * dst.SliceSkip;
			}
		}
LinearResampler