Example #1
0
        /// <inheritdoc/>
        public void Dispose()
        {
            this.lookahead?.Dispose();
            this.valOffset?.Dispose();
            this.maxcode?.Dispose();
            this.huffval?.Dispose();

            this.lookahead = null;
            this.valOffset = null;
            this.maxcode   = null;
            this.huffval   = null;
        }
Example #2
0
        /// <summary>
        /// Initializes a new instance of the <see cref="PdfJsHuffmanTable"/> struct.
        /// </summary>
        /// <param name="memoryManager">The <see cref="MemoryManager"/> to use for buffer allocations.</param>
        /// <param name="lengths">The code lengths</param>
        /// <param name="values">The huffman values</param>
        public PdfJsHuffmanTable(MemoryManager memoryManager, byte[] lengths, byte[] values)
        {
            // TODO: Replace FakeBuffer<T> usages with standard or array orfixed-sized arrays
            this.lookahead = memoryManager.AllocateFake <short>(256);
            this.valOffset = memoryManager.AllocateFake <short>(18);
            this.maxcode   = memoryManager.AllocateFake <long>(18);

            using (IBuffer <short> huffsize = memoryManager.Allocate <short>(257))
                using (IBuffer <short> huffcode = memoryManager.Allocate <short>(257))
                {
                    GenerateSizeTable(lengths, huffsize.Span);
                    GenerateCodeTable(huffsize.Span, huffcode.Span);
                    GenerateDecoderTables(lengths, huffcode.Span, this.valOffset.Span, this.maxcode.Span);
                    GenerateLookaheadTables(lengths, values, this.lookahead.Span);
                }

            this.huffval = memoryManager.AllocateManagedByteBuffer(values.Length, true);
            Buffer.BlockCopy(values, 0, this.huffval.Array, 0, values.Length);

            this.MaxCode   = this.maxcode.Array;
            this.ValOffset = this.valOffset.Array;
            this.HuffVal   = this.huffval.Array;
            this.Lookahead = this.lookahead.Array;
        }
 private void Return <T>(BasicArrayBuffer <T> buffer)
     where T : struct
 {
     this.returnLog.Add(new ReturnRequest(buffer.Array.GetHashCode()));
 }
        /// <inheritdoc/>
        protected override void OnFrameApply(ImageFrame <TPixel> source, Rectangle sourceRectangle, Configuration configuration)
        {
            Region    region = this.Region;
            Rectangle rect   = region.Bounds;

            // Align start/end positions.
            int minX = Math.Max(0, rect.Left);
            int maxX = Math.Min(source.Width, rect.Right);
            int minY = Math.Max(0, rect.Top);
            int maxY = Math.Min(source.Height, rect.Bottom);

            if (minX >= maxX)
            {
                return; // no effect inside image;
            }

            if (minY >= maxY)
            {
                return; // no effect inside image;
            }

            int   maxIntersections = region.MaxIntersections;
            float subpixelCount    = 4;

            // we need to offset the pixel grid to account for when we outline a path.
            // basically if the line is [1,2] => [3,2] then when outlining at 1 we end up with a region of [0.5,1.5],[1.5, 1.5],[3.5,2.5],[2.5,2.5]
            // and this can cause missed fills when not using antialiasing.so we offset the pixel grid by 0.5 in the x & y direction thus causing the#
            // region to alline with the pixel grid.
            float offset = 0.5f;

            if (this.Options.Antialias)
            {
                offset        = 0f; // we are antialising skip offsetting as real antalising should take care of offset.
                subpixelCount = this.Options.AntialiasSubpixelDepth;
                if (subpixelCount < 4)
                {
                    subpixelCount = 4;
                }
            }

            using (BrushApplicator <TPixel> applicator = this.Brush.CreateApplicator(source, rect, this.Options))
            {
                int scanlineWidth = maxX - minX;
                using (BasicArrayBuffer <float> buffer = source.MemoryManager.AllocateFake <float>(maxIntersections))
                    using (BasicArrayBuffer <float> scanline = source.MemoryManager.AllocateFake <float>(scanlineWidth))
                    {
                        bool  scanlineDirty         = true;
                        float subpixelFraction      = 1f / subpixelCount;
                        float subpixelFractionPoint = subpixelFraction / subpixelCount;
                        for (int y = minY; y < maxY; y++)
                        {
                            if (scanlineDirty)
                            {
                                // clear the buffer
                                for (int x = 0; x < scanlineWidth; x++)
                                {
                                    scanline[x] = 0;
                                }

                                scanlineDirty = false;
                            }

                            float yPlusOne = y + 1;
                            for (float subPixel = (float)y; subPixel < yPlusOne; subPixel += subpixelFraction)
                            {
                                int pointsFound = region.Scan(subPixel + offset, buffer.Array, 0);
                                if (pointsFound == 0)
                                {
                                    // nothing on this line skip
                                    continue;
                                }

                                QuickSort(new Span <float>(buffer.Array, 0, pointsFound));

                                for (int point = 0; point < pointsFound; point += 2)
                                {
                                    // points will be paired up
                                    float scanStart = buffer[point] - minX;
                                    float scanEnd   = buffer[point + 1] - minX;
                                    int   startX    = (int)MathF.Floor(scanStart + offset);
                                    int   endX      = (int)MathF.Floor(scanEnd + offset);

                                    if (startX >= 0 && startX < scanline.Length)
                                    {
                                        for (float x = scanStart; x < startX + 1; x += subpixelFraction)
                                        {
                                            scanline[startX] += subpixelFractionPoint;
                                            scanlineDirty     = true;
                                        }
                                    }

                                    if (endX >= 0 && endX < scanline.Length)
                                    {
                                        for (float x = endX; x < scanEnd; x += subpixelFraction)
                                        {
                                            scanline[endX] += subpixelFractionPoint;
                                            scanlineDirty   = true;
                                        }
                                    }

                                    int nextX = startX + 1;
                                    endX  = Math.Min(endX, scanline.Length); // reduce to end to the right edge
                                    nextX = Math.Max(nextX, 0);
                                    for (int x = nextX; x < endX; x++)
                                    {
                                        scanline[x]  += subpixelFraction;
                                        scanlineDirty = true;
                                    }
                                }
                            }

                            if (scanlineDirty)
                            {
                                if (!this.Options.Antialias)
                                {
                                    for (int x = 0; x < scanlineWidth; x++)
                                    {
                                        if (scanline[x] >= 0.5)
                                        {
                                            scanline[x] = 1;
                                        }
                                        else
                                        {
                                            scanline[x] = 0;
                                        }
                                    }
                                }

                                applicator.Apply(scanline.Span, minX, y);
                            }
                        }
                    }
            }
        }