├── tests
├── Assets
│ ├── JPEGsnoop.zip
│ ├── baseline
│ │ ├── lake.jpg
│ │ ├── cramps.jpg
│ │ ├── HETissueSlide.jpg
│ │ ├── cramps.jpg.high.png
│ │ ├── lake.jpg.high.png
│ │ ├── lake.jpg.low-diff.png
│ │ └── cramps.jpg.low-diff.png
│ ├── huffman_progressive
│ │ ├── progress.jpg
│ │ ├── progress.jpg.high.png
│ │ ├── progress.jpg.low-diff.png
│ │ ├── yellowcat_progressive_restart.jpg
│ │ ├── yellowcat_progressive_restart.jpg.high.png
│ │ └── yellowcat_progressive_restart.jpg.low-diff.png
│ ├── huffman_sequential
│ │ ├── testorig12.jpg
│ │ ├── testorig12.jpg.high.png
│ │ └── testorig12.jpg.low-diff.png
│ ├── huffman_lossless
│ │ ├── lossless1_s22.jpg
│ │ ├── lossless2_s22.jpg
│ │ ├── lossless3_s22.jpg
│ │ ├── lossless4_s22.jpg
│ │ ├── lossless5_s22.jpg
│ │ ├── lossless6_s22.jpg
│ │ ├── lossless7_s22.jpg
│ │ ├── lossless1_s22.jpg.high.png
│ │ ├── lossless2_s22.jpg.high.png
│ │ ├── lossless3_s22.jpg.high.png
│ │ ├── lossless4_s22.jpg.high.png
│ │ ├── lossless5_s22.jpg.high.png
│ │ ├── lossless6_s22.jpg.high.png
│ │ ├── lossless7_s22.jpg.high.png
│ │ ├── lossless1_s22.jpg.low-diff.png
│ │ ├── lossless2_s22.jpg.low-diff.png
│ │ ├── lossless3_s22.jpg.low-diff.png
│ │ ├── lossless4_s22.jpg.low-diff.png
│ │ ├── lossless5_s22.jpg.low-diff.png
│ │ ├── lossless6_s22.jpg.low-diff.png
│ │ ├── lossless7_s22.jpg.low-diff.png
│ │ ├── lossless1_s22.jpg.txt
│ │ ├── lossless2_s22.jpg.txt
│ │ ├── lossless3_s22.jpg.txt
│ │ ├── lossless4_s22.jpg.txt
│ │ ├── lossless5_s22.jpg.txt
│ │ ├── lossless6_s22.jpg.txt
│ │ └── lossless7_s22.jpg.txt
│ ├── arithmetic_sequential
│ │ ├── zackthecat_arith.jpg
│ │ ├── yellowcat_arith_restart.jpg
│ │ ├── zackthecat_arith_restart.jpg
│ │ ├── zackthecat_arith.jpg.high.png
│ │ ├── zackthecat_arith.jpg.low-diff.png
│ │ ├── yellowcat_arith_restart.jpg.high.png
│ │ ├── zackthecat_arith_restart.jpg.high.png
│ │ ├── yellowcat_arith_restart.jpg.low-diff.png
│ │ ├── zackthecat_arith_restart.jpg.low-diff.png
│ │ ├── zackthecat_arith.jpg.txt
│ │ ├── yellowcat_arith_restart.jpg.txt
│ │ └── zackthecat_arith_restart.jpg.txt
│ └── arithmetic_progressive
│ │ ├── yellowcat_progressive_arith.jpg
│ │ ├── yellowcat_progressive_arith.jpg.high.png
│ │ ├── yellowcat_progressive_arith_restart.jpg
│ │ ├── yellowcat_progressive_arith.jpg.low-diff.png
│ │ ├── yellowcat_progressive_arith_restart.jpg.high.png
│ │ └── yellowcat_progressive_arith_restart.jpg.low-diff.png
├── JpegLibrary.Benchmarks
│ ├── Program.cs
│ ├── SkipLocalsInitAttribute.cs
│ ├── JpegLibrary.Benchmarks.csproj
│ ├── NullWriteStream.cs
│ ├── JpegBufferInputReader.cs
│ ├── NullBufferWriter.cs
│ ├── JpegBufferOutputWriter.cs
│ ├── DecoderBenchmark.cs
│ ├── JpegRgbaInputReader.cs
│ ├── ColorConverters
│ │ └── JpegRgbToYCbCrConverter.cs
│ └── JpegRgbToYCbCrComponentConverter.cs
├── Directory.Build.targets
├── Directory.Build.props
└── JpegLibrary.Tests
│ ├── JpegLibrary.Tests.csproj
│ ├── Decoder
│ ├── HuffmanProgressiveDecodeTests.cs
│ ├── ArithmeticProgressiveDecodeTests.cs
│ ├── HuffmanSequentialDecodeTests.cs
│ ├── ArithmeticSequentialDecodeTests.cs
│ ├── HuffmanLosslessDecodeTests.cs
│ └── MetadataIdentifyTests.cs
│ ├── Optimizer
│ └── OptimizerTests.cs
│ └── Utils
│ ├── ImageHelper.cs
│ └── JpegExtendingOutputWriter.cs
├── THIRD-PARTY-NOTICES.md
├── src
├── JpegLibrary
│ ├── JpegMarkerHelper.cs
│ ├── JpegElementPrecision.cs
│ ├── Utils
│ │ ├── SkipLocalsInitAttribute.cs
│ │ └── NullableAnnotations.cs
│ ├── JpegHuffmanDecodingComponent.cs
│ ├── JpegTranscodeComponent.cs
│ ├── JpegBlockOutputWriter.cs
│ ├── JpegArithmeticDecodingComponent.cs
│ ├── JpegArithmeticStatistics.cs
│ ├── JpegHuffmanEncodingComponent.cs
│ ├── JpegBlockInputReader.cs
│ ├── JpegLibrary.csproj
│ ├── JpegHuffmanCanonicalCode.cs
│ ├── JpegHuffmanEncodingTableBuilderCollection.cs
│ ├── JpegBlock8x8.cs
│ ├── ScanDecoder
│ │ ├── JpegScanDecoder.cs
│ │ └── JpegHuffmanScanDecoder.cs
│ ├── JpegMathHelper.cs
│ ├── JpegHuffmanEncodingTable.cs
│ ├── JpegStandardQuantizationTable.cs
│ ├── JpegZigZag.cs
│ └── JpegArithmeticDecodingTable.cs
└── Directory.Build.props
├── version.json
├── apps
├── JpegOptimize
│ ├── JpegOptimize.csproj
│ ├── Program.cs
│ ├── OptimizeAction.cs
│ └── MemoryPoolBufferWriter.cs
├── JpegDecode
│ ├── JpegDecode.csproj
│ ├── Program.cs
│ ├── JpegBufferOutputWriter8Bit.cs
│ ├── JpegBufferOutputWriterGreaterThan8Bit.cs
│ ├── DecodeAction.cs
│ ├── JpegBufferOutputWriterLessThan8Bit.cs
│ └── MemoryPoolBufferWriter.cs
├── JpegEncode
│ ├── JpegEncode.csproj
│ ├── JpegBufferInputReader.cs
│ ├── Program.cs
│ ├── EncodeAction.cs
│ └── JpegRgbToYCbCrConverter.cs
└── JpegDebugDump
│ ├── JpegDebugDump.csproj
│ ├── Program.cs
│ ├── DebugDumpAction.cs
│ └── JpegExtendingOutputWriter.cs
├── LICENSE
├── Directory.Build.props
├── README.md
└── azure-pipelines.yml
/tests/Assets/JPEGsnoop.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yigolden/JpegLibrary/HEAD/tests/Assets/JPEGsnoop.zip
--------------------------------------------------------------------------------
/tests/Assets/baseline/lake.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yigolden/JpegLibrary/HEAD/tests/Assets/baseline/lake.jpg
--------------------------------------------------------------------------------
/tests/Assets/baseline/cramps.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yigolden/JpegLibrary/HEAD/tests/Assets/baseline/cramps.jpg
--------------------------------------------------------------------------------
/tests/Assets/baseline/HETissueSlide.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yigolden/JpegLibrary/HEAD/tests/Assets/baseline/HETissueSlide.jpg
--------------------------------------------------------------------------------
/tests/Assets/baseline/cramps.jpg.high.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yigolden/JpegLibrary/HEAD/tests/Assets/baseline/cramps.jpg.high.png
--------------------------------------------------------------------------------
/tests/Assets/baseline/lake.jpg.high.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yigolden/JpegLibrary/HEAD/tests/Assets/baseline/lake.jpg.high.png
--------------------------------------------------------------------------------
/tests/Assets/baseline/lake.jpg.low-diff.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yigolden/JpegLibrary/HEAD/tests/Assets/baseline/lake.jpg.low-diff.png
--------------------------------------------------------------------------------
/tests/Assets/baseline/cramps.jpg.low-diff.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yigolden/JpegLibrary/HEAD/tests/Assets/baseline/cramps.jpg.low-diff.png
--------------------------------------------------------------------------------
/tests/Assets/huffman_progressive/progress.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yigolden/JpegLibrary/HEAD/tests/Assets/huffman_progressive/progress.jpg
--------------------------------------------------------------------------------
/tests/Assets/huffman_sequential/testorig12.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yigolden/JpegLibrary/HEAD/tests/Assets/huffman_sequential/testorig12.jpg
--------------------------------------------------------------------------------
/tests/Assets/huffman_lossless/lossless1_s22.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yigolden/JpegLibrary/HEAD/tests/Assets/huffman_lossless/lossless1_s22.jpg
--------------------------------------------------------------------------------
/tests/Assets/huffman_lossless/lossless2_s22.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yigolden/JpegLibrary/HEAD/tests/Assets/huffman_lossless/lossless2_s22.jpg
--------------------------------------------------------------------------------
/tests/Assets/huffman_lossless/lossless3_s22.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yigolden/JpegLibrary/HEAD/tests/Assets/huffman_lossless/lossless3_s22.jpg
--------------------------------------------------------------------------------
/tests/Assets/huffman_lossless/lossless4_s22.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yigolden/JpegLibrary/HEAD/tests/Assets/huffman_lossless/lossless4_s22.jpg
--------------------------------------------------------------------------------
/tests/Assets/huffman_lossless/lossless5_s22.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yigolden/JpegLibrary/HEAD/tests/Assets/huffman_lossless/lossless5_s22.jpg
--------------------------------------------------------------------------------
/tests/Assets/huffman_lossless/lossless6_s22.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yigolden/JpegLibrary/HEAD/tests/Assets/huffman_lossless/lossless6_s22.jpg
--------------------------------------------------------------------------------
/tests/Assets/huffman_lossless/lossless7_s22.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yigolden/JpegLibrary/HEAD/tests/Assets/huffman_lossless/lossless7_s22.jpg
--------------------------------------------------------------------------------
/tests/Assets/arithmetic_sequential/zackthecat_arith.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yigolden/JpegLibrary/HEAD/tests/Assets/arithmetic_sequential/zackthecat_arith.jpg
--------------------------------------------------------------------------------
/tests/Assets/huffman_lossless/lossless1_s22.jpg.high.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yigolden/JpegLibrary/HEAD/tests/Assets/huffman_lossless/lossless1_s22.jpg.high.png
--------------------------------------------------------------------------------
/tests/Assets/huffman_lossless/lossless2_s22.jpg.high.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yigolden/JpegLibrary/HEAD/tests/Assets/huffman_lossless/lossless2_s22.jpg.high.png
--------------------------------------------------------------------------------
/tests/Assets/huffman_lossless/lossless3_s22.jpg.high.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yigolden/JpegLibrary/HEAD/tests/Assets/huffman_lossless/lossless3_s22.jpg.high.png
--------------------------------------------------------------------------------
/tests/Assets/huffman_lossless/lossless4_s22.jpg.high.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yigolden/JpegLibrary/HEAD/tests/Assets/huffman_lossless/lossless4_s22.jpg.high.png
--------------------------------------------------------------------------------
/tests/Assets/huffman_lossless/lossless5_s22.jpg.high.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yigolden/JpegLibrary/HEAD/tests/Assets/huffman_lossless/lossless5_s22.jpg.high.png
--------------------------------------------------------------------------------
/tests/Assets/huffman_lossless/lossless6_s22.jpg.high.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yigolden/JpegLibrary/HEAD/tests/Assets/huffman_lossless/lossless6_s22.jpg.high.png
--------------------------------------------------------------------------------
/tests/Assets/huffman_lossless/lossless7_s22.jpg.high.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yigolden/JpegLibrary/HEAD/tests/Assets/huffman_lossless/lossless7_s22.jpg.high.png
--------------------------------------------------------------------------------
/tests/Assets/huffman_progressive/progress.jpg.high.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yigolden/JpegLibrary/HEAD/tests/Assets/huffman_progressive/progress.jpg.high.png
--------------------------------------------------------------------------------
/tests/Assets/huffman_sequential/testorig12.jpg.high.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yigolden/JpegLibrary/HEAD/tests/Assets/huffman_sequential/testorig12.jpg.high.png
--------------------------------------------------------------------------------
/tests/Assets/huffman_progressive/progress.jpg.low-diff.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yigolden/JpegLibrary/HEAD/tests/Assets/huffman_progressive/progress.jpg.low-diff.png
--------------------------------------------------------------------------------
/tests/Assets/huffman_lossless/lossless1_s22.jpg.low-diff.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yigolden/JpegLibrary/HEAD/tests/Assets/huffman_lossless/lossless1_s22.jpg.low-diff.png
--------------------------------------------------------------------------------
/tests/Assets/huffman_lossless/lossless2_s22.jpg.low-diff.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yigolden/JpegLibrary/HEAD/tests/Assets/huffman_lossless/lossless2_s22.jpg.low-diff.png
--------------------------------------------------------------------------------
/tests/Assets/huffman_lossless/lossless3_s22.jpg.low-diff.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yigolden/JpegLibrary/HEAD/tests/Assets/huffman_lossless/lossless3_s22.jpg.low-diff.png
--------------------------------------------------------------------------------
/tests/Assets/huffman_lossless/lossless4_s22.jpg.low-diff.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yigolden/JpegLibrary/HEAD/tests/Assets/huffman_lossless/lossless4_s22.jpg.low-diff.png
--------------------------------------------------------------------------------
/tests/Assets/huffman_lossless/lossless5_s22.jpg.low-diff.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yigolden/JpegLibrary/HEAD/tests/Assets/huffman_lossless/lossless5_s22.jpg.low-diff.png
--------------------------------------------------------------------------------
/tests/Assets/huffman_lossless/lossless6_s22.jpg.low-diff.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yigolden/JpegLibrary/HEAD/tests/Assets/huffman_lossless/lossless6_s22.jpg.low-diff.png
--------------------------------------------------------------------------------
/tests/Assets/huffman_lossless/lossless7_s22.jpg.low-diff.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yigolden/JpegLibrary/HEAD/tests/Assets/huffman_lossless/lossless7_s22.jpg.low-diff.png
--------------------------------------------------------------------------------
/tests/Assets/huffman_sequential/testorig12.jpg.low-diff.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yigolden/JpegLibrary/HEAD/tests/Assets/huffman_sequential/testorig12.jpg.low-diff.png
--------------------------------------------------------------------------------
/tests/Assets/arithmetic_sequential/yellowcat_arith_restart.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yigolden/JpegLibrary/HEAD/tests/Assets/arithmetic_sequential/yellowcat_arith_restart.jpg
--------------------------------------------------------------------------------
/tests/Assets/arithmetic_sequential/zackthecat_arith_restart.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yigolden/JpegLibrary/HEAD/tests/Assets/arithmetic_sequential/zackthecat_arith_restart.jpg
--------------------------------------------------------------------------------
/tests/Assets/arithmetic_sequential/zackthecat_arith.jpg.high.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yigolden/JpegLibrary/HEAD/tests/Assets/arithmetic_sequential/zackthecat_arith.jpg.high.png
--------------------------------------------------------------------------------
/tests/Assets/huffman_progressive/yellowcat_progressive_restart.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yigolden/JpegLibrary/HEAD/tests/Assets/huffman_progressive/yellowcat_progressive_restart.jpg
--------------------------------------------------------------------------------
/tests/Assets/arithmetic_progressive/yellowcat_progressive_arith.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yigolden/JpegLibrary/HEAD/tests/Assets/arithmetic_progressive/yellowcat_progressive_arith.jpg
--------------------------------------------------------------------------------
/tests/Assets/arithmetic_sequential/zackthecat_arith.jpg.low-diff.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yigolden/JpegLibrary/HEAD/tests/Assets/arithmetic_sequential/zackthecat_arith.jpg.low-diff.png
--------------------------------------------------------------------------------
/tests/Assets/arithmetic_sequential/yellowcat_arith_restart.jpg.high.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yigolden/JpegLibrary/HEAD/tests/Assets/arithmetic_sequential/yellowcat_arith_restart.jpg.high.png
--------------------------------------------------------------------------------
/tests/Assets/arithmetic_sequential/zackthecat_arith_restart.jpg.high.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yigolden/JpegLibrary/HEAD/tests/Assets/arithmetic_sequential/zackthecat_arith_restart.jpg.high.png
--------------------------------------------------------------------------------
/tests/Assets/arithmetic_progressive/yellowcat_progressive_arith.jpg.high.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yigolden/JpegLibrary/HEAD/tests/Assets/arithmetic_progressive/yellowcat_progressive_arith.jpg.high.png
--------------------------------------------------------------------------------
/tests/Assets/arithmetic_progressive/yellowcat_progressive_arith_restart.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yigolden/JpegLibrary/HEAD/tests/Assets/arithmetic_progressive/yellowcat_progressive_arith_restart.jpg
--------------------------------------------------------------------------------
/tests/Assets/arithmetic_sequential/yellowcat_arith_restart.jpg.low-diff.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yigolden/JpegLibrary/HEAD/tests/Assets/arithmetic_sequential/yellowcat_arith_restart.jpg.low-diff.png
--------------------------------------------------------------------------------
/tests/Assets/arithmetic_sequential/zackthecat_arith_restart.jpg.low-diff.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yigolden/JpegLibrary/HEAD/tests/Assets/arithmetic_sequential/zackthecat_arith_restart.jpg.low-diff.png
--------------------------------------------------------------------------------
/tests/Assets/huffman_progressive/yellowcat_progressive_restart.jpg.high.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yigolden/JpegLibrary/HEAD/tests/Assets/huffman_progressive/yellowcat_progressive_restart.jpg.high.png
--------------------------------------------------------------------------------
/tests/Assets/arithmetic_progressive/yellowcat_progressive_arith.jpg.low-diff.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yigolden/JpegLibrary/HEAD/tests/Assets/arithmetic_progressive/yellowcat_progressive_arith.jpg.low-diff.png
--------------------------------------------------------------------------------
/tests/Assets/huffman_progressive/yellowcat_progressive_restart.jpg.low-diff.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yigolden/JpegLibrary/HEAD/tests/Assets/huffman_progressive/yellowcat_progressive_restart.jpg.low-diff.png
--------------------------------------------------------------------------------
/tests/Assets/arithmetic_progressive/yellowcat_progressive_arith_restart.jpg.high.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yigolden/JpegLibrary/HEAD/tests/Assets/arithmetic_progressive/yellowcat_progressive_arith_restart.jpg.high.png
--------------------------------------------------------------------------------
/tests/Assets/arithmetic_progressive/yellowcat_progressive_arith_restart.jpg.low-diff.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yigolden/JpegLibrary/HEAD/tests/Assets/arithmetic_progressive/yellowcat_progressive_arith_restart.jpg.low-diff.png
--------------------------------------------------------------------------------
/THIRD-PARTY-NOTICES.md:
--------------------------------------------------------------------------------
1 | This application contains materials from third parties, supplied under the following licenses:
2 |
3 | * SixLabors.ImageSharp
4 | Copyright 2018 Six Labors
5 | Licensed under the Apache License, Version 2.0 (https://github.com/SixLabors/ImageSharp/blob/master/LICENSE)
6 |
--------------------------------------------------------------------------------
/src/JpegLibrary/JpegMarkerHelper.cs:
--------------------------------------------------------------------------------
1 | #nullable enable
2 |
3 | namespace JpegLibrary
4 | {
5 | internal static class JpegMarkerHelper
6 | {
7 | public static bool IsRestartMarker(this JpegMarker marker)
8 | {
9 | return JpegMarker.DefineRestart0 <= marker && marker <= JpegMarker.DefineRestart7;
10 | }
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/version.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "https://raw.githubusercontent.com/dotnet/Nerdbank.GitVersioning/master/src/NerdBank.GitVersioning/version.schema.json",
3 | "version": "0.5-alpha",
4 | "publicReleaseRefSpec": [
5 | "^refs/heads/release/\\d+(?:\\.\\d+)?$"
6 | ],
7 | "cloudBuild": {
8 | "buildNumber": {
9 | "enabled": true
10 | }
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/tests/JpegLibrary.Benchmarks/Program.cs:
--------------------------------------------------------------------------------
1 | using System.Reflection;
2 | using BenchmarkDotNet.Running;
3 |
4 | namespace JpegLibrary.Benchmarks
5 | {
6 | internal class Program
7 | {
8 | private static void Main(string[] args)
9 | {
10 | new BenchmarkSwitcher(typeof(Program).GetTypeInfo().Assembly).Run(args);
11 | }
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/apps/JpegOptimize/JpegOptimize.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Exe
5 | net6.0
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
--------------------------------------------------------------------------------
/src/JpegLibrary/JpegElementPrecision.cs:
--------------------------------------------------------------------------------
1 | #nullable enable
2 |
3 | namespace JpegLibrary
4 | {
5 | ///
6 | /// Element precision of quantization tablse.
7 | ///
8 | public enum JpegElementPrecision : byte
9 | {
10 | ///
11 | /// 8 bit precision.
12 | ///
13 | Precision8Bit = 0,
14 |
15 | ///
16 | /// 12 bit precision.
17 | ///
18 | Precision12Bit = 1,
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/tests/Directory.Build.targets:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/src/JpegLibrary/Utils/SkipLocalsInitAttribute.cs:
--------------------------------------------------------------------------------
1 | #if NO_SKIP_LOCALS_INIT
2 |
3 | namespace System.Runtime.CompilerServices
4 | {
5 | [AttributeUsage(AttributeTargets.Module | AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Constructor | AttributeTargets.Method | AttributeTargets.Property | AttributeTargets.Event | AttributeTargets.Interface, Inherited = false)]
6 | internal sealed class SkipLocalsInitAttribute : Attribute
7 | {
8 | public SkipLocalsInitAttribute() { }
9 | }
10 | }
11 |
12 | #endif
13 |
--------------------------------------------------------------------------------
/apps/JpegDecode/JpegDecode.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Exe
5 | net6.0
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/apps/JpegEncode/JpegEncode.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Exe
5 | net6.0
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/tests/Directory.Build.props:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 | 10.0
11 | true
12 |
13 |
14 |
--------------------------------------------------------------------------------
/apps/JpegDebugDump/JpegDebugDump.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Exe
5 | net6.0
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/tests/JpegLibrary.Benchmarks/SkipLocalsInitAttribute.cs:
--------------------------------------------------------------------------------
1 | [module: System.Runtime.CompilerServices.SkipLocalsInit]
2 |
3 | #if NO_SKIP_LOCALS_INIT
4 |
5 | namespace System.Runtime.CompilerServices
6 | {
7 | [AttributeUsage(AttributeTargets.Module | AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Constructor | AttributeTargets.Method | AttributeTargets.Property | AttributeTargets.Event | AttributeTargets.Interface, Inherited = false)]
8 | internal sealed class SkipLocalsInitAttribute : Attribute
9 | {
10 | public SkipLocalsInitAttribute() { }
11 | }
12 | }
13 |
14 | #endif
15 |
--------------------------------------------------------------------------------
/src/JpegLibrary/Utils/NullableAnnotations.cs:
--------------------------------------------------------------------------------
1 | #if NO_NULLABLE_REFERENCE
2 |
3 | namespace System.Diagnostics.CodeAnalysis
4 | {
5 | [AttributeUsage(AttributeTargets.Parameter, Inherited = false)]
6 | internal sealed class NotNullWhenAttribute : Attribute
7 | {
8 | public NotNullWhenAttribute(bool returnValue)
9 | {
10 | ReturnValue = returnValue;
11 | }
12 |
13 | public bool ReturnValue { get; }
14 | }
15 |
16 | [AttributeUsage(AttributeTargets.Method, Inherited = false)]
17 | internal sealed class DoesNotReturnAttribute : Attribute
18 | {
19 | public DoesNotReturnAttribute() { }
20 | }
21 | }
22 |
23 | #endif
24 |
--------------------------------------------------------------------------------
/src/JpegLibrary/JpegHuffmanDecodingComponent.cs:
--------------------------------------------------------------------------------
1 | #nullable enable
2 |
3 | namespace JpegLibrary
4 | {
5 | internal class JpegHuffmanDecodingComponent
6 | {
7 | public int ComponentIndex { get; internal set; }
8 | public byte HorizontalSamplingFactor { get; internal set; }
9 | public byte VerticalSamplingFactor { get; internal set; }
10 | internal int DcPredictor { get; set; }
11 | internal JpegHuffmanDecodingTable? DcTable { get; set; }
12 | internal JpegHuffmanDecodingTable? AcTable { get; set; }
13 | internal JpegQuantizationTable QuantizationTable { get; set; }
14 | internal int HorizontalSubsamplingFactor { get; set; }
15 | internal int VerticalSubsamplingFactor { get; set; }
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/src/JpegLibrary/JpegTranscodeComponent.cs:
--------------------------------------------------------------------------------
1 | #nullable enable
2 |
3 | namespace JpegLibrary
4 | {
5 | internal class JpegTranscodeComponent
6 | {
7 | public int ComponentIndex { get; set; }
8 | public int HorizontalSamplingFactor { get; set; }
9 | public int VerticalSamplingFactor { get; set; }
10 | public JpegHuffmanDecodingTable? DcTable { get; set; }
11 | public JpegHuffmanDecodingTable? AcTable { get; set; }
12 | public JpegHuffmanEncodingTableBuilder? DcTableBuilder { get; set; }
13 | public JpegHuffmanEncodingTableBuilder? AcTableBuilder { get; set; }
14 | public JpegHuffmanEncodingTable? DcEncodingTable { get; set; }
15 | public JpegHuffmanEncodingTable? AcEncodingTable { get; set; }
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/src/JpegLibrary/JpegBlockOutputWriter.cs:
--------------------------------------------------------------------------------
1 | #nullable enable
2 |
3 | namespace JpegLibrary
4 | {
5 | ///
6 | /// A output writer that write spatial block to the destination buffer.
7 | ///
8 | public abstract partial class JpegBlockOutputWriter
9 | {
10 | ///
11 | /// Write a 8x8 spatial block into the destination buffer.
12 | ///
13 | /// The reference to the block that the implementation should read from.
14 | /// The index of the component.
15 | /// The X offset in the image.
16 | /// The Y offset in the image.
17 | public abstract void WriteBlock(ref short blockRef, int componentIndex, int x, int y);
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/src/JpegLibrary/JpegArithmeticDecodingComponent.cs:
--------------------------------------------------------------------------------
1 | #nullable enable
2 |
3 | namespace JpegLibrary
4 | {
5 | internal class JpegArithmeticDecodingComponent
6 | {
7 | public int ComponentIndex { get; internal set; }
8 | public byte HorizontalSamplingFactor { get; internal set; }
9 | public byte VerticalSamplingFactor { get; internal set; }
10 | internal int DcPredictor { get; set; }
11 | internal JpegArithmeticDecodingTable? DcTable { get; set; }
12 | internal JpegArithmeticDecodingTable? AcTable { get; set; }
13 | internal JpegQuantizationTable QuantizationTable { get; set; }
14 | internal int HorizontalSubsamplingFactor { get; set; }
15 | internal int VerticalSubsamplingFactor { get; set; }
16 |
17 | internal int DcContext { get; set; }
18 |
19 | internal JpegArithmeticStatistics? DcStatistics { get; set; }
20 | internal JpegArithmeticStatistics? AcStatistics { get; set; }
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/src/JpegLibrary/JpegArithmeticStatistics.cs:
--------------------------------------------------------------------------------
1 | #nullable enable
2 |
3 | using System;
4 |
5 | namespace JpegLibrary
6 | {
7 | internal class JpegArithmeticStatistics
8 | {
9 | private readonly bool _dc;
10 | private readonly byte _identifier;
11 | private readonly byte[] _statistics;
12 |
13 | public JpegArithmeticStatistics(bool dc, byte identifier)
14 | {
15 | _dc = dc;
16 | _identifier = identifier;
17 | _statistics = dc ? new byte[64] : new byte[256];
18 | }
19 |
20 | public bool IsDcStatistics => _dc;
21 |
22 | public byte Identifier => _identifier;
23 |
24 | public ref byte GetReference()
25 | {
26 | return ref _statistics[0];
27 | }
28 |
29 | public ref byte GetReference(int offset)
30 | {
31 | return ref _statistics[offset];
32 | }
33 |
34 | public void Reset()
35 | {
36 | _statistics.AsSpan().Clear();
37 | }
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/src/JpegLibrary/JpegHuffmanEncodingComponent.cs:
--------------------------------------------------------------------------------
1 | #nullable enable
2 |
3 | namespace JpegLibrary
4 | {
5 | internal class JpegHuffmanEncodingComponent
6 | {
7 | public int Index { get; internal set; }
8 | public int ComponentIndex { get; internal set; }
9 | public byte HorizontalSamplingFactor { get; internal set; }
10 | public byte VerticalSamplingFactor { get; internal set; }
11 | internal int DcPredictor { get; set; }
12 | internal byte DcTableIdentifier { get; set; }
13 | internal byte AcTableIdentifier { get; set; }
14 | internal JpegHuffmanEncodingTable? DcTable { get; set; }
15 | internal JpegHuffmanEncodingTable? AcTable { get; set; }
16 | internal JpegHuffmanEncodingTableBuilder? DcTableBuilder { get; set; }
17 | internal JpegHuffmanEncodingTableBuilder? AcTableBuilder { get; set; }
18 | internal JpegQuantizationTable QuantizationTable { get; set; }
19 |
20 | internal int HorizontalSubsamplingFactor { get; set; }
21 | internal int VerticalSubsamplingFactor { get; set; }
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/src/JpegLibrary/JpegBlockInputReader.cs:
--------------------------------------------------------------------------------
1 | #nullable enable
2 |
3 | namespace JpegLibrary
4 | {
5 | ///
6 | /// A input reader that read spatial block from the buffer.
7 | ///
8 | public abstract class JpegBlockInputReader
9 | {
10 | ///
11 | /// The width of the image.
12 | ///
13 | public abstract int Width { get; }
14 |
15 | ///
16 | /// The height of the image.
17 | ///
18 | public abstract int Height { get; }
19 |
20 | ///
21 | /// Read a 8x8 spatial block from the source buffer.
22 | ///
23 | /// The reference to the block that the implementation should write to.
24 | /// The index of the component.
25 | /// The X offset in the image.
26 | /// The Y offset in the image.
27 | public abstract void ReadBlock(ref short blockRef, int componentIndex, int x, int y);
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/tests/JpegLibrary.Benchmarks/JpegLibrary.Benchmarks.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Exe
6 | netcoreapp3.1;net6.0
7 | false
8 |
9 |
10 |
11 | $(DefineConstants);NO_SKIP_LOCALS_INIT
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 | Resources\HETissueSlide.jpg
27 |
28 |
29 |
30 |
31 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2019-2021 yigolden
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/Directory.Build.props:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | true
5 |
6 |
7 |
8 |
9 |
10 | JpegLibrary
11 | YiGolden
12 | Copyright (c) 2019-2021 yigolden
13 | jpeg
14 | MIT
15 | https://github.com/yigolden/JpegLibrary
16 | git
17 | https://github.com/yigolden/JpegLibrary.git
18 |
19 | $(MSBuildThisFileDirectory)build\key.snk
20 | true
21 |
22 |
23 |
24 |
25 | $(NerdbankGitVersioningPackageVersion)
26 | all
27 |
28 |
29 |
30 |
--------------------------------------------------------------------------------
/tests/JpegLibrary.Tests/JpegLibrary.Tests.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | netcoreapp3.1
6 | true
7 | false
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 | runtime; build; native; contentfiles; analyzers; buildtransitive
16 | all
17 |
18 |
19 | runtime; build; native; contentfiles; analyzers; buildtransitive
20 | all
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
--------------------------------------------------------------------------------
/tests/JpegLibrary.Benchmarks/NullWriteStream.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.IO;
3 |
4 | namespace JpegLibrary.Benchmarks
5 | {
6 | internal sealed class NullWriteStream : Stream
7 | {
8 | public override bool CanRead => false;
9 |
10 | public override bool CanSeek => false;
11 |
12 | public override bool CanWrite => true;
13 |
14 | public override long Length => throw new NotSupportedException();
15 |
16 | public override long Position { get => throw new NotSupportedException(); set => throw new NotSupportedException(); }
17 |
18 | public override void Flush()
19 | {
20 |
21 | }
22 |
23 | public override int Read(byte[] buffer, int offset, int count)
24 | {
25 | throw new NotSupportedException();
26 | }
27 |
28 | public override long Seek(long offset, SeekOrigin origin)
29 | {
30 | throw new NotSupportedException();
31 | }
32 |
33 | public override void SetLength(long value)
34 | {
35 | throw new NotSupportedException();
36 | }
37 |
38 | public override void Write(byte[] buffer, int offset, int count)
39 | {
40 |
41 | }
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # JpegLibrary
2 |
3 | JPEG decoder, encoder and optimizer implemented in C#.
4 |
5 | [](https://dev.azure.com/jinyi0679/yigolden/_build/latest?definitionId=2&branchName=master)
6 |
7 | ## Supported Runtimes
8 |
9 | * .NET Framework 4.6.1+
10 | * .NET Core 3.1+
11 | * Runtimes compatible with .NET Standard 2.0
12 |
13 | ## Supported Features
14 |
15 |
16 | ### Decode
17 | * Decode Huffman-coding baseline DCT-based JPEG (SOF0)
18 | * Decode Huffman-coding extended sequential DCT-based JPEG (SOF1)
19 | * Decode Huffman-coding progressive DCT-based JPEG (SOF2)
20 | * Decode Huffman-coding lossless JPEG (SOF3)
21 | * Decode arithmetic-coding sequential DCT-based JPEG (SOF9)
22 | * Decode arithmetic-coding progressive DCT-based JPEG (SOF10)
23 |
24 | See [JpegDecode](https://github.com/yigolden/JpegLibrary/blob/master/apps/JpegDecode/DecodeAction.cs) program for example.
25 |
26 | ### Encode
27 | * Encode Huffman-coding baseline DCT-based JPEG (SOF0) with optimized coding.
28 |
29 | See [JpegEncode](https://github.com/yigolden/JpegLibrary/blob/master/apps/JpegEncode/EncodeAction.cs) program for example.
30 |
31 | ### Optimize
32 | * Optimize an existing baseline image to use optimized Huffman coding.
33 |
34 | See [JpegOptimize](https://github.com/yigolden/JpegLibrary/blob/master/apps/JpegOptimize/OptimizeAction.cs) program for example.
35 |
--------------------------------------------------------------------------------
/apps/JpegDecode/Program.cs:
--------------------------------------------------------------------------------
1 | using System.CommandLine;
2 | using System.CommandLine.Builder;
3 | using System.CommandLine.Invocation;
4 | using System.CommandLine.Parsing;
5 | using System.IO;
6 | using System.Threading.Tasks;
7 |
8 | namespace JpegDecode
9 | {
10 | class Program
11 | {
12 | static async Task Main(string[] args)
13 | {
14 | var builder = new CommandLineBuilder();
15 |
16 | SetupDebugDumpCommand(builder.Command);
17 |
18 | builder.UseDefaults();
19 |
20 | Parser parser = builder.Build();
21 | await parser.InvokeAsync(args);
22 | }
23 |
24 | static void SetupDebugDumpCommand(Command command)
25 | {
26 | command.Description = "Decode image from JPEG file.";
27 |
28 | command.AddOption(Output());
29 |
30 | command.AddArgument(new Argument()
31 | {
32 | Name = "source",
33 | Description = "The JPEG file to decode.",
34 | Arity = ArgumentArity.ExactlyOne
35 | }.ExistingOnly());
36 |
37 |
38 | command.Handler = CommandHandler.Create(DecodeAction.Decode);
39 |
40 | static Option Output() =>
41 | new Option(new[] { "--output", "--out", "-o" }, "Output image file.")
42 | {
43 | Name = "output",
44 | Arity = ArgumentArity.ZeroOrOne
45 | };
46 | }
47 | }
48 | }
49 |
--------------------------------------------------------------------------------
/apps/JpegOptimize/Program.cs:
--------------------------------------------------------------------------------
1 | using System.CommandLine;
2 | using System.CommandLine.Builder;
3 | using System.CommandLine.Invocation;
4 | using System.CommandLine.Parsing;
5 | using System.IO;
6 | using System.Threading.Tasks;
7 |
8 | namespace JpegOptimize
9 | {
10 | class Program
11 | {
12 | static async Task Main(string[] args)
13 | {
14 | var builder = new CommandLineBuilder();
15 |
16 | SetupOptimizeCommand(builder.Command);
17 |
18 | builder.UseDefaults();
19 |
20 | Parser parser = builder.Build();
21 | await parser.InvokeAsync(args);
22 | }
23 |
24 | static void SetupOptimizeCommand(Command command)
25 | {
26 | command.Description = "Optimize a baseline JPEG image for file size.";
27 |
28 | command.AddOption(Output());
29 |
30 | command.AddArgument(new Argument()
31 | {
32 | Name = "source",
33 | Description = "The JPEG file to optimize.",
34 | Arity = ArgumentArity.ExactlyOne
35 | }.ExistingOnly());
36 |
37 |
38 | command.Handler = CommandHandler.Create(OptimizeAction.Optimize);
39 |
40 | static Option Output() =>
41 | new Option(new[] { "--output", "--out", "-o" }, "Output optimized JPEG file.")
42 | {
43 | Name = "output",
44 | Arity = ArgumentArity.ExactlyOne
45 | };
46 | }
47 | }
48 | }
49 |
--------------------------------------------------------------------------------
/tests/JpegLibrary.Tests/Decoder/HuffmanProgressiveDecodeTests.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.IO;
4 | using Xunit;
5 |
6 | namespace JpegLibrary.Tests.Decoder
7 | {
8 | public class HuffmanProgressiveDecodeTests
9 | {
10 | public static IEnumerable