예제 #1
0
        internal JpegDecoderCore.ErrorCodes EnsureNBits(int n, JpegDecoderCore decoder)
        {
            while (true)
            {
                JpegDecoderCore.ErrorCodes errorCode;

                // Grab the decode bytes, use them and then set them
                // back on the decoder.
                Bytes decoderBytes = decoder.Bytes;
                byte  c            = decoderBytes.ReadByteStuffedByte(decoder.InputStream, out errorCode);
                decoder.Bytes = decoderBytes;

                if (errorCode != JpegDecoderCore.ErrorCodes.NoError)
                {
                    return(errorCode);
                }

                this.Accumulator = (this.Accumulator << 8) | c;
                this.UnreadBits += 8;
                if (this.Mask == 0)
                {
                    this.Mask = 1 << 7;
                }
                else
                {
                    this.Mask <<= 8;
                }

                if (this.UnreadBits >= n)
                {
                    return(JpegDecoderCore.ErrorCodes.NoError);
                }
            }
        }
        public void PostProcess <TPixel>(TestImageProvider <TPixel> provider)
            where TPixel : unmanaged, IPixel <TPixel>
        {
            string imageFile = provider.SourceFileOrDescription;

            using (JpegDecoderCore decoder = JpegFixture.ParseJpegStream(imageFile))
                using (var pp = new JpegImagePostProcessor(Configuration.Default, decoder))
                    using (var image = new Image <Rgba32>(decoder.ImageWidth, decoder.ImageHeight))
                    {
                        pp.PostProcess(image.Frames.RootFrame);

                        image.DebugSave(provider);

                        ImagingTestCaseUtility testUtil = provider.Utility;
                        testUtil.TestGroupName = nameof(JpegDecoderTests);
                        testUtil.TestName      = JpegDecoderTests.DecodeBaselineJpegOutputName;

                        using (Image <TPixel> referenceImage =
                                   provider.GetReferenceOutputImage <TPixel>(appendPixelTypeToFileName: false))
                        {
                            ImageSimilarityReport report = ImageComparer.Exact.CompareImagesOrFrames(referenceImage, image);

                            this.Output.WriteLine($"*** {imageFile} ***");
                            this.Output.WriteLine($"Difference: {report.DifferencePercentageString}");

                            // ReSharper disable once PossibleInvalidOperationException
                            Assert.True(report.TotalNormalizedDifference.Value < 0.005f);
                        }
                    }
        }
        /// <inheritdoc/>
        protected override void Decompress(BufferedReadStream stream, int byteCount, int stripHeight, Span <byte> buffer)
        {
            if (this.jpegTables != null)
            {
                using var jpegDecoder = new JpegDecoderCore(this.configuration, new JpegDecoder());

                // TODO: Should we pass through the CancellationToken from the tiff decoder?
                // If the PhotometricInterpretation is YCbCr we explicitly assume the JPEG data is in RGB color space.
                // There seems no other way to determine that the JPEG data is RGB colorspace (no APP14 marker, componentId's are not RGB).
                using SpectralConverter <Rgb24> spectralConverter = this.photometricInterpretation == TiffPhotometricInterpretation.YCbCr ?
                                                                    new RgbJpegSpectralConverter <Rgb24>(this.configuration, CancellationToken.None) : new SpectralConverter <Rgb24>(this.configuration, CancellationToken.None);
                var scanDecoder = new HuffmanScanDecoder(stream, spectralConverter, CancellationToken.None);
                jpegDecoder.LoadTables(this.jpegTables, scanDecoder);
                scanDecoder.ResetInterval = 0;
                jpegDecoder.ParseStream(stream, scanDecoder, CancellationToken.None);

                using var image = new Image <Rgb24>(this.configuration, spectralConverter.PixelBuffer, new ImageMetadata());
                CopyImageBytesToBuffer(buffer, image);
            }
            else
            {
                using var image = Image.Load <Rgb24>(stream);
                CopyImageBytesToBuffer(buffer, image);
            }
        }
