예제 #1
0
            /// <inheritdoc />
            internal override void Apply(Span <float> scanline, int x, int y)
            {
                Span <TPixel> destinationRow = this.Target.GetPixelRowSpan(y).Slice(x);

                // constrain the spans to each other
                if (destinationRow.Length > scanline.Length)
                {
                    destinationRow = destinationRow.Slice(0, scanline.Length);
                }
                else
                {
                    scanline = scanline.Slice(0, destinationRow.Length);
                }

                MemoryAllocator memoryAllocator = this.Target.MemoryAllocator;
                Configuration   configuration   = this.Configuration;

                if (this.Options.BlendPercentage == 1f)
                {
                    this.Blender.Blend(configuration, destinationRow, destinationRow, this.Colors.Memory.Span, scanline);
                }
                else
                {
                    using (IMemoryOwner <float> amountBuffer = memoryAllocator.Allocate <float>(scanline.Length))
                    {
                        Span <float> amountSpan = amountBuffer.Memory.Span;

                        for (int i = 0; i < scanline.Length; i++)
                        {
                            amountSpan[i] = scanline[i] * this.Options.BlendPercentage;
                        }

                        this.Blender.Blend(
                            configuration,
                            destinationRow,
                            destinationRow,
                            this.Colors.Memory.Span,
                            amountSpan);
                    }
                }
            }
        /// <inheritdoc/>
        protected override void OnFrameApply(ImageFrame <TPixel> source)
        {
            MemoryAllocator memoryAllocator = this.Configuration.MemoryAllocator;
            int             numberOfPixels  = source.Width * source.Height;
            var             interest        = Rectangle.Intersect(this.SourceRectangle, source.Bounds());

            using IMemoryOwner <int> histogramBuffer = memoryAllocator.Allocate <int>(this.LuminanceLevels, AllocationOptions.Clean);

            // Build the histogram of the grayscale levels.
            var grayscaleOperation = new GrayscaleLevelsRowOperation(interest, histogramBuffer, source.PixelBuffer, this.LuminanceLevels);

            ParallelRowIterator.IterateRows(
                this.Configuration,
                interest,
                in grayscaleOperation);

            Span <int> histogram = histogramBuffer.GetSpan();

            if (this.ClipHistogramEnabled)
            {
                this.ClipHistogram(histogram, this.ClipLimit);
            }

            using IMemoryOwner <int> cdfBuffer = memoryAllocator.Allocate <int>(this.LuminanceLevels, AllocationOptions.Clean);

            // Calculate the cumulative distribution function, which will map each input pixel to a new value.
            int cdfMin = this.CalculateCdf(
                ref MemoryMarshal.GetReference(cdfBuffer.GetSpan()),
                ref MemoryMarshal.GetReference(histogram),
                histogram.Length - 1);

            float numberOfPixelsMinusCdfMin = numberOfPixels - cdfMin;

            // Apply the cdf to each pixel of the image
            var cdfOperation = new CdfApplicationRowOperation(interest, cdfBuffer, source.PixelBuffer, this.LuminanceLevels, numberOfPixelsMinusCdfMin);

            ParallelRowIterator.IterateRows(
                this.Configuration,
                interest,
                in cdfOperation);
        }
