private static unsafe void BrotliBuildMetaBlockGreedyInternal( ref MemoryManager m, byte *ringbuffer, size_t pos, size_t mask, byte prev_byte, byte prev_byte2, ContextType literal_context_mode, size_t num_contexts, uint *static_context_map, Command *commands, size_t n_commands, MetaBlockSplit *mb) { lit_blocks_union lit_blocks = new lit_blocks_union(); BlockSplitterCommand cmd_blocks; BlockSplitterDistance dist_blocks; size_t num_literals = 0; size_t i; for (i = 0; i < n_commands; ++i) { num_literals += commands[i].insert_len_; } if (num_contexts == 1) { BlockSplitterLiteral.InitBlockSplitter(ref m, (BlockSplitterLiteral *)&lit_blocks, 256, 512, 400.0, num_literals, &mb->literal_split, &mb->literal_histograms, &mb->literal_histograms_size); } else { InitContextBlockSplitter(ref m, &lit_blocks.ctx, 256, num_contexts, 512, 400.0, num_literals, &mb->literal_split, &mb->literal_histograms, &mb->literal_histograms_size); } BlockSplitterCommand.InitBlockSplitter(ref m, &cmd_blocks, BROTLI_NUM_COMMAND_SYMBOLS, 1024, 500.0, n_commands, &mb->command_split, &mb->command_histograms, &mb->command_histograms_size); BlockSplitterDistance.InitBlockSplitter(ref m, &dist_blocks, 64, 512, 100.0, n_commands, &mb->distance_split, &mb->distance_histograms, &mb->distance_histograms_size); for (i = 0; i < n_commands; ++i) { Command cmd = commands[i]; size_t j; BlockSplitterCommand.BlockSplitterAddSymbol(&cmd_blocks, cmd.cmd_prefix_); for (j = cmd.insert_len_; j != 0; --j) { byte literal = ringbuffer[pos & mask]; if (num_contexts == 1) { BlockSplitterLiteral.BlockSplitterAddSymbol((BlockSplitterLiteral *)&lit_blocks, literal); } else { size_t context = Context(prev_byte, prev_byte2, literal_context_mode); ContextBlockSplitterAddSymbol(&lit_blocks.ctx, ref m, literal, static_context_map[context]); } prev_byte2 = prev_byte; prev_byte = literal; ++pos; } pos += CommandCopyLen(&cmd); if (CommandCopyLen(&cmd) != 0) { prev_byte2 = ringbuffer[(pos - 2) & mask]; prev_byte = ringbuffer[(pos - 1) & mask]; if (cmd.cmd_prefix_ >= 128) { BlockSplitterDistance.BlockSplitterAddSymbol(&dist_blocks, cmd.dist_prefix_); } } } if (num_contexts == 1) { BlockSplitterLiteral.BlockSplitterFinishBlock( (BlockSplitterLiteral *)&lit_blocks, /* is_final = */ true); } else { ContextBlockSplitterFinishBlock( &lit_blocks.ctx, ref m, /* is_final = */ true); } BlockSplitterCommand.BlockSplitterFinishBlock(&cmd_blocks, /* is_final = */ true); BlockSplitterDistance.BlockSplitterFinishBlock(&dist_blocks, /* is_final = */ true); if (num_contexts > 1) { MapStaticContexts(ref m, num_contexts, static_context_map, mb); } }
private static unsafe void BrotliSplitBlock(ref MemoryManager m, Command *cmds, size_t num_commands, byte *data, size_t pos, size_t mask, BrotliEncoderParams *params_, BlockSplit *literal_split, BlockSplit *insert_and_copy_split, BlockSplit *dist_split) { { size_t literals_count = CountLiterals(cmds, num_commands); byte * literals = (byte *)BrotliAllocate(ref m, literals_count * sizeof(byte)); /* Create a continuous array of literals. */ CopyLiteralsToByteArray(cmds, num_commands, data, pos, mask, literals); /* Create the block split on the array of literals. * Literal histograms have alphabet size 256. */ BlockSplitterLiteral.SplitByteVector( ref m, literals, literals_count, kSymbolsPerLiteralHistogram, kMaxLiteralHistograms, kLiteralStrideLength, kLiteralBlockSwitchCost, params_, literal_split); BrotliFree(ref m, literals); } { /* Compute prefix codes for commands. */ ushort *insert_and_copy_codes = (ushort *)BrotliAllocate(ref m, num_commands * sizeof(ushort)); size_t i; for (i = 0; i < num_commands; ++i) { insert_and_copy_codes[i] = cmds[i].cmd_prefix_; } /* Create the block split on the array of command prefixes. */ BlockSplitterCommand.SplitByteVector( ref m, insert_and_copy_codes, num_commands, kSymbolsPerCommandHistogram, kMaxCommandHistograms, kCommandStrideLength, kCommandBlockSwitchCost, params_, insert_and_copy_split); /* TODO: reuse for distances? */ BrotliFree(ref m, insert_and_copy_codes); } { /* Create a continuous array of distance prefixes. */ ushort *distance_prefixes = (ushort *)BrotliAllocate(ref m, num_commands * sizeof(ushort)); size_t j = 0; size_t i; for (i = 0; i < num_commands; ++i) { Command *cmd = &cmds[i]; if (CommandCopyLen(cmd) != 0 && cmd->cmd_prefix_ >= 128) { distance_prefixes[j++] = cmd->dist_prefix_; } } /* Create the block split on the array of distance prefixes. */ BlockSplitterDistance.SplitByteVector( ref m, distance_prefixes, j, kSymbolsPerDistanceHistogram, kMaxCommandHistograms, kCommandStrideLength, kDistanceBlockSwitchCost, params_, dist_split); BrotliFree(ref m, distance_prefixes); } }