예제 #4
0
        private void ProcessComponentImpl(
            JpegDecoderCore decoder,
            int i,
            ref ComponentScan currentComponentScan,
            ref int totalHv,
            ref Component currentComponent)
        {
            // Section B.2.3 states that "the value of Cs_j shall be different from
            // the values of Cs_1 through Cs_(j-1)". Since we have previously
            // verified that a frame's component identifiers (C_i values in section
            // B.2.2) are unique, it suffices to check that the implicit indexes
            // into comp are unique.
            for (int j = 0; j < i; j++)
            {
                if (currentComponentScan.ComponentIndex == this.pointers.ComponentScan[j].ComponentIndex)
                {
                    throw new ImageFormatException("Repeated component selector");
                }
            }

            totalHv += currentComponent.HorizontalFactor * currentComponent.VerticalFactor;

            currentComponentScan.DcTableSelector = (byte)(decoder.Temp[2 + (2 * i)] >> 4);
            if (currentComponentScan.DcTableSelector > HuffmanTree.MaxTh)
            {
                throw new ImageFormatException("Bad DC table selector value");
            }

            currentComponentScan.AcTableSelector = (byte)(decoder.Temp[2 + (2 * i)] & 0x0f);
            if (currentComponentScan.AcTableSelector > HuffmanTree.MaxTh)
            {
                throw new ImageFormatException("Bad AC table selector  value");
            }
        }
            public static SpectralData LoadFromImageSharpDecoder(JpegDecoderCore decoder)
            {
                JpegComponent[] srcComponents = decoder.Frame.Components;
                LibJpegTools.ComponentData[] destComponents = srcComponents.Select(LibJpegTools.ComponentData.Load).ToArray();

                return(new SpectralData(destComponents));
            }
예제 #6
0
        internal JpegDecoderCore.ErrorCodes EnsureNBits(int n, JpegDecoderCore decoder)
        {
            while (true)
            {
                JpegDecoderCore.ErrorCodes errorCode;

                byte c = decoder.bytes.ReadByteStuffedByte(decoder.inputStream, out errorCode);

                if (errorCode != JpegDecoderCore.ErrorCodes.NoError)
                {
                    return(errorCode);
                }

                this.Accumulator = (this.Accumulator << 8) | c;
                this.UnreadBits += 8;
                if (this.Mask == 0)
                {
                    this.Mask = 1 << 7;
                }
                else
                {
                    this.Mask <<= 8;
                }

                if (this.UnreadBits >= n)
                {
                    return(JpegDecoderCore.ErrorCodes.NoError);
                }
            }
        }
예제 #7
0
        public void Decoder_PixelBufferComparison <TPixel>(TestImageProvider <TPixel> provider)
            where TPixel : unmanaged, IPixel <TPixel>
        {
            // Stream
            byte[] sourceBytes = TestFile.Create(provider.SourceFileOrDescription).Bytes;
            using var ms             = new MemoryStream(sourceBytes);
            using var bufferedStream = new BufferedReadStream(Configuration.Default, ms);

            // Decoding
            using var converter = new SpectralConverter <TPixel>(Configuration.Default, cancellationToken: default);
            var decoder     = new JpegDecoderCore(Configuration.Default, new JpegDecoder());
            var scanDecoder = new HuffmanScanDecoder(bufferedStream, converter, cancellationToken: default);

            decoder.ParseStream(bufferedStream, scanDecoder, cancellationToken: default);

            // Test metadata
            provider.Utility.TestGroupName = nameof(JpegDecoderTests);
            provider.Utility.TestName      = JpegDecoderTests.DecodeBaselineJpegOutputName;

            // Comparison
            using (Image <TPixel> image = new Image <TPixel>(Configuration.Default, converter.GetPixelBuffer(), new ImageMetadata()))
                using (Image <TPixel> referenceImage = provider.GetReferenceOutputImage <TPixel>(appendPixelTypeToFileName: false))
                {
                    ImageSimilarityReport report = ImageComparer.Exact.CompareImagesOrFrames(referenceImage, image);

                    this.Output.WriteLine($"*** {provider.SourceFileOrDescription} ***");
                    this.Output.WriteLine($"Difference: {report.DifferencePercentageString}");

                    // ReSharper disable once PossibleInvalidOperationException
                    Assert.True(report.TotalNormalizedDifference.Value < 0.005f);
                }
        }
        /// <summary>
        /// Dequantize, perform the inverse DCT and store the blocks to the into the corresponding <see cref="JpegPixelArea"/> instances.
        /// </summary>
        /// <param name="decoder">The <see cref="JpegDecoderCore"/> instance</param>
        public void ProcessAllBlocks(JpegDecoderCore decoder)
        {
            DecodedBlockArray blockArray = decoder.DecodedBlocks[this.componentIndex];

            for (int i = 0; i < blockArray.Count; i++)
            {
                this.ProcessBlockColors(decoder, ref blockArray.Buffer[i]);
            }
        }
