/// <summary> /// Adapted from https://github.com/google/brotli/blob/master/c/enc/encode.c (EncodeData). /// </summary> public (MetaBlock MetaBlock, BrotliEncodeInfo Next) Encode(BrotliEncodeInfo info) { var builder = info.NewBuilder(); do { position = lastProcessedPos; // TODO extend last command somehow??? int chunkLength = Math.Min(input.Length - position - lastInsertLen, InputBlockSize(lgBlock)); if (chunkLength == 0) { break; } hasher.StitchToPreviousBlock(chunkLength, position); lastProcessedPos = position + chunkLength; CreateBackwardReferences(builder, chunkLength); }while(lastProcessedPos + lastInsertLen < input.Length && ShouldContinueThisBlock(builder)); if (lastInsertLen > 0) { builder.AddInsert(Literal.FromBytes(info.Bytes.Slice(builder.OutputSize, lastInsertLen))); lastInsertLen = 0; } return(builder.Build(info)); }
public (MetaBlock, BrotliEncodeInfo) Encode(BrotliEncodeInfo info) { var bytes = CollectionHelper.SliceAtMost(info.Bytes, DataLength.MaxUncompressedBytes).ToArray(); return(info.NewBuilder() .AddInsert(Literal.FromBytes(bytes)) .Build(info)); }
public (MetaBlock, BrotliEncodeInfo) Encode(BrotliEncodeInfo info) { (literalTree, literalRatio) = Huffman.EstimateLiteralRatio(new ArraySegment <byte>(input, ip, blockSize)); var builder = info.NewBuilder(); var nextStep = NextStep.EmitCommands; while (true) { switch (nextStep) { case NextStep.EmitCommands: nextStep = EmitCommands(); break; case NextStep.EmitCommandsNextHash: nextStep = EmitCommandsNextHash(); break; case NextStep.Trawl: nextStep = Trawl(builder); break; case NextStep.EmitRemainder: nextStep = EmitRemainder(builder); break; case NextStep.OutputCompressed: OnNextBlock(); return(builder.Build(info, new BrotliCompressionParameters.Builder(info.CompressionParameters) { GenerateLiteralTree = _ => literalTree }.Build())); case NextStep.OutputUncompressed: var metaBlock = new MetaBlock.Uncompressed(input, metaBlockStart, outputTo - metaBlockStart); inputSize -= metaBlock.DataLength.UncompressedBytes; nextIpStart = outputTo; nextEmit = nextIpStart; OnNextBlock(); return(metaBlock, info.WithOutputtedMetaBock(metaBlock)); } } }