public PpmdProperties(ReadOnlySpan <byte> properties) { if (properties.Length == 2) { ushort props = BinaryPrimitives.ReadUInt16LittleEndian(properties); AllocatorSize = (((props >> 4) & 0xff) + 1) << 20; ModelOrder = (props & 0x0f) + 1; RestorationMethod = (ModelRestorationMethod)(props >> 12); } else if (properties.Length == 5) { Version = PpmdVersion.H7Z; AllocatorSize = BinaryPrimitives.ReadInt32LittleEndian(properties.Slice(1)); ModelOrder = properties[0]; } }
public PpmdProperties(byte[] properties) { if (properties.Length == 2) { ushort props = DataConverter.LittleEndian.GetUInt16(properties, 0); AllocatorSize = (((props >> 4) & 0xff) + 1) << 20; ModelOrder = (props & 0x0f) + 1; RestorationMethod = (ModelRestorationMethod)(props >> 12); } else if (properties.Length == 5) { Version = PpmdVersion.H7Z; AllocatorSize = DataConverter.LittleEndian.GetInt32(properties, 1); ModelOrder = properties[0]; } }
private void RestoreModel(PpmContext context, PpmContext minimumContext, PpmContext foundStateSuccessor) { PpmContext currentContext; Allocator.Text = Allocator.Heap; for (currentContext = maximumContext; currentContext != context; currentContext = currentContext.Suffix) { if (--currentContext.NumberStatistics == 0) { currentContext.Flags = (byte)((currentContext.Flags & 0x10) + ((currentContext.Statistics.Symbol >= 0x40) ? 0x08 : 0x00)); PpmState state = currentContext.Statistics; Copy(currentContext.FirstState, state); Allocator.SpecialFreeUnits(state); currentContext.FirstStateFrequency = (byte)((currentContext.FirstStateFrequency + 11) >> 3); } else { Refresh((uint)((currentContext.NumberStatistics + 3) >> 1), false, currentContext); } } for (; currentContext != minimumContext; currentContext = currentContext.Suffix) { if (currentContext.NumberStatistics == 0) { currentContext.FirstStateFrequency -= (byte)(currentContext.FirstStateFrequency >> 1); } else if ((currentContext.SummaryFrequency += 4) > 128 + 4 * currentContext.NumberStatistics) { Refresh((uint)((currentContext.NumberStatistics + 2) >> 1), true, currentContext); } } if (method > ModelRestorationMethod.Freeze) { maximumContext = foundStateSuccessor; Allocator.GlueCount += (uint)(((Allocator.MemoryNodes[1].Stamp & 1) == 0) ? 1 : 0); } else if (method == ModelRestorationMethod.Freeze) { while (maximumContext.Suffix != PpmContext.Zero) { maximumContext = maximumContext.Suffix; } RemoveBinaryContexts(0, maximumContext); method = (ModelRestorationMethod)(method + 1); Allocator.GlueCount = 0; orderFall = modelOrder; } else if (method == ModelRestorationMethod.Restart || Allocator.GetMemoryUsed() < (Allocator.AllocatorSize >> 1)) { StartModel(modelOrder, method); escapeCount = 0; } else { while (maximumContext.Suffix != PpmContext.Zero) { maximumContext = maximumContext.Suffix; } do { CutOff(0, maximumContext); Allocator.ExpandText(); } while (Allocator.GetMemoryUsed() > 3 * (Allocator.AllocatorSize >> 2)); Allocator.GlueCount = 0; orderFall = modelOrder; } }
/// <summary> /// Initialise the model (unless the model order is set to 1 in which case the model should be cleared so that /// the statistics are carried over, allowing "solid" mode compression). /// </summary> private void StartModel(int modelOrder, ModelRestorationMethod modelRestorationMethod) { Array.Clear(characterMask, 0, characterMask.Length); escapeCount = 1; // Compress in "solid" mode if the model order value is set to 1 (this will examine the current PPM context // structures to determine the value of orderFall). if (modelOrder < 2) { orderFall = this.modelOrder; for (PpmContext context = maximumContext; context.Suffix != PpmContext.Zero; context = context.Suffix) { orderFall--; } return; } this.modelOrder = modelOrder; orderFall = modelOrder; method = modelRestorationMethod; Allocator.Initialize(); initialRunLength = -((modelOrder < 12) ? modelOrder : 12) - 1; runLength = initialRunLength; // Allocate the context structure. maximumContext = Allocator.AllocateContext(); maximumContext.Suffix = PpmContext.Zero; maximumContext.NumberStatistics = 255; maximumContext.SummaryFrequency = (ushort)(maximumContext.NumberStatistics + 2); maximumContext.Statistics = Allocator.AllocateUnits(256 / 2); // allocates enough space for 256 PPM states (each is 6 bytes) previousSuccess = 0; for (int index = 0; index < 256; index++) { PpmState state = maximumContext.Statistics[index]; state.Symbol = (byte)index; state.Frequency = 1; state.Successor = PpmContext.Zero; } uint probability = 0; for (int index1 = 0; probability < 25; probability++) { while (probabilities[index1] == probability) { index1++; } for (int index2 = 0; index2 < 8; index2++) { binarySummary[probability, index2] = (ushort)(BinaryScale - InitialBinaryEscapes[index2] / (index1 + 1)); } for (int index2 = 8; index2 < 64; index2 += 8) { for (int index3 = 0; index3 < 8; index3++) { binarySummary[probability, index2 + index3] = binarySummary[probability, index3]; } } } probability = 0; for (uint index1 = 0; probability < 24; probability++) { while (probabilities[index1 + 3] == probability + 3) { index1++; } for (int index2 = 0; index2 < 32; index2++) { see2Contexts[probability, index2].Initialize(2 * index1 + 5); } } }
internal PpmdProperties(int allocatorSize, int modelOrder, ModelRestorationMethod modelRestorationMethod) { AllocatorSize = allocatorSize; ModelOrder = modelOrder; RestorationMethod = modelRestorationMethod; }
private void RestoreModel(PpmContext context, PpmContext minimumContext, PpmContext foundStateSuccessor) { PpmContext currentContext; Allocator.Text = Allocator.Heap; for (currentContext = maximumContext; currentContext != context; currentContext = currentContext.Suffix) { if (--currentContext.NumberStatistics == 0) { currentContext.Flags = (byte) ((currentContext.Flags & 0x10) + ((currentContext.Statistics.Symbol >= 0x40) ? 0x08 : 0x00)); PpmState state = currentContext.Statistics; Copy(currentContext.FirstState, state); Allocator.SpecialFreeUnits(state); currentContext.FirstStateFrequency = (byte) ((currentContext.FirstStateFrequency + 11) >> 3); } else { Refresh((uint) ((currentContext.NumberStatistics + 3) >> 1), false, currentContext); } } for (; currentContext != minimumContext; currentContext = currentContext.Suffix) { if (currentContext.NumberStatistics == 0) currentContext.FirstStateFrequency -= (byte) (currentContext.FirstStateFrequency >> 1); else if ((currentContext.SummaryFrequency += 4) > 128 + 4*currentContext.NumberStatistics) Refresh((uint) ((currentContext.NumberStatistics + 2) >> 1), true, currentContext); } if (method > ModelRestorationMethod.Freeze) { maximumContext = foundStateSuccessor; Allocator.GlueCount += (uint) (((Allocator.MemoryNodes[1].Stamp & 1) == 0) ? 1 : 0); } else if (method == ModelRestorationMethod.Freeze) { while (maximumContext.Suffix != PpmContext.Zero) maximumContext = maximumContext.Suffix; RemoveBinaryContexts(0, maximumContext); method = (ModelRestorationMethod) (method + 1); Allocator.GlueCount = 0; orderFall = modelOrder; } else if (method == ModelRestorationMethod.Restart || Allocator.GetMemoryUsed() < (Allocator.AllocatorSize >> 1)) { StartModel(modelOrder, method); escapeCount = 0; } else { while (maximumContext.Suffix != PpmContext.Zero) maximumContext = maximumContext.Suffix; do { CutOff(0, maximumContext); Allocator.ExpandText(); } while (Allocator.GetMemoryUsed() > 3*(Allocator.AllocatorSize >> 2)); Allocator.GlueCount = 0; orderFall = modelOrder; } }
/// <summary> /// Initialise the model (unless the model order is set to 1 in which case the model should be cleared so that /// the statistics are carried over, allowing "solid" mode compression). /// </summary> private void StartModel(int modelOrder, ModelRestorationMethod modelRestorationMethod) { Array.Clear(characterMask, 0, characterMask.Length); escapeCount = 1; // Compress in "solid" mode if the model order value is set to 1 (this will examine the current PPM context // structures to determine the value of orderFall). if (modelOrder < 2) { orderFall = this.modelOrder; for (PpmContext context = maximumContext; context.Suffix != PpmContext.Zero; context = context.Suffix) orderFall--; return; } this.modelOrder = modelOrder; orderFall = modelOrder; method = modelRestorationMethod; Allocator.Initialize(); initialRunLength = -((modelOrder < 12) ? modelOrder : 12) - 1; runLength = initialRunLength; // Allocate the context structure. maximumContext = Allocator.AllocateContext(); maximumContext.Suffix = PpmContext.Zero; maximumContext.NumberStatistics = 255; maximumContext.SummaryFrequency = (ushort) (maximumContext.NumberStatistics + 2); maximumContext.Statistics = Allocator.AllocateUnits(256/2); // allocates enough space for 256 PPM states (each is 6 bytes) previousSuccess = 0; for (int index = 0; index < 256; index++) { PpmState state = maximumContext.Statistics[index]; state.Symbol = (byte) index; state.Frequency = 1; state.Successor = PpmContext.Zero; } uint probability = 0; for (int index1 = 0; probability < 25; probability++) { while (probabilities[index1] == probability) index1++; for (int index2 = 0; index2 < 8; index2++) binarySummary[probability, index2] = (ushort) (BinaryScale - InitialBinaryEscapes[index2]/(index1 + 1)); for (int index2 = 8; index2 < 64; index2 += 8) for (int index3 = 0; index3 < 8; index3++) binarySummary[probability, index2 + index3] = binarySummary[probability, index3]; } probability = 0; for (uint index1 = 0; probability < 24; probability++) { while (probabilities[index1 + 3] == probability + 3) index1++; for (int index2 = 0; index2 < 32; index2++) see2Contexts[probability, index2].Initialize(2*index1 + 5); } }