예제 #9
0
        public void ColorSpace_IsDeducedCorrectly(string imageFile, object expectedColorSpaceValue)
        {
            var expectedColorSpace = (JpegColorSpace)expectedColorSpaceValue;

            using (JpegDecoderCore decoder = JpegFixture.ParseJpegStream(imageFile))
            {
                Assert.Equal(expectedColorSpace, decoder.ColorSpace);
            }
        }
예제 #10
0
        /// <inheritdoc/>
        public Image <TPixel> Decode <TPixel>(Configuration configuration, Stream stream)
            where TPixel : struct, IPixel <TPixel>
        {
            Guard.NotNull(stream, "stream");

            using (JpegDecoderCore decoder = new JpegDecoderCore(configuration, this))
            {
                return(decoder.Decode <TPixel>(stream));
            }
        }
        public void ParseStream()
        {
            using var memoryStream   = new MemoryStream(this.jpegBytes);
            using var bufferedStream = new BufferedReadStream(Configuration.Default, memoryStream);

            using var decoder = new JpegDecoderCore(Configuration.Default, new JpegDecoder { IgnoreMetadata = true });
            var scanDecoder = new HuffmanScanDecoder(bufferedStream, new NoopSpectralConverter(), cancellationToken: default);

            decoder.ParseStream(bufferedStream, scanDecoder, cancellationToken: default);
        }
예제 #12
0
        /// <inheritdoc/>
        public Image <TColor> Decode <TColor>(Configuration configuration, Stream stream, IDecoderOptions options)
            where TColor : struct, IPixel <TColor>
        {
            Guard.NotNull(stream, "stream");

            using (JpegDecoderCore decoder = new JpegDecoderCore(options, configuration))
            {
                return(decoder.Decode <TColor>(stream));
            }
        }
예제 #13
0
 internal static JpegDecoderCore ParseJpegStream(string testFileName, bool metaDataOnly = false)
 {
     byte[] bytes = TestFile.Create(testFileName).Bytes;
     using (var ms = new MemoryStream(bytes))
     {
         var decoder = new JpegDecoderCore(Configuration.Default, new JpegDecoder());
         decoder.ParseStream(ms, metaDataOnly);
         return(decoder);
     }
 }
예제 #14
0
        public void Decode(Image2 image, Stream stream)
        {
            if (image == null || stream == null)
            {
                throw new ArgumentNullException();
            }
            JpegDecoderCore decoder = new JpegDecoderCore();

            decoder.Decode(image, stream, false);
        }
예제 #15
0
        /// <inheritdoc/>
        public void Decode <TColor>(Image <TColor> image, Stream stream, IDecoderOptions options)
            where TColor : struct, IPixel <TColor>
        {
            Guard.NotNull(image, "image");
            Guard.NotNull(stream, "stream");

            using (JpegDecoderCore decoder = new JpegDecoderCore(options))
            {
                decoder.Decode(image, stream, false);
            }
        }
예제 #16
0
        /// <inheritdoc/>
        public void Decode <TColor, TPacked>(Image <TColor, TPacked> image, Stream stream)
            where TColor : struct, IPackedPixel <TPacked>
            where TPacked : struct
        {
            Guard.NotNull(image, "image");
            Guard.NotNull(stream, "stream");

            JpegDecoderCore decoder = new JpegDecoderCore();

            decoder.Decode(image, stream, false);
        }
예제 #17
0
        /// <inheritdoc/>
        public void Decode <TColor>(Image <TColor> image, Stream stream)
            where TColor : struct, IPackedPixel, IEquatable <TColor>
        {
            Guard.NotNull(image, "image");
            Guard.NotNull(stream, "stream");

            using (JpegDecoderCore decoder = new JpegDecoderCore())
            {
                decoder.Decode(image, stream, false);
            }
        }
예제 #18
0
        /// <inheritdoc/>
        public void Decode <T, TP>(Image <T, TP> image, Stream stream)
            where T : IPackedVector <TP>
            where TP : struct
        {
            Guard.NotNull(image, "image");
            Guard.NotNull(stream, "stream");

            JpegDecoderCore decoder = new JpegDecoderCore();

            decoder.Decode(image, stream, false);
        }