예제 #3
0
        public void Decode3D(IntPtr input, int width, int height, int depth, int inputWidthStride, int inputHeightStride,
                             int inputOffset, IntPtr output, int outputWidthStride = -1, int outputHeightStride = -1, int outputOffset = -1)
        {
            if (outputWidthStride == -1)
            {
                outputWidthStride = inputWidthStride;
            }
            if (outputHeightStride == -1)
            {
                outputHeightStride = inputHeightStride;
            }
            if (outputOffset == -1)
            {
                outputOffset = inputOffset;
            }

            // Decode depth vectors
            for (int row = 0; row < height; row++)
            {
                for (int column = 0; column < width; column++)
                {
                    Decode1D(input, depth, inputWidthStride * inputHeightStride, row * inputWidthStride + column,
                             output, outputWidthStride * outputHeightStride, outputOffset + row * outputWidthStride + column);
                }
            }


            IntPtr buffer = Marshal.AllocHGlobal(width * height * depth * ElementSize);

            MemoryAllocator.Copy3D(output, width, height, depth, outputWidthStride, outputHeightStride, outputOffset, buffer, width, height, 0, ElementSize);


            // Decode 2d surface in depth
            for (int surface = 0; surface < depth; surface++)
            {
                Decode2D(buffer, width, height, width, surface * width * height,
                         output, outputWidthStride, outputOffset + surface * outputWidthStride * outputHeightStride);
            }

            Marshal.FreeHGlobal(buffer);
        }
        public void Encode2D(IntPtr input, int width, int height, int inputWidthStride, int inputOffset, IntPtr output,
                             int outputWidthStride = -1, int outputOffset = -1)
        {
            if (outputWidthStride == -1)
            {
                outputWidthStride = inputWidthStride;
            }
            if (outputOffset == -1)
            {
                outputOffset = inputOffset;
            }

            IntPtr buffer = Marshal.AllocHGlobal(width * height * ElementSize);

            MemoryAllocator.Copy2D(input, width, height, inputWidthStride, inputOffset,
                                   buffer, width, 0, ElementSize);

            Encode2D(buffer, width, height, width, 0, output, outputWidthStride, outputOffset, 0);

            Marshal.FreeHGlobal(buffer);
        }
        public void Decode1D(IntPtr input, int size, int inputStride, int inputOffset, IntPtr output, int outputStride = -1,
                             int outputOffset = -1)
        {
            if (outputStride == -1)
            {
                outputStride = inputStride;
            }
            if (outputOffset == -1)
            {
                outputOffset = inputOffset;
            }


            IntPtr buffer = Marshal.AllocHGlobal(size * ElementSize);

            MemoryAllocator.Copy1D(input, size, inputStride, inputOffset, buffer, 1, 0, ElementSize);

            Decode1D(buffer, size, 1, 0, output, outputStride, outputOffset, 0);

            Marshal.FreeHGlobal(buffer);
        }
예제 #6
0
 public PeriodicKernelMap(
     MemoryAllocator memoryAllocator,
     int sourceLength,
     int destinationLength,
     double ratio,
     double scale,
     int radius,
     int period,
     int cornerInterval)
     : base(
         memoryAllocator,
         sourceLength,
         destinationLength,
         (cornerInterval * 2) + period,
         ratio,
         scale,
         radius)
 {
     this.cornerInterval = cornerInterval;
     this.period         = period;
 }
        private static void BackwardReferencesTraceBackwards(
            int xSize,
            int ySize,
            MemoryAllocator memoryAllocator,
            ReadOnlySpan <uint> bgra,
            int cacheBits,
            Vp8LHashChain hashChain,
            Vp8LBackwardRefs refsSrc,
            Vp8LBackwardRefs refsDst)
        {
            int distArraySize = xSize * ySize;

            using IMemoryOwner <ushort> distArrayBuffer = memoryAllocator.Allocate <ushort>(distArraySize);
            Span <ushort> distArray = distArrayBuffer.GetSpan();

            BackwardReferencesHashChainDistanceOnly(xSize, ySize, memoryAllocator, bgra, cacheBits, hashChain, refsSrc, distArrayBuffer);
            int           chosenPathSize = TraceBackwards(distArray, distArraySize);
            Span <ushort> chosenPath     = distArray.Slice(distArraySize - chosenPathSize);

            BackwardReferencesHashChainFollowChosenPath(bgra, cacheBits, chosenPath, chosenPathSize, hashChain, refsDst);
        }
예제 #8
0
 public SlidingWindowOperation(
     Configuration configuration,
     AdaptiveHistogramEqualizationSlidingWindowProcessor <TPixel> processor,
     ImageFrame <TPixel> source,
     MemoryAllocator memoryAllocator,
     Buffer2D <TPixel> targetPixels,
     SlidingWindowInfos swInfos,
     int yStart,
     int yEnd,
     bool useFastPath)
 {
     this.configuration   = configuration;
     this.processor       = processor;
     this.source          = source;
     this.memoryAllocator = memoryAllocator;
     this.targetPixels    = targetPixels;
     this.swInfos         = swInfos;
     this.yStart          = yStart;
     this.yEnd            = yEnd;
     this.useFastPath     = useFastPath;
 }
