public void Execute_should_call_DeleteFilter_on_ProjectController() { var projectController = MockRepository.GenerateStub<IProjectController>(); var filterExpr = new NoneFilter<ITestDescriptor>().ToFilterExpr(); var filterInfo = new FilterInfo("None", filterExpr); var command = new DeleteFilterCommand(projectController) { FilterInfo = filterInfo }; command.Execute(MockProgressMonitor.Instance); projectController.AssertWasCalled(pc => pc.DeleteFilter(Arg<IProgressMonitor>.Is.Anything, Arg.Is(filterInfo))); }
public void Execute_should_call_DeleteFilter_on_ProjectController() { var projectController = MockRepository.GenerateStub <IProjectController>(); var filterExpr = new NoneFilter <ITestDescriptor>().ToFilterExpr(); var filterInfo = new FilterInfo("None", filterExpr); var command = new DeleteFilterCommand(projectController) { FilterInfo = filterInfo }; command.Execute(MockProgressMonitor.Instance); projectController.AssertWasCalled(pc => pc.DeleteFilter(Arg <IProgressMonitor> .Is.Anything, Arg.Is(filterInfo))); }
/// <summary> /// Encodes the pixel data line by line. /// Each scanline is encoded in the most optimal manner to improve compression. /// </summary> /// <typeparam name="TPixel">The pixel format.</typeparam> /// <param name="rowSpan">The row span.</param> /// <param name="quantizedPixelsSpan">The span of quantized pixels. Can be null.</param> /// <param name="row">The row.</param> /// <returns>The <see cref="IManagedByteBuffer"/></returns> private IManagedByteBuffer EncodePixelRow <TPixel>(ReadOnlySpan <TPixel> rowSpan, ReadOnlySpan <byte> quantizedPixelsSpan, int row) where TPixel : struct, IPixel <TPixel> { switch (this.pngColorType) { case PngColorType.Palette: int stride = this.rawScanline.Length(); quantizedPixelsSpan.Slice(row * stride, stride).CopyTo(this.rawScanline.GetSpan()); break; case PngColorType.Grayscale: case PngColorType.GrayscaleWithAlpha: this.CollectGrayscaleBytes(rowSpan); break; default: this.CollectTPixelBytes(rowSpan); break; } switch (this.pngFilterMethod) { case PngFilterMethod.None: NoneFilter.Encode(this.rawScanline.GetSpan(), this.result.GetSpan()); return(this.result); case PngFilterMethod.Sub: SubFilter.Encode(this.rawScanline.GetSpan(), this.sub.GetSpan(), this.bytesPerPixel, out int _); return(this.sub); case PngFilterMethod.Up: UpFilter.Encode(this.rawScanline.GetSpan(), this.previousScanline.GetSpan(), this.up.GetSpan(), out int _); return(this.up); case PngFilterMethod.Average: AverageFilter.Encode(this.rawScanline.GetSpan(), this.previousScanline.GetSpan(), this.average.GetSpan(), this.bytesPerPixel, out int _); return(this.average); case PngFilterMethod.Paeth: PaethFilter.Encode(this.rawScanline.GetSpan(), this.previousScanline.GetSpan(), this.paeth.GetSpan(), this.bytesPerPixel, out int _); return(this.paeth); default: return(this.GetOptimalFilteredScanline()); } }
/// <summary> /// Applies all PNG filters to the given scanline and returns the filtered scanline that is deemed /// to be most compressible, using lowest total variation as proxy for compressibility. /// </summary> /// <returns>The <see cref="T:byte[]"/></returns> private Buffer <byte> GetOptimalFilteredScanline() { Span <byte> scanSpan = this.rawScanline.Span; Span <byte> prevSpan = this.previousScanline.Span; // Palette images don't compress well with adaptive filtering. if (this.pngColorType == PngColorType.Palette || this.bitDepth < 8) { NoneFilter.Encode(this.rawScanline, this.result); return(this.result); } // This order, while different to the enumerated order is more likely to produce a smaller sum // early on which shaves a couple of milliseconds off the processing time. UpFilter.Encode(scanSpan, prevSpan, this.up); int currentSum = this.CalculateTotalVariation(this.up, int.MaxValue); int lowestSum = currentSum; Buffer <byte> actualResult = this.up; PaethFilter.Encode(scanSpan, prevSpan, this.paeth, this.bytesPerPixel); currentSum = this.CalculateTotalVariation(this.paeth, currentSum); if (currentSum < lowestSum) { lowestSum = currentSum; actualResult = this.paeth; } SubFilter.Encode(scanSpan, this.sub, this.bytesPerPixel); currentSum = this.CalculateTotalVariation(this.sub, int.MaxValue); if (currentSum < lowestSum) { lowestSum = currentSum; actualResult = this.sub; } AverageFilter.Encode(scanSpan, prevSpan, this.average, this.bytesPerPixel); currentSum = this.CalculateTotalVariation(this.average, currentSum); if (currentSum < lowestSum) { actualResult = this.average; } return(actualResult); }
/// <summary> /// Applies all PNG filters to the given scanline and returns the filtered scanline that is deemed /// to be most compressible, using lowest total variation as proxy for compressibility. /// </summary> /// <returns>The <see cref="T:byte[]"/></returns> private IManagedByteBuffer GetOptimalFilteredScanline() { // Palette images don't compress well with adaptive filtering. if (this.pngColorType == PngColorType.Palette || this.bitDepth < 8) { NoneFilter.Encode(this.rawScanline.GetSpan(), this.result.GetSpan()); return(this.result); } Span <byte> scanSpan = this.rawScanline.GetSpan(); Span <byte> prevSpan = this.previousScanline.GetSpan(); // This order, while different to the enumerated order is more likely to produce a smaller sum // early on which shaves a couple of milliseconds off the processing time. UpFilter.Encode(scanSpan, prevSpan, this.up.GetSpan(), out int currentSum); // TODO: PERF.. We should be breaking out of the encoding for each line as soon as we hit the sum. // That way the above comment would actually be true. It used to be anyway... // If we could use SIMD for none branching filters we could really speed it up. int lowestSum = currentSum; IManagedByteBuffer actualResult = this.up; PaethFilter.Encode(scanSpan, prevSpan, this.paeth.GetSpan(), this.bytesPerPixel, out currentSum); if (currentSum < lowestSum) { lowestSum = currentSum; actualResult = this.paeth; } SubFilter.Encode(scanSpan, this.sub.GetSpan(), this.bytesPerPixel, out currentSum); if (currentSum < lowestSum) { lowestSum = currentSum; actualResult = this.sub; } AverageFilter.Encode(scanSpan, prevSpan, this.average.GetSpan(), this.bytesPerPixel, out currentSum); if (currentSum < lowestSum) { actualResult = this.average; } return(actualResult); }
/// <summary> /// Encodes the pixel data line by line. /// Each scanline is encoded in the most optimal manner to improve compression. /// </summary> /// <typeparam name="TPixel">The pixel format.</typeparam> /// <param name="rowSpan">The row span.</param> /// <param name="row">The row.</param> /// <returns>The <see cref="IManagedByteBuffer"/></returns> private IManagedByteBuffer EncodePixelRow <TPixel>(ReadOnlySpan <TPixel> rowSpan, int row) where TPixel : struct, IPixel <TPixel> { switch (this.pngColorType) { case PngColorType.Palette: // TODO: Use Span copy! Buffer.BlockCopy(this.palettePixelData, row * this.rawScanline.Length(), this.rawScanline.Array, 0, this.rawScanline.Length()); break; case PngColorType.Grayscale: case PngColorType.GrayscaleWithAlpha: this.CollectGrayscaleBytes(rowSpan); break; default: this.CollectTPixelBytes(rowSpan); break; } switch (this.pngFilterMethod) { case PngFilterMethod.None: NoneFilter.Encode(this.rawScanline.Span, this.result.Span); return(this.result); case PngFilterMethod.Sub: SubFilter.Encode(this.rawScanline.Span, this.sub.Span, this.bytesPerPixel, out int _); return(this.sub); case PngFilterMethod.Up: UpFilter.Encode(this.rawScanline.Span, this.previousScanline.Span, this.up.Span, out int _); return(this.up); case PngFilterMethod.Average: AverageFilter.Encode(this.rawScanline.Span, this.previousScanline.Span, this.average.Span, this.bytesPerPixel, out int _); return(this.average); case PngFilterMethod.Paeth: PaethFilter.Encode(this.rawScanline.Span, this.previousScanline.Span, this.paeth.Span, this.bytesPerPixel, out int _); return(this.paeth); default: return(this.GetOptimalFilteredScanline()); } }
/// <summary> /// Applies all PNG filters to the given scanline and returns the filtered scanline that is deemed /// to be most compressible, using lowest total variation as proxy for compressibility. /// </summary> /// <returns>The <see cref="T:byte[]"/></returns> private IManagedByteBuffer GetOptimalFilteredScanline() { // Palette images don't compress well with adaptive filtering. if (this.pngColorType == PngColorType.Palette || this.bitDepth < 8) { NoneFilter.Encode(this.rawScanline.GetSpan(), this.result.GetSpan()); return(this.result); } Span <byte> scanSpan = this.rawScanline.GetSpan(); Span <byte> prevSpan = this.previousScanline.GetSpan(); // This order, while different to the enumerated order is more likely to produce a smaller sum // early on which shaves a couple of milliseconds off the processing time. UpFilter.Encode(scanSpan, prevSpan, this.up.GetSpan(), out int currentSum); int lowestSum = currentSum; IManagedByteBuffer actualResult = this.up; PaethFilter.Encode(scanSpan, prevSpan, this.paeth.GetSpan(), this.bytesPerPixel, out currentSum); if (currentSum < lowestSum) { lowestSum = currentSum; actualResult = this.paeth; } SubFilter.Encode(scanSpan, this.sub.GetSpan(), this.bytesPerPixel, out currentSum); if (currentSum < lowestSum) { lowestSum = currentSum; actualResult = this.sub; } AverageFilter.Encode(scanSpan, prevSpan, this.average.GetSpan(), this.bytesPerPixel, out currentSum); if (currentSum < lowestSum) { actualResult = this.average; } return(actualResult); }
private void DecodePixelData(byte[][] pixelData) { // data = new Color[_width * _height]; _colors = new Color[width * height]; pixels = new int[width * height]; var previousScanline = new byte[bytesPerScanline]; for (var y = 0; y < height; ++y) { var scanline = pixelData[y]; byte[] defilteredScanline; switch (scanline[0]) { case 0: defilteredScanline = NoneFilter.Decode(scanline); break; case 1: defilteredScanline = SubFilter.Decode(scanline, bytesPerPixel); break; case 2: defilteredScanline = UpFilter.Decode(scanline, previousScanline); break; case 3: defilteredScanline = AverageFilter.Decode(scanline, previousScanline, bytesPerPixel); break; case 4: defilteredScanline = PaethFilter.Decode(scanline, previousScanline, bytesPerPixel); break; default: throw new Exception("Unknown filter type."); } previousScanline = defilteredScanline; ProcessDefilteredScanline(defilteredScanline, y); } }
public void ToStringTest(string id) { NoneFilter<object> filter = new NoneFilter<object>(); Assert.AreEqual(filter.ToString(), "None()"); }
public void ToStringTest(string id) { NoneFilter <object> filter = new NoneFilter <object>(); Assert.AreEqual(filter.ToString(), "None()"); }