protected override (MetaBlock, BrotliGlobalState) Transform(MetaBlock.Compressed original, BrotliGlobalState state, BrotliCompressionParameters parameters) { var builder = new CompressedMetaBlockBuilder(original, state) { LiteralCtxMap = ContextMapBuilder.Literals.Simple, DistanceCtxMap = ContextMapBuilder.Distances.Simple }; foreach (var category in Categories.LID) { builder.BlockTypes[category].Reset(); } builder.UseSameLiteralContextMode(LiteralContextMode.UTF8); var tracker = new MetaBlockSizeTracker(state); tracker.Test(builder, parameters); foreach (var category in Categories.LID) { TestBlockSplits(builder, parameters, tracker, category); } tracker.Test(original); return(tracker.Smallest ?? throw new InvalidOperationException("Transformation did not generate any meta-blocks.")); }
protected override (MetaBlock, BrotliGlobalState) Transform(MetaBlock.Compressed original, BrotliGlobalState state, BrotliCompressionParameters parameters) { var builder = new CompressedMetaBlockBuilder(original, state) { LiteralCtxMap = ContextMapBuilder.Literals.Simple, DistanceCtxMap = ContextMapBuilder.Distances.Simple }; foreach (var category in Categories.LID) { builder.BlockTypes[category].Reset(); } return(builder.UseSameLiteralContextMode(LiteralContextMode.LSB6).Build(parameters)); }
private void PrepareContextMap(CompressedMetaBlockBuilder builder, Category category, int lengthSplits) { int blockTypes = Math.Min(lengthSplits, 256); if (category == Category.Literal) { if (builder.LiteralCtxMap.BlockTypes != blockTypes) { builder.UseSameLiteralContextMode(LiteralContextMode.UTF8); builder.LiteralCtxMap = new ContextMapBuilder.Literals(blockTypes).RepeatFirstBlockType(lengthSplits <= blockTypes).Build(); } } else if (category == Category.Distance) { if (builder.DistanceCtxMap.BlockTypes != blockTypes) { builder.DistanceCtxMap = new ContextMapBuilder.Distances(blockTypes).RepeatFirstBlockType(lengthSplits <= blockTypes).Build(); } } }
protected override (MetaBlock, BrotliGlobalState) Transform(MetaBlock.Compressed original, BrotliGlobalState state, BrotliCompressionParameters parameters) { var builder = new CompressedMetaBlockBuilder(original, state); var literals = new List <Literal>(builder.GetTotalBlockLength(Category.Literal)); var lengthCodes = new List <InsertCopyLengthCode>(builder.GetTotalBlockLength(Category.InsertCopy)); var distanceCodes = new List <DistanceCode>(builder.GetTotalBlockLength(Category.Distance)); var distanceFreq = new FrequencyList <DistanceCode>(); var validDistanceCodes = new List <DistanceCode>(5); foreach (var command in original.Data.InsertCopyCommands) { literals.AddRange(command.Literals); state.OutputLiterals(command.Literals); if (command.CopyDistance == DistanceInfo.EndsAfterLiterals) { lengthCodes.Add(command.Lengths.MakeCode(ImplicitDistanceCodeZero.PreferEnabled)); break; } if (!command.CopyDistance.FindCodes(original.Header.DistanceParameters, state, validDistanceCodes)) { lengthCodes.Add(command.Lengths.MakeCode(ImplicitDistanceCodeZero.ForceEnabled)); } else { DistanceCode distanceCode; if (command.CopyDistance == DistanceInfo.ExplicitCodeZero) { distanceCode = DistanceCode.Zero; } else { distanceCode = validDistanceCodes.Count > 1 ? parameters.DistanceCodePicker(validDistanceCodes, distanceFreq) : validDistanceCodes[0]; } distanceFreq.Add(distanceCode); distanceCodes.Add(distanceCode); lengthCodes.Add(command.Lengths.MakeCode(ImplicitDistanceCodeZero.Disable)); } } var origLitCtxMap = builder.LiteralCtxMap; if (origLitCtxMap.TreeCount == 1) { Split(builder, Category.Literal, literals, 512, 400.0); builder.UseSameLiteralContextMode(LiteralContextMode.UTF8); builder.LiteralCtxMap = new ContextMapBuilder.Literals(builder).RepeatFirstBlockType(true).Build(); } else { var literalContextMap = Enumerable.Range(0, origLitCtxMap.ContextsPerBlockType).Select(index => origLitCtxMap.DetermineTreeID(0, index)).ToArray(); var literalContextMode = builder.LiteralContextModes[0]; var literalBuffer = RingBufferFast <byte> .From(0, 0); Split(builder, Category.Literal, literals, 512, 400.0, new BlockSplitter <Literal> .ContextInfo(literalContextMap, literal => { literalBuffer.Push(literal.Value); return(literalContextMode.DetermineContextID(literalBuffer.Front, literalBuffer.Back)); })); builder.UseSameLiteralContextMode(literalContextMode); builder.LiteralCtxMap = new ContextMapBuilder.Literals(builder).Set(0, literalContextMap).RepeatFirstBlockType(true).Build(); } Split(builder, Category.InsertCopy, lengthCodes, 1024, 500.0); Split(builder, Category.Distance, distanceCodes, 512, 100.0); builder.DistanceCtxMap = new ContextMapBuilder.Distances(builder).RepeatFirstBlockType(true).Build(); return(builder.Build(parameters)); }