Exemple #1
0
        public unsafe void Fill(int pixelOffset, Span <byte> destination)
        {
            int startPixelOffset    = dataOffset / Components;
            int requestedPixelCount = (int)MathF.Ceiling(destination.Length / (float)Components);

            int column = startPixelOffset % Width;
            int row    = startPixelOffset / Width;

            var converter32 = new PixelConverter32();
            int pixelSize   = _pixels.PixelType.ElementSize;

            // each iteration is supposed to read pixels from a single row at the time
            int destinationOffset = 0;
            int pixelsLeft        = requestedPixelCount;

            while (pixelsLeft > 0)
            {
                int lastByteOffset = destinationOffset;
                int count          = Math.Min(pixelsLeft, _pixels.Size.Width - column);

                _pixels.GetPixelByteRow(column, row, _rowBuffer);

                if (_transform32.Invoke(
                        _rowBuffer, Components, count, destination,
                        ref destinationOffset, ref converter32))
                {
                    goto ReadEnd;
                }

                // copy over the remaining bytes,
                // as the Fill() caller may request less bytes than sizeof(TPixel)
                int bytesRead     = destinationOffset - lastByteOffset;
                int leftoverBytes = Math.Min(Components, count * Components - bytesRead);

                for (int j = 0; j < leftoverBytes; j++)
                {
                    destination[j + destinationOffset] = converter32.Raw[j];
                }
                destinationOffset += leftoverBytes;

                // a case for code that copies bytes directly,
                // not needing to copy leftovers
ReadEnd:
                pixelsLeft -= count;

                column = 0; // read from row beginning on next loop
                row++;      // and jump to the next row
            }
        }
        public void GetByteRow(int row, Span <byte> destination)
        {
            CancellationToken.ThrowIfCancellationRequested();

            if (_pixelBuffer != null)
            {
                var rowSpan = _pixelBuffer.GetPixelByteRowSpan(row);
                _convertPixels.Invoke(rowSpan, destination);
            }
            else
            {
                _pixelRows.GetPixelByteRow(0, row, _rowBuffer);
                _convertPixels.Invoke(_rowBuffer, destination);
            }
        }
        public static void LoadPixels <TPixelFrom, TPixelTo>(
            IReadOnlyPixelRows pixels, IPixelBuffer <TPixelTo> destination, Rectangle?sourceRectangle = null)
            where TPixelFrom : unmanaged, IPixel
            where TPixelTo : unmanaged, IPixel <TPixelTo>
        {
            if (pixels == null)
            {
                throw new ArgumentNullException(nameof(pixels));
            }
            if (destination == null)
            {
                throw new ArgumentNullException(nameof(destination));
            }

            var rect = sourceRectangle ?? pixels.GetBounds();

            ImagingArgumentGuard.AssertNonEmptyRectangle(rect, nameof(sourceRectangle));

            Span <byte> rowByteBuffer = stackalloc byte[4096];
            var         rowBuffer     = MemoryMarshal.Cast <byte, TPixelFrom>(rowByteBuffer);

            for (int y = 0; y < rect.Height; y++)
            {
                var dstRow = destination.GetPixelRowSpan(y);

                int offsetX = 0;
                do
                {
                    int left  = rect.Width - offsetX;
                    int count = Math.Min(rowBuffer.Length, left);
                    var slice = rowBuffer.Slice(0, count);

                    pixels.GetPixelByteRow(rect.X + offsetX, rect.Y + y, MemoryMarshal.AsBytes(slice));

                    ConvertPixels(slice, dstRow);
                    dstRow   = dstRow[count..];