public void CopyTo(int horizontalFactor, int verticalFactor) { Block8x8F block = CreateRandomFloatBlock(0, 100); var start = new Point(50, 50); using (Buffer2D <float> buffer = Configuration.Default.MemoryAllocator.Allocate2D <float>(100, 100, AllocationOptions.Clean)) { BufferArea <float> area = buffer.GetArea(start.X, start.Y, 8 * horizontalFactor, 8 * verticalFactor); block.CopyTo(area, horizontalFactor, verticalFactor); for (int y = 0; y < 8 * verticalFactor; y++) { for (int x = 0; x < 8 * horizontalFactor; x++) { int yy = y / verticalFactor; int xx = x / horizontalFactor; float expected = block[xx, yy]; float actual = area[x, y]; Assert.Equal(expected, actual); } } VerifyAllZeroOutsideSubArea(buffer, start.X, start.Y, horizontalFactor, verticalFactor); } }
/// <summary> /// Invoke <see cref="JpegBlockPostProcessor"/> for <see cref="BlockRowsPerStep"/> block rows, copy the result into <see cref="ColorBuffer"/>. /// </summary> public void CopyBlocksToColorBuffer() { var blockPp = new JpegBlockPostProcessor(this.ImagePostProcessor.RawJpeg, this.Component); for (int y = 0; y < this.BlockRowsPerStep; y++) { int yBlock = this.currentComponentRowInBlocks + y; if (yBlock >= this.SizeInBlocks.Height) { break; } int yBuffer = y * this.blockAreaSize.Height; for (int x = 0; x < this.SizeInBlocks.Width; x++) { int xBlock = x; int xBuffer = x * this.blockAreaSize.Width; ref Block8x8 block = ref this.Component.GetBlockReference(xBlock, yBlock); BufferArea <float> destArea = this.ColorBuffer.GetArea( xBuffer, yBuffer, this.blockAreaSize.Width, this.blockAreaSize.Height); blockPp.ProcessBlockColorsInto(ref block, destArea); } }
/// <summary> /// Invoke <see cref="JpegBlockPostProcessor"/> for <see cref="BlockRowsPerStep"/> block rows, copy the result into <see cref="ColorBuffer"/>. /// </summary> public void CopyBlocksToColorBuffer() { var blockPp = new JpegBlockPostProcessor(this.ImagePostProcessor.RawJpeg, this.Component); for (int y = 0; y < this.BlockRowsPerStep; y++) { int yBlock = this.currentComponentRowInBlocks + y; if (yBlock >= this.SizeInBlocks.Height) { break; } int yBuffer = y * this.blockAreaSize.Height; Span <Block8x8> blockRow = this.Component.SpectralBlocks.GetRowSpan(yBlock); ref Block8x8 blockRowBase = ref MemoryMarshal.GetReference(blockRow); for (int xBlock = 0; xBlock < this.SizeInBlocks.Width; xBlock++) { ref Block8x8 block = ref Unsafe.Add(ref blockRowBase, xBlock); int xBuffer = xBlock * this.blockAreaSize.Width; BufferArea <float> destArea = this.ColorBuffer.GetArea( xBuffer, yBuffer, this.blockAreaSize.Width, this.blockAreaSize.Height); blockPp.ProcessBlockColorsInto(ref block, destArea); }
/// <summary> /// Copy block data into the destination color buffer pixel area with the provided horizontal and vertical. /// </summary> public void CopyTo(BufferArea <float> area, int horizontalScale, int verticalScale) { if (horizontalScale == 1 && verticalScale == 1) { this.CopyTo(area); return; } else if (horizontalScale == 2 && verticalScale == 2) { this.CopyTo2x2(area); return; } // TODO: Optimize: implement all the cases with loopless special code! (T4?) for (int y = 0; y < 8; y++) { int yy = y * verticalScale; int y8 = y * 8; for (int x = 0; x < 8; x++) { int xx = x * horizontalScale; float value = this[y8 + x]; for (int i = 0; i < verticalScale; i++) { for (int j = 0; j < horizontalScale; j++) { area[xx + j, yy + i] = value; } } } } }
public void GetReferenceToOrigin(int bufferCapacity) { this.memoryAllocator.BufferCapacityInBytes = sizeof(int) * bufferCapacity; using Buffer2D <int> buffer = this.CreateTestBuffer(20, 30); BufferArea <int> area0 = buffer.GetArea(6, 8, 10, 10); ref int r = ref area0.GetReferenceToOrigin();
public void Construct() { using Buffer2D <int> buffer = this.memoryAllocator.Allocate2D <int>(10, 20); var rectangle = new Rectangle(3, 2, 5, 6); var area = new BufferArea <int>(buffer, rectangle); Assert.Equal(buffer, area.DestinationBuffer); Assert.Equal(rectangle, area.Rectangle); }
/// <inheritdoc/> protected override void OnFrameApply(ImageFrame <TPixel> source, ImageFrame <TPixel> destination) { Rectangle sourceRectangle = this.SourceRectangle; Configuration configuration = this.Configuration; // Handle resize dimensions identical to the original if (source.Width == destination.Width && source.Height == destination.Height && sourceRectangle == this.targetRectangle) { // The cloned will be blank here copy all the pixel data over source.GetPixelMemoryGroup().CopyTo(destination.GetPixelMemoryGroup()); return; } int width = this.targetWidth; int height = this.targetHeight; var interest = Rectangle.Intersect(this.targetRectangle, new Rectangle(0, 0, width, height)); if (this.resampler is NearestNeighborResampler) { // Scaling factors float widthFactor = sourceRectangle.Width / (float)this.targetRectangle.Width; float heightFactor = sourceRectangle.Height / (float)this.targetRectangle.Height; var operation = new RowIntervalOperation(sourceRectangle, this.targetRectangle, widthFactor, heightFactor, source, destination); ParallelRowIterator.IterateRows( configuration, interest, in operation); return; } PixelConversionModifiers conversionModifiers = PixelConversionModifiers.Premultiply.ApplyCompanding(this.compand); BufferArea <TPixel> sourceArea = source.PixelBuffer.GetArea(sourceRectangle); // To reintroduce parallel processing, we to launch multiple workers // for different row intervals of the image. using (var worker = new ResizeWorker <TPixel>( configuration, sourceArea, conversionModifiers, this.horizontalKernelMap, this.verticalKernelMap, width, interest, this.targetRectangle.Location)) { worker.Initialize(); var workingInterval = new RowInterval(interest.Top, interest.Bottom); worker.FillDestinationPixels(workingInterval, destination.PixelBuffer); } }
public void Setup() { if (!SimdUtils.IsAvx2CompatibleArchitecture) { throw new InvalidOperationException("Benchmark Block8x8F_CopyTo1x1 is invalid on platforms without AVX2 support."); } this.buffer = Configuration.Default.MemoryAllocator.Allocate2D <float>(1000, 500); this.destArea = this.buffer.GetArea(200, 100, 64, 64); }
public void DangerousGetPinnableReference() { using (Buffer2D <int> buffer = CreateTestBuffer(20, 30)) { BufferArea <int> area0 = buffer.GetArea(6, 8, 10, 10); ref int r = ref area0.GetReferenceToOrigo(); int expected = buffer[6, 8]; Assert.Equal(expected, r); }
public void Construct() { using (var buffer = Configuration.Default.MemoryAllocator.Allocate2D <int>(10, 20)) { var rectangle = new Rectangle(3, 2, 5, 6); var area = new BufferArea <int>(buffer, rectangle); Assert.Equal(buffer, area.DestinationBuffer); Assert.Equal(rectangle, area.Rectangle); } }
public void Construct() { using (var buffer = new Buffer2D <int>(10, 20)) { var rectangle = new Rectangle(3, 2, 5, 6); var area = new BufferArea <int>(buffer, rectangle); Assert.Equal(buffer, area.DestinationBuffer); Assert.Equal(rectangle, area.Rectangle); } }
public void Indexer(int rx, int ry, int x, int y) { using (Buffer2D <int> buffer = CreateTestBuffer(20, 30)) { Rectangle r = new Rectangle(rx, ry, 5, 6); BufferArea <int> area = buffer.GetArea(r); int value = area[x, y]; int expected = (ry + y) * 100 + rx + x; Assert.Equal(expected, value); } }
public void Indexer(int bufferCapacity, int rx, int ry, int x, int y) { this.memoryAllocator.BufferCapacityInBytes = sizeof(int) * bufferCapacity; using Buffer2D <int> buffer = this.CreateTestBuffer(20, 30); var r = new Rectangle(rx, ry, 5, 6); BufferArea <int> area = buffer.GetArea(r); int value = area[x, y]; int expected = ((ry + y) * 100) + rx + x; Assert.Equal(expected, value); }
/// <summary> /// Copy block data into the destination color buffer pixel area with the provided horizontal and vertical. /// </summary> public void CopyTo(BufferArea <float> area, int horizontalScale, int verticalScale) { if (horizontalScale == 1 && verticalScale == 1) { this.CopyTo(area); return; } else if (horizontalScale == 2 && verticalScale == 2) { this.CopyTo2x2(area); return; } ref float destBase = ref area.GetReferenceToOrigin();
public void GetSubArea() { using Buffer2D <int> buffer = this.CreateTestBuffer(20, 30); BufferArea <int> area0 = buffer.GetArea(6, 8, 10, 10); BufferArea <int> area1 = area0.GetSubArea(4, 4, 5, 5); var expectedRect = new Rectangle(10, 12, 5, 5); Assert.Equal(buffer, area1.DestinationBuffer); Assert.Equal(expectedRect, area1.Rectangle); int value00 = (12 * 100) + 10; Assert.Equal(value00, area1[0, 0]); }
public void Copy1x1Scale() { Block8x8F block = CreateRandomFloatBlock(0, 100); using (Buffer2D <float> buffer = Configuration.Default.MemoryAllocator.Allocate2D <float>(20, 20, AllocationOptions.Clean)) { BufferArea <float> area = buffer.GetArea(5, 10, 8, 8); block.Copy1x1Scale(area); Assert.Equal(block[0, 0], buffer[5, 10]); Assert.Equal(block[1, 0], buffer[6, 10]); Assert.Equal(block[0, 1], buffer[5, 11]); Assert.Equal(block[0, 7], buffer[5, 17]); Assert.Equal(block[63], buffer[12, 17]); VerifyAllZeroOutsideSubArea(buffer, 5, 10); } }
//[Fact] public void Unscaled() { Block8x8F block = CreateRandomFloatBlock(0, 100); using (var buffer = Configuration.Default.MemoryManager.Allocate2D <float>(20, 20)) { BufferArea <float> area = buffer.GetArea(5, 10, 8, 8); block.CopyTo(area); Assert.Equal(block[0, 0], buffer[5, 10]); Assert.Equal(block[1, 0], buffer[6, 10]); Assert.Equal(block[0, 1], buffer[5, 11]); Assert.Equal(block[0, 7], buffer[5, 17]); Assert.Equal(block[63], buffer[12, 17]); VerifyAllZeroOutsideSubArea(buffer, 5, 10); } }
public ResizeWorker( Configuration configuration, BufferArea <TPixel> source, PixelConversionModifiers conversionModifiers, ResizeKernelMap horizontalKernelMap, ResizeKernelMap verticalKernelMap, int destWidth, Rectangle targetWorkingRect, Point targetOrigin) { this.configuration = configuration; this.source = source; this.sourceRectangle = source.Rectangle; this.conversionModifiers = conversionModifiers; this.horizontalKernelMap = horizontalKernelMap; this.verticalKernelMap = verticalKernelMap; this.destWidth = destWidth; this.targetWorkingRect = targetWorkingRect; this.targetOrigin = targetOrigin; this.windowBandHeight = verticalKernelMap.MaxDiameter; // We need to make sure the working buffer is contiguous: int workingBufferLimitHintInBytes = Math.Min( configuration.WorkingBufferSizeHintInBytes, configuration.MemoryAllocator.GetBufferCapacityInBytes()); int numberOfWindowBands = ResizeHelper.CalculateResizeWorkerHeightInWindowBands( this.windowBandHeight, destWidth, workingBufferLimitHintInBytes); this.workerHeight = Math.Min(this.sourceRectangle.Height, numberOfWindowBands * this.windowBandHeight); this.transposedFirstPassBuffer = configuration.MemoryAllocator.Allocate2D <Vector4>( this.workerHeight, destWidth, AllocationOptions.Clean); this.tempRowBuffer = configuration.MemoryAllocator.Allocate <Vector4>(this.sourceRectangle.Width); this.tempColumnBuffer = configuration.MemoryAllocator.Allocate <Vector4>(destWidth); this.currentWindow = new RowInterval(0, this.workerHeight); }
public void GetRowSpan(int bufferCapacity, int rx, int ry, int y, int w, int h) { this.memoryAllocator.BufferCapacityInBytes = sizeof(int) * bufferCapacity; using Buffer2D <int> buffer = this.CreateTestBuffer(20, 30); var r = new Rectangle(rx, ry, w, h); BufferArea <int> area = buffer.GetArea(r); Span <int> span = area.GetRowSpan(y); Assert.Equal(w, span.Length); for (int i = 0; i < w; i++) { int expected = ((ry + y) * 100) + rx + i; int value = span[i]; Assert.Equal(expected, value); } }
public void GetRowSpan(int rx, int ry, int y, int w, int h) { using (Buffer2D <int> buffer = CreateTestBuffer(20, 30)) { Rectangle r = new Rectangle(rx, ry, w, h); BufferArea <int> area = buffer.GetArea(r); Span <int> span = area.GetRowSpan(y); Assert.Equal(w, span.Length); for (int i = 0; i < w; i++) { int expected = (ry + y) * 100 + rx + i; int value = span[i]; Assert.Equal(expected, value); } } }
// [MethodImpl(MethodImplOptions.AggressiveInlining)] public void CopyTo(BufferArea <float> area) { ref byte selfBase = ref Unsafe.As <Block8x8F, byte>(ref this);
/// <summary> /// Processes 'sourceBlock' producing Jpeg color channel values from spectral values: /// - Dequantize /// - Applying IDCT /// - Level shift by +128, clip to [0, 255] /// - Copy the resultin color values into 'destArea' scaling up the block by amount defined in <see cref="subSamplingDivisors"/> /// </summary> public void ProcessBlockColorsInto( ref Block8x8 sourceBlock, BufferArea <float> destArea) { ref Block8x8F b = ref this.SourceBlock;
/// <inheritdoc/> protected override void OnFrameApply(ImageFrame <TPixel> source, ImageFrame <TPixel> destination) { Rectangle sourceRectangle = this.SourceRectangle; Configuration configuration = this.Configuration; // Handle resize dimensions identical to the original if (source.Width == destination.Width && source.Height == destination.Height && sourceRectangle == this.targetRectangle) { // The cloned will be blank here copy all the pixel data over source.GetPixelSpan().CopyTo(destination.GetPixelSpan()); return; } int width = this.targetWidth; int height = this.targetHeight; int sourceX = sourceRectangle.X; int sourceY = sourceRectangle.Y; int startY = this.targetRectangle.Y; int startX = this.targetRectangle.X; var targetWorkingRect = Rectangle.Intersect( this.targetRectangle, new Rectangle(0, 0, width, height)); if (this.resampler is NearestNeighborResampler) { // Scaling factors float widthFactor = sourceRectangle.Width / (float)this.targetRectangle.Width; float heightFactor = sourceRectangle.Height / (float)this.targetRectangle.Height; ParallelHelper.IterateRows( targetWorkingRect, configuration, rows => { for (int y = rows.Min; y < rows.Max; y++) { // Y coordinates of source points Span <TPixel> sourceRow = source.GetPixelRowSpan((int)(((y - startY) * heightFactor) + sourceY)); Span <TPixel> targetRow = destination.GetPixelRowSpan(y); for (int x = targetWorkingRect.Left; x < targetWorkingRect.Right; x++) { // X coordinates of source points targetRow[x] = sourceRow[(int)(((x - startX) * widthFactor) + sourceX)]; } } }); return; } PixelConversionModifiers conversionModifiers = PixelConversionModifiers.Premultiply.ApplyCompanding(this.compand); BufferArea <TPixel> sourceArea = source.PixelBuffer.GetArea(sourceRectangle); // To reintroduce parallel processing, we to launch multiple workers // for different row intervals of the image. using (var worker = new ResizeWorker <TPixel>( configuration, sourceArea, conversionModifiers, this.horizontalKernelMap, this.verticalKernelMap, width, targetWorkingRect, this.targetRectangle.Location)) { worker.Initialize(); var workingInterval = new RowInterval(targetWorkingRect.Top, targetWorkingRect.Bottom); worker.FillDestinationPixels(workingInterval, destination.PixelBuffer); } }
public void Setup() { this.buffer = Configuration.Default.MemoryAllocator.Allocate2D <float>(1000, 500); this.destArea = this.buffer.GetArea(200, 100, 128, 128); }
public override void Init() { base.Init(); buffer = ConsoleRenderer.ActiveBuffer; textBox = new TextBox(controlManager) { Width = 34, Height = 13, Text = "Hello there", Attributes = CharAttribute.ForegroundWhite | CharAttribute.BackgroundDarkRed, WordBreak = WordBreak.Hard, TextAlign = TextAlign.Left }; textBox.Text = lorem; textBox.MousePressed += TextBox_MousePressed; textBox.Visible = false; //textBox.MouseReleased += TextBox_MouseReleased; dataBox = new TextBox(controlManager) { Width = 20, Height = 2, Name = "hello", Text = textBox.Rectangle.Size.ToString(), Attributes = CharAttribute.ForegroundGreen }; dataBox.Width = dataBox.Text.Length; dataBox.Visible = false; vs = new VerticalScrollbar(controlManager) { Height = 5, Left = 20, Top = 4 }; hs = new HorizontalScrollbar(controlManager) { Width = 10, Left = 3, Top = Height - 1 }; new ScrollableTextBox(controlManager) { Width = 20, Height = 5 }; colorfulString = new ColorfulString { Value = new string(Enumerable.Repeat('A', Enum.GetValues(typeof(CharAttribute)).Length - 0).ToArray()), ColorThing = ColorSelectMode.Repeat, Attributes = (CharAttribute[])Enum.GetValues(typeof(CharAttribute)) }; strings = new string[] { "Haha", "Console", "Go", "Brrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrr" }.NormalizeLengths() .PadAround(2); int ratioX = 2; int ratioY = 1; int scale = 2; int spacingX = ratioX * scale; int spacingY = ratioY * scale; int pieceWidth = 2; int pieceHeight = 1; int tileWidth = pieceWidth + spacingX * 2; int tileHeight = pieceHeight + spacingY * 2; square = new CharInfo[8 * tileHeight, 8 * tileWidth]; for (int y = 0; y < square.GetLength(0); y++) { for (int x = 0; x < square.GetLength(1); x++) { square[y, x].Attributes |= ((x / tileWidth + y / tileHeight) % 2 == 0 ? CharAttribute.BackgroundGrey | CharAttribute.ForegroundBlack : CharAttribute.BackgroundBlack | CharAttribute.ForegroundWhite); } } for (int y = 0; y < square.GetLength(0); y++) { for (int x = 0; x < square.GetLength(1); x++) { if (x % tileWidth == 0 && y % tileHeight == 0) { int px = x + spacingX; int py = y + spacingY; square[py, px].UnicodeChar = '♕'; square[py, px].Attributes |= CharAttribute.LeadingByte; var yellow = CharAttribute.BackgroundYellow | CharAttribute.ForegroundBlack; var marker = new CharInfo { UnicodeChar = ShadingCharacter.Light, Attributes = yellow }; } } } backface = new BufferArea(square.GetLength(1) + 4, square.GetLength(0) + 2); CharInfo backChar = new CharInfo { UnicodeChar = ShadingCharacter.Dark, Attributes = CharAttribute.BackgroundDarkGrey }; backface.Fill(backChar); //Draw(); ConsoleInput.KeyPressed += ConsoleInput_KeyPressed; ConsoleInput.KeyHeld += ConsoleInput_KeyPressed; ConsoleInput.MouseReleased += TextBox_MouseReleased; ConsoleInput.MouseDragged += ConsoleInput_MouseDragged; ConsoleInput.Resized += ConsoleInput_Resized; //ConsoleInput.Resized += delegate //{ // Draw(); //}; Draw(); }