예제 #9
0
        private static void WriteWideRgb <TPixel>(Configuration configuration, Stream stream, ImageFrame <TPixel> image)
            where TPixel : unmanaged, IPixel <TPixel>
        {
            int width  = image.Width;
            int height = image.Height;
            Buffer2D <TPixel> pixelBuffer = image.PixelBuffer;
            MemoryAllocator   allocator   = configuration.MemoryAllocator;

            using IMemoryOwner <Rgb48> row = allocator.Allocate <Rgb48>(width);
            Span <Rgb48> rowSpan           = row.GetSpan();

            using IMemoryOwner <byte> plainMemory = allocator.Allocate <byte>(width * MaxCharsPerPixelRgbWide);
            Span <byte> plainSpan = plainMemory.GetSpan();

            for (int y = 0; y < height; y++)
            {
                Span <TPixel> pixelSpan = pixelBuffer.DangerousGetRowSpan(y);
                PixelOperations <TPixel> .Instance.ToRgb48(
                    configuration,
                    pixelSpan,
                    rowSpan);

                int written = 0;
                for (int x = 0; x < width; x++)
                {
                    Utf8Formatter.TryFormat(rowSpan[x].R, plainSpan.Slice(written), out int bytesWritten, DecimalFormat);
                    written += bytesWritten;
                    plainSpan[written++] = Space;
                    Utf8Formatter.TryFormat(rowSpan[x].G, plainSpan.Slice(written), out bytesWritten, DecimalFormat);
                    written += bytesWritten;
                    plainSpan[written++] = Space;
                    Utf8Formatter.TryFormat(rowSpan[x].B, plainSpan.Slice(written), out bytesWritten, DecimalFormat);
                    written += bytesWritten;
                    plainSpan[written++] = Space;
                }

                plainSpan[written - 1] = NewLine;
                stream.Write(plainSpan, 0, written);
            }
        }
예제 #10
0
        public void AllocationAndFreeOutOfOrderRepeatFirstOrder()
        {
            var allocator = new MemoryAllocator(_logger, new FarPtr(SEGMENT, 2), 0xFFFE, DEFAULT_ALIGNMENT);

            var memory1 = allocator.Malloc(16);

            memory1.Segment.Should().Be(SEGMENT);
            memory1.Offset.Should().Be(2);
            allocator.GetAllocatedMemorySize(memory1).Should().Be(16);

            var memory2 = allocator.Malloc(256);

            memory2.Segment.Should().Be(SEGMENT);
            memory2.Offset.Should().Be(18);
            allocator.GetAllocatedMemorySize(memory2).Should().Be(256);

            var memory3 = allocator.Malloc(16);

            memory3.Segment.Should().Be(SEGMENT);
            memory3.Offset.Should().Be(256 + 18);
            allocator.GetAllocatedMemorySize(memory3).Should().Be(16);

            allocator.FreeBlocks.Should().Be(1);

            // free middle one, nothing should be able to be compacted
            allocator.Free(memory2);

            allocator.FreeBlocks.Should().Be(2);

            // free first one, should compact
            allocator.Free(memory1);
            allocator.FreeBlocks.Should().Be(2);

            // free final one, should compact
            allocator.Free(memory3);
            allocator.FreeBlocks.Should().Be(1);

            allocator.RemainingBytes.Should().Be(0xFFFE);
        }
        private void Encode2D(IntPtr input, int width, int height, int inputWidthStride, int inputOffset, IntPtr output, int outputWidthStride,
                              int outputOffset, int level)
        {
            if (level < MaximumLevelNumber && width > MinimumBandSize && height > MinimumBandSize)
            {
                _waveletTransformation.Encode2D(input, width, height, inputWidthStride, inputOffset, output, outputWidthStride,
                                                outputOffset);

                width++;
                height++;
                width  /= 2;
                height /= 2;
                level++;
                if (level < MaximumLevelNumber && width > MinimumBandSize && height > MinimumBandSize)
                {
                    MemoryAllocator.Copy2D(output, width, height, outputWidthStride, outputOffset,
                                           input, inputWidthStride, 0, ElementSize);

                    Encode2D(input, width, height, inputWidthStride, inputOffset, output, outputWidthStride, outputOffset, level);
                }
            }
        }
 public bool AddBis(byte *words, int length, byte *value)
 {
     _b = *words;
     if (length == 0)
     {
         _value = value;
         return(true);
     }
     else
     {
         if (_next == null)
         {
             _next = (ByteStringToPtrByteTreeNode *)MemoryAllocator.New(sizeof(ByteStringToPtrByteTreeNode) * 256);
             MemoryHelper.Fill((byte *)_next, 0x00, sizeof(ByteStringToPtrByteTreeNode) * 256);
         }
         if (_next[*words].AddBis(++words, --length, value))
         {
             _count++;
         }
     }
     return(false);
 }
