コード例 #1
0
        /// <summary>
        /// Processes the SOS (Start of scan marker).
        /// </summary>
        private void ProcessStartOfScanMarker()
        {
            int selectorsCount = this.InputStream.ReadByte();
            int componentIndex = -1;

            for (int i = 0; i < selectorsCount; i++)
            {
                componentIndex = -1;
                int selector = this.InputStream.ReadByte();

                for (int j = 0; j < this.Frame.ComponentIds.Length; j++)
                {
                    byte id = this.Frame.ComponentIds[j];
                    if (selector == id)
                    {
                        componentIndex = j;
                    }
                }

                if (componentIndex < 0)
                {
                    throw new ImageFormatException("Unknown component selector");
                }

                ref PdfJsFrameComponent component = ref this.Frame.Components[componentIndex];
                int tableSpec = this.InputStream.ReadByte();
                component.DCHuffmanTableId = tableSpec >> 4;
                component.ACHuffmanTableId = tableSpec & 15;
            }
コード例 #2
0
        internal void QuantizeAndInverseAllComponents()
        {
            for (int i = 0; i < this.components.Components.Length; i++)
            {
                PdfJsFrameComponent frameComponent = this.Frame.Components[i];
                PdfJsComponent      component      = this.components.Components[i];

                this.QuantizeAndInverseComponentData(component, frameComponent);
            }
        }
コード例 #3
0
        /// <summary>
        /// Processes the Start of Frame marker.  Specified in section B.2.2.
        /// </summary>
        /// <param name="remaining">The remaining bytes in the segment block.</param>
        /// <param name="frameMarker">The current frame marker.</param>
        private void ProcessStartOfFrameMarker(int remaining, PdfJsFileMarker frameMarker)
        {
            if (this.Frame != null)
            {
                throw new ImageFormatException("Multiple SOF markers. Only single frame jpegs supported.");
            }

            this.InputStream.Read(this.temp, 0, remaining);

            this.Frame = new PdfJsFrame
            {
                Extended       = frameMarker.Marker == PdfJsJpegConstants.Markers.SOF1,
                Progressive    = frameMarker.Marker == PdfJsJpegConstants.Markers.SOF2,
                Precision      = this.temp[0],
                Scanlines      = (short)((this.temp[1] << 8) | this.temp[2]),
                SamplesPerLine = (short)((this.temp[3] << 8) | this.temp[4]),
                ComponentCount = this.temp[5]
            };

            int maxH  = 0;
            int maxV  = 0;
            int index = 6;

            // No need to pool this. They max out at 4
            this.Frame.ComponentIds = new byte[this.Frame.ComponentCount];
            this.Frame.Components   = new PdfJsFrameComponent[this.Frame.ComponentCount];

            for (int i = 0; i < this.Frame.Components.Length; i++)
            {
                int h = this.temp[index + 1] >> 4;
                int v = this.temp[index + 1] & 15;

                if (maxH < h)
                {
                    maxH = h;
                }

                if (maxV < v)
                {
                    maxV = v;
                }

                var component = new PdfJsFrameComponent(this.Frame, this.temp[index], h, v, this.temp[index + 2], i);

                this.Frame.Components[i]   = component;
                this.Frame.ComponentIds[i] = component.Id;

                index += 3;
            }

            this.Frame.MaxHorizontalFactor = maxH;
            this.Frame.MaxVerticalFactor   = maxV;
            this.Frame.InitComponents();
        }
コード例 #4
0
        public void ComponentScalingIsCorrect_1ChannelJpegPdfJs()
        {
            using (PdfJsJpegDecoderCore decoder = JpegFixture.ParsePdfJsStream(TestImages.Jpeg.Baseline.Jpeg400))
            {
                Assert.Equal(1, decoder.ComponentCount);
                Assert.Equal(1, decoder.Components.Length);

                Size expectedSizeInBlocks = decoder.ImageSizeInPixels.DivideRoundUp(8);

                Assert.Equal(expectedSizeInBlocks, decoder.ImageSizeInMCU);

                var uniform1           = new Size(1, 1);
                PdfJsFrameComponent c0 = decoder.Components[0];
                VerifyJpeg.VerifyComponent(c0, expectedSizeInBlocks, uniform1, uniform1);
            }
        }
コード例 #5
0
        public void PrintComponentDataPdfJs(string imageFile)
        {
            var sb = new StringBuilder();

            using (PdfJsJpegDecoderCore decoder = JpegFixture.ParsePdfJsStream(imageFile))
            {
                sb.AppendLine(imageFile);
                sb.AppendLine($"Size:{decoder.ImageSizeInPixels} MCU:{decoder.ImageSizeInMCU}");
                PdfJsFrameComponent c0 = decoder.Components[0];
                PdfJsFrameComponent c1 = decoder.Components[1];

                sb.AppendLine($"Luma: SAMP: {c0.SamplingFactors} BLOCKS: {c0.SizeInBlocks}");
                sb.AppendLine($"Chroma: {c1.SamplingFactors} BLOCKS: {c1.SizeInBlocks}");
            }
            this.Output.WriteLine(sb.ToString());
        }
コード例 #6
0
            public static ComponentData Load(PdfJsFrameComponent c, int index)
            {
                var result = new ComponentData(
                    c.WidthInBlocks,
                    c.HeightInBlocks,
                    index
                    );

                for (int y = 0; y < result.HeightInBlocks; y++)
                {
                    for (int x = 0; x < result.WidthInBlocks; x++)
                    {
                        short[] data = c.GetBlockReference(x, y).ToArray();
                        result.MakeBlock(data, y, x);
                    }
                }

                return(result);
            }
コード例 #7
0
        public void ComponentScalingIsCorrect_MultiChannelJpegPdfJs(
            string imageFile,
            int componentCount,
            object expectedLumaFactors,
            object expectedChromaFactors)
        {
            var fLuma   = (Size)expectedLumaFactors;
            var fChroma = (Size)expectedChromaFactors;

            using (PdfJsJpegDecoderCore decoder = JpegFixture.ParsePdfJsStream(imageFile))
            {
                Assert.Equal(componentCount, decoder.ComponentCount);
                Assert.Equal(componentCount, decoder.Components.Length);

                PdfJsFrameComponent c0 = decoder.Components[0];
                PdfJsFrameComponent c1 = decoder.Components[1];
                PdfJsFrameComponent c2 = decoder.Components[2];

                var uniform1 = new Size(1, 1);

                Size expectedLumaSizeInBlocks = decoder.ImageSizeInMCU.MultiplyBy(fLuma);

                Size divisor = fLuma.DivideBy(fChroma);

                Size expectedChromaSizeInBlocks = expectedLumaSizeInBlocks.DivideRoundUp(divisor);

                VerifyJpeg.VerifyComponent(c0, expectedLumaSizeInBlocks, fLuma, uniform1);
                VerifyJpeg.VerifyComponent(c1, expectedChromaSizeInBlocks, fChroma, divisor);
                VerifyJpeg.VerifyComponent(c2, expectedChromaSizeInBlocks, fChroma, divisor);

                if (componentCount == 4)
                {
                    PdfJsFrameComponent c3 = decoder.Components[2];
                    VerifyJpeg.VerifyComponent(c3, expectedLumaSizeInBlocks, fLuma, uniform1);
                }
            }
        }
コード例 #8
0
        /// <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;
        }