/// <summary> /// Initializes a new instance of the <see cref="ScanDecoder"/> class. /// </summary> /// <param name="stream">The input stream.</param> /// <param name="frame">The image frame.</param> /// <param name="dcHuffmanTables">The DC Huffman tables.</param> /// <param name="acHuffmanTables">The AC Huffman tables.</param> /// <param name="fastACTables">The fast AC decoding tables.</param> /// <param name="componentsLength">The length of the components. Different to the array length.</param> /// <param name="restartInterval">The reset interval.</param> /// <param name="spectralStart">The spectral selection start.</param> /// <param name="spectralEnd">The spectral selection end.</param> /// <param name="successiveHigh">The successive approximation bit high end.</param> /// <param name="successiveLow">The successive approximation bit low end.</param> public ScanDecoder( DoubleBufferedStreamReader stream, JpegFrame frame, HuffmanTables dcHuffmanTables, HuffmanTables acHuffmanTables, FastACTables fastACTables, int componentsLength, int restartInterval, int spectralStart, int spectralEnd, int successiveHigh, int successiveLow) { this.dctZigZag = ZigZag.CreateUnzigTable(); this.stream = stream; this.frame = frame; this.dcHuffmanTables = dcHuffmanTables; this.acHuffmanTables = acHuffmanTables; this.fastACTables = fastACTables; this.components = frame.Components; this.marker = JpegConstants.Markers.XFF; this.markerPosition = 0; this.componentsLength = componentsLength; this.restartInterval = restartInterval; this.spectralStart = spectralStart; this.spectralEnd = spectralEnd; this.successiveHigh = successiveHigh; this.successiveLow = successiveLow; }
public JpegComponent(MemoryAllocator memoryAllocator, JpegFrame frame, byte id, int horizontalFactor, int verticalFactor, byte quantizationTableIndex, int index) { this.memoryAllocator = memoryAllocator; this.Frame = frame; this.Id = id; // Valid sampling factors are 1..2 if (horizontalFactor == 0 || verticalFactor == 0 || horizontalFactor > 2 || verticalFactor > 2) { JpegThrowHelper.ThrowBadSampling(); } this.HorizontalSamplingFactor = horizontalFactor; this.VerticalSamplingFactor = verticalFactor; this.SamplingFactors = new Size(this.HorizontalSamplingFactor, this.VerticalSamplingFactor); if (quantizationTableIndex > 3) { JpegThrowHelper.ThrowBadQuantizationTable(); } this.QuantizationTableIndex = quantizationTableIndex; this.Index = index; }
/// <summary> /// Initializes a new instance of the <see cref="HuffmanScanDecoder"/> class. /// </summary> /// <param name="stream">The input stream.</param> /// <param name="frame">The image frame.</param> /// <param name="dcHuffmanTables">The DC Huffman tables.</param> /// <param name="acHuffmanTables">The AC Huffman tables.</param> /// <param name="componentsLength">The length of the components. Different to the array length.</param> /// <param name="restartInterval">The reset interval.</param> /// <param name="spectralStart">The spectral selection start.</param> /// <param name="spectralEnd">The spectral selection end.</param> /// <param name="successiveHigh">The successive approximation bit high end.</param> /// <param name="successiveLow">The successive approximation bit low end.</param> public HuffmanScanDecoder( DoubleBufferedStreamReader stream, JpegFrame frame, HuffmanTable[] dcHuffmanTables, HuffmanTable[] acHuffmanTables, int componentsLength, int restartInterval, int spectralStart, int spectralEnd, int successiveHigh, int successiveLow) { this.dctZigZag = ZigZag.CreateUnzigTable(); this.stream = stream; this.scanBuffer = new HuffmanScanBuffer(stream); this.frame = frame; this.dcHuffmanTables = dcHuffmanTables; this.acHuffmanTables = acHuffmanTables; this.components = frame.Components; this.componentsLength = componentsLength; this.restartInterval = restartInterval; this.todo = restartInterval; this.spectralStart = spectralStart; this.spectralEnd = spectralEnd; this.successiveHigh = successiveHigh; this.successiveLow = successiveLow; }
/// <inheritdoc/> public override void InjectFrameData(JpegFrame frame, IRawJpegData jpegData) { MemoryAllocator allocator = this.configuration.MemoryAllocator; // iteration data IJpegComponent c0 = frame.Components[0]; const int blockPixelHeight = 8; this.blockRowsPerStep = c0.SamplingFactors.Height; this.pixelRowsPerStep = this.blockRowsPerStep * blockPixelHeight; // pixel buffer for resulting image this.pixelBuffer = allocator.Allocate2D <TPixel>(frame.PixelWidth, frame.PixelHeight); this.paddedProxyPixelRow = allocator.Allocate <TPixel>(frame.PixelWidth + 3); // component processors from spectral to Rgba32 var postProcessorBufferSize = new Size(c0.SizeInBlocks.Width * 8, this.pixelRowsPerStep); this.componentProcessors = new JpegComponentPostProcessor[frame.Components.Length]; for (int i = 0; i < this.componentProcessors.Length; i++) { this.componentProcessors[i] = new JpegComponentPostProcessor(allocator, frame, jpegData, postProcessorBufferSize, frame.Components[i]); } // single 'stride' rgba32 buffer for conversion between spectral and TPixel // this.rgbaBuffer = allocator.Allocate<Vector4>(frame.PixelWidth); this.rgbBuffer = allocator.Allocate <byte>(frame.PixelWidth * 3); // color converter from Rgba32 to TPixel this.colorConverter = this.GetColorConverter(frame, jpegData); }
public void InjectFrameData(JpegFrame frame, IRawJpegData jpegData) { this.frame = frame; this.components = frame.Components; this.spectralConverter.InjectFrameData(frame, jpegData); }
public JpegComponent(MemoryAllocator memoryAllocator, JpegFrame frame, byte id, int horizontalFactor, int verticalFactor, byte quantizationTableIndex, int index) { this.memoryAllocator = memoryAllocator; this.Frame = frame; this.Id = id; this.HorizontalSamplingFactor = horizontalFactor; this.VerticalSamplingFactor = verticalFactor; this.SamplingFactors = new Size(this.HorizontalSamplingFactor, this.VerticalSamplingFactor); this.QuantizationTableIndex = quantizationTableIndex; this.Index = index; }
/// <summary> /// Initializes a new instance of the <see cref="JpegComponentPostProcessor"/> class. /// </summary> public JpegComponentPostProcessor(MemoryAllocator memoryAllocator, JpegFrame frame, IRawJpegData rawJpeg, Size postProcessorBufferSize, IJpegComponent component) { this.frame = frame; this.component = component; this.rawJpeg = rawJpeg; this.blockAreaSize = this.component.SubSamplingDivisors * 8; this.ColorBuffer = memoryAllocator.Allocate2DOveraligned <float>( postProcessorBufferSize.Width, postProcessorBufferSize.Height, this.blockAreaSize.Height); this.blockRowsPerStep = postProcessorBufferSize.Height / 8 / this.component.SubSamplingDivisors.Height; }
/// <summary> /// Gets the color converter. /// </summary> /// <param name="frame">The jpeg frame with the color space to convert to.</param> /// <param name="jpegData">The raw JPEG data.</param> /// <returns>The color converter.</returns> protected virtual JpegColorConverterBase GetColorConverter(JpegFrame frame, IRawJpegData jpegData) => JpegColorConverterBase.GetConverter(jpegData.ColorSpace, frame.Precision);
/// <summary> /// Injects jpeg image decoding metadata. /// </summary> /// <remarks> /// This is guaranteed to be called only once at SOF marker by <see cref="HuffmanScanDecoder"/>. /// </remarks> /// <param name="frame"><see cref="JpegFrame"/> instance containing decoder-specific parameters.</param> /// <param name="jpegData"><see cref="IRawJpegData"/> instance containing decoder-specific parameters.</param> public abstract void InjectFrameData(JpegFrame frame, IRawJpegData jpegData);
/// <summary> /// Gets the color converter. /// </summary> /// <param name="frame">The jpeg frame with the color space to convert to.</param> /// <param name="jpegData">The raw JPEG data.</param> /// <returns>The color converter.</returns> public virtual JpegColorConverter GetColorConverter(JpegFrame frame, IRawJpegData jpegData) => JpegColorConverter.GetConverter(jpegData.ColorSpace, frame.Precision);