예제 #13
0
        private static void ExecuteActions(MemoryAllocator allocator, RecordBatch batch, IReadOnlyList <IAction> actions,
                                           int iterations)
        {
            var builder = new RecordBatch.Builder(allocator);

            for (var i = 0; i < iterations; i++)
            {
                foreach (var action in actions)
                {
                    action.Execute(batch, builder);
                }

                try
                {
                    batch   = builder.Build();
                    builder = new RecordBatch.Builder(allocator);
                }
                catch (InvalidOperationException)
                {
                }
            }
        }
예제 #14
0
 private ResizeKernelMap(
     MemoryAllocator memoryAllocator,
     IResampler sampler,
     int sourceLength,
     int destinationLength,
     int bufferHeight,
     double ratio,
     double scale,
     int radius)
 {
     this.sampler           = sampler;
     this.ratio             = ratio;
     this.scale             = scale;
     this.radius            = radius;
     this.sourceLength      = sourceLength;
     this.DestinationLength = destinationLength;
     this.MaxDiameter       = (radius * 2) + 1;
     this.data       = memoryAllocator.Allocate2D <float>(this.MaxDiameter, bufferHeight, AllocationOptions.Clean);
     this.pinHandle  = this.data.GetMemory().Pin();
     this.kernels    = new ResizeKernel[destinationLength];
     this.tempValues = new double[this.MaxDiameter];
 }
        /// <summary>
        /// Blends 2 rows together
        /// </summary>
        /// <typeparam name="TPixelSrc">the pixel format of the source span</typeparam>
        /// <param name="memoryManager">memory manager to use internally</param>
        /// <param name="destination">the destination span</param>
        /// <param name="background">the background span</param>
        /// <param name="source">the source span</param>
        /// <param name="amount">
        /// A span with values between 0 and 1 indicating the weight of the second source vector.
        /// At amount = 0, "from" is returned, at amount = 1, "to" is returned.
        /// </param>
        public void Blend <TPixelSrc>(MemoryAllocator memoryManager, Span <TPixel> destination, ReadOnlySpan <TPixel> background, ReadOnlySpan <TPixelSrc> source, ReadOnlySpan <float> amount)
            where TPixelSrc : struct, IPixel <TPixelSrc>
        {
            Guard.MustBeGreaterThanOrEqualTo(background.Length, destination.Length, nameof(background.Length));
            Guard.MustBeGreaterThanOrEqualTo(source.Length, destination.Length, nameof(source.Length));
            Guard.MustBeGreaterThanOrEqualTo(amount.Length, destination.Length, nameof(amount.Length));

            using (IMemoryOwner <Vector4> buffer = memoryManager.Allocate <Vector4>(destination.Length * 3))
            {
                Span <Vector4> destinationSpan = buffer.Slice(0, destination.Length);
                Span <Vector4> backgroundSpan  = buffer.Slice(destination.Length, destination.Length);
                Span <Vector4> sourceSpan      = buffer.Slice(destination.Length * 2, destination.Length);

                PixelOperations <TPixel> .Instance.ToScaledVector4(background, backgroundSpan, destination.Length);

                PixelOperations <TPixelSrc> .Instance.ToScaledVector4(source, sourceSpan, destination.Length);

                this.BlendFunction(destinationSpan, backgroundSpan, sourceSpan, amount);

                PixelOperations <TPixel> .Instance.PackFromScaledVector4(destinationSpan, destination, destination.Length);
            }
        }
예제 #16
0
        public void AllocateEverything()
        {
            var random    = new Random();
            var memory    = new List <FarPtr>();
            var allocator = new MemoryAllocator(_logger, new FarPtr(SEGMENT, 2), 0xFFFE, DEFAULT_ALIGNMENT);

            // allocate all the memory
            while (allocator.RemainingBytes > 0)
            {
                var size = random.Next(Math.Min(256, (int)allocator.RemainingBytes)) + 1;
                var ptr  = allocator.Malloc((ushort)size);
                // could be null due to fragmentation of the memory space, so just skip and move on to another size
                if (ptr.IsNull())
                {
                    continue;
                }

                memory.Add(ptr);

                // randomly free in the middle of the allocations to fragment memory space on purpose
                if (random.Next(4) == 0)
                {
                    FreeRandom(random, memory, allocator);
                }
            }

            // ensure future requests fail since we're out of memory
            allocator.Malloc(0).Should().Be(FarPtr.Empty);
            allocator.Malloc(1).Should().Be(FarPtr.Empty);

            while (memory.Count > 0)
            {
                FreeRandom(random, memory, allocator);
            }

            allocator.RemainingBytes.Should().Be(0xFFFE);
            allocator.FreeBlocks.Should().Be(1);
        }
