Ejemplo n.º 1
0
        /// <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;
        }
Ejemplo n.º 2
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.MemoryAllocator, stream);

            // Check for the Start Of Image marker.
            this.InputStream.Read(this.markerBuffer, 0, 2);
            var fileMarker = new JpegFileMarker(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 JpegFileMarker(marker, (int)this.InputStream.Position - 2);
            this.QuantizationTables = new Block8x8F[4];

            // Only assign what we need
            if (!metadataOnly)
            {
                this.dcHuffmanTables = new HuffmanTables();
                this.acHuffmanTables = new HuffmanTables();
                this.fastACTables    = new FastACTables(this.configuration.MemoryAllocator);
            }

            // Break only when we discover a valid EOI marker.
            // https://github.com/SixLabors/ImageSharp/issues/695
            while (fileMarker.Marker != JpegConstants.Markers.EOI ||
                   (fileMarker.Marker == JpegConstants.Markers.EOI && fileMarker.Invalid))
            {
                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:
                        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);
            }
        }