public static void Resize(I <Vector3> source, IntRect sourceRect, I <Vector3> destination, ResizeFilterType filterType, CancellationToken cancel = default(CancellationToken)) { if (source == null) { throw new ArgumentNullException("buffer"); } if (destination == null) { throw new ArgumentNullException("destination"); } sourceRect = sourceRect.Clip(new IntRect(0, 0, source.Width, source.Height)); if (sourceRect.Width <= 0 || sourceRect.Height <= 0 || source.Channels <= 0) { throw new ArgumentNullException("Source image must not be empty"); } if (destination.Width <= 0 || destination.Height <= 0 || destination.Channels <= 0) { return; } var s = source.Data.Buffer; var d = destination.Data.Buffer; var contribX = ImageBufferResize.CreateContributors(filterType, source.Width, sourceRect.Left, sourceRect.Right, destination.Width); var contribY = ImageBufferResize.CreateContributors(filterType, source.Height, sourceRect.Top, sourceRect.Bottom, destination.Height); float filterRadius = ImageBufferResize.GetFilterRadius(filterType); int ringBufferLines = contribY.Max(x => x.N); var ringBuffer = new Vector3[destination.Width * ringBufferLines]; var ranges = destination.Format.ChannelRanges; var low = new Vector3((float)ranges[0].Low, (float)ranges[1].Low, (float)ranges[2].Low); var high = new Vector3((float)ranges[0].High, (float)ranges[1].High, (float)ranges[2].High); int sY = sourceRect.Top; int dX, j; int offset = 0; int positionInRing = sY % ringBufferLines; for (int dY = 0; dY < destination.Height; ++dY) { if ((dY % 128) == 0 && cancel.IsCancellationRequested) { break; } int rowIn, rowOut; while (sY < sourceRect.Bottom && sY <= contribY[dY].MaxPixel) { rowIn = sY * source.Width; rowOut = positionInRing * destination.Width; for (dX = 0; dX < destination.Width; ++dX) { var contrib = contribX[dX]; var value = Vector3.Zero; for (j = 0; j < contribX[dX].N; ++j) { float weight = contrib.P[j].Weight; if (weight != 0) { offset = contrib.P[j].Pixel; value = value + s[rowIn + offset] * weight; } } ringBuffer[rowOut] = value * contrib.Normalize; ++rowOut; } ++sY; positionInRing = (positionInRing + 1) % ringBufferLines; } // resize lines vertically for (int k = 0; k < destination.Width; ++k) { var contrib = contribY[dY]; var value = Vector3.Zero; for (j = 0; j < contrib.N; ++j) { float weight = contrib.P[j].Weight; if (weight != 0) { offset = contrib.P[j].Pixel % ringBufferLines; offset = offset * destination.Width + k; value = value + ringBuffer[offset] * weight; } } value = Vector3.Max(Vector3.Min(value * contrib.Normalize, high), low); d[dY * destination.Width + k] = value; } } }