예제 #17
0
        /// <summary>
        /// Initializes a new instance of the <see cref="AlphaDecoder"/> class.
        /// </summary>
        /// <param name="width">The width of the image.</param>
        /// <param name="height">The height of the image.</param>
        /// <param name="data">The (maybe compressed) alpha data.</param>
        /// <param name="alphaChunkHeader">The first byte of the alpha image stream contains information on how to decode the stream.</param>
        /// <param name="memoryAllocator">Used for allocating memory during decoding.</param>
        /// <param name="configuration">The configuration.</param>
        public AlphaDecoder(int width, int height, IMemoryOwner <byte> data, byte alphaChunkHeader, MemoryAllocator memoryAllocator, Configuration configuration)
        {
            this.Width           = width;
            this.Height          = height;
            this.Data            = data;
            this.memoryAllocator = memoryAllocator;
            this.LastRow         = 0;
            int totalPixels = width * height;

            var compression = (WebpAlphaCompressionMethod)(alphaChunkHeader & 0x03);

            if (compression is not WebpAlphaCompressionMethod.NoCompression and not WebpAlphaCompressionMethod.WebpLosslessCompression)
            {
                WebpThrowHelper.ThrowImageFormatException($"unexpected alpha compression method {compression} found");
            }

            this.Compressed = compression == WebpAlphaCompressionMethod.WebpLosslessCompression;

            // The filtering method used. Only values between 0 and 3 are valid.
            int filter = (alphaChunkHeader >> 2) & 0x03;

            if (filter is < (int)WebpAlphaFilterType.None or > (int)WebpAlphaFilterType.Gradient)
            {
                WebpThrowHelper.ThrowImageFormatException($"unexpected alpha filter method {filter} found");
            }

            this.Alpha           = memoryAllocator.Allocate <byte>(totalPixels);
            this.AlphaFilterType = (WebpAlphaFilterType)filter;
            this.Vp8LDec         = new Vp8LDecoder(width, height, memoryAllocator);

            if (this.Compressed)
            {
                var bitReader = new Vp8LBitReader(data);
                this.LosslessDecoder = new WebpLosslessDecoder(bitReader, memoryAllocator, configuration);
                this.LosslessDecoder.DecodeImageStream(this.Vp8LDec, width, height, true);
                this.Use8BDecode = this.Vp8LDec.Transforms.Count > 0 && Is8BOptimizable(this.Vp8LDec.Metadata);
            }
        }
예제 #18
0
        /// <summary>
        /// Initializes a new instance of the <see cref="T4BitReader" /> class.
        /// </summary>
        /// <param name="input">The compressed input stream.</param>
        /// <param name="fillOrder">The logical order of bits within a byte.</param>
        /// <param name="bytesToRead">The number of bytes to read from the stream.</param>
        /// <param name="allocator">The memory allocator.</param>
        /// <param name="eolPadding">Indicates, if fill bits have been added as necessary before EOL codes such that EOL always ends on a byte boundary. Defaults to false.</param>
        public T4BitReader(Stream input, TiffFillOrder fillOrder, int bytesToRead, MemoryAllocator allocator, bool eolPadding = false)
        {
            this.fillOrder = fillOrder;
            this.Data      = allocator.Allocate <byte>(bytesToRead);
            this.ReadImageDataFromStream(input, bytesToRead);

            this.DataLength           = bytesToRead;
            this.BitsRead             = 0;
            this.Value                = 0;
            this.CurValueBitsRead     = 0;
            this.Position             = 0;
            this.IsWhiteRun           = true;
            this.isFirstScanLine      = true;
            this.isStartOfRow         = true;
            this.terminationCodeFound = false;
            this.RunLength            = 0;
            this.eolPadding           = eolPadding;

            if (this.eolPadding)
            {
                this.maxCodeLength = 24;
            }
        }
            private (Edge edge, Intersection?info) FindIntersection(PointF start, PointF end)
            {
                (Edge edge, Intersection? info)closest = default;

                MemoryAllocator allocator = this.Configuration.MemoryAllocator;

                foreach (Edge edge in this.edges)
                {
                    Intersection?intersection = edge.FindIntersection(start, end, allocator);

                    if (!intersection.HasValue)
                    {
                        continue;
                    }

                    if (closest.info == null || closest.info.Value.Distance > intersection.Value.Distance)
                    {
                        closest = (edge, intersection);
                    }
                }

                return(closest);
            }
