/// <inheritdoc /> public void Compress(TiffCompressionContext context, ReadOnlyMemory <byte> input, IBufferWriter <byte> outputWriter) { if (context is null) { throw new ArgumentNullException(nameof(context)); } if (outputWriter is null) { throw new ArgumentNullException(nameof(outputWriter)); } if (_encoder is null) { throw new InvalidOperationException("JPEG encoder is not initialized."); } if (context.PhotometricInterpretation != _photometricInterpretation) { throw new InvalidOperationException(); } CheckBitsPerSample(context.BitsPerSample); TiffJpegEncoder encoder = _encoder.CloneParameter(); encoder.MemoryPool = context.MemoryPool; // Input JpegBufferInputReader inputReader = Interlocked.Exchange(ref _inputReader, null) ?? new JpegBufferInputReader(); encoder.SetInputReader(inputReader); // Update InputReader inputReader.Update(context.ImageSize.Width, context.ImageSize.Height, _componentCount, input); // Output encoder.SetOutput(outputWriter); // Encoder encoder.Encode(!_useSharedHuffmanTables, !_useSharedQuantizationTables, _optimizeCoding); // Reset state inputReader.Reset(); // Cache the input reader instance Interlocked.CompareExchange(ref _inputReader, inputReader, null); }
private void Initialize(int quality, bool optimizeCoding) { TiffJpegEncoder encoder; switch (_photometricInterpretation) { case TiffPhotometricInterpretation.BlackIsZero: case TiffPhotometricInterpretation.WhiteIsZero: _componentCount = 1; encoder = new TiffJpegEncoder(minimumBufferSegmentSize: MinimumBufferSegmentSize); encoder.SetQuantizationTable(JpegStandardQuantizationTable.ScaleByQuality(JpegStandardQuantizationTable.GetLuminanceTable(JpegElementPrecision.Precision8Bit, 0), quality)); if (optimizeCoding) { encoder.SetHuffmanTable(true, 0); encoder.SetHuffmanTable(false, 0); } else { encoder.SetHuffmanTable(true, 0, JpegStandardHuffmanEncodingTable.GetLuminanceDCTable()); encoder.SetHuffmanTable(false, 0, JpegStandardHuffmanEncodingTable.GetLuminanceACTable()); } encoder.AddComponent(0, 0, 0, 0, 1, 1); // Y component break; case TiffPhotometricInterpretation.RGB: _componentCount = 3; encoder = new TiffJpegEncoder(minimumBufferSegmentSize: MinimumBufferSegmentSize); encoder.SetQuantizationTable(JpegStandardQuantizationTable.ScaleByQuality(JpegStandardQuantizationTable.GetLuminanceTable(JpegElementPrecision.Precision8Bit, 0), quality)); if (optimizeCoding) { encoder.SetHuffmanTable(true, 0); encoder.SetHuffmanTable(false, 0); } else { encoder.SetHuffmanTable(true, 0, JpegStandardHuffmanEncodingTable.GetLuminanceDCTable()); encoder.SetHuffmanTable(false, 0, JpegStandardHuffmanEncodingTable.GetLuminanceACTable()); } encoder.AddComponent(0, 0, 0, 0, 1, 1); // R component encoder.AddComponent(1, 0, 0, 0, 1, 1); // G component encoder.AddComponent(2, 0, 0, 0, 1, 1); // B component break; case TiffPhotometricInterpretation.Seperated: _componentCount = 4; encoder = new TiffJpegEncoder(minimumBufferSegmentSize: MinimumBufferSegmentSize); encoder.SetQuantizationTable(JpegStandardQuantizationTable.ScaleByQuality(JpegStandardQuantizationTable.GetLuminanceTable(JpegElementPrecision.Precision8Bit, 0), quality)); if (optimizeCoding) { encoder.SetHuffmanTable(true, 0); encoder.SetHuffmanTable(false, 0); } else { encoder.SetHuffmanTable(true, 0, JpegStandardHuffmanEncodingTable.GetLuminanceDCTable()); encoder.SetHuffmanTable(false, 0, JpegStandardHuffmanEncodingTable.GetLuminanceACTable()); } encoder.AddComponent(0, 0, 0, 0, 1, 1); // C component encoder.AddComponent(1, 0, 0, 0, 1, 1); // M component encoder.AddComponent(2, 0, 0, 0, 1, 1); // Y component encoder.AddComponent(3, 0, 0, 0, 1, 1); // K component break; case TiffPhotometricInterpretation.YCbCr: _componentCount = 3; encoder = new TiffJpegEncoder(minimumBufferSegmentSize: MinimumBufferSegmentSize); encoder.SetQuantizationTable(JpegStandardQuantizationTable.ScaleByQuality(JpegStandardQuantizationTable.GetLuminanceTable(JpegElementPrecision.Precision8Bit, 0), quality)); encoder.SetQuantizationTable(JpegStandardQuantizationTable.ScaleByQuality(JpegStandardQuantizationTable.GetChrominanceTable(JpegElementPrecision.Precision8Bit, 1), quality)); if (optimizeCoding) { encoder.SetHuffmanTable(true, 0); encoder.SetHuffmanTable(false, 0); encoder.SetHuffmanTable(true, 1); encoder.SetHuffmanTable(false, 1); } else { encoder.SetHuffmanTable(true, 0, JpegStandardHuffmanEncodingTable.GetLuminanceDCTable()); encoder.SetHuffmanTable(false, 0, JpegStandardHuffmanEncodingTable.GetLuminanceACTable()); encoder.SetHuffmanTable(true, 1, JpegStandardHuffmanEncodingTable.GetChrominanceDCTable()); encoder.SetHuffmanTable(false, 1, JpegStandardHuffmanEncodingTable.GetChrominanceACTable()); } encoder.AddComponent(0, 0, 0, 0, (byte)_horizontalSubsampling, (byte)_verticalSubsampling); // Y component encoder.AddComponent(1, 1, 1, 1, 1, 1); // Cb component encoder.AddComponent(2, 1, 1, 1, 1, 1); // Cr component break; default: throw new NotSupportedException("JPEG compression only supports BlackIsZero, WhiteIsZero, RGB, YCbCr and CMYK photometric interpretation."); } _encoder = encoder; }
public JpegTableWriter(TiffJpegEncoder encoder, bool useSharedHuffmanTables, bool useSharedQuantizationTables) { _encoder = encoder; _useSharedHuffmanTables = useSharedHuffmanTables; _useSharedQuantizationTables = useSharedQuantizationTables; }