/// <summary> /// Applies a resolution function over all runs in the data. /// </summary> public RunResolution Resolve(Func <Run, int> resolver) { var resolution = new RunResolution.Builder(); for (int index = 0; index < data.Length;) { byte symbol = data[index]; if (symbol == 0) { int runLength = GetRunLength(index); int retained = runLength < Run.MinSpecialCodeLength ? runLength : resolver(new Run(runLength)); if (retained > runLength) { throw new InvalidOperationException("Cannot request encoding a run longer than originally asked for (" + retained + " > " + runLength + ")."); } if (retained < Run.MinSpecialCodeLength) { if (retained == 0) { retained = runLength; } for (int i = 0; i < retained; i++) { resolution.AddRaw(0); } } else { resolution.AddRun(retained); } index += retained; } else { resolution.AddRaw(symbol); index += 1; } } return(resolution.Build()); }
/// <summary> /// Applies a resolution function over all runs in the data. /// </summary> public RunResolution Resolve(Func <Run, int> resolver) { var resolution = new RunResolution.Builder(symbolLengths); for (int entryIndex = 0, lastRepeatStartIndex = 1, lastRepeatedCode = InitialRepeatedCode; entryIndex < resolution.CodeCount + 1; entryIndex++) { int nextCode = entryIndex < resolution.CodeCount ? resolution.GetCodeAt(entryIndex) : -1; if (nextCode != lastRepeatedCode) { if (lastRepeatedCode == 0 || lastRepeatedCode == resolution.FindLastNonRepetitionNonZeroCode(lastRepeatStartIndex - 2)) { --lastRepeatStartIndex; } int runLength = entryIndex - lastRepeatStartIndex; if (runLength >= Run.MinSpecialCodeLength) { int retained = resolver(new Run((byte)lastRepeatedCode, runLength)); if (retained > runLength) { throw new InvalidOperationException("Cannot request encoding a run longer than originally asked for (" + retained + " > " + runLength + ")."); } if (retained >= Run.MinSpecialCodeLength) { int runStartIndex = lastRepeatStartIndex + runLength - retained; entryIndex = lastRepeatedCode == 0 ? resolution.EncodeRepetition(runStartIndex, Skip, retained, 1 << SkipCodeExtraBits) : resolution.EncodeRepetition(runStartIndex, Repeat, retained, 1 << RepeatCodeExtraBits); } } lastRepeatedCode = nextCode; lastRepeatStartIndex = entryIndex + 1; } } return(resolution.Build()); }