예제 #20
0
            /// <inheritdoc />
            internal override void Apply(Span <float> scanline, int x, int y)
            {
                int             patternY        = y % this.pattern.Rows;
                MemoryAllocator memoryAllocator = this.Target.MemoryAllocator;

                using (IMemoryOwner <float> amountBuffer = memoryAllocator.Allocate <float>(scanline.Length))
                    using (IMemoryOwner <TPixel> overlay = memoryAllocator.Allocate <TPixel>(scanline.Length))
                    {
                        Span <float>  amountSpan  = amountBuffer.GetSpan();
                        Span <TPixel> overlaySpan = overlay.GetSpan();

                        for (int i = 0; i < scanline.Length; i++)
                        {
                            amountSpan[i] = (scanline[i] * this.Options.BlendPercentage).Clamp(0, 1);

                            int patternX = (x + i) % this.pattern.Columns;
                            overlaySpan[i] = this.pattern[patternY, patternX];
                        }

                        Span <TPixel> destinationRow = this.Target.GetPixelRowSpan(y).Slice(x, scanline.Length);
                        this.Blender.Blend(memoryAllocator, destinationRow, destinationRow, overlaySpan, amountSpan);
                    }
            }
예제 #21
0
        /// <inheritdoc/>
        protected override void OnFrameApply(ImageFrame <TPixel> source, Rectangle sourceRectangle, Configuration configuration)
        {
            Image <TPixel>        targetImage = this.Image;
            PixelBlender <TPixel> blender     = this.Blender;
            int locationY = this.Location.Y;

            // Align start/end positions.
            Rectangle bounds = targetImage.Bounds();

            int minX    = Math.Max(this.Location.X, sourceRectangle.X);
            int maxX    = Math.Min(this.Location.X + bounds.Width, sourceRectangle.Width);
            int targetX = minX - this.Location.X;

            int minY = Math.Max(this.Location.Y, sourceRectangle.Y);
            int maxY = Math.Min(this.Location.Y + bounds.Height, sourceRectangle.Bottom);

            int width = maxX - minX;

            MemoryAllocator memoryAllocator = this.Image.GetConfiguration().MemoryAllocator;

            using (IMemoryOwner <float> amount = memoryAllocator.Allocate <float>(width))
            {
                amount.GetSpan().Fill(this.Opacity);

                ParallelFor.WithConfiguration(
                    minY,
                    maxY,
                    configuration,
                    y =>
                {
                    Span <TPixel> background = source.GetPixelRowSpan(y).Slice(minX, width);
                    Span <TPixel> foreground = targetImage.GetPixelRowSpan(y - locationY).Slice(targetX, width);
                    blender.Blend(memoryAllocator, background, background, foreground, amount.GetSpan());
                });
            }
        }
예제 #22
0
        private static void WriteGrayscale <TPixel>(Configuration configuration, Stream stream, ImageFrame <TPixel> image)
            where TPixel : unmanaged, IPixel <TPixel>
        {
            int width  = image.Width;
            int height = image.Height;
            Buffer2D <TPixel> pixelBuffer = image.PixelBuffer;
            MemoryAllocator   allocator   = configuration.MemoryAllocator;

            using IMemoryOwner <byte> row = allocator.Allocate <byte>(width);
            Span <byte> rowSpan           = row.GetSpan();

            for (int y = 0; y < height; y++)
            {
                Span <TPixel> pixelSpan = pixelBuffer.DangerousGetRowSpan(y);

                PixelOperations <TPixel> .Instance.ToL8Bytes(
                    configuration,
                    pixelSpan,
                    rowSpan,
                    width);

                stream.Write(rowSpan);
            }
        }