예제 #19
0
 public void ParseStreamPdfJs()
 {
     using (var memoryStream = new MemoryStream(this.jpegBytes))
     {
         var decoder = new JpegDecoderCore(Configuration.Default, new Formats.Jpeg.JpegDecoder {
             IgnoreMetadata = true
         });
         decoder.ParseStream(memoryStream);
         decoder.Dispose();
     }
 }
예제 #20
0
        public void ParseStreamPdfJs()
        {
            using var memoryStream   = new MemoryStream(this.jpegBytes);
            using var bufferedStream = new BufferedReadStream(Configuration.Default, memoryStream);

            var decoder = new JpegDecoderCore(Configuration.Default, new JpegDecoder {
                IgnoreMetadata = true
            });

            decoder.ParseStream(bufferedStream);
            decoder.Dispose();
        }
예제 #21
0
        public void ParseStream_BasicPropertiesAreCorrect()
        {
            byte[] bytes = TestFile.Create(TestImages.Jpeg.Progressive.Progress).Bytes;
            using var ms             = new MemoryStream(bytes);
            using var bufferedStream = new BufferedReadStream(Configuration.Default, ms);
            var decoder = new JpegDecoderCore(Configuration.Default, new JpegDecoder());

            decoder.ParseStream(bufferedStream);

            // I don't know why these numbers are different. All I know is that the decoder works
            // and spectral data is exactly correct also.
            // VerifyJpeg.VerifyComponentSizes3(decoder.Frame.Components, 43, 61, 22, 31, 22, 31);
            VerifyJpeg.VerifyComponentSizes3(decoder.Frame.Components, 44, 62, 22, 31, 22, 31);
        }
예제 #22
0
        public void Decoder_ParseStream_SaveSpectralResult <TPixel>(TestImageProvider <TPixel> provider)
            where TPixel : unmanaged, IPixel <TPixel>
        {
            var decoder = new JpegDecoderCore(Configuration.Default, new JpegDecoder());

            byte[] sourceBytes = TestFile.Create(provider.SourceFileOrDescription).Bytes;

            using (var ms = new MemoryStream(sourceBytes))
            {
                decoder.ParseStream(ms);

                var data = LibJpegTools.SpectralData.LoadFromImageSharpDecoder(decoder);
                VerifyJpeg.SaveSpectralImage(provider, data);
            }
        }
예제 #23
0
        public void PrintComponentData(string imageFile)
        {
            var sb = new StringBuilder();

            using (JpegDecoderCore decoder = JpegFixture.ParseJpegStream(imageFile))
            {
                sb.AppendLine(imageFile);
                sb.AppendLine($"Size:{decoder.ImageSizeInPixels} MCU:{decoder.ImageSizeInMCU}");
                JpegComponent c0 = decoder.Components[0];
                JpegComponent 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());
        }
예제 #24
0
        public void ComponentScalingIsCorrect_1ChannelJpeg()
        {
            using (JpegDecoderCore decoder = JpegFixture.ParseJpegStream(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);
                JpegComponent c0       = decoder.Components[0];
                VerifyJpeg.VerifyComponent(c0, expectedSizeInBlocks, uniform1, uniform1);
            }
        }
        /// <summary>
        /// Dequantize, perform the inverse DCT and store decodedBlock.Block to the into the corresponding <see cref="JpegPixelArea"/> instance.
        /// </summary>
        /// <param name="decoder">The <see cref="JpegDecoderCore"/></param>
        /// <param name="decodedBlock">The <see cref="DecodedBlock"/></param>
        private void ProcessBlockColors(JpegDecoderCore decoder, ref DecodedBlock decodedBlock)
        {
            this.data.Block = decodedBlock.Block;
            int qtIndex = decoder.ComponentArray[this.componentIndex].Selector;

            this.data.QuantiazationTable = decoder.QuantizationTables[qtIndex];

            Block8x8F *b = this.pointers.Block;

            Block8x8F.UnZig(b, this.pointers.QuantiazationTable, this.pointers.Unzig);

            DCT.TransformIDCT(ref *b, ref *this.pointers.Temp1, ref *this.pointers.Temp2);

            JpegPixelArea destChannel = decoder.GetDestinationChannel(this.componentIndex);
            JpegPixelArea destArea    = destChannel.GetOffsetedSubAreaForBlock(decodedBlock.Bx, decodedBlock.By);

            destArea.LoadColorsFrom(this.pointers.Temp1, this.pointers.Temp2);
        }
        public void DoProcessorStep <TPixel>(TestImageProvider <TPixel> provider)
            where TPixel : unmanaged, IPixel <TPixel>
        {
            string imageFile = provider.SourceFileOrDescription;

            using (JpegDecoderCore decoder = JpegFixture.ParseJpegStream(imageFile))
                using (var pp = new JpegImagePostProcessor(Configuration.Default, decoder))
                    using (var imageFrame = new ImageFrame <Rgba32>(Configuration.Default, decoder.ImageWidth, decoder.ImageHeight))
                    {
                        pp.DoPostProcessorStep(imageFrame);

                        JpegComponentPostProcessor[] cp = pp.ComponentProcessors;

                        SaveBuffer(cp[0], provider);
                        SaveBuffer(cp[1], provider);
                        SaveBuffer(cp[2], provider);
                    }
        }
