private TilePartComponent[] DecodePackets(TilePartHeader tilePartHeader) { var tile = Image.Tiles[tilePartHeader.SOT.I_TileIndexNumber]; var tilePart = new TilePart(tile, tilePartHeader); var tilePartComponents = new TilePartComponent[Image.Components.Length]; for (var iComponent = 0; iComponent < Image.Components.Length; iComponent++) { var tileComponent = tile.TileComponents[iComponent]; tilePartComponents[iComponent] = new TilePartComponent(tilePart, tileComponent); } var progressionOrder = tilePartHeader.COD.SG_ProgressionOrder; if (progressionOrder == ProgressionOrder.LayerResolutionComponentPosition) { DecodePacketsInLayerResolutionComponentPositionOrder(tilePartHeader, tilePartComponents); } else { throw NotSupported(progressionOrder); } return(tilePartComponents); }
private static double GetQuantizationStepSize(TilePartComponent tilePartComponent, Subband subband) { var qcc = tilePartComponent.QCC; ThrowIf(qcc.QuantizationStyle == QuantizationStyle.NoQuantization); // See E.1.1.1 "Determination of the quantization step size" var ri = tilePartComponent.TileComponent.Component.ComponentSampleBitDepth; var rb = ri + GetLog2SubbandGain(subband); if (qcc.QuantizationStyle == QuantizationStyle.ScalarExpounded) { var qss = qcc.QuantizationStepSizes[subband.SubbandIndex]; return(Math.Pow(2, rb - qss.Exponent) * (1 + qss.Mantissa / Math.Pow(2, 11))); } else { throw NotSupported(qcc.QuantizationStyle); } }
private void StartDecodeCodeBlock(TilePartComponent tilePartComponent, CodeBlock codeBlock) { if (codeBlock.LengthInBytes > int.MaxValue - 2) { throw new NotSupportedException($"Code block too long ({codeBlock.LengthInBytes})"); } var bytes = new byte[codeBlock.LengthInBytes + 2]; DataReader.Read(bytes.AsSpan(0, (int)codeBlock.LengthInBytes)); // Two 0xFF bytes must be added to flush the entropy coder (see D.4.1 "Expected codestream termination") bytes[codeBlock.LengthInBytes] = 0xFF; bytes[codeBlock.LengthInBytes + 1] = 0xFF; codeBlock.DecodeTask = Task.Run(() => { var coefficientDecoder = new CoefficientDecoder(codeBlock, bytes); coefficientDecoder.Run(tilePartComponent); }); }
private static void CopyToPixelDataBuffer(TilePartComponent tilePartComponent, Signal2D a, int[] buffer, int offset, int count) { var inverseDCLevelShifter = InverseDCLevelShifter.Create(tilePartComponent.ArithmeticType); inverseDCLevelShifter.CopyToPixelDataBuffer(tilePartComponent.TileComponent.Component, a, buffer, offset, count); }
protected sealed override void Dequantisize(Signal2D <T> transformCoefficientValues, TilePartComponent component, Subband subband) { var quantizationStepSize = GetQuantizationStepSize(component, subband); if (quantizationStepSize != 1) { transformCoefficientValues.URange.GetBounds(out int u0, out int u1); transformCoefficientValues.VRange.GetBounds(out int v0, out int v1); Parallel.For(v0, v1, v => { for (var u = u0; u < u1; u++) { ApplyQuantizationStepSize(transformCoefficientValues, u, v, quantizationStepSize); } }); } }
protected sealed override void Dequantisize(Signal2D <T> transformCoefficientValues, TilePartComponent tilePartComponent, Subband subband) { // Nothing to do }
public abstract void Dequantisize(Signal2D transformCoefficientValues, TilePartComponent tilePartComponent, Subband subband);