예제 #23
0
            /// <inheritdoc />
            public override void Blend(MemoryAllocator memoryManager, Span <TPixel> destination, Span <TPixel> background, Span <TPixel> source, Span <float> amount)
            {
                Guard.MustBeGreaterThanOrEqualTo(background.Length, destination.Length, nameof(background.Length));
                Guard.MustBeGreaterThanOrEqualTo(source.Length, destination.Length, nameof(source.Length));
                Guard.MustBeGreaterThanOrEqualTo(amount.Length, destination.Length, nameof(amount.Length));

                using (IMemoryOwner <Vector4> buffer = memoryManager.Allocate <Vector4>(destination.Length * 3))
                {
                    Span <Vector4> destinationSpan = buffer.Slice(0, destination.Length);
                    Span <Vector4> backgroundSpan  = buffer.Slice(destination.Length, destination.Length);
                    Span <Vector4> sourceSpan      = buffer.Slice(destination.Length * 2, destination.Length);

                    PixelOperations <TPixel> .Instance.ToVector4(background, backgroundSpan, destination.Length);

                    PixelOperations <TPixel> .Instance.ToVector4(source, sourceSpan, destination.Length);

                    for (int i = 0; i < destination.Length; i++)
                    {
                        destinationSpan[i] = PorterDuffFunctions.Xor(backgroundSpan[i], sourceSpan[i], amount[i]);
                    }

                    PixelOperations <TPixel> .Instance.PackFromVector4(destinationSpan, destination, destination.Length);
                }
            }
        /// <summary>
        /// Applies the sliding window equalization to one column of the image. The window is moved from top to bottom.
        /// Moving the window one pixel down requires to remove one row from the top of the window from the histogram and
        /// adding a new row at the bottom.
        /// </summary>
        /// <param name="source">The source image.</param>
        /// <param name="memoryAllocator">The memory allocator.</param>
        /// <param name="targetPixels">The target pixels.</param>
        /// <param name="swInfos"><see cref="SlidingWindowInfos"/> about the sliding window dimensions.</param>
        /// <param name="yStart">The y start position.</param>
        /// <param name="yEnd">The y end position.</param>
        /// <param name="useFastPath">if set to true the borders of the image will not be checked.</param>
        /// <param name="configuration">The configuration.</param>
        /// <returns>Action Delegate.</returns>
        private Action <int> ProcessSlidingWindow(
            ImageFrame <TPixel> source,
            MemoryAllocator memoryAllocator,
            Buffer2D <TPixel> targetPixels,
            SlidingWindowInfos swInfos,
            int yStart,
            int yEnd,
            bool useFastPath,
            Configuration configuration)
        {
            return(x =>
            {
                using (IMemoryOwner <int> histogramBuffer = memoryAllocator.Allocate <int>(this.LuminanceLevels, AllocationOptions.Clean))
                    using (IMemoryOwner <int> histogramBufferCopy = memoryAllocator.Allocate <int>(this.LuminanceLevels, AllocationOptions.Clean))
                        using (IMemoryOwner <int> cdfBuffer = memoryAllocator.Allocate <int>(this.LuminanceLevels, AllocationOptions.Clean))
                            using (IMemoryOwner <Vector4> pixelRowBuffer = memoryAllocator.Allocate <Vector4>(swInfos.TileWidth, AllocationOptions.Clean))
                            {
                                Span <int> histogram = histogramBuffer.GetSpan();
                                ref int histogramBase = ref MemoryMarshal.GetReference(histogram);

                                Span <int> histogramCopy = histogramBufferCopy.GetSpan();
                                ref int histogramCopyBase = ref MemoryMarshal.GetReference(histogramCopy);

                                ref int cdfBase = ref MemoryMarshal.GetReference(cdfBuffer.GetSpan());
예제 #25
0
        /// <inheritdoc/>
        protected override void BeforeImageApply(Image <TPixel> destination)
        {
            if (!(this.resampler is NearestNeighborResampler))
            {
                Image <TPixel> source          = this.Source;
                Rectangle      sourceRectangle = this.SourceRectangle;

                // Since all image frame dimensions have to be the same we can calculate this for all frames.
                MemoryAllocator memoryAllocator = source.GetMemoryAllocator();
                this.horizontalKernelMap = ResizeKernelMap.Calculate(
                    this.resampler,
                    this.targetRectangle.Width,
                    sourceRectangle.Width,
                    memoryAllocator);

                this.verticalKernelMap = ResizeKernelMap.Calculate(
                    this.resampler,
                    this.targetRectangle.Height,
                    sourceRectangle.Height,
                    memoryAllocator);
            }

            base.BeforeImageApply(destination);
        }
예제 #26
0
        /// <inheritdoc/>
        protected override void OnFrameApply(ImageFrame <TPixelDst> source, Rectangle sourceRectangle, Configuration configuration)
        {
            Image <TPixelSrc>        targetImage = this.Image;
            PixelBlender <TPixelDst> blender     = this.Blender;
            int locationY = this.Location.Y;

            // Align start/end positions.
            Rectangle bounds = targetImage.Bounds();

            int minX    = Math.Max(this.Location.X, sourceRectangle.X);
            int maxX    = Math.Min(this.Location.X + bounds.Width, sourceRectangle.Width);
            int targetX = minX - this.Location.X;

            int minY = Math.Max(this.Location.Y, sourceRectangle.Y);
            int maxY = Math.Min(this.Location.Y + bounds.Height, sourceRectangle.Bottom);

            int width = maxX - minX;

            MemoryAllocator memoryAllocator = this.Image.GetConfiguration().MemoryAllocator;

            var workingRect = Rectangle.FromLTRB(minX, minY, maxX, maxY);

            ParallelHelper.IterateRows(
                workingRect,
                configuration,
                rows =>
            {
                for (int y = rows.Min; y < rows.Max; y++)
                {
                    Span <TPixelDst> background = source.GetPixelRowSpan(y).Slice(minX, width);
                    Span <TPixelSrc> foreground =
                        targetImage.GetPixelRowSpan(y - locationY).Slice(targetX, width);
                    blender.Blend <TPixelSrc>(memoryAllocator, background, background, foreground, this.Opacity);
                }
            });
        }
예제 #27
0
        public JpegComponent(MemoryAllocator memoryAllocator, JpegFrame frame, byte id, int horizontalFactor, int verticalFactor, byte quantizationTableIndex, int index)
        {
            this.memoryAllocator = memoryAllocator;
            this.Frame           = frame;
            this.Id = id;

            // Validate sampling factors.
            if (horizontalFactor == 0 || verticalFactor == 0)
            {
                JpegThrowHelper.ThrowBadSampling();
            }

            this.HorizontalSamplingFactor = horizontalFactor;
            this.VerticalSamplingFactor   = verticalFactor;
            this.SamplingFactors          = new Size(this.HorizontalSamplingFactor, this.VerticalSamplingFactor);

            if (quantizationTableIndex > 3)
            {
                JpegThrowHelper.ThrowBadQuantizationTableIndex(quantizationTableIndex);
            }

            this.QuantizationTableIndex = quantizationTableIndex;
            this.Index = index;
        }
예제 #28
0
 public YCbCrTiffColor(MemoryAllocator memoryAllocator, Rational[] referenceBlackAndWhite, Rational[] coefficients, ushort[] ycbcrSubSampling)
 {
     this.memoryAllocator  = memoryAllocator;
     this.converter        = new YCbCrConverter(referenceBlackAndWhite, coefficients);
     this.ycbcrSubSampling = ycbcrSubSampling;
 }
예제 #29
0
 /// <summary>
 /// Initializes a new instance of the <see cref="LzwEncoder"/> class.
 /// </summary>
 /// <param name="memoryAllocator">The <see cref="MemoryAllocator"/> to use for buffer allocations.</param>
 /// <param name="colorDepth">The color depth in bits.</param>
 public LzwEncoder(MemoryAllocator memoryAllocator, int colorDepth)
 {
     this.initialCodeSize = Math.Max(2, colorDepth);
     this.hashTable       = memoryAllocator.Allocate <int>(HashSize, AllocationOptions.Clean);
     this.codeTable       = memoryAllocator.Allocate <int>(HashSize, AllocationOptions.Clean);
 }
예제 #30
0
 /// <summary>
 /// Initializes a new instance of the <see cref="ParallelExecutionSettings"/> struct.
 /// </summary>
 public ParallelExecutionSettings(int maxDegreeOfParallelism, MemoryAllocator memoryAllocator)
     : this(maxDegreeOfParallelism, DefaultMinimumPixelsProcessedPerTask, memoryAllocator)
 {
 }