예제 #27
0
        internal static JpegDecoderCore ParseJpegStream(string testFileName, bool metaDataOnly = false)
        {
            byte[] bytes = TestFile.Create(testFileName).Bytes;
            using var ms             = new MemoryStream(bytes);
            using var bufferedStream = new BufferedReadStream(Configuration.Default, ms);

            var decoder = new JpegDecoderCore(Configuration.Default, new JpegDecoder());

            if (metaDataOnly)
            {
                decoder.Identify(bufferedStream, cancellationToken: default);
            }
            else
            {
                using Image <Rgba32> image = decoder.Decode <Rgba32>(bufferedStream, cancellationToken: default);
            }

            return(decoder);
        }
예제 #28
0
        public void VerifySpectralCorrectness <TPixel>(TestImageProvider <TPixel> provider)
            where TPixel : unmanaged, IPixel <TPixel>
        {
            if (!TestEnvironment.IsWindows)
            {
                return;
            }

            var decoder = new JpegDecoderCore(Configuration.Default, new JpegDecoder());

            byte[] sourceBytes = TestFile.Create(provider.SourceFileOrDescription).Bytes;

            using (var ms = new MemoryStream(sourceBytes))
            {
                decoder.ParseStream(ms);
                var imageSharpData = LibJpegTools.SpectralData.LoadFromImageSharpDecoder(decoder);

                this.VerifySpectralCorrectnessImpl(provider, imageSharpData);
            }
        }
예제 #29
0
        /// <summary>
        /// Refines non-zero entries of b in zig-zag order.
        /// If <paramref name="nz" /> >= 0, the first <paramref name="nz" /> zero entries are skipped over.
        /// </summary>
        /// <param name="decoder">The decoder</param>
        /// <param name="zig">The zig-zag start index</param>
        /// <param name="nz">The non-zero entry</param>
        /// <param name="delta">The low transform offset</param>
        /// <returns>The <see cref="int" /></returns>
        private int RefineNonZeroes(JpegDecoderCore decoder, int zig, int nz, int delta)
        {
            var b = this.pointers.Block;

            for (; zig <= this.zigEnd; zig++)
            {
                int   u  = this.pointers.Unzig[zig];
                float bu = Block8x8F.GetScalarAt(b, u);

                // TODO: Are the equality comparsions OK with floating point values? Isn't an epsilon value necessary?
                if (bu == 0)
                {
                    if (nz == 0)
                    {
                        break;
                    }

                    nz--;
                    continue;
                }

                bool bit = decoder.DecodeBit();
                if (!bit)
                {
                    continue;
                }

                if (bu >= 0)
                {
                    // b[u] += delta;
                    Block8x8F.SetScalarAt(b, u, bu + delta);
                }
                else
                {
                    // b[u] -= delta;
                    Block8x8F.SetScalarAt(b, u, bu - delta);
                }
            }

            return(zig);
        }
예제 #30
0
        public void DecodeGenerated_MetadataOnly <TPixel>(
            TestImageProvider <TPixel> provider)
            where TPixel : struct, IPixel <TPixel>
        {
            using (Image <TPixel> image = provider.GetImage())
            {
                using (MemoryStream ms = new MemoryStream())
                {
                    image.Save(ms, new JpegEncoder());
                    ms.Seek(0, SeekOrigin.Begin);

                    using (JpegDecoderCore decoder = new JpegDecoderCore(null, new JpegDecoder()))
                    {
                        Image <TPixel> mirror = decoder.Decode <TPixel>(ms);

                        Assert.Equal(decoder.ImageWidth, image.Width);
                        Assert.Equal(decoder.ImageHeight, image.Height);
                    }
                }
            }
        }