diff options
Diffstat (limited to 'rust/vendor/brotli/src/enc/encode.rs')
-rwxr-xr-x | rust/vendor/brotli/src/enc/encode.rs | 3038 |
1 files changed, 3038 insertions, 0 deletions
diff --git a/rust/vendor/brotli/src/enc/encode.rs b/rust/vendor/brotli/src/enc/encode.rs new file mode 100755 index 0000000..fdc9dd6 --- /dev/null +++ b/rust/vendor/brotli/src/enc/encode.rs @@ -0,0 +1,3038 @@ +#![allow(dead_code)] +use super::hash_to_binary_tree::InitializeH10; +use super::constants::{BROTLI_WINDOW_GAP, BROTLI_CONTEXT_LUT, BROTLI_CONTEXT, + BROTLI_NUM_HISTOGRAM_DISTANCE_SYMBOLS, BROTLI_MAX_NPOSTFIX, BROTLI_MAX_NDIRECT}; +use super::backward_references::{BrotliCreateBackwardReferences, Struct1, UnionHasher, + BrotliEncoderParams, BrotliEncoderMode, BrotliHasherParams, H2Sub, + H3Sub, H4Sub, H5Sub, H6Sub, H54Sub, HQ5Sub, HQ7Sub, AdvHasher, BasicHasher, H9, + H9_BUCKET_BITS, H9_BLOCK_SIZE, H9_BLOCK_BITS, H9_NUM_LAST_DISTANCES_TO_CHECK, + AnyHasher, HowPrepared, StoreLookaheadThenStore, AdvHashSpecialization}; +use alloc::Allocator; +pub use super::parameters::BrotliEncoderParameter; +use super::combined_alloc::BrotliAlloc; +use super::interface; +use super::bit_cost::{BitsEntropy, ShannonEntropy}; +#[allow(unused_imports)] +use super::block_split::BlockSplit; +#[allow(unused_imports)] +use super::brotli_bit_stream::{BrotliBuildAndStoreHuffmanTreeFast, BrotliStoreHuffmanTree, + BrotliStoreMetaBlock, BrotliStoreMetaBlockFast, + BrotliStoreMetaBlockTrivial, BrotliStoreUncompressedMetaBlock, + BrotliWriteEmptyLastMetaBlock, BrotliWriteMetadataMetaBlock, + MetaBlockSplit, RecoderState, JumpToByteBoundary}; + +use enc::input_pair::InputReferenceMut; +use super::command::{Command, GetLengthCode, BrotliDistanceParams}; +use super::compress_fragment::BrotliCompressFragmentFast; +use super::compress_fragment_two_pass::{BrotliCompressFragmentTwoPass, BrotliWriteBits}; +#[allow(unused_imports)] +use super::entropy_encode::{BrotliConvertBitDepthsToSymbols, BrotliCreateHuffmanTree, HuffmanTree}; +use super::metablock::{BrotliBuildMetaBlock, BrotliBuildMetaBlockGreedy, BrotliOptimizeHistograms, BrotliInitDistanceParams}; +use super::static_dict::{BrotliGetDictionary, kNumDistanceCacheEntries}; +use super::histogram::{ContextType, HistogramLiteral, HistogramCommand, HistogramDistance, CostAccessors}; +use super::super::alloc; +use super::super::alloc::{SliceWrapper, SliceWrapperMut}; +use super::utf8_util::BrotliIsMostlyUTF8; +use super::util::{brotli_min_size_t, Log2FloorNonZero}; +use core; +//fn BrotliCreateHqZopfliBackwardReferences(m: &mut [MemoryManager], +// dictionary: &[BrotliDictionary], +// num_bytes: usize, +// position: usize, +// ringbuffer: &[u8], +// ringbuffer_mask: usize, +// params: &[BrotliEncoderParams], +// hasher: &mut [u8], +// dist_cache: &mut [i32], +// last_insert_len: &mut [usize], +// commands: &mut [Command], +// num_commands: &mut [usize], +// num_literals: &mut [usize]); +//fn BrotliCreateZopfliBackwardReferences(m: &mut [MemoryManager], +// dictionary: &[BrotliDictionary], +// num_bytes: usize, +// position: usize, +// ringbuffer: &[u8], +// ringbuffer_mask: usize, +// params: &[BrotliEncoderParams], +// hasher: &mut [u8], +// dist_cache: &mut [i32], +// last_insert_len: &mut [usize], +// commands: &mut [Command], +// num_commands: &mut [usize], +// num_literals: &mut [usize]); +//fn BrotliInitBlockSplit(xself: &mut BlockSplit); +//fn BrotliInitMemoryManager(m: &mut [MemoryManager], +// alloc_func: fn(&mut [::std::os::raw::c_void], usize) +// -> *mut ::std::os::raw::c_void, +// free_func: fn(*mut ::std::os::raw::c_void, +// *mut ::std::os::raw::c_void), +// opaque: *mut ::std::os::raw::c_void); +//fn BrotliInitZopfliNodes(array: &mut [ZopfliNode], length: usize); +//fn BrotliWipeOutMemoryManager(m: &mut [MemoryManager]); + + + +static kCompressFragmentTwoPassBlockSize: usize = (1i32 << 17i32) as (usize); + +static kMinUTF8Ratio: super::util::floatX = 0.75 as super::util::floatX; + + + +pub struct RingBuffer<AllocU8: alloc::Allocator<u8>> { + pub size_: u32, + pub mask_: u32, + pub tail_size_: u32, + pub total_size_: u32, + pub cur_size_: u32, + pub pos_: u32, + pub data_mo: AllocU8::AllocatedMemory, + pub buffer_index: usize, +} + + +#[derive(PartialEq, Eq, Copy, Clone)] +#[repr(i32)] +pub enum BrotliEncoderStreamState { + BROTLI_STREAM_PROCESSING = 0, + BROTLI_STREAM_FLUSH_REQUESTED = 1, + BROTLI_STREAM_FINISHED = 2, + BROTLI_STREAM_METADATA_HEAD = 3, + BROTLI_STREAM_METADATA_BODY = 4, +} + +#[derive(Clone,Copy,Debug)] +enum NextOut { + DynamicStorage(u32), + TinyBuf(u32), + None, +} +fn GetNextOutInternal<'a>( + next_out :&NextOut, + storage : &'a mut [u8], + tiny_buf : &'a mut [u8;16], +) -> &'a mut[u8]{ + match next_out { + &NextOut::DynamicStorage(offset) => + return &mut storage[offset as usize..], + &NextOut::TinyBuf(offset) => + return &mut tiny_buf[offset as usize..], + &NextOut::None => &mut [], + } +} +macro_rules! GetNextOut { + ($s : expr) => { + GetNextOutInternal(&$s.next_out_, + $s.storage_.slice_mut(), + &mut $s.tiny_buf_) + }; +} +fn NextOutIncrement(next_out :&NextOut, inc : i32) -> NextOut{ + match next_out { + &NextOut::DynamicStorage(offset) => + return NextOut::DynamicStorage((offset as i32 + inc) as u32), + &NextOut::TinyBuf(offset) => + return NextOut::TinyBuf((offset as i32 + inc) as u32), + &NextOut::None => NextOut::None, + } +} +fn IsNextOutNull(next_out :&NextOut) -> bool { + match next_out { + &NextOut::DynamicStorage(_) => + false, + &NextOut::TinyBuf(_) => + false, + &NextOut::None => true, + } +} + +#[derive(Clone,Copy,Debug)] +pub enum IsFirst { + NothingWritten, + HeaderWritten, + FirstCatableByteWritten, + BothCatableBytesWritten, +} + +pub struct BrotliEncoderStateStruct<Alloc: BrotliAlloc> +{ + pub params: BrotliEncoderParams, + pub m8: Alloc, + pub hasher_: UnionHasher<Alloc>, + pub input_pos_: u64, + pub ringbuffer_: RingBuffer<Alloc>, + pub cmd_alloc_size_: usize, + pub commands_: <Alloc as Allocator<Command>>::AllocatedMemory, // not sure about this one + pub num_commands_: usize, + pub num_literals_: usize, + pub last_insert_len_: usize, + pub last_flush_pos_: u64, + pub last_processed_pos_: u64, + pub dist_cache_: [i32; 16], + pub saved_dist_cache_: [i32; kNumDistanceCacheEntries], + pub last_bytes_: u16, + pub last_bytes_bits_: u8, + pub prev_byte_: u8, + pub prev_byte2_: u8, + pub storage_size_: usize, + pub storage_: <Alloc as Allocator<u8>>::AllocatedMemory, + pub small_table_: [i32; 1024], + pub large_table_: <Alloc as Allocator<i32>>::AllocatedMemory, +// pub large_table_size_: usize, // <-- get this by doing large_table_.len() + pub cmd_depths_: [u8; 128], + pub cmd_bits_: [u16; 128], + pub cmd_code_: [u8; 512], + pub cmd_code_numbits_: usize, + pub command_buf_: <Alloc as Allocator<u32>>::AllocatedMemory, + pub literal_buf_: <Alloc as Allocator<u8>>::AllocatedMemory, + next_out_: NextOut, + pub available_out_: usize, + pub total_out_: u64, + pub tiny_buf_: [u8; 16], + pub remaining_metadata_bytes_: u32, + pub stream_state_: BrotliEncoderStreamState, + pub is_last_block_emitted_: bool, + pub is_initialized_: bool, + pub is_first_mb: IsFirst, + pub literal_scratch_space: <HistogramLiteral as CostAccessors>::i32vec, + pub command_scratch_space: <HistogramCommand as CostAccessors>::i32vec, + pub distance_scratch_space: <HistogramDistance as CostAccessors>::i32vec, + pub recoder_state: RecoderState, + custom_dictionary: bool, +} + +pub fn set_parameter(params: &mut BrotliEncoderParams, + p: BrotliEncoderParameter, +value: u32) -> i32 { + if p as (i32) == BrotliEncoderParameter::BROTLI_PARAM_MODE as (i32) { + params.mode = match value { + 0 => BrotliEncoderMode::BROTLI_MODE_GENERIC, + 1 => BrotliEncoderMode::BROTLI_MODE_TEXT, + 2 => BrotliEncoderMode::BROTLI_MODE_FONT, + 3 => BrotliEncoderMode::BROTLI_FORCE_LSB_PRIOR, + 4 => BrotliEncoderMode::BROTLI_FORCE_MSB_PRIOR, + 5 => BrotliEncoderMode::BROTLI_FORCE_UTF8_PRIOR, + 6 => BrotliEncoderMode::BROTLI_FORCE_SIGNED_PRIOR, + _ => BrotliEncoderMode::BROTLI_MODE_GENERIC, + }; + return 1i32; + } + if p as (i32) == BrotliEncoderParameter::BROTLI_PARAM_QUALITY as (i32) { + params.quality = value as (i32); + return 1i32; + } + if p as (i32) == BrotliEncoderParameter::BROTLI_PARAM_STRIDE_DETECTION_QUALITY as (i32) { + params.stride_detection_quality = value as (u8); + return 1i32; + } + if p as (i32) == BrotliEncoderParameter::BROTLI_PARAM_HIGH_ENTROPY_DETECTION_QUALITY as (i32) { + params.high_entropy_detection_quality = value as (u8); + return 1i32; + } + if p as (i32) == BrotliEncoderParameter::BROTLI_PARAM_CDF_ADAPTATION_DETECTION as (i32) { + params.cdf_adaptation_detection = value as (u8); + return 1i32; + } + if p as (i32) == BrotliEncoderParameter::BROTLI_PARAM_Q9_5 as (i32) { + params.q9_5 = (value != 0); + return 1i32; + } + if p as (i32) == BrotliEncoderParameter::BROTLI_PARAM_PRIOR_BITMASK_DETECTION as (i32) { + params.prior_bitmask_detection = value as u8; + return 1i32; + } + if p as (i32) == BrotliEncoderParameter::BROTLI_PARAM_SPEED as (i32) { + params.literal_adaptation[1].0 = value as u16; + if params.literal_adaptation[0] == (0,0) { + params.literal_adaptation[0].0 = value as u16; + } + return 1i32; + } + if p as (i32) == BrotliEncoderParameter::BROTLI_PARAM_SPEED_MAX as (i32) { + params.literal_adaptation[1].1 = value as u16; + if params.literal_adaptation[0].1 == 0 { + params.literal_adaptation[0].1 = value as u16; + } + return 1i32; + } + if p as (i32) == BrotliEncoderParameter::BROTLI_PARAM_CM_SPEED as (i32) { + params.literal_adaptation[3].0 = value as u16; + if params.literal_adaptation[2] == (0,0) { + params.literal_adaptation[2].0 = value as u16; + } + return 1i32; + } + if p as (i32) == BrotliEncoderParameter::BROTLI_PARAM_CM_SPEED_MAX as (i32) { + params.literal_adaptation[3].1 = value as u16; + if params.literal_adaptation[2].1 == 0 { + params.literal_adaptation[2].1 = value as u16; + } + return 1i32; + } + if p as (i32) == BrotliEncoderParameter::BROTLI_PARAM_SPEED_LOW as (i32) { + params.literal_adaptation[0].0 = value as u16; + return 1i32; + } + if p as (i32) == BrotliEncoderParameter::BROTLI_PARAM_SPEED_LOW_MAX as (i32) { + params.literal_adaptation[0].1 = value as u16; + return 1i32; + } + if p as (i32) == BrotliEncoderParameter::BROTLI_PARAM_CM_SPEED_LOW as (i32) { + params.literal_adaptation[2].0 = value as u16; + return 1i32; + } + if p as (i32) == BrotliEncoderParameter::BROTLI_PARAM_CM_SPEED_LOW_MAX as (i32) { + params.literal_adaptation[2].1 = value as u16; + return 1i32; + } + if p as (i32) == BrotliEncoderParameter::BROTLI_PARAM_LITERAL_BYTE_SCORE as (i32) { + params.hasher.literal_byte_score = value as i32; + return 1i32; + } + if p as (i32) == BrotliEncoderParameter::BROTLI_METABLOCK_CALLBACK as (i32) { + params.log_meta_block = if value != 0 {true} else {false}; + return 1i32; + } + if p as (i32) == BrotliEncoderParameter::BROTLI_PARAM_LGWIN as (i32) { + params.lgwin = value as (i32); + return 1i32; + } + if p as (i32) == BrotliEncoderParameter::BROTLI_PARAM_LGBLOCK as (i32) { + params.lgblock = value as (i32); + return 1i32; + } + if p as (i32) == BrotliEncoderParameter::BROTLI_PARAM_DISABLE_LITERAL_CONTEXT_MODELING as (i32) { + if value != 0u32 && (value != 1u32) { + return 0i32; + } + params.disable_literal_context_modeling = if !!!(value == 0) { 1i32 } else { 0i32 }; + return 1i32; + } + if p as (i32) == BrotliEncoderParameter::BROTLI_PARAM_SIZE_HINT as (i32) { + params.size_hint = value as (usize); + return 1i32; + } + if p as (i32) == BrotliEncoderParameter::BROTLI_PARAM_LARGE_WINDOW as (i32) { + params.large_window = value != 0; + return 1i32; + } + if p as (i32) == BrotliEncoderParameter::BROTLI_PARAM_AVOID_DISTANCE_PREFIX_SEARCH as (i32) { + params.avoid_distance_prefix_search = value != 0; + return 1i32; + } + if p as (i32) == BrotliEncoderParameter::BROTLI_PARAM_CATABLE as (i32) { + params.catable = value != 0; + if !params.appendable { + params.appendable = value != 0; + } + params.use_dictionary = (value == 0); + return 1i32; + } + if p as (i32) == BrotliEncoderParameter::BROTLI_PARAM_APPENDABLE as (i32) { + params.appendable = value != 0; + return 1i32; + } + if p as (i32) == BrotliEncoderParameter::BROTLI_PARAM_MAGIC_NUMBER as (i32) { + params.magic_number = value != 0; + return 1i32; + } + if p as (i32) == BrotliEncoderParameter::BROTLI_PARAM_FAVOR_EFFICIENCY as (i32) { + params.favor_cpu_efficiency = value != 0; + return 1i32; + } + 0i32 +} + +pub fn BrotliEncoderSetParameter<Alloc: BrotliAlloc> + (state: &mut BrotliEncoderStateStruct<Alloc>, + p: BrotliEncoderParameter, + value: u32) + -> i32 { + if (*state).is_initialized_ { + return 0i32; + } + set_parameter(&mut state.params, p, value) +} +/* "Large Window Brotli" */ +pub const BROTLI_LARGE_MAX_DISTANCE_BITS: u32 = 62; +pub const BROTLI_LARGE_MIN_WBITS: u32 = 10; +pub const BROTLI_LARGE_MAX_WBITS: u32 = 30; + +pub const BROTLI_MAX_DISTANCE_BITS:u32 = 24; +pub const BROTLI_MAX_WINDOW_BITS:usize = BROTLI_MAX_DISTANCE_BITS as usize; +pub const BROTLI_MAX_DISTANCE:usize = 0x3FFFFFC; +pub const BROTLI_MAX_ALLOWED_DISTANCE:usize = 0x7FFFFFC; +pub const BROTLI_NUM_DISTANCE_SHORT_CODES:u32 = 16; +pub fn BROTLI_DISTANCE_ALPHABET_SIZE(NPOSTFIX: u32, NDIRECT:u32, MAXNBITS: u32) -> u32 { + BROTLI_NUM_DISTANCE_SHORT_CODES + (NDIRECT) + + ((MAXNBITS) << ((NPOSTFIX) + 1)) +} + +//#define BROTLI_NUM_DISTANCE_SYMBOLS \ +// BROTLI_DISTANCE_ALPHABET_SIZE( \ +// BROTLI_MAX_NDIRECT, BROTLI_MAX_NPOSTFIX, BROTLI_LARGE_MAX_DISTANCE_BITS) + +pub const BROTLI_NUM_DISTANCE_SYMBOLS:usize = 1128; + +pub fn BrotliEncoderInitParams() -> BrotliEncoderParams { + return BrotliEncoderParams { + dist: BrotliDistanceParams { + distance_postfix_bits:0, + num_direct_distance_codes:0, + alphabet_size: BROTLI_DISTANCE_ALPHABET_SIZE(0, 0, BROTLI_MAX_DISTANCE_BITS), + max_distance: BROTLI_MAX_DISTANCE, + }, + mode: BrotliEncoderMode::BROTLI_MODE_GENERIC, + log_meta_block: false, + large_window:false, + avoid_distance_prefix_search:false, + quality: 11, + q9_5: false, + lgwin: 22i32, + lgblock: 0i32, + size_hint: 0usize, + disable_literal_context_modeling: 0i32, + stride_detection_quality: 0, + high_entropy_detection_quality: 0, + cdf_adaptation_detection: 0, + prior_bitmask_detection: 0, + literal_adaptation: [(0,0);4], + catable: false, + use_dictionary: true, + appendable: false, + magic_number: false, + favor_cpu_efficiency:false, + hasher: BrotliHasherParams { + type_: 6, + block_bits: 9 - 1, + bucket_bits: 15, + hash_len: 5, + num_last_distances_to_check: 16, + literal_byte_score: 0, + }, + }; +} + +fn ExtendLastCommand<Alloc:BrotliAlloc>( + s: &mut BrotliEncoderStateStruct<Alloc>, + bytes: &mut u32, + wrapped_last_processed_pos: &mut u32 +) { + let last_command = &mut s.commands_.slice_mut()[s.num_commands_ - 1]; + + let mask = s.ringbuffer_.mask_; + let max_backward_distance:u64 = (1u64 << s.params.lgwin) - BROTLI_WINDOW_GAP as u64; + let last_copy_len = u64::from(last_command.copy_len_) & 0x1ffffff; + let last_processed_pos:u64 = s.last_processed_pos_ - last_copy_len; + let max_distance:u64 = if last_processed_pos < max_backward_distance { + last_processed_pos + } else { + max_backward_distance + }; + let cmd_dist:u64 = s.dist_cache_[0] as u64; + let distance_code:u32 = super::command::CommandRestoreDistanceCode(last_command, &s.params.dist); + if (distance_code < BROTLI_NUM_DISTANCE_SHORT_CODES || + distance_code as u64 - (BROTLI_NUM_DISTANCE_SHORT_CODES - 1) as u64 == cmd_dist) { + if (cmd_dist <= max_distance) { + while (*bytes != 0 && + s.ringbuffer_.data_mo.slice()[s.ringbuffer_.buffer_index + (*wrapped_last_processed_pos as usize & mask as usize)] == + s.ringbuffer_.data_mo.slice()[s.ringbuffer_.buffer_index + (((*wrapped_last_processed_pos as usize).wrapping_sub(cmd_dist as usize)) & mask as usize)]) { + last_command.copy_len_+=1; + (*bytes)-=1; + (*wrapped_last_processed_pos)+=1; + } + } + /* The copy length is at most the metablock size, and thus expressible. */ + GetLengthCode(last_command.insert_len_ as usize, + ((last_command.copy_len_ & 0x1FFFFFF) as i32 + + (last_command.copy_len_ >> 25) as i32) as usize, + ((last_command.dist_prefix_ & 0x3FF) == 0) as i32, + &mut last_command.cmd_prefix_); + } +} + + +fn RingBufferInit<AllocU8: alloc::Allocator<u8>>() -> RingBuffer<AllocU8> { + return RingBuffer { + size_: 0, + mask_: 0, // 0xff?? + tail_size_: 0, + total_size_: 0, + + cur_size_: 0, + pos_: 0, + data_mo: AllocU8::AllocatedMemory::default(), + buffer_index: 0usize, + }; +} + +pub fn BrotliEncoderCreateInstance<Alloc: BrotliAlloc> + (m8: Alloc) + -> BrotliEncoderStateStruct<Alloc> { + let cache: [i32; 16] = [4, 11, 15, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]; + BrotliEncoderStateStruct::<Alloc> { + params: BrotliEncoderInitParams(), + input_pos_: 0, + num_commands_: 0usize, + num_literals_: 0usize, + last_insert_len_: 0usize, + last_flush_pos_: 0, + last_processed_pos_: 0, + prev_byte_: 0i32 as (u8), + prev_byte2_: 0i32 as (u8), + storage_size_: 0usize, + storage_: <Alloc as Allocator<u8>>::AllocatedMemory::default(), + hasher_: UnionHasher::<Alloc>::default(), + large_table_: <Alloc as Allocator<i32>>::AllocatedMemory::default(), +// large_table_size_: 0usize, + cmd_code_numbits_: 0usize, + command_buf_: <Alloc as Allocator<u32>>::AllocatedMemory::default(), + literal_buf_: <Alloc as Allocator<u8>>::AllocatedMemory::default(), + next_out_: NextOut::None, + available_out_: 0usize, + total_out_: 0u64, + is_first_mb: IsFirst::NothingWritten, + stream_state_: BrotliEncoderStreamState::BROTLI_STREAM_PROCESSING, + is_last_block_emitted_: false, + is_initialized_: false, + ringbuffer_: RingBufferInit(), + commands_: <Alloc as Allocator<Command>>::AllocatedMemory::default(), + cmd_alloc_size_: 0usize, + dist_cache_: cache, + saved_dist_cache_: [cache[0], cache[1], cache[2], cache[3]], + cmd_bits_: [0; 128], + cmd_depths_: [0; 128], + last_bytes_: 0, + last_bytes_bits_: 0, + cmd_code_: [0; 512], + m8: m8, + remaining_metadata_bytes_: 0, + small_table_: [0; 1024], + tiny_buf_: [0; 16], + literal_scratch_space: HistogramLiteral::make_nnz_storage(), + command_scratch_space: HistogramCommand::make_nnz_storage(), + distance_scratch_space: HistogramDistance::make_nnz_storage(), + recoder_state: RecoderState::new(), + custom_dictionary: false, + } +} + +fn RingBufferFree<AllocU8: alloc::Allocator<u8>>(m: &mut AllocU8, + rb: &mut RingBuffer<AllocU8>) { + m.free_cell(core::mem::replace(&mut rb.data_mo, AllocU8::AllocatedMemory::default())); +} +fn DestroyHasher<Alloc:alloc::Allocator<u16> + alloc::Allocator<u32>>( +m16: &mut Alloc, handle: &mut UnionHasher<Alloc>){ + handle.free(m16); +} +/* +fn DestroyHasher<AllocU16:alloc::Allocator<u16>, AllocU32:alloc::Allocator<u32>>( +m16: &mut AllocU16, m32:&mut AllocU32, handle: &mut UnionHasher<AllocU16, AllocU32>){ + match handle { + &mut UnionHasher::H2(ref mut hasher) => { + m32.free_cell(core::mem::replace(&mut hasher.buckets_.buckets_, <Alloc as Allocator<u32>>::AllocatedMemory::default())); + } + &mut UnionHasher::H3(ref mut hasher) => { + m32.free_cell(core::mem::replace(&mut hasher.buckets_.buckets_, <Alloc as Allocator<u32>>::AllocatedMemory::default())); + } + &mut UnionHasher::H4(ref mut hasher) => { + m32.free_cell(core::mem::replace(&mut hasher.buckets_.buckets_, <Alloc as Allocator<u32>>::AllocatedMemory::default())); + } + &mut UnionHasher::H54(ref mut hasher) => { + m32.free_cell(core::mem::replace(&mut hasher.buckets_.buckets_, <Alloc as Allocator<u32>>::AllocatedMemory::default())); + } + &mut UnionHasher::H5(ref mut hasher) => { + m16.free_cell(core::mem::replace(&mut hasher.num, AllocU16::AllocatedMemory::default())); + m32.free_cell(core::mem::replace(&mut hasher.buckets, <Alloc as Allocator<u32>>::AllocatedMemory::default())); + } + &mut UnionHasher::H6(ref mut hasher) => { + m16.free_cell(core::mem::replace(&mut hasher.num, AllocU16::AllocatedMemory::default())); + m32.free_cell(core::mem::replace(&mut hasher.buckets, <Alloc as Allocator<u32>>::AllocatedMemory::default())); + } + &mut UnionHasher::H9(ref mut hasher) => { + m16.free_cell(core::mem::replace(&mut hasher.num_, AllocU16::AllocatedMemory::default())); + m32.free_cell(core::mem::replace(&mut hasher.buckets_, <Alloc as Allocator<u32>>::AllocatedMemory::default())); + } + _ => {} + } + *handle = UnionHasher::<AllocU16, AllocU32>::default(); +} +*/ + +fn BrotliEncoderCleanupState<Alloc:BrotliAlloc> + (s: &mut BrotliEncoderStateStruct<Alloc>) { + { + <Alloc as Allocator<u8>>::free_cell(&mut s.m8, core::mem::replace(&mut (*s).storage_, + <Alloc as Allocator<u8>>::AllocatedMemory::default())); + } + { + <Alloc as Allocator<Command>>::free_cell(&mut s.m8, core::mem::replace(&mut (*s).commands_, + <Alloc as Allocator<Command>>::AllocatedMemory::default())); + } + RingBufferFree(&mut s.m8, &mut (*s).ringbuffer_); + DestroyHasher(&mut s.m8, &mut (*s).hasher_); + { + <Alloc as Allocator<i32>>::free_cell(&mut s.m8, core::mem::replace(&mut (*s).large_table_, + <Alloc as Allocator<i32>>::AllocatedMemory::default())); + } + { + <Alloc as Allocator<u32>>::free_cell(&mut s.m8, core::mem::replace(&mut (*s).command_buf_, + <Alloc as Allocator<u32>>::AllocatedMemory::default())); + } + { + <Alloc as Allocator<u8>>::free_cell(&mut s.m8, core::mem::replace(&mut (*s).literal_buf_, <Alloc as Allocator<u8>>::AllocatedMemory::default())); + } +} + +pub fn BrotliEncoderDestroyInstance<Alloc: BrotliAlloc> + (s: &mut BrotliEncoderStateStruct<Alloc>) { + BrotliEncoderCleanupState(s); +} + +fn brotli_min_int(a: i32, b: i32) -> i32 { + if a < b { a } else { b } +} + +fn brotli_max_int(a: i32, b: i32) -> i32 { + if a > b { a } else { b } +} + +#[cfg(not(feature="disallow_large_window_size"))] +fn check_large_window_ok() -> bool { + true +} +#[cfg(feature="disallow_large_window_size")] +fn check_large_window_ok() -> bool { + false +} + + +pub fn SanitizeParams(params: &mut BrotliEncoderParams) { + (*params).quality = brotli_min_int(11i32, brotli_max_int(0i32, (*params).quality)); + if (*params).lgwin < 10i32 { + (*params).lgwin = 10i32; + } else if (*params).lgwin > 24i32 { + if params.large_window && check_large_window_ok() { + if (*params).lgwin > 30i32 { + (*params).lgwin = 30i32; + } + } else { + (*params).lgwin = 24i32; + } + } + if params.catable { + params.appendable = true; + } +} + +fn ComputeLgBlock(params: &BrotliEncoderParams) -> i32 { + let mut lgblock: i32 = (*params).lgblock; + if (*params).quality == 0i32 || (*params).quality == 1i32 { + lgblock = (*params).lgwin; + } else if (*params).quality < 4i32 { + lgblock = 14i32; + } else if lgblock == 0i32 { + lgblock = 16i32; + if (*params).quality >= 9i32 && ((*params).lgwin > lgblock) { + lgblock = brotli_min_int(18i32, (*params).lgwin); + } + } else { + lgblock = brotli_min_int(24i32, brotli_max_int(16i32, lgblock)); + } + lgblock +} + +fn ComputeRbBits(params: &BrotliEncoderParams) -> i32 { + 1i32 + brotli_max_int((*params).lgwin, (*params).lgblock) +} + +fn RingBufferSetup<AllocU8: alloc::Allocator<u8>>(params: &BrotliEncoderParams, + rb: &mut RingBuffer<AllocU8>) { + let window_bits: i32 = ComputeRbBits(params); + let tail_bits: i32 = (*params).lgblock; + *(&mut (*rb).size_) = 1u32 << window_bits; + *(&mut (*rb).mask_) = (1u32 << window_bits).wrapping_sub(1u32); + *(&mut (*rb).tail_size_) = 1u32 << tail_bits; + *(&mut (*rb).total_size_) = (*rb).size_.wrapping_add((*rb).tail_size_); +} + +fn EncodeWindowBits(lgwin: i32, large_window: bool, last_bytes: &mut u16, last_bytes_bits: &mut u8) { + if large_window { + *last_bytes = (((lgwin & 0x3F) << 8) | 0x11) as u16; + *last_bytes_bits = 14; + } else { + if lgwin == 16i32 { + *last_bytes = 0i32 as (u16); + *last_bytes_bits = 1i32 as (u8); + } else if lgwin == 17i32 { + *last_bytes = 1i32 as (u16); + *last_bytes_bits = 7i32 as (u8); + } else if lgwin > 17i32 { + *last_bytes = (lgwin - 17i32 << 1i32 | 1i32) as (u16); + *last_bytes_bits = 4i32 as (u8); + } else { + *last_bytes = (lgwin - 8i32 << 4i32 | 1i32) as (u16); + *last_bytes_bits = 7i32 as (u8); + } + } +} + +fn InitCommandPrefixCodes(cmd_depths: &mut [u8], + cmd_bits: &mut [u16], + cmd_code: &mut [u8], + cmd_code_numbits: &mut usize) { + static kDefaultCommandDepths: [u8; 128] = [ + 0,4,4,5,6,6,7,7,7,7,7,8,8,8,8,8,0,0,0,4,4,4,4,4,5,5,6,6,6,6,7,7,7,7, + 10,10,10,10,10,10,0,4,4,5,5,5,6,6,7,8,8,9,10,10,10,10,10,10,10,10,10,10,10,10, + 5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,6,6,6,6,6,6,5,5,5,5,5,5,4,4,4,4,4,4,4,5,5,5,5,5,5, + 6,6,7,7,7,8,10,12,12,12,12,12,12,12,12,12,12,12,12,0,0,0,0]; + static kDefaultCommandBits: [u16; 128] = [ + 0,0,8,9,3,35,7,71,39,103,23,47,175,111,239,31,0,0,0,4,12,2,10,6,13,29, + 11,43,27,59,87,55,15,79,319,831,191,703,447,959,0,14,1,25,5,21,19,51, + 119,159,95,223,479,991,63,575,127,639,383,895,255,767,511,1023,14, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,27,59,7,39,23,55,30,1,17,9,25,5,0,8,4,12, + 2,10,6,21,13,29,3,19,11,15,47,31,95,63,127,255,767,2815,1791,3839, + 511,2559,1535,3583,1023,3071,2047,4095,0,0,0,0]; + static kDefaultCommandCode: [u8; 57] = [ + 0xff,0x77,0xd5,0xbf,0xe7,0xde,0xea,0x9e,0x51,0x5d,0xde,0xc6,0x70,0x57, + 0xbc,0x58,0x58,0x58,0xd8,0xd8,0x58,0xd5,0xcb,0x8c,0xea,0xe0,0xc3,0x87, + 0x1f,0x83,0xc1,0x60,0x1c,0x67,0xb2,0xaa,0x6,0x83,0xc1,0x60,0x30,0x18, + 0xcc,0xa1,0xce,0x88,0x54,0x94,0x46,0xe1,0xb0,0xd0,0x4e,0xb2,0xf7,0x4,0x0]; + static kDefaultCommandCodeNumBits: usize = 448usize; + cmd_depths[..].clone_from_slice(&kDefaultCommandDepths[..]); + cmd_bits[..].clone_from_slice(&kDefaultCommandBits[..]); + cmd_code[..kDefaultCommandCode.len()].clone_from_slice(&kDefaultCommandCode[..]); + *cmd_code_numbits = kDefaultCommandCodeNumBits; +} + +fn EnsureInitialized<Alloc: BrotliAlloc> + (s: &mut BrotliEncoderStateStruct<Alloc>) + -> i32 { + if (*s).is_initialized_ { + return 1i32; + } + SanitizeParams(&mut (*s).params); + (*s).params.lgblock = ComputeLgBlock(&mut (*s).params); + ChooseDistanceParams(&mut s.params); + (*s).remaining_metadata_bytes_ = !(0u32); + RingBufferSetup(&mut (*s).params, &mut (*s).ringbuffer_); + { + let mut lgwin: i32 = (*s).params.lgwin; + if (*s).params.quality == 0i32 || (*s).params.quality == 1i32 { + lgwin = brotli_max_int(lgwin, 18i32); + } + EncodeWindowBits(lgwin, s.params.large_window, &mut (*s).last_bytes_, &mut (*s).last_bytes_bits_); + } + if (*s).params.quality == 0i32 { + InitCommandPrefixCodes(&mut (*s).cmd_depths_[..], + &mut (*s).cmd_bits_[..], + &mut (*s).cmd_code_[..], + &mut (*s).cmd_code_numbits_); + } + if s.params.catable { + // if we want to properly concatenate, then we need to ignore any distances + // this value 0x7ffffff0 was chosen to be larger than max_distance + gap + // but small enough so that +/-3 will not overflow (due to distance modifications) + for item in s.dist_cache_.iter_mut() { + *item = 0x7ffffff0; + } + for item in s.saved_dist_cache_.iter_mut() { + *item = 0x7ffffff0; + } + } + (*s).is_initialized_ = true; + 1i32 +} + +fn RingBufferInitBuffer<AllocU8: alloc::Allocator<u8>>(m: &mut AllocU8, + buflen: u32, + rb: &mut RingBuffer<AllocU8>) { + static kSlackForEightByteHashingEverywhere: usize = 7usize; + let mut new_data = + m.alloc_cell(((2u32).wrapping_add(buflen) as (usize)) + .wrapping_add(kSlackForEightByteHashingEverywhere)); + let mut i: usize; + if (*rb).data_mo.slice().len() != 0 { + let lim: usize = ((2u32).wrapping_add((*rb).cur_size_) as (usize)) + .wrapping_add(kSlackForEightByteHashingEverywhere); + new_data.slice_mut()[..lim].clone_from_slice(&(*rb).data_mo.slice()[..lim]); + m.free_cell(core::mem::replace(&mut (*rb).data_mo, AllocU8::AllocatedMemory::default())); + } + let _ = core::mem::replace(&mut (*rb).data_mo, new_data); + (*rb).cur_size_ = buflen; + (*rb).buffer_index = 2usize; + (*rb).data_mo.slice_mut()[((*rb).buffer_index.wrapping_sub(2usize))] = 0; + (*rb).data_mo.slice_mut()[((*rb).buffer_index.wrapping_sub(1usize))] = 0; + i = 0usize; + while i < kSlackForEightByteHashingEverywhere { + { + (*rb).data_mo.slice_mut()[((*rb) + .buffer_index + .wrapping_add((*rb).cur_size_ as (usize)) + .wrapping_add(i) as (usize))] = 0; + } + i = i.wrapping_add(1 as (usize)); + } +} + + +fn RingBufferWriteTail<AllocU8: alloc::Allocator<u8>>(bytes: &[u8], + n: usize, + rb: &mut RingBuffer<AllocU8>) { + let masked_pos: usize = ((*rb).pos_ & (*rb).mask_) as (usize); + if masked_pos < (*rb).tail_size_ as (usize) { + let p: usize = ((*rb).size_ as (usize)).wrapping_add(masked_pos); + let begin = ((*rb).buffer_index.wrapping_add(p) as (usize)); + let lim = brotli_min_size_t(n, ((*rb).tail_size_ as (usize)).wrapping_sub(masked_pos)); + (*rb).data_mo.slice_mut()[begin..(begin + lim)].clone_from_slice(&bytes[..lim]); + } +} + +fn RingBufferWrite<AllocU8: alloc::Allocator<u8>>(m: &mut AllocU8, + bytes: &[u8], + n: usize, + rb: &mut RingBuffer<AllocU8>) { + if (*rb).pos_ == 0u32 && (n < (*rb).tail_size_ as (usize)) { + (*rb).pos_ = n as (u32); + RingBufferInitBuffer(m, (*rb).pos_, rb); + (*rb).data_mo.slice_mut()[((*rb).buffer_index as (usize))..(((*rb).buffer_index as (usize)) + n)] + .clone_from_slice(&bytes[..n]); + return; + } + if (*rb).cur_size_ < (*rb).total_size_ { + RingBufferInitBuffer(m, (*rb).total_size_, rb); + if !(0i32 == 0) { + return; + } + (*rb).data_mo.slice_mut()[((*rb) + .buffer_index + .wrapping_add((*rb).size_ as (usize)) + .wrapping_sub(2usize) as (usize))] = 0i32 as (u8); + (*rb).data_mo.slice_mut()[((*rb) + .buffer_index + .wrapping_add((*rb).size_ as (usize)) + .wrapping_sub(1usize) as (usize))] = 0i32 as (u8); + } + { + let masked_pos: usize = ((*rb).pos_ & (*rb).mask_) as (usize); + RingBufferWriteTail(bytes, n, rb); + if masked_pos.wrapping_add(n) <= (*rb).size_ as (usize) { + // a single write fits + let start = ((*rb).buffer_index.wrapping_add(masked_pos) as (usize)); + (*rb).data_mo.slice_mut()[start..(start + n)].clone_from_slice(&bytes[..n]); + } else { + { + let start = ((*rb).buffer_index.wrapping_add(masked_pos) as (usize)); + let mid = brotli_min_size_t(n, ((*rb).total_size_ as (usize)).wrapping_sub(masked_pos)); + (*rb).data_mo.slice_mut()[start..(start + mid)].clone_from_slice(&bytes[..mid]); + } + let xstart = ((*rb).buffer_index.wrapping_add(0usize) as (usize)); + let size = n.wrapping_sub(((*rb).size_ as (usize)).wrapping_sub(masked_pos)); + let bytes_start = (((*rb).size_ as (usize)).wrapping_sub(masked_pos) as (usize)); + (*rb).data_mo.slice_mut()[xstart..(xstart + size)].clone_from_slice(&bytes[bytes_start.. + (bytes_start + + size)]); + } + } + let data_2 = (*rb).data_mo.slice()[((*rb) + .buffer_index + .wrapping_add((*rb).size_ as (usize)) + .wrapping_sub(2usize) as (usize))]; + (*rb).data_mo.slice_mut()[((*rb).buffer_index.wrapping_sub(2usize) as (usize))] = data_2; + let data_1 = (*rb).data_mo.slice()[((*rb) + .buffer_index + .wrapping_add((*rb).size_ as (usize)) + .wrapping_sub(1usize) as (usize))]; + (*rb).data_mo.slice_mut()[((*rb).buffer_index.wrapping_sub(1usize) as (usize))] = data_1; + (*rb).pos_ = (*rb).pos_.wrapping_add(n as (u32)); + if (*rb).pos_ > 1u32 << 30i32 { + (*rb).pos_ = (*rb).pos_ & (1u32 << 30i32).wrapping_sub(1u32) | 1u32 << 30i32; + } +} + +fn CopyInputToRingBuffer<Alloc: BrotliAlloc> + (s: &mut BrotliEncoderStateStruct<Alloc>, + input_size: usize, + input_buffer: &[u8]) { + if EnsureInitialized(s) == 0 { + return; + } + RingBufferWrite(&mut s.m8, input_buffer, input_size, &mut s.ringbuffer_); + if !(0i32 == 0) { + return; + } + (*s).input_pos_ = (*s).input_pos_.wrapping_add(input_size as u64); + if (s.ringbuffer_).pos_ <= (s.ringbuffer_).mask_ { + let start = ((s.ringbuffer_).buffer_index.wrapping_add((s.ringbuffer_).pos_ as (usize)) as + (usize)); + for item in (s.ringbuffer_).data_mo.slice_mut()[start..(start + 7)].iter_mut() { + *item = 0; + } + } +} + + +fn ChooseHasher(params: &mut BrotliEncoderParams) { + let hparams = &mut params.hasher; + if (*params).quality >= 10 && !params.q9_5{ + (*hparams).type_ = 10; + } else if (*params).quality == 10 { // we are using quality 10 as a proxy for "9.5" + (*hparams).type_ = 9; + (*hparams).num_last_distances_to_check = H9_NUM_LAST_DISTANCES_TO_CHECK as i32; + (*hparams).block_bits = H9_BLOCK_BITS as i32; + (*hparams).bucket_bits = H9_BUCKET_BITS as i32; + (*hparams).hash_len = 4; + } else if (*params).quality == 9 { + (*hparams).type_ = 9; + (*hparams).num_last_distances_to_check = H9_NUM_LAST_DISTANCES_TO_CHECK as i32; + (*hparams).block_bits = H9_BLOCK_BITS as i32; + (*hparams).bucket_bits = H9_BUCKET_BITS as i32; + (*hparams).hash_len = 4; + } else if (*params).quality == 4 && ((*params).size_hint >= (1i32 << 20i32) as (usize)) { + (*hparams).type_ = 54i32; + } else if (*params).quality < 5 { + (*hparams).type_ = (*params).quality; + } else if (*params).lgwin <= 16 { + (*hparams).type_ = if (*params).quality < 7 { + 40i32 + } else if (*params).quality < 9 { + 41i32 + } else { + 42i32 + }; + } else if ((params.q9_5 && (*params).size_hint > (1usize << 20i32)) + || (*params).size_hint > (1usize << 22i32)) && ((*params).lgwin >= 19i32) { + (*hparams).type_ = 6i32; + (*hparams).block_bits = core::cmp::min((*params).quality - 1, 9); + (*hparams).bucket_bits = 15i32; + (*hparams).hash_len = 5i32; + (*hparams).num_last_distances_to_check = if (*params).quality < 7 { + 4i32 + } else if (*params).quality < 9 { + 10i32 + } else { + 16i32 + }; + } else { + (*hparams).type_ = 5i32; + (*hparams).block_bits = core::cmp::min((*params).quality - 1, 9); + (*hparams).bucket_bits = if (*params).quality < 7 && (*params).size_hint <= (1usize << 20i32) { + 14i32 + } else { + 15i32 + }; + (*hparams).num_last_distances_to_check = if (*params).quality < 7 { + 4i32 + } else if (*params).quality < 9 { + 10i32 + } else { + 16i32 + }; + } +} + +fn InitializeH2<AllocU32:alloc::Allocator<u32>>(m32: &mut AllocU32, params : &BrotliEncoderParams) -> BasicHasher<H2Sub<AllocU32>> { + BasicHasher { + GetHasherCommon:Struct1{ + params:params.hasher, + is_prepared_:1, + dict_num_lookups:0, + dict_num_matches:0, + }, + buckets_:H2Sub{buckets_:m32.alloc_cell(65537 + 8)}, + h9_opts: super::backward_references::H9Opts::new(¶ms.hasher), + } +} +fn InitializeH3<AllocU32:alloc::Allocator<u32>>(m32: &mut AllocU32, params : &BrotliEncoderParams) -> BasicHasher<H3Sub<AllocU32>> { + BasicHasher { + GetHasherCommon:Struct1{ + params:params.hasher, + is_prepared_:1, + dict_num_lookups:0, + dict_num_matches:0, + }, + buckets_:H3Sub{buckets_:m32.alloc_cell(65538 + 8)}, + h9_opts: super::backward_references::H9Opts::new(¶ms.hasher), + } +} +fn InitializeH4<AllocU32:alloc::Allocator<u32>>(m32: &mut AllocU32, params : &BrotliEncoderParams) -> BasicHasher<H4Sub<AllocU32>> { + BasicHasher { + GetHasherCommon:Struct1{ + params:params.hasher, + is_prepared_:1, + dict_num_lookups:0, + dict_num_matches:0, + }, + buckets_:H4Sub{buckets_:m32.alloc_cell(131072 + 8)}, + h9_opts: super::backward_references::H9Opts::new(¶ms.hasher), + } +} +fn InitializeH54<AllocU32:alloc::Allocator<u32>>(m32: &mut AllocU32, params : &BrotliEncoderParams) -> BasicHasher<H54Sub<AllocU32>> { + BasicHasher { + GetHasherCommon:Struct1{ + params:params.hasher, + is_prepared_:1, + dict_num_lookups:0, + dict_num_matches:0, + }, + buckets_:H54Sub{buckets_:m32.alloc_cell(1048580 + 8)}, + h9_opts: super::backward_references::H9Opts::new(¶ms.hasher), + } +} + +fn InitializeH9<Alloc:alloc::Allocator<u16> + alloc::Allocator<u32>>(m16: &mut Alloc, + params : &BrotliEncoderParams) -> H9<Alloc> { + H9 { + dict_search_stats_:Struct1{ + params:params.hasher, + is_prepared_:1, + dict_num_lookups:0, + dict_num_matches:0, + }, + num_:<Alloc as Allocator<u16>>::alloc_cell(m16, 1<<H9_BUCKET_BITS), + buckets_:<Alloc as Allocator<u32>>::alloc_cell(m16, H9_BLOCK_SIZE<<H9_BUCKET_BITS), + h9_opts: super::backward_references::H9Opts::new(¶ms.hasher), + } +} + +fn InitializeH5<Alloc: alloc::Allocator<u16> + alloc::Allocator<u32>> + (m16: &mut Alloc, + params: &BrotliEncoderParams, +) -> UnionHasher<Alloc> { + let block_size = 1u64 << params.hasher.block_bits; + let bucket_size = 1u64 << params.hasher.bucket_bits; + let buckets : <Alloc as Allocator<u32>>::AllocatedMemory = <Alloc as Allocator<u32>>::alloc_cell(m16, (bucket_size * block_size) as usize); + let num : <Alloc as Allocator<u16>>::AllocatedMemory = <Alloc as Allocator<u16>>::alloc_cell(m16, bucket_size as usize); + + if params.hasher.block_bits == (HQ5Sub{}).block_bits() && (1<<params.hasher.bucket_bits) == (HQ5Sub{}).bucket_size() { + return UnionHasher::H5q5(AdvHasher { + buckets: buckets, + h9_opts: super::backward_references::H9Opts::new(¶ms.hasher), + num: num, + GetHasherCommon: Struct1 { + params: params.hasher, + is_prepared_: 1, + dict_num_lookups: 0, + dict_num_matches: 0, + }, + specialization: HQ5Sub {} + }) + } + if params.hasher.block_bits == (HQ7Sub{}).block_bits() && (1 <<params.hasher.bucket_bits) == (HQ7Sub{}).bucket_size() { + return UnionHasher::H5q7(AdvHasher { + buckets: buckets, + h9_opts: super::backward_references::H9Opts::new(¶ms.hasher), + num: num, + GetHasherCommon: Struct1 { + params: params.hasher, + is_prepared_: 1, + dict_num_lookups: 0, + dict_num_matches: 0, + }, + specialization: HQ7Sub {} + }) + } + UnionHasher::H5(AdvHasher { + buckets: buckets, + h9_opts: super::backward_references::H9Opts::new(¶ms.hasher), + num: num, + GetHasherCommon: Struct1 { + params: params.hasher, + is_prepared_: 1, + dict_num_lookups: 0, + dict_num_matches: 0, + }, + specialization: H5Sub { + hash_shift_: 32i32 - params.hasher.bucket_bits, + bucket_size_: bucket_size as u32, + block_bits_: params.hasher.block_bits as i32, + block_mask_: block_size.wrapping_sub(1u64) as u32, + } + }) +} +fn InitializeH6<Alloc: alloc::Allocator<u16> + alloc::Allocator<u32>> + (m16: &mut Alloc, + params: &BrotliEncoderParams) + -> UnionHasher<Alloc> { + let block_size = 1u64 << params.hasher.block_bits; + let bucket_size = 1u64 << params.hasher.bucket_bits; + let buckets: <Alloc as Allocator<u32>>::AllocatedMemory = <Alloc as Allocator<u32>>::alloc_cell(m16, (bucket_size * block_size) as usize); + let num: <Alloc as Allocator<u16>>::AllocatedMemory = <Alloc as Allocator<u16>>::alloc_cell(m16, bucket_size as usize); + UnionHasher::H6(AdvHasher { + buckets: buckets, + num: num, + h9_opts: super::backward_references::H9Opts::new(¶ms.hasher), + GetHasherCommon: Struct1 { + params: params.hasher, + is_prepared_: 1, + dict_num_lookups: 0, + dict_num_matches: 0, + }, + specialization: H6Sub { + bucket_size_: 1u32 << params.hasher.bucket_bits, + block_bits_: params.hasher.block_bits, + block_mask_: block_size.wrapping_sub(1) as u32, + hash_mask: 0xffffffffffffffffu64 >> 64i32 - 8i32 * params.hasher.hash_len, + hash_shift_: 64i32 - params.hasher.bucket_bits, + }, + }) +} + +fn BrotliMakeHasher<Alloc: alloc::Allocator<u16> + alloc::Allocator<u32>> + (m: &mut Alloc, + params: &BrotliEncoderParams) + -> UnionHasher<Alloc> { + let hasher_type: i32 = params.hasher.type_; + if hasher_type == 2i32 { + return UnionHasher::H2(InitializeH2(m, params)); + } + if hasher_type == 3i32 { + return UnionHasher::H3(InitializeH3(m, params)); + } + if hasher_type == 4i32 { + return UnionHasher::H4(InitializeH4(m, params)); + } + if hasher_type == 5i32 { + return InitializeH5(m, params); + } + if hasher_type == 6i32 { + return InitializeH6(m, params); + } + if hasher_type == 9i32 { + return UnionHasher::H9(InitializeH9(m, params)); + } + /* + if hasher_type == 40i32 { + return InitializeH40(params); + } + if hasher_type == 41i32 { + return InitializeH41(params); + } + if hasher_type == 42i32 { + return InitializeH42(params); + } +*/ + if hasher_type == 54i32 { + return UnionHasher::H54(InitializeH54(m, params)); + } + if hasher_type == 10i32 { + return UnionHasher::H10(InitializeH10(m, false, params, 0)); + } + // since we don't support all of these, fall back to something sane + return InitializeH6(m, params); + +// return UnionHasher::Uninit; +} +fn HasherReset<Alloc:alloc::Allocator<u16> + alloc::Allocator<u32>,>(t: &mut UnionHasher<Alloc>){ + match t { + &mut UnionHasher::Uninit => {} + _ => (t.GetHasherCommon()).is_prepared_ = 0i32, + }; +} +fn GetHasherCommon<Alloc: alloc::Allocator<u16> + alloc::Allocator<u32>> + (t: &mut UnionHasher<Alloc>) + -> &mut Struct1 { + t.GetHasherCommon() +} + +pub fn HasherSetup<Alloc:alloc::Allocator<u16> + alloc::Allocator<u32>>(m16: &mut Alloc, + handle: &mut UnionHasher<Alloc>, + params: &mut BrotliEncoderParams, + data: &[u8], + position: usize, + input_size: usize, + is_last: i32){ + let one_shot: i32 = (position == 0usize && (is_last != 0)) as (i32); + let is_uninit = match (handle) { + &mut UnionHasher::Uninit => true, + _ => false, + }; + if is_uninit { + //let alloc_size: usize; + ChooseHasher(&mut (*params)); + //alloc_size = HasherSize(params, one_shot, input_size); + //xself = BrotliAllocate(m, alloc_size.wrapping_mul(::std::mem::size_of::<u8>())) + *handle = BrotliMakeHasher(m16, params); + handle.GetHasherCommon().params = (*params).hasher; + HasherReset(handle); // this sets everything to zero, unlike in C + handle.GetHasherCommon().is_prepared_ = 1; + } else { + match handle.Prepare(one_shot != 0, input_size, data) { + HowPrepared::ALREADY_PREPARED => {} + HowPrepared::NEWLY_PREPARED => { + if position == 0usize { + let common = handle.GetHasherCommon(); + (*common).dict_num_lookups = 0usize; + (*common).dict_num_matches = 0usize; + } + } + } + } +} + +fn HasherPrependCustomDictionary<Alloc: alloc::Allocator<u16> + alloc::Allocator<u32>> + (m: &mut Alloc, + handle: &mut UnionHasher<Alloc>, + params: &mut BrotliEncoderParams, + size: usize, + dict: &[u8]) { + HasherSetup(m, handle, params, dict, 0usize, size, 0i32); + match handle { + &mut UnionHasher::H2(ref mut hasher) => StoreLookaheadThenStore(hasher, size, dict), + &mut UnionHasher::H3(ref mut hasher) => StoreLookaheadThenStore(hasher, size, dict), + &mut UnionHasher::H4(ref mut hasher) => StoreLookaheadThenStore(hasher, size, dict), + &mut UnionHasher::H5(ref mut hasher) => StoreLookaheadThenStore(hasher, size, dict), + &mut UnionHasher::H5q7(ref mut hasher) => StoreLookaheadThenStore(hasher, size, dict), + &mut UnionHasher::H5q5(ref mut hasher) => StoreLookaheadThenStore(hasher, size, dict), + &mut UnionHasher::H6(ref mut hasher) => StoreLookaheadThenStore(hasher, size, dict), + &mut UnionHasher::H9(ref mut hasher) => StoreLookaheadThenStore(hasher, size, dict), + &mut UnionHasher::H54(ref mut hasher) => StoreLookaheadThenStore(hasher, size, dict), + &mut UnionHasher::H10(ref mut hasher) => StoreLookaheadThenStore(hasher, size, dict), + &mut UnionHasher::Uninit => panic!("Uninitialized"), + } +} + +pub fn BrotliEncoderSetCustomDictionary<Alloc: BrotliAlloc> + (s: &mut BrotliEncoderStateStruct<Alloc>, + size: usize, + dict: &[u8]) { + BrotliEncoderSetCustomDictionaryWithOptionalPrecomputedHasher(s, size, dict, UnionHasher::Uninit) +} + + +pub fn BrotliEncoderSetCustomDictionaryWithOptionalPrecomputedHasher<Alloc: BrotliAlloc> + (s: &mut BrotliEncoderStateStruct<Alloc>, + size: usize, + mut dict: &[u8], + opt_hasher: UnionHasher<Alloc>, +) { + let has_optional_hasher = if let UnionHasher::Uninit = opt_hasher { false } else {true}; + let max_dict_size: usize = (1usize << (*s).params.lgwin).wrapping_sub(16usize); + s.hasher_ = opt_hasher; + let mut dict_size: usize = size; + if EnsureInitialized(s) == 0 { + return; + } + if dict_size == 0usize || (*s).params.quality == 0i32 || (*s).params.quality == 1i32 || size <= 1 { + (*s).params.catable = true; // don't risk a too-short dictionary + (*s).params.appendable = true; // don't risk a too-short dictionary + return; + } + s.custom_dictionary = true; + if size > max_dict_size { + dict = &dict[(size.wrapping_sub(max_dict_size) as (usize))..]; + dict_size = max_dict_size; + } + CopyInputToRingBuffer(s, dict_size, dict); + (*s).last_flush_pos_ = dict_size as u64; + (*s).last_processed_pos_ = dict_size as u64; + if dict_size > 0 { + (*s).prev_byte_ = dict[(dict_size.wrapping_sub(1usize) as (usize))]; + } + if dict_size > 1usize { + (*s).prev_byte2_ = dict[(dict_size.wrapping_sub(2usize) as (usize))]; + } + let m16 = &mut s.m8; + if cfg!(debug_assertions) || !has_optional_hasher { + let mut orig_hasher = UnionHasher::Uninit; + if has_optional_hasher { + orig_hasher = core::mem::replace(&mut s.hasher_, UnionHasher::Uninit); + } + HasherPrependCustomDictionary(m16, + &mut (*s).hasher_, + &mut (*s).params, + dict_size, + dict); + if has_optional_hasher { + debug_assert!(orig_hasher == s.hasher_); + DestroyHasher(m16, &mut orig_hasher); + } + } +} +pub fn BrotliEncoderMaxCompressedSizeMulti(input_size: usize, num_threads: usize) -> usize { + BrotliEncoderMaxCompressedSize(input_size) + num_threads * 8 +} + +pub fn BrotliEncoderMaxCompressedSize(input_size: usize) -> usize { + let magic_size = 16usize; + let num_large_blocks: usize = input_size >> 14i32; + let tail: usize = input_size.wrapping_sub(num_large_blocks << 24i32); + let tail_overhead: usize = (if tail > (1i32 << 20i32) as (usize) { + 4i32 + } else { + 3i32 + }) as (usize); + let overhead: usize = (2usize) + .wrapping_add((4usize).wrapping_mul(num_large_blocks)) + .wrapping_add(tail_overhead) + .wrapping_add(1usize); + let result: usize = input_size.wrapping_add(overhead); + if input_size == 0usize { + return 1usize + magic_size; + } + if result < input_size { 0usize } else { result + magic_size } +} + +fn InitOrStitchToPreviousBlock<Alloc: alloc::Allocator<u16> + alloc::Allocator<u32>> + (m: &mut Alloc, + handle: &mut UnionHasher<Alloc>, + data: &[u8], + mask: usize, + params: &mut BrotliEncoderParams, + position: usize, + input_size: usize, + is_last: i32) { + HasherSetup(m, + handle, + params, + data, + position, + input_size, + is_last); + handle.StitchToPreviousBlock(input_size, position, data, mask); +} + +pub fn InitInsertCommand(xself: &mut Command, insertlen: usize) { + (*xself).insert_len_ = insertlen as (u32); + (*xself).copy_len_ = (4i32 << 25i32) as (u32); + (*xself).dist_extra_ = 0u32; + (*xself).dist_prefix_ = (1u16 << 10) | BROTLI_NUM_DISTANCE_SHORT_CODES as (u16); + GetLengthCode(insertlen, 4usize, 0i32, &mut (*xself).cmd_prefix_); +} + + + +fn ShouldCompress(data: &[u8], + mask: usize, + last_flush_pos: u64, + bytes: usize, + num_literals: usize, + num_commands: usize) + -> i32 { + if num_commands < (bytes >> 8i32).wrapping_add(2usize) { + if num_literals as (super::util::floatX) > 0.99 as super::util::floatX * bytes as (super::util::floatX) { + let mut literal_histo: [u32; 256] = + [0u32, 0u32, 0u32, 0u32, 0u32, 0u32, 0u32, 0u32, 0u32, 0u32, 0u32, 0u32, 0u32, 0u32, 0u32, + 0u32, 0u32, 0u32, 0u32, 0u32, 0u32, 0u32, 0u32, 0u32, 0u32, 0u32, 0u32, 0u32, 0u32, 0u32, + 0u32, 0u32, 0u32, 0u32, 0u32, 0u32, 0u32, 0u32, 0u32, 0u32, 0u32, 0u32, 0u32, 0u32, 0u32, + 0u32, 0u32, 0u32, 0u32, 0u32, 0u32, 0u32, 0u32, 0u32, 0u32, 0u32, 0u32, 0u32, 0u32, 0u32, + 0u32, 0u32, 0u32, 0u32, 0u32, 0u32, 0u32, 0u32, 0u32, 0u32, 0u32, 0u32, 0u32, 0u32, 0u32, + 0u32, 0u32, 0u32, 0u32, 0u32, 0u32, 0u32, 0u32, 0u32, 0u32, 0u32, 0u32, 0u32, 0u32, 0u32, + 0u32, 0u32, 0u32, 0u32, 0u32, 0u32, 0u32, 0u32, 0u32, 0u32, 0u32, 0u32, 0u32, 0u32, 0u32, + 0u32, 0u32, 0u32, 0u32, 0u32, 0u32, 0u32, 0u32, 0u32, 0u32, 0u32, 0u32, 0u32, 0u32, 0u32, + 0u32, 0u32, 0u32, 0u32, 0u32, 0u32, 0u32, 0u32, 0u32, 0u32, 0u32, 0u32, 0u32, 0u32, 0u32, + 0u32, 0u32, 0u32, 0u32, 0u32, 0u32, 0u32, 0u32, 0u32, 0u32, 0u32, 0u32, 0u32, 0u32, 0u32, + 0u32, 0u32, 0u32, 0u32, 0u32, 0u32, 0u32, 0u32, 0u32, 0u32, 0u32, 0u32, 0u32, 0u32, 0u32, + 0u32, 0u32, 0u32, 0u32, 0u32, 0u32, 0u32, 0u32, 0u32, 0u32, 0u32, 0u32, 0u32, 0u32, 0u32, + 0u32, 0u32, 0u32, 0u32, 0u32, 0u32, 0u32, 0u32, 0u32, 0u32, 0u32, 0u32, 0u32, 0u32, 0u32, + 0u32, 0u32, 0u32, 0u32, 0u32, 0u32, 0u32, 0u32, 0u32, 0u32, 0u32, 0u32, 0u32, 0u32, 0u32, + 0u32, 0u32, 0u32, 0u32, 0u32, 0u32, 0u32, 0u32, 0u32, 0u32, 0u32, 0u32, 0u32, 0u32, 0u32, + 0u32, 0u32, 0u32, 0u32, 0u32, 0u32, 0u32, 0u32, 0u32, 0u32, 0u32, 0u32, 0u32, 0u32, 0u32, + 0u32, 0u32, 0u32, 0u32, 0u32, 0u32, 0u32, 0u32, 0u32, 0u32, 0u32, 0u32, 0u32, 0u32, 0u32, + 0u32]; + static kSampleRate: u32 = 13u32; + static kMinEntropy: super::util::floatX = 7.92 as super::util::floatX; + let bit_cost_threshold: super::util::floatX = bytes as (super::util::floatX) * kMinEntropy / kSampleRate as (super::util::floatX); + let t: usize = bytes.wrapping_add(kSampleRate as (usize)) + .wrapping_sub(1usize) + .wrapping_div(kSampleRate as (usize)); + let mut pos: u32 = last_flush_pos as (u32); + let mut i: usize; + i = 0usize; + while i < t { + { + { + let _rhs = 1; + let _lhs = &mut literal_histo[data[((pos as (usize) & mask) as (usize))] as (usize)]; + *_lhs = (*_lhs).wrapping_add(_rhs as (u32)); + } + pos = pos.wrapping_add(kSampleRate); + } + i = i.wrapping_add(1 as (usize)); + } + if BitsEntropy(&literal_histo[..], 256usize) > bit_cost_threshold { + return 0i32; + } + } + } + 1i32 +} + +/* Chooses the literal context mode for a metablock */ +fn ChooseContextMode(params: &BrotliEncoderParams, + data: &[u8], pos: usize, mask: usize, + length: usize) -> ContextType{ + /* We only do the computation for the option of something else than + CONTEXT_UTF8 for the highest qualities */ + match params.mode { + BrotliEncoderMode::BROTLI_FORCE_LSB_PRIOR => return ContextType::CONTEXT_LSB6, + BrotliEncoderMode::BROTLI_FORCE_MSB_PRIOR => return ContextType::CONTEXT_MSB6, + BrotliEncoderMode::BROTLI_FORCE_UTF8_PRIOR => return ContextType::CONTEXT_UTF8, + BrotliEncoderMode::BROTLI_FORCE_SIGNED_PRIOR => return ContextType::CONTEXT_SIGNED, + _ => {}, + } + if (params.quality >= 10 && + BrotliIsMostlyUTF8(data, pos, mask, length, kMinUTF8Ratio) == 0) { + return ContextType::CONTEXT_SIGNED; + } + return ContextType::CONTEXT_UTF8; +} + + +#[derive(PartialEq, Eq, Copy, Clone)] +pub enum BrotliEncoderOperation { + BROTLI_OPERATION_PROCESS = 0, + BROTLI_OPERATION_FLUSH = 1, + BROTLI_OPERATION_FINISH = 2, + BROTLI_OPERATION_EMIT_METADATA = 3, +} + +fn MakeUncompressedStream(input: &[u8], input_size: usize, output: &mut [u8]) -> usize { + let mut size: usize = input_size; + let mut result: usize = 0usize; + let mut offset: usize = 0usize; + if input_size == 0usize { + output[(0usize)] = 6i32 as (u8); + return 1usize; + } + output[({ + let _old = result; + result = result.wrapping_add(1 as (usize)); + _old + } as (usize))] = 0x21i32 as (u8); + output[({ + let _old = result; + result = result.wrapping_add(1 as (usize)); + _old + } as (usize))] = 0x3i32 as (u8); + while size > 0usize { + let mut nibbles: u32 = 0u32; + let chunk_size: u32; + let bits: u32; + chunk_size = if size > (1u32 << 24i32) as (usize) { + 1u32 << 24i32 + } else { + size as (u32) + }; + if chunk_size > 1u32 << 16i32 { + nibbles = if chunk_size > 1u32 << 20i32 { + 2i32 + } else { + 1i32 + } as (u32); + } + bits = nibbles << 1i32 | chunk_size.wrapping_sub(1u32) << 3i32 | + 1u32 << (19u32).wrapping_add((4u32).wrapping_mul(nibbles)); + output[({ + let _old = result; + result = result.wrapping_add(1 as (usize)); + _old + } as (usize))] = bits as (u8); + output[({ + let _old = result; + result = result.wrapping_add(1 as (usize)); + _old + } as (usize))] = (bits >> 8i32) as (u8); + output[({ + let _old = result; + result = result.wrapping_add(1 as (usize)); + _old + } as (usize))] = (bits >> 16i32) as (u8); + if nibbles == 2u32 { + output[({ + let _old = result; + result = result.wrapping_add(1 as (usize)); + _old + } as (usize))] = (bits >> 24i32) as (u8); + } + output[(result as usize)..(result + chunk_size as usize)].clone_from_slice( + &input[offset .. (offset + chunk_size as usize)]); + result = result.wrapping_add(chunk_size as (usize)); + offset = offset.wrapping_add(chunk_size as (usize)); + size = size.wrapping_sub(chunk_size as (usize)); + } + output[({ + let _old = result; + result = result.wrapping_add(1 as (usize)); + _old + } as (usize))] = 3i32 as (u8); + result +} +pub fn BrotliEncoderCompress<Alloc: BrotliAlloc, + MetablockCallback: FnMut(&mut interface::PredictionModeContextMap<InputReferenceMut>, + &mut [interface::StaticCommand], + interface::InputPair, &mut Alloc)>( + empty_m8: Alloc, + m8: &mut Alloc, + quality: i32, + lgwin: i32, + mode: BrotliEncoderMode, + input_size: usize, + input_buffer: &[u8], + encoded_size: &mut usize, + encoded_buffer: &mut [u8], + metablock_callback: &mut MetablockCallback) + -> i32 { + let out_size: usize = *encoded_size; + let input_start = input_buffer; + let output_start = encoded_buffer; + let max_out_size: usize = BrotliEncoderMaxCompressedSize(input_size); + if out_size == 0usize { + return 0i32; + } + if input_size == 0usize { + *encoded_size = 1; + output_start[0] = 6; + return 1i32; + } + let mut is_fallback: i32 = 0i32; + if quality == 10i32 { + panic!("Unimplemented: need to set 9.5 here"); + } + if is_fallback == 0 { + + let mut s_orig = BrotliEncoderCreateInstance(core::mem::replace(m8, empty_m8)); + let mut result: i32; + { + let s = &mut s_orig; + let mut available_in: usize = input_size; + let mut next_in_array: &[u8] = input_buffer; + let mut next_in_offset: usize = 0; + let mut available_out: usize = *encoded_size; + let mut next_out_array: &mut [u8] = output_start; + let mut next_out_offset: usize = 0; + let mut total_out = Some(0usize); + BrotliEncoderSetParameter(s, + BrotliEncoderParameter::BROTLI_PARAM_QUALITY, + quality as (u32)); + BrotliEncoderSetParameter(s, + BrotliEncoderParameter::BROTLI_PARAM_LGWIN, + lgwin as (u32)); + BrotliEncoderSetParameter(s, BrotliEncoderParameter::BROTLI_PARAM_MODE, mode as (u32)); + BrotliEncoderSetParameter(s, + BrotliEncoderParameter::BROTLI_PARAM_SIZE_HINT, + input_size as (u32)); + if lgwin > BROTLI_MAX_WINDOW_BITS as i32 { + BrotliEncoderSetParameter(s, BrotliEncoderParameter::BROTLI_PARAM_LARGE_WINDOW, 1); + } + result = BrotliEncoderCompressStream(s, + BrotliEncoderOperation::BROTLI_OPERATION_FINISH, + &mut available_in, + &mut next_in_array, + &mut next_in_offset, + &mut available_out, + &mut next_out_array, + &mut next_out_offset, + &mut total_out, + metablock_callback); + if BrotliEncoderIsFinished(s) == 0 { + result = 0i32; + } + + *encoded_size = total_out.unwrap(); + BrotliEncoderDestroyInstance(s); + } + let _ = core::mem::replace(m8, s_orig.m8); + if result == 0 || max_out_size != 0 && (*encoded_size > max_out_size) { + is_fallback = 1i32; + } else { + return 1i32; + } + } + assert!(is_fallback != 0); + *encoded_size = 0usize; + if max_out_size == 0 { + return 0i32; + } + if out_size >= max_out_size { + *encoded_size = MakeUncompressedStream(input_start, input_size, output_start); + return 1i32; + } + 0i32 +} + +fn InjectBytePaddingBlock<Alloc: BrotliAlloc>(s: &mut BrotliEncoderStateStruct<Alloc>) { + let mut seal: u32 = (*s).last_bytes_ as (u32); + let mut seal_bits: usize = (*s).last_bytes_bits_ as (usize); + let destination: &mut [u8]; + (*s).last_bytes_ = 0; + (*s).last_bytes_bits_ = 0; + seal = seal | 0x6u32 << seal_bits; + seal_bits = seal_bits.wrapping_add(6usize); + if !IsNextOutNull(&(*s).next_out_) { + destination = &mut GetNextOut!(*s)[((*s).available_out_ as (usize))..]; + } else { + destination = &mut (*s).tiny_buf_[..]; + (*s).next_out_ = NextOut::TinyBuf(0); + } + destination[(0usize)] = seal as (u8); + if seal_bits > 8usize { + destination[(1usize)] = (seal >> 8i32) as (u8); + } + if seal_bits > 16usize { + destination[(2usize)] = (seal >> 16i32) as (u8); + } + (*s).available_out_ = (*s).available_out_.wrapping_add(seal_bits.wrapping_add(7usize) >> 3i32); +} +fn InjectFlushOrPushOutput<Alloc: BrotliAlloc>( + s: &mut BrotliEncoderStateStruct<Alloc>, + available_out: &mut usize, + next_out_array: &mut [u8], + next_out_offset: &mut usize, + total_out: &mut Option<usize>) + -> i32 { + if (*s).stream_state_ as (i32) == + BrotliEncoderStreamState::BROTLI_STREAM_FLUSH_REQUESTED as (i32) && + ((*s).last_bytes_bits_ as (i32) != 0i32) { + InjectBytePaddingBlock(s); + return 1i32; + } + if (*s).available_out_ != 0usize && (*available_out != 0usize) { + let copy_output_size: usize = brotli_min_size_t((*s).available_out_, *available_out); + (*next_out_array)[(*next_out_offset)..(*next_out_offset + copy_output_size)].clone_from_slice(&GetNextOut!(s)[..copy_output_size]); + //memcpy(*next_out, (*s).next_out_, copy_output_size); + *next_out_offset = (*next_out_offset).wrapping_add(copy_output_size); + *available_out = (*available_out).wrapping_sub(copy_output_size); + (*s).next_out_ = NextOutIncrement(&(*s).next_out_, (copy_output_size as (i32))); + (*s).available_out_ = (*s).available_out_.wrapping_sub(copy_output_size); + (*s).total_out_ = (*s).total_out_.wrapping_add(copy_output_size as u64); + if let &mut Some(ref mut total_out_inner) = total_out { + *total_out_inner = (*s).total_out_ as usize; + } + return 1i32; + } + 0i32 +} + +fn UnprocessedInputSize<Alloc:BrotliAlloc>( + s: &BrotliEncoderStateStruct<Alloc>) -> u64 { + (*s).input_pos_.wrapping_sub((*s).last_processed_pos_) +} + +fn UpdateSizeHint<Alloc: BrotliAlloc>(s: &mut BrotliEncoderStateStruct<Alloc>, + available_in: usize) { + if (*s).params.size_hint == 0usize { + let delta: u64 = UnprocessedInputSize(s); + let tail: u64 = available_in as u64; + let limit: u32 = 1u32 << 30i32; + let total: u32; + if delta >= u64::from(limit) || tail >= u64::from(limit) || + delta.wrapping_add(tail) >= u64::from(limit) { + total = limit; + } else { + total = delta.wrapping_add(tail) as (u32); + } + (*s).params.size_hint = total as (usize); + } +} + + +fn WrapPosition(position: u64) -> u32 { + let mut result: u32 = position as (u32); + let gb: u64 = position >> 30i32; + if gb > 2 { + result = result & (1u32 << 30i32).wrapping_sub(1u32) | + ((gb.wrapping_sub(1) & 1) as (u32)).wrapping_add(1u32) << 30i32; + } + result +} + +fn InputBlockSize<Alloc: BrotliAlloc>(s: &mut BrotliEncoderStateStruct<Alloc>) -> usize { + if EnsureInitialized(s) == 0 { + return 0usize; + } + 1usize << (*s).params.lgblock +} + +fn GetBrotliStorage<Alloc:BrotliAlloc>(s: &mut BrotliEncoderStateStruct<Alloc>, + size: usize) { + if (*s).storage_size_ < size { + <Alloc as Allocator<u8>>::free_cell(&mut (*s).m8, core::mem::replace(&mut (*s).storage_, <Alloc as Allocator<u8>>::AllocatedMemory::default())); + (*s).storage_ = <Alloc as Allocator<u8>>::alloc_cell(&mut (*s).m8, size); + (*s).storage_size_ = size; + } +} + +fn MaxHashTableSize(quality: i32) -> usize { + (if quality == 0i32 { + 1i32 << 15i32 + } else { + 1i32 << 17i32 + }) as (usize) +} + +fn HashTableSize(max_table_size: usize, input_size: usize) -> usize { + let mut htsize: usize = 256usize; + while htsize < max_table_size && (htsize < input_size) { + htsize = htsize << 1i32; + } + htsize +} + +macro_rules! GetHashTable { + ($s : expr, $quality: expr, $input_size : expr, $table_size : expr) => { + GetHashTableInternal(&mut $s.m8, &mut $s.small_table_, &mut $s.large_table_, + $quality, $input_size, $table_size) + }; +} +fn GetHashTableInternal<'a, AllocI32: alloc::Allocator<i32>>(mi32: &mut AllocI32, + small_table_: &'a mut [i32; 1024], + large_table_: &'a mut AllocI32::AllocatedMemory, + quality: i32, + input_size: usize, + table_size: &mut usize) + -> &'a mut [i32] { + let max_table_size: usize = MaxHashTableSize(quality); + let mut htsize: usize = HashTableSize(max_table_size, input_size); + let table: &mut [i32]; + if quality == 0i32 { + if htsize & 0xaaaaausize == 0usize { + htsize = htsize << 1i32; + } + } + if htsize <= small_table_.len() { + table = &mut small_table_[..]; + } else { + if htsize > large_table_.slice().len() { + //(*s).large_table_size_ = htsize; + { + mi32.free_cell(core::mem::replace(large_table_, + AllocI32::AllocatedMemory::default())); + } + *large_table_ = mi32.alloc_cell(htsize); + } + table = large_table_.slice_mut(); + } + *table_size = htsize; + for item in table[..htsize].iter_mut() { + *item = 0; + } + table // FIXME: probably need a macro to do this without borrowing the whole EncoderStateStruct +} +fn UpdateLastProcessedPos<Alloc:BrotliAlloc>(s: &mut BrotliEncoderStateStruct<Alloc>) -> i32 { + let wrapped_last_processed_pos: u32 = WrapPosition((*s).last_processed_pos_); + let wrapped_input_pos: u32 = WrapPosition((*s).input_pos_); + (*s).last_processed_pos_ = (*s).input_pos_; + if !!(wrapped_input_pos < wrapped_last_processed_pos) { + 1i32 + } else { + 0i32 + } +} + +fn MaxMetablockSize(params: &BrotliEncoderParams) -> usize { + let bits: i32 = brotli_min_int(ComputeRbBits(params), 24i32); + 1usize << bits +} + + + +fn ChooseContextMap(quality: i32, + bigram_histo: &mut [u32], + num_literal_contexts: &mut usize, + literal_context_map: &mut &[u32]) { + static kStaticContextMapContinuation: [u32; 64] = + [1u32, 1u32, 2u32, 2u32, 0u32, 0u32, 0u32, 0u32, 0u32, 0u32, 0u32, 0u32, 0u32, 0u32, 0u32, + 0u32, 0u32, 0u32, 0u32, 0u32, 0u32, 0u32, 0u32, 0u32, 0u32, 0u32, 0u32, 0u32, 0u32, 0u32, + 0u32, 0u32, 0u32, 0u32, 0u32, 0u32, 0u32, 0u32, 0u32, 0u32, 0u32, 0u32, 0u32, 0u32, 0u32, + 0u32, 0u32, 0u32, 0u32, 0u32, 0u32, 0u32, 0u32, 0u32, 0u32, 0u32, 0u32, 0u32, 0u32, 0u32, + 0u32, 0u32, 0u32, 0u32]; + static kStaticContextMapSimpleUTF8: [u32; 64] = + [0u32, 0u32, 1u32, 1u32, 0u32, 0u32, 0u32, 0u32, 0u32, 0u32, 0u32, 0u32, 0u32, 0u32, 0u32, + 0u32, 0u32, 0u32, 0u32, 0u32, 0u32, 0u32, 0u32, 0u32, 0u32, 0u32, 0u32, 0u32, 0u32, 0u32, + 0u32, 0u32, 0u32, 0u32, 0u32, 0u32, 0u32, 0u32, 0u32, 0u32, 0u32, 0u32, 0u32, 0u32, 0u32, + 0u32, 0u32, 0u32, 0u32, 0u32, 0u32, 0u32, 0u32, 0u32, 0u32, 0u32, 0u32, 0u32, 0u32, 0u32, + 0u32, 0u32, 0u32, 0u32]; + let mut monogram_histo: [u32; 3] = [0u32, 0u32, 0u32]; + let mut two_prefix_histo: [u32; 6] = [0u32, 0u32, 0u32, 0u32, 0u32, 0u32]; + let total: usize; + let mut i: usize; + let mut dummy: usize = 0; + let mut entropy: [super::util::floatX; 4] = [0.0 as super::util::floatX;4]; + i = 0usize; + while i < 9usize { + { + { + let _rhs = bigram_histo[(i as (usize))]; + let _lhs = &mut monogram_histo[i.wrapping_rem(3usize)]; + *_lhs = (*_lhs).wrapping_add(_rhs); + } + { + let _rhs = bigram_histo[(i as (usize))]; + let _lhs = &mut two_prefix_histo[i.wrapping_rem(6usize)]; + *_lhs = (*_lhs).wrapping_add(_rhs); + } + } + i = i.wrapping_add(1 as (usize)); + } + entropy[1usize] = ShannonEntropy(&monogram_histo[..], 3usize, &mut dummy); + entropy[2usize] = ShannonEntropy(&two_prefix_histo[..], 3usize, &mut dummy) + + ShannonEntropy(&two_prefix_histo[3i32 as (usize)..], + 3usize, + &mut dummy); + entropy[3usize] = 0i32 as (super::util::floatX); + i = 0usize; + while i < 3usize { + { + let _rhs = ShannonEntropy(&bigram_histo[((3usize).wrapping_mul(i) as (usize))..], + 3usize, + &mut dummy); + let _lhs = &mut entropy[3usize]; + *_lhs = *_lhs + _rhs; + } + i = i.wrapping_add(1 as (usize)); + } + total = monogram_histo[0usize] + .wrapping_add(monogram_histo[1usize]) + .wrapping_add(monogram_histo[2usize]) as (usize); + 0i32; + entropy[0usize] = 1.0 as super::util::floatX / total as (super::util::floatX); + { + let _rhs = entropy[0usize]; + let _lhs = &mut entropy[1usize]; + *_lhs = *_lhs * _rhs; + } + { + let _rhs = entropy[0usize]; + let _lhs = &mut entropy[2usize]; + *_lhs = *_lhs * _rhs; + } + { + let _rhs = entropy[0usize]; + let _lhs = &mut entropy[3usize]; + *_lhs = *_lhs * _rhs; + } + if quality < 7i32 { + entropy[3usize] = entropy[1usize] * 10i32 as (super::util::floatX); + } + if entropy[1usize] - entropy[2usize] < 0.2 as super::util::floatX && (entropy[1usize] - entropy[3usize] < 0.2 as super::util::floatX) { + *num_literal_contexts = 1usize; + } else if entropy[2usize] - entropy[3usize] < 0.02 as super::util::floatX { + *num_literal_contexts = 2usize; + *literal_context_map = &kStaticContextMapSimpleUTF8[..]; + } else { + *num_literal_contexts = 3usize; + *literal_context_map = &kStaticContextMapContinuation[..]; + } +} + +static kStaticContextMapComplexUTF8: [u32; 64] = [ + 11, 11, 12, 12, /* 0 special */ + 0, 0, 0, 0, /* 4 lf */ + 1, 1, 9, 9, /* 8 space */ + 2, 2, 2, 2, /* !, first after space/lf and after something else. */ + 1, 1, 1, 1, /* " */ + 8, 3, 3, 3, /* % */ + 1, 1, 1, 1, /* ({[ */ + 2, 2, 2, 2, /* }]) */ + 8, 4, 4, 4, /* :; */ + 8, 7, 4, 4, /* . */ + 8, 0, 0, 0, /* > */ + 3, 3, 3, 3, /* [0..9] */ + 5, 5, 10, 5, /* [A-Z] */ + 5, 5, 10, 5, + 6, 6, 6, 6, /* [a-z] */ + 6, 6, 6, 6, + ]; +/* Decide if we want to use a more complex static context map containing 13 + context values, based on the entropy reduction of histograms over the + first 5 bits of literals. */ +fn ShouldUseComplexStaticContextMap(input: &[u8], + mut start_pos: usize, length : usize, mask : usize, quality: i32, + size_hint: usize, + num_literal_contexts: &mut usize, literal_context_map: &mut &[u32]) -> bool { + let _ = quality; + //BROTLI_UNUSED(quality); + /* Try the more complex static context map only for long data. */ + if (size_hint < (1 << 20)) { + return false; + } else { + let end_pos = start_pos + length; + /* To make entropy calculations faster and to fit on the stack, we collect + histograms over the 5 most significant bits of literals. One histogram + without context and 13 additional histograms for each context value. */ + let mut combined_histo:[u32; 32] = [0;32]; + let mut context_histo:[[u32;32]; 13] = [[0;32];13]; + let mut total = 0u32; + let mut entropy = [0.0 as super::util::floatX;3]; + let mut dummy = 0usize; + let utf8_lut = BROTLI_CONTEXT_LUT(ContextType::CONTEXT_UTF8); + while start_pos + 64 <= end_pos { + let stride_end_pos = start_pos + 64; + let mut prev2 = input[start_pos & mask]; + let mut prev1 = input[(start_pos + 1) & mask]; + + /* To make the analysis of the data faster we only examine 64 byte long + strides at every 4kB intervals. */ + for pos in start_pos + 2..stride_end_pos { + let literal = input[pos & mask]; + let context = kStaticContextMapComplexUTF8[ + BROTLI_CONTEXT(prev1, prev2, utf8_lut) as usize] as u8; + total += 1; + combined_histo[(literal >> 3) as usize] += 1; + context_histo[context as usize][(literal >> 3) as usize] += 1; + prev2 = prev1; + prev1 = literal; + } + start_pos += 4096; + } + entropy[1] = ShannonEntropy(&combined_histo[..], 32, &mut dummy); + entropy[2] = 0.0 as super::util::floatX; + for i in 0..13 { + assert!(i < 13); + entropy[2] += ShannonEntropy(&context_histo[i][..], 32, &mut dummy); + } + entropy[0] = (1.0 as super::util::floatX) / (total as super::util::floatX); + entropy[1] *= entropy[0]; + entropy[2] *= entropy[0]; + /* The triggering heuristics below were tuned by compressing the individual + files of the silesia corpus. If we skip this kind of context modeling + for not very well compressible input (i.e. entropy using context modeling + is 60% of maximal entropy) or if expected savings by symbol are less + than 0.2 bits, then in every case when it triggers, the final compression + ratio is improved. Note however that this heuristics might be too strict + for some cases and could be tuned further. */ + if (entropy[2] > 3.0 || entropy[1] - entropy[2] < 0.2) { + return false; + } else { + *num_literal_contexts = 13; + *literal_context_map = &kStaticContextMapComplexUTF8; + return true; + } + } +} + +fn DecideOverLiteralContextModeling(input: &[u8], + mut start_pos: usize, + length: usize, + mask: usize, + quality: i32, + size_hint: usize, + num_literal_contexts: &mut usize, + literal_context_map: &mut &[u32]) { + + if quality < 5i32 || length < 64usize { + } else if ShouldUseComplexStaticContextMap(input, start_pos, length, mask, quality, size_hint, + num_literal_contexts, literal_context_map) { + } else { + let end_pos: usize = start_pos.wrapping_add(length); + let mut bigram_prefix_histo: [u32; 9] = [0u32, 0u32, 0u32, 0u32, 0u32, 0u32, 0u32, 0u32, 0u32]; + while start_pos.wrapping_add(64usize) <= end_pos { + { + static lut: [i32; 4] = [0i32, 0i32, 1i32, 2i32]; + let stride_end_pos: usize = start_pos.wrapping_add(64usize); + let mut prev: i32 = lut[(input[((start_pos & mask) as (usize))] as (i32) >> 6i32) as + (usize)] * 3i32; + let mut pos: usize; + pos = start_pos.wrapping_add(1usize); + while pos < stride_end_pos { + { + let literal: u8 = input[((pos & mask) as (usize))]; + { + let _rhs = 1; + let cur_ind = (prev + lut[(literal as (i32) >> 6i32) as (usize)]); + let _lhs = &mut bigram_prefix_histo[cur_ind as + (usize)]; + *_lhs = (*_lhs).wrapping_add(_rhs as (u32)); + } + prev = lut[(literal as (i32) >> 6i32) as (usize)] * 3i32; + } + pos = pos.wrapping_add(1 as (usize)); + } + } + start_pos = start_pos.wrapping_add(4096usize); + } + ChooseContextMap(quality, + &mut bigram_prefix_histo[..], + num_literal_contexts, + literal_context_map); + } +} +fn WriteMetaBlockInternal<Alloc: BrotliAlloc, + Cb> + (alloc: &mut Alloc, + data: &[u8], + mask: usize, + last_flush_pos: u64, + bytes: usize, + mut is_last: i32, + literal_context_mode: ContextType, + params: &BrotliEncoderParams, + lit_scratch_space: &mut <HistogramLiteral as CostAccessors>::i32vec, + cmd_scratch_space: &mut <HistogramCommand as CostAccessors>::i32vec, + dst_scratch_space: &mut <HistogramDistance as CostAccessors>::i32vec, + prev_byte: u8, + prev_byte2: u8, + num_literals: usize, + num_commands: usize, + commands: &mut [Command], + saved_dist_cache: &[i32;kNumDistanceCacheEntries], + dist_cache: &mut [i32;16], + recoder_state: &mut RecoderState, + storage_ix: &mut usize, + storage: &mut [u8], + cb: &mut Cb) where Cb: FnMut(&mut interface::PredictionModeContextMap<InputReferenceMut>, + &mut [interface::StaticCommand], + interface::InputPair, &mut Alloc) { + let actual_is_last = is_last; + if params.appendable { + is_last = 0; + } else { + assert_eq!(params.catable, false); // Sanitize Params senforces this constraint + } + let wrapped_last_flush_pos: u32 = WrapPosition(last_flush_pos); + let last_bytes: u16; + let last_bytes_bits: u8; + let literal_context_lut = BROTLI_CONTEXT_LUT(literal_context_mode); + let mut block_params = params.clone(); + if bytes == 0usize { + BrotliWriteBits(2usize, 3, storage_ix, storage); + *storage_ix = (*storage_ix).wrapping_add(7u32 as (usize)) & !7u32 as (usize); + return; + } + if ShouldCompress(data, + mask, + last_flush_pos, + bytes, + num_literals, + num_commands) == 0 { + dist_cache[..4].clone_from_slice(&saved_dist_cache[..4]); + BrotliStoreUncompressedMetaBlock(alloc, + is_last, + data, + wrapped_last_flush_pos as (usize), + mask, + params, + bytes, + recoder_state, + storage_ix, + storage, + false, + cb); + if actual_is_last != is_last { + BrotliWriteEmptyLastMetaBlock(storage_ix, storage) + } + return; + } + let saved_byte_location = (*storage_ix) >> 3; + last_bytes = ((storage[saved_byte_location + 1] as u16) << 8) | storage[saved_byte_location] as u16; + last_bytes_bits = *storage_ix as u8; + /*if params.dist.num_direct_distance_codes != 0 || + params.dist.distance_postfix_bits != 0 { + RecomputeDistancePrefixes(commands, + num_commands, + params.dist.num_direct_distance_codes, + params.dist.distance_postfix_bits); + }*/ // why was this removed?? + if (*params).quality <= 2i32 { + BrotliStoreMetaBlockFast(alloc, + data, + wrapped_last_flush_pos as (usize), + bytes, + mask, + is_last, + params, + saved_dist_cache, + commands, + num_commands, + recoder_state, + storage_ix, + storage, + cb); + } else if (*params).quality < 4i32 { + BrotliStoreMetaBlockTrivial(alloc, + data, + wrapped_last_flush_pos as (usize), + bytes, + mask, + is_last, + params, + saved_dist_cache, + commands, + num_commands, + recoder_state, + storage_ix, + storage, + cb); + } else { + //let mut literal_context_mode: ContextType = ContextType::CONTEXT_UTF8; + + let mut mb = MetaBlockSplit::<Alloc>::new(); + if (*params).quality < 10i32 { + let mut num_literal_contexts: usize = 1usize; + let mut literal_context_map: &[u32] = &[]; + if (*params).disable_literal_context_modeling == 0 { + DecideOverLiteralContextModeling(data, + wrapped_last_flush_pos as (usize), + bytes, + mask, + (*params).quality, + (*params).size_hint, + &mut num_literal_contexts, + &mut literal_context_map); + } + BrotliBuildMetaBlockGreedy(alloc, + data, + wrapped_last_flush_pos as (usize), + mask, + prev_byte, + prev_byte2, + literal_context_mode, + literal_context_lut, + num_literal_contexts, + literal_context_map, + commands, + num_commands, + &mut mb); + } else { + BrotliBuildMetaBlock(alloc, + data, + wrapped_last_flush_pos as (usize), + mask, + &mut block_params, + prev_byte, + prev_byte2, + commands, + num_commands, + literal_context_mode, + lit_scratch_space, + cmd_scratch_space, + dst_scratch_space, + &mut mb); + } + if (*params).quality >= 4i32 { + let mut num_effective_dist_codes = block_params.dist.alphabet_size; + if num_effective_dist_codes > BROTLI_NUM_HISTOGRAM_DISTANCE_SYMBOLS as u32 { + num_effective_dist_codes = BROTLI_NUM_HISTOGRAM_DISTANCE_SYMBOLS as u32; + } + BrotliOptimizeHistograms(num_effective_dist_codes as usize, + &mut mb); + } + BrotliStoreMetaBlock(alloc, + data, + wrapped_last_flush_pos as (usize), + bytes, + mask, + prev_byte, + prev_byte2, + is_last, + &block_params, + literal_context_mode, + saved_dist_cache, + commands, + num_commands, + &mut mb, + recoder_state, + storage_ix, + storage, + cb); + mb.destroy(alloc); + } + if bytes + 4 + saved_byte_location < (*storage_ix >> 3i32) { + dist_cache[..4].clone_from_slice(&saved_dist_cache[..4]); + //memcpy(dist_cache, + // saved_dist_cache, + // (4usize).wrapping_mul(::std::mem::size_of::<i32>())); + storage[saved_byte_location] = last_bytes as u8; + storage[saved_byte_location + 1] = (last_bytes >> 8) as u8; + *storage_ix = last_bytes_bits as (usize); + BrotliStoreUncompressedMetaBlock(alloc, + is_last, + data, + wrapped_last_flush_pos as (usize), + mask, + params, + bytes, + recoder_state, + storage_ix, + storage, + true, + cb); + } + if actual_is_last != is_last { + BrotliWriteEmptyLastMetaBlock(storage_ix, storage) + } +} + +fn ChooseDistanceParams(params: &mut BrotliEncoderParams) { + let mut num_direct_distance_codes = 0u32; + let mut distance_postfix_bits = 0u32; + + if params.quality >= 4 { + let ndirect_msb; + if params.mode == BrotliEncoderMode::BROTLI_MODE_FONT { + distance_postfix_bits = 1; + num_direct_distance_codes = 12; + } else { + distance_postfix_bits = params.dist.distance_postfix_bits; + num_direct_distance_codes = params.dist.num_direct_distance_codes; + } + ndirect_msb = (num_direct_distance_codes >> distance_postfix_bits) & 0x0f; + if distance_postfix_bits > BROTLI_MAX_NPOSTFIX as u32 || num_direct_distance_codes > BROTLI_MAX_NDIRECT as u32 || (ndirect_msb << distance_postfix_bits) != num_direct_distance_codes { + distance_postfix_bits = 0; + num_direct_distance_codes = 0; + } + } + BrotliInitDistanceParams(params, distance_postfix_bits, num_direct_distance_codes); + /*( + if (params.large_window) { + max_distance = BROTLI_MAX_ALLOWED_DISTANCE; + if (num_direct_distance_codes != 0 || distance_postfix_bits != 0) { + max_distance = (3 << 29) - 4; + } + alphabet_size = BROTLI_DISTANCE_ALPHABET_SIZE( + num_direct_distance_codes, distance_postfix_bits, + BROTLI_LARGE_MAX_DISTANCE_BITS); + } else { + alphabet_size = BROTLI_DISTANCE_ALPHABET_SIZE( + num_direct_distance_codes, distance_postfix_bits, + BROTLI_MAX_DISTANCE_BITS); + + } + + params.dist.num_direct_distance_codes = num_direct_distance_codes; + params.dist.distance_postfix_bits = distance_postfix_bits; + params.dist.alphabet_size = alphabet_size; + params.dist.max_distance = max_distance;*/ +} + + +fn EncodeData<Alloc: BrotliAlloc, + MetablockCallback>( + s: &mut BrotliEncoderStateStruct<Alloc>, + is_last: i32, + force_flush: i32, + out_size: &mut usize, + callback: &mut MetablockCallback +// mut output: &'a mut &'a mut [u8] +) -> i32 where MetablockCallback: FnMut(&mut interface::PredictionModeContextMap<InputReferenceMut>, + &mut [interface::StaticCommand], + interface::InputPair, &mut Alloc){ + let mut delta: u64 = UnprocessedInputSize(s); + let mut bytes: u32 = delta as (u32); + let mask = (*s).ringbuffer_.mask_; + if EnsureInitialized(s) == 0 { + return 0i32; + } + let dictionary = BrotliGetDictionary(); + if (*s).is_last_block_emitted_ { + return 0i32; + } + if is_last != 0 { + (*s).is_last_block_emitted_ = true; + } + if delta > InputBlockSize(s) as u64 { + return 0i32; + } + let mut storage_ix: usize = usize::from((*s).last_bytes_bits_); + { + let meta_size = core::cmp::max(bytes as usize, + (*s).input_pos_.wrapping_sub((*s).last_flush_pos_) as usize); + GetBrotliStorage(s, + (2usize).wrapping_mul(meta_size).wrapping_add(503 + 24)); + } + { + (*s).storage_.slice_mut()[0] = (*s).last_bytes_ as u8; + (*s).storage_.slice_mut()[1] = ((*s).last_bytes_ >> 8) as u8; + } + let mut catable_header_size = 0; + if let IsFirst::NothingWritten = s.is_first_mb { + if s.params.magic_number { + BrotliWriteMetadataMetaBlock(&s.params, &mut storage_ix, (*s).storage_.slice_mut()); + (*s).last_bytes_ = (*s).storage_.slice()[((storage_ix >> 3i32) as (usize))] as u16 | ( + ((*s).storage_.slice()[1 + ((storage_ix >> 3i32) as (usize))] as u16)<<8); + (*s).last_bytes_bits_ = (storage_ix & 7u32 as (usize)) as (u8); + (*s).next_out_ = NextOut::DynamicStorage(0); + catable_header_size = storage_ix >> 3; + *out_size = catable_header_size; + s.is_first_mb = IsFirst::HeaderWritten; + } + } + if let IsFirst::BothCatableBytesWritten = s.is_first_mb { + // nothing to do here, move along + } else if !s.params.catable { + s.is_first_mb = IsFirst::BothCatableBytesWritten; + } else if bytes != 0 { + assert!(s.last_processed_pos_ < 2 || s.custom_dictionary); + let num_bytes_to_write_uncompressed:usize = core::cmp::min(2, bytes as usize); + { + let data = &mut (*s).ringbuffer_.data_mo.slice_mut ()[((*s).ringbuffer_.buffer_index as (usize))..]; + BrotliStoreUncompressedMetaBlock(&mut s.m8, + 0, + data, + s.last_flush_pos_ as usize, + mask as usize, + &s.params, + num_bytes_to_write_uncompressed, + &mut (*s).recoder_state, + &mut storage_ix, + (*s).storage_.slice_mut(), + false /* suppress meta-block logging */, + callback); + (*s).last_bytes_ = (*s).storage_.slice()[((storage_ix >> 3i32) as (usize))] as u16 | ( + ((*s).storage_.slice()[1 + ((storage_ix >> 3i32) as (usize))] as u16)<<8); + (*s).last_bytes_bits_ = (storage_ix & 7u32 as (usize)) as (u8); + s.prev_byte2_ = s.prev_byte_; + s.prev_byte_ = data[s.last_flush_pos_ as usize & mask as usize]; + if num_bytes_to_write_uncompressed == 2 { + s.prev_byte2_ = s.prev_byte_; + s.prev_byte_ = data[(s.last_flush_pos_ + 1) as usize & mask as usize]; + } + } + s.last_flush_pos_ += num_bytes_to_write_uncompressed as u64; + bytes -= num_bytes_to_write_uncompressed as u32; + (*s).last_processed_pos_ += num_bytes_to_write_uncompressed as u64; + if num_bytes_to_write_uncompressed >= 2 { + s.is_first_mb = IsFirst::BothCatableBytesWritten; + } else if num_bytes_to_write_uncompressed == 1 { + if let IsFirst::FirstCatableByteWritten = s.is_first_mb { + s.is_first_mb = IsFirst::BothCatableBytesWritten; + } else { + s.is_first_mb = IsFirst::FirstCatableByteWritten; + } + } + catable_header_size = storage_ix >> 3; + (*s).next_out_ = NextOut::DynamicStorage(0); + *out_size = catable_header_size; + delta = UnprocessedInputSize(s); + } + let mut wrapped_last_processed_pos: u32 = WrapPosition((*s).last_processed_pos_); + if (*s).params.quality == 1i32 && (*s).command_buf_.slice().len() == 0 { + let new_buf = <Alloc as Allocator<u32>>::alloc_cell(&mut (*s).m8, kCompressFragmentTwoPassBlockSize); + (*s).command_buf_ = new_buf; + let new_buf8 = <Alloc as Allocator<u8>>::alloc_cell(&mut (*s).m8, kCompressFragmentTwoPassBlockSize); + (*s).literal_buf_ = new_buf8; + } + if (*s).params.quality == 0i32 || (*s).params.quality == 1i32 { + let mut table_size: usize = 0; + { + let table: &mut [i32]; + if delta == 0 && (is_last == 0) { + *out_size = catable_header_size; + return 1i32; + } + let data = &mut (*s).ringbuffer_.data_mo.slice_mut ()[((*s).ringbuffer_.buffer_index as (usize))..]; + + //(*s).storage_.slice_mut()[0] = (*s).last_bytes_ as u8; + // (*s).storage_.slice_mut()[1] = ((*s).last_bytes_ >> 8) as u8; + + table = GetHashTable!(s, (*s).params.quality, bytes as (usize), &mut table_size); + + if (*s).params.quality == 0i32 { + BrotliCompressFragmentFast(&mut s.m8, + &mut data[((wrapped_last_processed_pos & mask) as (usize))..], + bytes as (usize), + is_last, + table, + table_size, + &mut (*s).cmd_depths_[..], + &mut (*s).cmd_bits_[..], + &mut (*s).cmd_code_numbits_, + &mut (*s).cmd_code_[..], + &mut storage_ix, + (*s).storage_.slice_mut()); + } else { + BrotliCompressFragmentTwoPass(&mut s.m8, + &mut data[((wrapped_last_processed_pos & mask) as (usize))..], + bytes as (usize), + is_last, + (*s).command_buf_.slice_mut(), + (*s).literal_buf_.slice_mut(), + table, + table_size, + &mut storage_ix, + (*s).storage_.slice_mut()); + } + (*s).last_bytes_ = (*s).storage_.slice()[((storage_ix >> 3i32) as (usize))] as u16 | (( + (*s).storage_.slice()[((storage_ix >> 3i32) as (usize)) + 1] as u16) << 8); + (*s).last_bytes_bits_ = (storage_ix & 7u32 as (usize)) as (u8); + } + UpdateLastProcessedPos(s); + // *output = &mut (*s).storage_.slice_mut(); + (*s).next_out_ = NextOut::DynamicStorage(0); // this always returns that + *out_size = storage_ix >> 3i32; + return 1i32; + } + { + let mut newsize: usize = + (*s).num_commands_.wrapping_add(bytes.wrapping_div(2u32) as (usize)).wrapping_add(1usize); + if newsize > (*s).cmd_alloc_size_ { + newsize = newsize.wrapping_add(bytes.wrapping_div(4u32).wrapping_add(16u32) as (usize)); + (*s).cmd_alloc_size_ = newsize; + let mut new_commands = <Alloc as Allocator<Command>>::alloc_cell(&mut s.m8, newsize); + if (*s).commands_.slice().len() != 0 { + new_commands.slice_mut()[..(*s).num_commands_].clone_from_slice(&(*s).commands_.slice()[..(*s).num_commands_]); + <Alloc as Allocator<Command>>::free_cell(&mut s.m8, core::mem::replace(&mut (*s).commands_, <Alloc as Allocator<Command>>::AllocatedMemory::default())); + } + (*s).commands_ = new_commands; + } + } + InitOrStitchToPreviousBlock(&mut (*s).m8, + &mut (*s).hasher_, + &mut (*s).ringbuffer_.data_mo.slice_mut()[((*s).ringbuffer_.buffer_index as (usize))..], + mask as (usize), + &mut (*s).params, + wrapped_last_processed_pos as (usize), + bytes as (usize), + is_last); + let literal_context_mode = ChooseContextMode( + &s.params, (*s).ringbuffer_.data_mo.slice(), WrapPosition(s.last_flush_pos_) as usize, + mask as usize, (s.input_pos_.wrapping_sub(s.last_flush_pos_)) as usize); + if s.num_commands_ != 0 && s.last_insert_len_ == 0 { + ExtendLastCommand(s, &mut bytes, &mut wrapped_last_processed_pos); + } + if false { // we are remapping 10 as quality=9.5 since Zopfli doesn't seem to offer much benefits here + panic!(r####" + BrotliCreateZopfliBackwardReferences(m, + dictionary, + bytes as (usize), + wrapped_last_processed_pos as (usize), + data, + mask as (usize), + &mut (*s).params, + (*s).hasher_, + (*s).dist_cache_.as_mut_ptr(), + &mut (*s).last_insert_len_, + &mut *(*s).commands_[((*s).num_commands_ as (usize))..], + &mut (*s).num_commands_, + &mut (*s).num_literals_);"####); + } else if false && (*s).params.quality == 11i32 { + panic!(r####"BrotliCreateHqZopfliBackwardReferences(m, + dictionary, + bytes as (usize), + wrapped_last_processed_pos as (usize), + data, + mask as (usize), + &mut (*s).params, + (*s).hasher_, + (*s).dist_cache_.as_mut_ptr(), + &mut (*s).last_insert_len_, + &mut *(*s).commands_[((*s).num_commands_ as (usize))..], + &mut (*s).num_commands_, + &mut (*s).num_literals_);"####); + } else { + BrotliCreateBackwardReferences(&mut (*s).m8, &dictionary, + bytes as (usize), + wrapped_last_processed_pos as (usize), + &mut (*s).ringbuffer_.data_mo.slice_mut()[((*s).ringbuffer_.buffer_index as usize)..], + mask as (usize), + &mut (*s).params, + &mut (*s).hasher_, + &mut (*s).dist_cache_, + &mut (*s).last_insert_len_, + &mut (*s).commands_.slice_mut()[((*s).num_commands_ as (usize))..], + &mut (*s).num_commands_, + &mut (*s).num_literals_); + } + { + let max_length: usize = MaxMetablockSize(&mut (*s).params); + let max_literals: usize = max_length.wrapping_div(8usize); + let max_commands: usize = max_length.wrapping_div(8usize); + let processed_bytes: usize = (*s).input_pos_.wrapping_sub((*s).last_flush_pos_) as usize; + let next_input_fits_metablock: i32 = if !!(processed_bytes.wrapping_add(InputBlockSize(s)) <= + max_length) { + 1i32 + } else { + 0i32 + }; + let should_flush: i32 = if !!((*s).params.quality < 4i32 && + ((*s).num_literals_.wrapping_add((*s).num_commands_) >= + 0x2fffusize)) { + 1i32 + } else { + 0i32 + }; + if is_last == 0 && (force_flush == 0) && (should_flush == 0) && + (next_input_fits_metablock != 0) && ((*s).num_literals_ < max_literals) && + ((*s).num_commands_ < max_commands) { + if UpdateLastProcessedPos(s) != 0 { + HasherReset(&mut (*s).hasher_); + } + *out_size = catable_header_size; + return 1i32; + } + } + if (*s).last_insert_len_ > 0usize { + InitInsertCommand(&mut (*s).commands_.slice_mut()[({ + let _old = (*s).num_commands_; + (*s).num_commands_ = (*s).num_commands_.wrapping_add(1 as (usize)); + _old + } as (usize))], + (*s).last_insert_len_); + (*s).num_literals_ = (*s).num_literals_.wrapping_add((*s).last_insert_len_); + (*s).last_insert_len_ = 0usize; + } + if is_last == 0 && ((*s).input_pos_ == (*s).last_flush_pos_) { + *out_size = catable_header_size; + return 1i32; + } + { + let metablock_size: u32 = (*s).input_pos_.wrapping_sub((*s).last_flush_pos_) as (u32); + //let mut storage_ix: usize = (*s).last_bytes_bits_ as (usize); + //(*s).storage_.slice_mut()[(0usize)] = (*s).last_bytes_ as u8; + //(*s).storage_.slice_mut()[(1usize)] = ((*s).last_bytes_ >> 8) as u8; + + WriteMetaBlockInternal(&mut (*s).m8, + &mut (*s).ringbuffer_.data_mo.slice_mut()[((*s).ringbuffer_.buffer_index as usize)..], + mask as (usize), + (*s).last_flush_pos_, + metablock_size as (usize), + is_last, + literal_context_mode, + &mut (*s).params, + &mut (*s).literal_scratch_space, + &mut (*s).command_scratch_space, + &mut (*s).distance_scratch_space, + (*s).prev_byte_, + (*s).prev_byte2_, + (*s).num_literals_, + (*s).num_commands_, + (*s).commands_.slice_mut(), + &mut (*s).saved_dist_cache_, + &mut (*s).dist_cache_, + &mut (*s).recoder_state, + &mut storage_ix, + (*s).storage_.slice_mut(), + callback); + + (*s).last_bytes_ = (*s).storage_.slice()[((storage_ix >> 3i32) as (usize))] as u16 | ( + ((*s).storage_.slice()[1 + ((storage_ix >> 3i32) as (usize))] as u16)<<8); + (*s).last_bytes_bits_ = (storage_ix & 7u32 as (usize)) as (u8); + (*s).last_flush_pos_ = (*s).input_pos_; + if UpdateLastProcessedPos(s) != 0 { + HasherReset(&mut (*s).hasher_); + } + let data = &(*s).ringbuffer_.data_mo.slice()[(*s).ringbuffer_.buffer_index as usize..]; + if (*s).last_flush_pos_ > 0 { + (*s).prev_byte_ = data[((((*s).last_flush_pos_ as (u32)).wrapping_sub(1u32) & mask) as + (usize))]; + } + if (*s).last_flush_pos_ > 1 { + (*s).prev_byte2_ = data[(((*s).last_flush_pos_.wrapping_sub(2) as (u32) & mask) as + (usize))]; + } + (*s).num_commands_ = 0usize; + (*s).num_literals_ = 0usize; + (*s).saved_dist_cache_.clone_from_slice(&(*s).dist_cache_.split_at(4).0); + (*s).next_out_ = NextOut::DynamicStorage(0); // this always returns that + *out_size = storage_ix >> 3i32; + 1i32 + } +} + +fn WriteMetadataHeader<Alloc:BrotliAlloc>(s: &mut BrotliEncoderStateStruct<Alloc>) + -> usize { + let block_size = (*s).remaining_metadata_bytes_ as (usize); + let header = GetNextOut!(*s); + let mut storage_ix: usize; + storage_ix = (*s).last_bytes_bits_ as (usize); + header[(0usize)] = (*s).last_bytes_ as u8; + header[(1usize)] = ((*s).last_bytes_ >> 8) as u8; + (*s).last_bytes_ = 0; + (*s).last_bytes_bits_ = 0; + BrotliWriteBits(1usize, 0, &mut storage_ix, header); + BrotliWriteBits(2usize, 3, &mut storage_ix, header); + BrotliWriteBits(1usize, 0, &mut storage_ix, header); + if block_size == 0usize { + BrotliWriteBits(2usize, 0, &mut storage_ix, header); + } else { + let nbits: u32 = if block_size == 1usize { + 0u32 + } else { + Log2FloorNonZero((block_size as (u32)).wrapping_sub(1u32) as (u64)).wrapping_add(1u32) + }; + let nbytes: u32 = nbits.wrapping_add(7u32).wrapping_div(8u32); + BrotliWriteBits(2usize, nbytes as (u64), &mut storage_ix, header); + BrotliWriteBits((8u32).wrapping_mul(nbytes) as (usize), + block_size.wrapping_sub(1usize) as u64, + &mut storage_ix, + header); + } + storage_ix.wrapping_add(7u32 as (usize)) >> 3i32 +} + +fn brotli_min_uint32_t(a: u32, b: u32) -> u32 { + if a < b { a } else { b } +} +fn ProcessMetadata<Alloc: BrotliAlloc, + MetaBlockCallback:FnMut(&mut interface::PredictionModeContextMap<InputReferenceMut>, + &mut [interface::StaticCommand], + interface::InputPair, &mut Alloc)>( + s: &mut BrotliEncoderStateStruct<Alloc>, + available_in: &mut usize, + next_in_array: &[u8], + next_in_offset: &mut usize, + available_out: &mut usize, + next_out_array: &mut[u8], + next_out_offset: &mut usize, + total_out: &mut Option<usize>, + metablock_callback: &mut MetaBlockCallback) + -> i32 { + if *available_in > (1u32 << 24i32) as (usize) { + return 0i32; + } + if (*s).stream_state_ as (i32) == BrotliEncoderStreamState::BROTLI_STREAM_PROCESSING as (i32) { + (*s).remaining_metadata_bytes_ = *available_in as (u32); + (*s).stream_state_ = BrotliEncoderStreamState::BROTLI_STREAM_METADATA_HEAD; + } + if (*s).stream_state_ as (i32) != + BrotliEncoderStreamState::BROTLI_STREAM_METADATA_HEAD as (i32) && + ((*s).stream_state_ as (i32) != + BrotliEncoderStreamState::BROTLI_STREAM_METADATA_BODY as (i32)) { + return 0i32; + } + while 1i32 != 0 { + if InjectFlushOrPushOutput(s, available_out, next_out_array, next_out_offset, total_out) != 0 { + { + continue; + } + } + if (*s).available_out_ != 0usize { + { + break; + } + } + if (*s).input_pos_ != (*s).last_flush_pos_ { + let mut avail_out : usize = (*s).available_out_; + let result: i32 = + EncodeData(s, 0i32, 1i32, &mut avail_out, metablock_callback); + (*s).available_out_ = avail_out; + if result == 0 { + return 0i32; + } + { + { + continue; + } + } + } + if (*s).stream_state_ as (i32) == + BrotliEncoderStreamState::BROTLI_STREAM_METADATA_HEAD as (i32) { + (*s).next_out_ = NextOut::TinyBuf(0); + (*s).available_out_ = WriteMetadataHeader(s); + (*s).stream_state_ = BrotliEncoderStreamState::BROTLI_STREAM_METADATA_BODY; + { + { + continue; + } + } + } else { + if (*s).remaining_metadata_bytes_ == 0u32 { + (*s).remaining_metadata_bytes_ = !(0u32); + (*s).stream_state_ = BrotliEncoderStreamState::BROTLI_STREAM_PROCESSING; + { + { + break; + } + } + } + if *available_out != 0 { + let copy: u32 = brotli_min_size_t((*s).remaining_metadata_bytes_ as (usize), + *available_out) as (u32); + next_out_array[*next_out_offset .. (*next_out_offset + copy as usize)].clone_from_slice( + &next_in_array[*next_in_offset ..(*next_in_offset + copy as usize)]); + //memcpy(*next_out, *next_in, copy as (usize)); + // *next_in = (*next_in).offset(copy as (isize)); + *next_in_offset += copy as usize; + *available_in = (*available_in).wrapping_sub(copy as (usize)); + (*s).remaining_metadata_bytes_ = (*s).remaining_metadata_bytes_.wrapping_sub(copy); + *next_out_offset += copy as usize; + // *next_out = (*next_out).offset(copy as (isize)); + *available_out = (*available_out).wrapping_sub(copy as (usize)); + } else { + let copy: u32 = brotli_min_uint32_t((*s).remaining_metadata_bytes_, 16u32); + (*s).next_out_ = NextOut::TinyBuf(0); + GetNextOut!(s)[..(copy as usize)].clone_from_slice( + &next_in_array[*next_in_offset ..(*next_in_offset + copy as usize)]); + //memcpy((*s).next_out_, *next_in, copy as (usize)); + // *next_in = (*next_in).offset(copy as (isize)); + *next_in_offset += copy as usize; + *available_in = (*available_in).wrapping_sub(copy as (usize)); + (*s).remaining_metadata_bytes_ = (*s).remaining_metadata_bytes_.wrapping_sub(copy); + (*s).available_out_ = copy as (usize); + } + { + { + continue; + } + } + } + } + 1i32 +} +fn CheckFlushCompleteInner(stream_state: &mut BrotliEncoderStreamState, + available_out: usize, + next_out: &mut NextOut) { + + if *stream_state == + BrotliEncoderStreamState::BROTLI_STREAM_FLUSH_REQUESTED && + (available_out == 0) { + *stream_state = BrotliEncoderStreamState::BROTLI_STREAM_PROCESSING; + *next_out = NextOut::None; + } +} + +fn CheckFlushComplete<Alloc: BrotliAlloc>(s: &mut BrotliEncoderStateStruct<Alloc>) { + CheckFlushCompleteInner(&mut (*s).stream_state_, + (*s).available_out_, + &mut (*s).next_out_); +} + + +fn BrotliEncoderCompressStreamFast<Alloc: BrotliAlloc>( + s: &mut BrotliEncoderStateStruct<Alloc>, + op: BrotliEncoderOperation, + available_in: &mut usize, + next_in_array: &[u8], + next_in_offset: &mut usize, + available_out: &mut usize, + next_out_array: &mut [u8], + next_out_offset: &mut usize, + total_out: &mut Option<usize>) + -> i32 { + let block_size_limit: usize = 1usize << (*s).params.lgwin; + let buf_size: usize = brotli_min_size_t(kCompressFragmentTwoPassBlockSize, + brotli_min_size_t(*available_in, block_size_limit)); + let mut command_buf = <Alloc as Allocator<u32>>::AllocatedMemory::default(); + let mut literal_buf = <Alloc as Allocator<u8>>::AllocatedMemory::default(); + if (*s).params.quality != 0i32 && ((*s).params.quality != 1i32) { + return 0i32; + } + if (*s).params.quality == 1i32 { + if (*s).command_buf_.slice().len() == 0 && (buf_size == kCompressFragmentTwoPassBlockSize) { + (*s).command_buf_ = <Alloc as Allocator<u32>>::alloc_cell(&mut s.m8, kCompressFragmentTwoPassBlockSize); + (*s).literal_buf_ = <Alloc as Allocator<u8>>::alloc_cell(&mut s.m8, kCompressFragmentTwoPassBlockSize); + } + if (*s).command_buf_.slice().len() != 0 { + command_buf = core::mem::replace(&mut (*s).command_buf_, <Alloc as Allocator<u32>>::AllocatedMemory::default()); + literal_buf = core::mem::replace(&mut (*s).literal_buf_, <Alloc as Allocator<u8>>::AllocatedMemory::default()); + } else { + command_buf = <Alloc as Allocator<u32>>::alloc_cell(&mut s.m8, buf_size); + literal_buf = <Alloc as Allocator<u8>>::alloc_cell(&mut s.m8, buf_size); + } + } + while 1i32 != 0 { + if InjectFlushOrPushOutput(s, available_out, next_out_array, next_out_offset, total_out) != 0 { + { + continue; + } + } + if (*s).available_out_ == 0usize && + ((*s).stream_state_ as (i32) == + BrotliEncoderStreamState::BROTLI_STREAM_PROCESSING as (i32)) && + (*available_in != 0usize || + op as (i32) != BrotliEncoderOperation::BROTLI_OPERATION_PROCESS as (i32)) { + let block_size: usize = brotli_min_size_t(block_size_limit, *available_in); + let is_last: i32 = (*available_in == block_size && + (op as (i32) == + BrotliEncoderOperation::BROTLI_OPERATION_FINISH as (i32))) as + (i32); + let force_flush: i32 = + (*available_in == block_size && + (op as (i32) == BrotliEncoderOperation::BROTLI_OPERATION_FLUSH as (i32))) as (i32); + let max_out_size: usize = (2usize).wrapping_mul(block_size).wrapping_add(503usize); + let mut inplace: i32 = 1i32; + let storage: &mut [u8]; + let mut storage_ix: usize = (*s).last_bytes_bits_ as (usize); + let mut table_size: usize = 0; + let table: &mut [i32]; + if force_flush != 0 && (block_size == 0usize) { + (*s).stream_state_ = BrotliEncoderStreamState::BROTLI_STREAM_FLUSH_REQUESTED; + { + { + continue; + } + } + } + if max_out_size <= *available_out { + storage = &mut next_out_array[*next_out_offset..];//GetNextOut!(s); + } else { + inplace = 0i32; + GetBrotliStorage(s, max_out_size); + storage = (*s).storage_.slice_mut(); + } + storage[(0usize)] = (*s).last_bytes_ as u8; + storage[(1usize)] = ((*s).last_bytes_ >> 8) as u8; + table = GetHashTable!(s, (*s).params.quality, block_size, &mut table_size); + if (*s).params.quality == 0i32 { + BrotliCompressFragmentFast(&mut s.m8, + &(next_in_array)[*next_in_offset..], + block_size, + is_last, + table, + table_size, + &mut (*s).cmd_depths_[..], + &mut (*s).cmd_bits_[..], + &mut (*s).cmd_code_numbits_, + &mut (*s).cmd_code_[..], + &mut storage_ix, + storage); + } else { + BrotliCompressFragmentTwoPass(&mut s.m8, + &(next_in_array)[*next_in_offset..], + block_size, + is_last, + command_buf.slice_mut(), + literal_buf.slice_mut(), + table, + table_size, + &mut storage_ix, + storage); + } + *next_in_offset += block_size as usize; + *available_in = (*available_in).wrapping_sub(block_size); + if inplace != 0 { + let out_bytes: usize = storage_ix >> 3i32; + 0i32; + 0i32; + *next_out_offset += out_bytes as (usize); + *available_out = (*available_out).wrapping_sub(out_bytes); + (*s).total_out_ = (*s).total_out_.wrapping_add(out_bytes as u64); + if let &mut Some(ref mut total_out_inner) = total_out { + *total_out_inner = (*s).total_out_ as usize; + } + } else { + let out_bytes: usize = storage_ix >> 3i32; + (*s).next_out_ = NextOut::DynamicStorage(0); + (*s).available_out_ = out_bytes; + } + (*s).last_bytes_ = storage[((storage_ix >> 3i32) as (usize))] as u16 | ( + ((storage[1 + ((storage_ix >> 3i32) as (usize))] as u16)<< 8)); + (*s).last_bytes_bits_ = (storage_ix & 7u32 as (usize)) as (u8); + if force_flush != 0 { + (*s).stream_state_ = BrotliEncoderStreamState::BROTLI_STREAM_FLUSH_REQUESTED; + } + if is_last != 0 { + (*s).stream_state_ = BrotliEncoderStreamState::BROTLI_STREAM_FINISHED; + } + { + { + continue; + } + } + } + { + { + break; + } + } + } + if command_buf.slice().len() == kCompressFragmentTwoPassBlockSize && s.command_buf_.slice().len() == 0 { + // undo temporary aliasing of command_buf and literal_buf + (*s).command_buf_ = core::mem::replace(&mut command_buf, <Alloc as Allocator<u32>>::AllocatedMemory::default()); + (*s).literal_buf_ = core::mem::replace(&mut literal_buf, <Alloc as Allocator<u8>>::AllocatedMemory::default()); + } else { + <Alloc as Allocator<u32>>::free_cell(&mut s.m8, command_buf); + <Alloc as Allocator<u8>>::free_cell(&mut s.m8, literal_buf); + } + CheckFlushComplete(s); + 1i32 +} +fn RemainingInputBlockSize<Alloc: BrotliAlloc>(s: &mut BrotliEncoderStateStruct<Alloc>) -> usize { + let delta: u64 = UnprocessedInputSize(s); + let block_size: usize = InputBlockSize(s); + if delta >= block_size as u64 { + return 0usize; + } + (block_size as u64).wrapping_sub(delta) as usize +} + +pub fn BrotliEncoderCompressStream<Alloc: BrotliAlloc, + MetablockCallback:FnMut(&mut interface::PredictionModeContextMap<InputReferenceMut>, + &mut [interface::StaticCommand], + interface::InputPair, &mut Alloc)>( + s: &mut BrotliEncoderStateStruct<Alloc>, + op: BrotliEncoderOperation, + available_in: &mut usize, + next_in_array: &[u8], + next_in_offset: &mut usize, + available_out: &mut usize, + next_out_array: &mut [u8], + next_out_offset: &mut usize, + total_out: &mut Option<usize>, + metablock_callback: &mut MetablockCallback) + -> i32 { + if EnsureInitialized(s) == 0 { + return 0i32; + } + if (*s).remaining_metadata_bytes_ != !(0u32) { + if *available_in != (*s).remaining_metadata_bytes_ as (usize) { + return 0i32; + } + if op as (i32) != BrotliEncoderOperation::BROTLI_OPERATION_EMIT_METADATA as (i32) { + return 0i32; + } + } + if op as (i32) == BrotliEncoderOperation::BROTLI_OPERATION_EMIT_METADATA as (i32) { + UpdateSizeHint(s, 0usize); + return ProcessMetadata(s, available_in, next_in_array, next_in_offset, available_out, next_out_array, next_out_offset, total_out, metablock_callback); + } + if (*s).stream_state_ as (i32) == + BrotliEncoderStreamState::BROTLI_STREAM_METADATA_HEAD as (i32) || + (*s).stream_state_ as (i32) == BrotliEncoderStreamState::BROTLI_STREAM_METADATA_BODY as (i32) { + return 0i32; + } + if (*s).stream_state_ as (i32) != + BrotliEncoderStreamState::BROTLI_STREAM_PROCESSING as (i32) && (*available_in != 0usize) { + return 0i32; + } + if ((*s).params.quality == 0i32 || (*s).params.quality == 1i32) && !s.params.catable { // this part of the code does not support concatability + return BrotliEncoderCompressStreamFast(s, + op, + available_in, + next_in_array, + next_in_offset, + available_out, + next_out_array, + next_out_offset, + total_out); + } + while 1i32 != 0 { + let remaining_block_size: usize = RemainingInputBlockSize(s); + if remaining_block_size != 0usize && (*available_in != 0usize) { + let copy_input_size: usize = brotli_min_size_t(remaining_block_size, *available_in); + CopyInputToRingBuffer(s, copy_input_size, &next_in_array[*next_in_offset..]); + *next_in_offset += copy_input_size as (usize); + *available_in = (*available_in).wrapping_sub(copy_input_size); + { + { + continue; + } + } + } + if InjectFlushOrPushOutput(s, available_out, next_out_array, next_out_offset, total_out) != 0 { + { + continue; + } + } + if (*s).available_out_ == 0usize && + ((*s).stream_state_ as (i32) == + BrotliEncoderStreamState::BROTLI_STREAM_PROCESSING as (i32)) { + if remaining_block_size == 0usize || + op as (i32) != BrotliEncoderOperation::BROTLI_OPERATION_PROCESS as (i32) { + let is_last: i32 = if !!(*available_in == 0usize && + (op as (i32) == + BrotliEncoderOperation::BROTLI_OPERATION_FINISH as (i32))) { + 1i32 + } else { + 0i32 + }; + let force_flush: i32 = + if !!(*available_in == 0usize && + (op as (i32) == BrotliEncoderOperation::BROTLI_OPERATION_FLUSH as (i32))) { + 1i32 + } else { + 0i32 + }; + let result: i32; + UpdateSizeHint(s, *available_in); + let mut avail_out = (*s).available_out_; + result = EncodeData(s, + is_last, + force_flush, + &mut avail_out, + metablock_callback); + (*s).available_out_ = avail_out; + //this function set next_out to &storage[0] + if result == 0 { + return 0i32; + } + if force_flush != 0 { + (*s).stream_state_ = BrotliEncoderStreamState::BROTLI_STREAM_FLUSH_REQUESTED; + } + if is_last != 0 { + (*s).stream_state_ = BrotliEncoderStreamState::BROTLI_STREAM_FINISHED; + } + { + { + continue; + } + } + } + } + { + { + break; + } + } + } + CheckFlushComplete(s); + 1i32 +} + +pub fn BrotliEncoderIsFinished<Alloc:BrotliAlloc>(s: &BrotliEncoderStateStruct<Alloc>) -> i32 { + if !!((*s).stream_state_ as (i32) == BrotliEncoderStreamState::BROTLI_STREAM_FINISHED as (i32) && + (BrotliEncoderHasMoreOutput(s) == 0)) { + 1i32 + } else { + 0i32 + } +} + + +pub fn BrotliEncoderHasMoreOutput<Alloc: BrotliAlloc>( + s: &BrotliEncoderStateStruct<Alloc>) -> i32 { + if !!((*s).available_out_ != 0usize) { + 1i32 + } else { + 0i32 + } +} + + +pub fn BrotliEncoderTakeOutput<'a, Alloc:BrotliAlloc>(s: &'a mut BrotliEncoderStateStruct<Alloc>, + size: &mut usize) + -> &'a [u8] { + let mut consumed_size: usize = (*s).available_out_; + let mut result: &[u8] = GetNextOut!(*s); + if *size != 0 { + consumed_size = brotli_min_size_t(*size, (*s).available_out_); + } + if consumed_size != 0 { + (*s).next_out_ = NextOutIncrement(&(*s).next_out_, consumed_size as i32); + (*s).available_out_ = (*s).available_out_.wrapping_sub(consumed_size); + (*s).total_out_ = (*s).total_out_.wrapping_add(consumed_size as u64); + CheckFlushCompleteInner(&mut (*s).stream_state_, + (*s).available_out_, + &mut (*s).next_out_); + *size = consumed_size; + } else { + *size = 0usize; + result = &[]; + } + result +} + + +pub fn BrotliEncoderVersion() -> u32 { + 0x1000f01u32 +} + + +pub fn BrotliEncoderInputBlockSize<Alloc:BrotliAlloc>(s: &mut BrotliEncoderStateStruct<Alloc>) -> usize { + InputBlockSize(s) +} + + +pub fn BrotliEncoderCopyInputToRingBuffer<Alloc: BrotliAlloc>(s: &mut BrotliEncoderStateStruct<Alloc>, + input_size: usize, + input_buffer: &[u8]) { + CopyInputToRingBuffer(s, input_size, input_buffer); +} + + +pub fn BrotliEncoderWriteData<'a, Alloc: BrotliAlloc, + MetablockCallback:FnMut(&mut interface::PredictionModeContextMap<InputReferenceMut>, + &mut [interface::StaticCommand], + interface::InputPair, &mut Alloc)>( + s: &'a mut BrotliEncoderStateStruct<Alloc>, + is_last: i32, + force_flush: i32, + out_size: &mut usize, + output: &'a mut &'a mut [u8], + metablock_callback: &mut MetablockCallback) + -> i32 { + let ret = EncodeData(s, is_last, force_flush, out_size, metablock_callback); + *output = (*s).storage_.slice_mut(); + ret +} |