/// <inheritdoc/>
        public void Dispose()
        {
            this.Frame?.Dispose();

            // Set large fields to null.
            this.Frame           = null;
            this.dcHuffmanTables = null;
            this.acHuffmanTables = null;
        }
        /// <inheritdoc/>
        public void Dispose()
        {
            this.InputStream?.Dispose();
            this.Frame?.Dispose();
            this.fastACTables?.Dispose();

            // Set large fields to null.
            this.InputStream     = null;
            this.Frame           = null;
            this.dcHuffmanTables = null;
            this.acHuffmanTables = null;
            this.fastACTables    = null;
        }
        /// <inheritdoc/>
        public void Dispose()
        {
            this.Frame?.Dispose();
            this.components?.Dispose();
            this.quantizationTables?.Dispose();
            this.dcHuffmanTables?.Dispose();
            this.acHuffmanTables?.Dispose();
            this.pixelArea.Dispose();

            // Set large fields to null.
            this.Frame              = null;
            this.components         = null;
            this.quantizationTables = null;
            this.dcHuffmanTables    = null;
            this.acHuffmanTables    = null;
        }
Exemple #4
0
        /// <summary>
        /// Parses the input stream for file markers
        /// </summary>
        /// <param name="stream">The input stream</param>
        /// <param name="metadataOnly">Whether to decode metadata only.</param>
        public void ParseStream(Stream stream, bool metadataOnly = false)
        {
            this.MetaData    = new ImageMetaData();
            this.InputStream = new DoubleBufferedStreamReader(this.configuration.MemoryManager, stream);

            // Check for the Start Of Image marker.
            this.InputStream.Read(this.markerBuffer, 0, 2);
            var fileMarker = new PdfJsFileMarker(this.markerBuffer[1], 0);

            if (fileMarker.Marker != JpegConstants.Markers.SOI)
            {
                throw new ImageFormatException("Missing SOI marker.");
            }

            this.InputStream.Read(this.markerBuffer, 0, 2);
            byte marker = this.markerBuffer[1];

            fileMarker = new PdfJsFileMarker(marker, (int)this.InputStream.Position - 2);

            // Only assign what we need
            if (!metadataOnly)
            {
                this.QuantizationTables = new Block8x8F[4];
                this.dcHuffmanTables    = new PdfJsHuffmanTables();
                this.acHuffmanTables    = new PdfJsHuffmanTables();
            }

            while (fileMarker.Marker != JpegConstants.Markers.EOI)
            {
                if (!fileMarker.Invalid)
                {
                    // Get the marker length
                    int remaining = this.ReadUint16() - 2;

                    switch (fileMarker.Marker)
                    {
                    case JpegConstants.Markers.SOF0:
                    case JpegConstants.Markers.SOF1:
                    case JpegConstants.Markers.SOF2:
                        this.ProcessStartOfFrameMarker(remaining, fileMarker, metadataOnly);
                        break;

                    case JpegConstants.Markers.SOS:
                        if (!metadataOnly)
                        {
                            this.ProcessStartOfScanMarker();
                            break;
                        }
                        else
                        {
                            // It's highly unlikely that APPn related data will be found after the SOS marker
                            // We should have gathered everything we need by now.
                            return;
                        }

                    case JpegConstants.Markers.DHT:
                        if (metadataOnly)
                        {
                            this.InputStream.Skip(remaining);
                        }
                        else
                        {
                            this.ProcessDefineHuffmanTablesMarker(remaining);
                        }

                        break;

                    case JpegConstants.Markers.DQT:
                        if (metadataOnly)
                        {
                            this.InputStream.Skip(remaining);
                        }
                        else
                        {
                            this.ProcessDefineQuantizationTablesMarker(remaining);
                        }

                        break;

                    case JpegConstants.Markers.DRI:
                        if (metadataOnly)
                        {
                            this.InputStream.Skip(remaining);
                        }
                        else
                        {
                            this.ProcessDefineRestartIntervalMarker(remaining);
                        }

                        break;

                    case JpegConstants.Markers.APP0:
                        this.ProcessApplicationHeaderMarker(remaining);
                        break;

                    case JpegConstants.Markers.APP1:
                        this.ProcessApp1Marker(remaining);
                        break;

                    case JpegConstants.Markers.APP2:
                        this.ProcessApp2Marker(remaining);
                        break;

                    case JpegConstants.Markers.APP3:
                    case JpegConstants.Markers.APP4:
                    case JpegConstants.Markers.APP5:
                    case JpegConstants.Markers.APP6:
                    case JpegConstants.Markers.APP7:
                    case JpegConstants.Markers.APP8:
                    case JpegConstants.Markers.APP9:
                    case JpegConstants.Markers.APP10:
                    case JpegConstants.Markers.APP11:
                    case JpegConstants.Markers.APP12:
                    case JpegConstants.Markers.APP13:
                        this.InputStream.Skip(remaining);
                        break;

                    case JpegConstants.Markers.APP14:
                        this.ProcessApp14Marker(remaining);
                        break;

                    case JpegConstants.Markers.APP15:
                    case JpegConstants.Markers.COM:
                        this.InputStream.Skip(remaining);
                        break;
                    }
                }

                // Read on.
                fileMarker = FindNextFileMarker(this.markerBuffer, this.InputStream);
            }
        }
        /// <summary>
        /// Parses the input stream for file markers
        /// </summary>
        /// <param name="stream">The input stream</param>
        /// <param name="metadataOnly">Whether to decode metadata only.</param>
        public void ParseStream(Stream stream, bool metadataOnly = false)
        {
            this.MetaData    = new ImageMetaData();
            this.InputStream = stream;

            // Check for the Start Of Image marker.
            var fileMarker = new PdfJsFileMarker(this.ReadUint16(), 0);

            if (fileMarker.Marker != PdfJsJpegConstants.Markers.SOI)
            {
                throw new ImageFormatException("Missing SOI marker.");
            }

            ushort marker = this.ReadUint16();

            fileMarker = new PdfJsFileMarker(marker, (int)this.InputStream.Position - 2);

            this.QuantizationTables = new Block8x8F[4];

            // this.quantizationTables = new PdfJsQuantizationTables(this.configuration.MemoryManager);
            this.dcHuffmanTables = new PdfJsHuffmanTables();
            this.acHuffmanTables = new PdfJsHuffmanTables();

            while (fileMarker.Marker != PdfJsJpegConstants.Markers.EOI)
            {
                // Get the marker length
                int remaining = this.ReadUint16() - 2;

                switch (fileMarker.Marker)
                {
                case PdfJsJpegConstants.Markers.APP0:
                    this.ProcessApplicationHeaderMarker(remaining);
                    break;

                case PdfJsJpegConstants.Markers.APP1:
                    this.ProcessApp1Marker(remaining);
                    break;

                case PdfJsJpegConstants.Markers.APP2:
                    this.ProcessApp2Marker(remaining);
                    break;

                case PdfJsJpegConstants.Markers.APP3:
                case PdfJsJpegConstants.Markers.APP4:
                case PdfJsJpegConstants.Markers.APP5:
                case PdfJsJpegConstants.Markers.APP6:
                case PdfJsJpegConstants.Markers.APP7:
                case PdfJsJpegConstants.Markers.APP8:
                case PdfJsJpegConstants.Markers.APP9:
                case PdfJsJpegConstants.Markers.APP10:
                case PdfJsJpegConstants.Markers.APP11:
                case PdfJsJpegConstants.Markers.APP12:
                case PdfJsJpegConstants.Markers.APP13:
                    this.InputStream.Skip(remaining);
                    break;

                case PdfJsJpegConstants.Markers.APP14:
                    this.ProcessApp14Marker(remaining);
                    break;

                case PdfJsJpegConstants.Markers.APP15:
                case PdfJsJpegConstants.Markers.COM:
                    this.InputStream.Skip(remaining);
                    break;

                case PdfJsJpegConstants.Markers.DQT:
                    if (metadataOnly)
                    {
                        this.InputStream.Skip(remaining);
                    }
                    else
                    {
                        this.ProcessDefineQuantizationTablesMarker(remaining);
                    }

                    break;

                case PdfJsJpegConstants.Markers.SOF0:
                case PdfJsJpegConstants.Markers.SOF1:
                case PdfJsJpegConstants.Markers.SOF2:
                    this.ProcessStartOfFrameMarker(remaining, fileMarker);
                    if (metadataOnly && !this.jFif.Equals(default))
                    {
                        this.InputStream.Skip(remaining);
                    }

                    break;

                case PdfJsJpegConstants.Markers.DHT:
                    if (metadataOnly)
                    {
                        this.InputStream.Skip(remaining);
                    }
                    else
                    {
                        this.ProcessDefineHuffmanTablesMarker(remaining);
                    }

                    break;

                case PdfJsJpegConstants.Markers.DRI:
                    if (metadataOnly)
                    {
                        this.InputStream.Skip(remaining);
                    }
                    else
                    {
                        this.ProcessDefineRestartIntervalMarker(remaining);
                    }

                    break;

                case PdfJsJpegConstants.Markers.SOS:
                    if (!metadataOnly)
                    {
                        this.ProcessStartOfScanMarker();
                    }

                    break;
                }

                // Read on.
                fileMarker = FindNextFileMarker(this.markerBuffer, this.InputStream);
            }

            this.ImageWidth     = this.Frame.SamplesPerLine;
            this.ImageHeight    = this.Frame.Scanlines;
            this.ComponentCount = this.Frame.ComponentCount;
        }
        /// <summary>
        /// Parses the input stream for file markers
        /// </summary>
        /// <param name="metaData">Contains the metadata for an image</param>
        /// <param name="metadataOnly">Whether to decode metadata only.</param>
        private void ParseStream(ImageMetaData metaData, bool metadataOnly)
        {
            // TODO: metadata only logic
            // Check for the Start Of Image marker.
            var fileMarker = new PdfJsFileMarker(this.ReadUint16(), 0);

            if (fileMarker.Marker != PdfJsJpegConstants.Markers.SOI)
            {
                throw new ImageFormatException("Missing SOI marker.");
            }

            ushort marker = this.ReadUint16();

            fileMarker = new PdfJsFileMarker(marker, (int)this.InputStream.Position - 2);

            this.quantizationTables = new PdfJsQuantizationTables();
            this.dcHuffmanTables    = new PdfJsHuffmanTables();
            this.acHuffmanTables    = new PdfJsHuffmanTables();

            while (fileMarker.Marker != PdfJsJpegConstants.Markers.EOI)
            {
                // Get the marker length
                int remaining = this.ReadUint16() - 2;

                switch (fileMarker.Marker)
                {
                case PdfJsJpegConstants.Markers.APP0:
                    this.ProcessApplicationHeaderMarker(remaining);
                    break;

                case PdfJsJpegConstants.Markers.APP1:
                    this.ProcessApp1Marker(remaining, metaData);
                    break;

                case PdfJsJpegConstants.Markers.APP2:
                    this.ProcessApp2Marker(remaining, metaData);
                    break;

                case PdfJsJpegConstants.Markers.APP3:
                case PdfJsJpegConstants.Markers.APP4:
                case PdfJsJpegConstants.Markers.APP5:
                case PdfJsJpegConstants.Markers.APP6:
                case PdfJsJpegConstants.Markers.APP7:
                case PdfJsJpegConstants.Markers.APP8:
                case PdfJsJpegConstants.Markers.APP9:
                case PdfJsJpegConstants.Markers.APP10:
                case PdfJsJpegConstants.Markers.APP11:
                case PdfJsJpegConstants.Markers.APP12:
                case PdfJsJpegConstants.Markers.APP13:
                    this.InputStream.Skip(remaining);
                    break;

                case PdfJsJpegConstants.Markers.APP14:
                    this.ProcessApp14Marker(remaining);
                    break;

                case PdfJsJpegConstants.Markers.APP15:
                case PdfJsJpegConstants.Markers.COM:
                    this.InputStream.Skip(remaining);
                    break;

                case PdfJsJpegConstants.Markers.DQT:
                    this.ProcessDefineQuantizationTablesMarker(remaining);
                    break;

                case PdfJsJpegConstants.Markers.SOF0:
                case PdfJsJpegConstants.Markers.SOF1:
                case PdfJsJpegConstants.Markers.SOF2:
                    this.ProcessStartOfFrameMarker(remaining, fileMarker);
                    break;

                case PdfJsJpegConstants.Markers.DHT:
                    this.ProcessDefineHuffmanTablesMarker(remaining);
                    break;

                case PdfJsJpegConstants.Markers.DRI:
                    this.ProcessDefineRestartIntervalMarker(remaining);
                    break;

                case PdfJsJpegConstants.Markers.SOS:
                    this.ProcessStartOfScanMarker();
                    break;
                }

                // Read on.
                fileMarker = FindNextFileMarker(this.markerBuffer, this.InputStream);
            }

            this.ImageWidth  = this.Frame.SamplesPerLine;
            this.ImageHeight = this.Frame.Scanlines;
            this.components  = new PdfJsComponentBlocks {
                Components = new PdfJsComponent[this.Frame.ComponentCount]
            };

            for (int i = 0; i < this.components.Components.Length; i++)
            {
                PdfJsFrameComponent frameComponent = this.Frame.Components[i];
                var component = new PdfJsComponent
                {
                    Scale = new System.Numerics.Vector2(
                        frameComponent.HorizontalSamplingFactor / (float)this.Frame.MaxHorizontalFactor,
                        frameComponent.VerticalSamplingFactor / (float)this.Frame.MaxVerticalFactor),
                    BlocksPerLine   = frameComponent.WidthInBlocks,
                    BlocksPerColumn = frameComponent.HeightInBlocks
                };

                // this.QuantizeAndInverseComponentData(ref component, frameComponent);
                this.components.Components[i] = component;
            }

            this.NumberOfComponents = this.components.Components.Length;
        }