public void Init() { this.WidthInBlocks = (int)MathF.Ceiling( MathF.Ceiling(this.Frame.SamplesPerLine / 8F) * this.HorizontalSamplingFactor / this.Frame.MaxHorizontalFactor); this.HeightInBlocks = (int)MathF.Ceiling( MathF.Ceiling(this.Frame.Scanlines / 8F) * this.VerticalSamplingFactor / this.Frame.MaxVerticalFactor); int blocksPerLineForMcu = this.Frame.McusPerLine * this.HorizontalSamplingFactor; int blocksPerColumnForMcu = this.Frame.McusPerColumn * this.VerticalSamplingFactor; this.SizeInBlocks = new Size(blocksPerLineForMcu, blocksPerColumnForMcu); JpegComponent c0 = this.Frame.Components[0]; this.SubSamplingDivisors = c0.SamplingFactors.DivideBy(this.SamplingFactors); if (this.SubSamplingDivisors.Width == 0 || this.SubSamplingDivisors.Height == 0) { JpegThrowHelper.ThrowBadSampling(); } int totalNumberOfBlocks = blocksPerColumnForMcu * (blocksPerLineForMcu + 1); int width = this.WidthInBlocks + 1; int height = totalNumberOfBlocks / width; this.SpectralBlocks = this.memoryAllocator.Allocate2D <Block8x8>(width, height, AllocationOptions.Clean); }
public void Init() { this.WidthInBlocks = (int)MathF.Ceiling( MathF.Ceiling(this.Frame.SamplesPerLine / 8F) * this.HorizontalSamplingFactor / this.Frame.MaxHorizontalFactor); this.HeightInBlocks = (int)MathF.Ceiling( MathF.Ceiling(this.Frame.Scanlines / 8F) * this.VerticalSamplingFactor / this.Frame.MaxVerticalFactor); int blocksPerLineForMcu = this.Frame.McusPerLine * this.HorizontalSamplingFactor; int blocksPerColumnForMcu = this.Frame.McusPerColumn * this.VerticalSamplingFactor; this.SizeInBlocks = new Size(blocksPerLineForMcu, blocksPerColumnForMcu); // For 4-component images (either CMYK or YCbCrK), we only support two // hv vectors: [0x11 0x11 0x11 0x11] and [0x22 0x11 0x11 0x22]. // Theoretically, 4-component JPEG images could mix and match hv values // but in practice, those two combinations are the only ones in use, // and it simplifies the applyBlack code below if we can assume that: // - for CMYK, the C and K channels have full samples, and if the M // and Y channels subsample, they subsample both horizontally and // vertically. // - for YCbCrK, the Y and K channels have full samples. if (this.Index == 0 || this.Index == 3) { this.SubSamplingDivisors = new Size(1, 1); } else { JpegComponent c0 = this.Frame.Components[0]; this.SubSamplingDivisors = c0.SamplingFactors.DivideBy(this.SamplingFactors); } this.SpectralBlocks = this.memoryAllocator.Allocate2D <Block8x8>(blocksPerColumnForMcu, blocksPerLineForMcu + 1, AllocationOptions.Clean); }
public void AllocateComponents(bool fullScan) { for (int i = 0; i < this.ComponentCount; i++) { JpegComponent component = this.Components[i]; component.AllocateSpectral(fullScan); } }
/// <summary> /// Allocates the frame component blocks. /// </summary> public void InitComponents() { this.McusPerLine = (int)MathF.Ceiling(this.SamplesPerLine / 8F / this.MaxHorizontalFactor); this.McusPerColumn = (int)MathF.Ceiling(this.Scanlines / 8F / this.MaxVerticalFactor); for (int i = 0; i < this.ComponentCount; i++) { JpegComponent component = this.Components[i]; component.Init(); } }
/// <summary> /// Allocates the frame component blocks. /// </summary> /// <param name="maxSubFactorH">Maximal horizontal subsampling factor among all the components.</param> /// <param name="maxSubFactorV">Maximal vertical subsampling factor among all the components.</param> public void Init(int maxSubFactorH, int maxSubFactorV) { this.McusPerLine = (int)Numerics.DivideCeil((uint)this.PixelWidth, (uint)maxSubFactorH * 8); this.McusPerColumn = (int)Numerics.DivideCeil((uint)this.PixelHeight, (uint)maxSubFactorV * 8); for (int i = 0; i < this.ComponentCount; i++) { JpegComponent component = this.Components[i]; component.Init(maxSubFactorH, maxSubFactorV); } }
private void ParseBaselineDataInterleaved() { // Interleaved int mcu = 0; int mcusPerColumn = this.frame.McusPerColumn; int mcusPerLine = this.frame.McusPerLine; for (int j = 0; j < mcusPerColumn; j++) { for (int i = 0; i < mcusPerLine; i++) { // Scan an interleaved mcu... process components in order for (int k = 0; k < this.componentsLength; k++) { int order = this.frame.ComponentOrder[k]; JpegComponent component = this.components[order]; ref HuffmanTable dcHuffmanTable = ref this.dcHuffmanTables[component.DCHuffmanTableId]; ref HuffmanTable acHuffmanTable = ref this.acHuffmanTables[component.ACHuffmanTableId]; ref short fastACRef = ref this.fastACTables.GetAcTableReference(component); int h = component.HorizontalSamplingFactor; int v = component.VerticalSamplingFactor; int mcuRow = mcu / mcusPerLine; // Scan out an mcu's worth of this component; that's just determined // by the basic H and V specified for the component for (int y = 0; y < v; y++) { int blockRow = (mcuRow * v) + y; Span <Block8x8> blockSpan = component.SpectralBlocks.GetRowSpan(blockRow); for (int x = 0; x < h; x++) { if (this.eof) { return; } int mcuCol = mcu % mcusPerLine; int blockCol = (mcuCol * h) + x; this.DecodeBlockBaseline( component, ref blockSpan[blockCol], ref dcHuffmanTable, ref acHuffmanTable, ref fastACRef); } } }
private unsafe void ParseBaselineDataInterleaved() { // Interleaved int mcu = 0; int mcusPerColumn = this.frame.McusPerColumn; int mcusPerLine = this.frame.McusPerLine; // Pre-derive the huffman table to avoid in-loop checks. for (int i = 0; i < this.componentsLength; i++) { int order = this.frame.ComponentOrder[i]; JpegComponent component = this.components[order]; ref HuffmanTable dcHuffmanTable = ref this.dcHuffmanTables[component.DCHuffmanTableId]; ref HuffmanTable acHuffmanTable = ref this.acHuffmanTables[component.ACHuffmanTableId];
public ref short GetAcTableReference(JpegComponent component) { return(ref this.tables.GetRowSpan(component.ACHuffmanTableId)[0]); }