Ejemplo n.º 1
0
 private static unsafe void EmitCopyLen(size_t copylen, uint **commands)
 {
     if (copylen < 10)
     {
         **commands = (uint)(copylen + 38);
     }
     else if (copylen < 134)
     {
         size_t tail     = copylen - 6;
         size_t nbits    = Log2FloorNonZero(tail) - 1;
         size_t prefix   = tail >> (int)nbits;
         size_t code     = (nbits << 1) + prefix + 44;
         size_t extra    = tail - (prefix << (int)nbits);
         **     commands = (uint)(code | (extra << 8));
     }
     else if (copylen < 2118)
     {
         size_t tail     = copylen - 70;
         size_t nbits    = Log2FloorNonZero(tail);
         size_t code     = nbits + 52;
         size_t extra    = tail - ((size_t)1 << (int)nbits);
         **     commands = (uint)(code | (extra << 8));
     }
     else
     {
         size_t extra    = copylen - 2118;
         **     commands = (uint)(63 | (extra << 8));
     }
     ++(*commands);
 }
Ejemplo n.º 2
0
        private static unsafe void AddMatch(size_t distance, size_t len, size_t len_code,
                                            uint *matches)
        {
            uint match = (uint)((distance << 5) + len_code);

            matches[len] = Math.Min(matches[len], match);
        }
Ejemplo n.º 3
0
        private static unsafe void CopyLiteralsToByteArray(Command *cmds,
                                                           size_t num_commands,
                                                           byte *data,
                                                           size_t offset,
                                                           size_t mask,
                                                           byte *literals)
        {
            size_t pos      = 0;
            size_t from_pos = offset & mask;
            size_t i;

            for (i = 0; i < num_commands; ++i)
            {
                size_t insert_len = cmds[i].insert_len_;
                if (from_pos + insert_len > mask)
                {
                    size_t head_size = mask + 1 - from_pos;
                    memcpy(literals + pos, data + from_pos, head_size);
                    from_pos    = 0;
                    pos        += head_size;
                    insert_len -= head_size;
                }
                if (insert_len > 0)
                {
                    memcpy(literals + pos, data + from_pos, insert_len);
                    pos += insert_len;
                }
                from_pos = (from_pos + insert_len + CommandCopyLen(&cmds[i])) & mask;
            }
        }
Ejemplo n.º 4
0
        private static unsafe size_t FindMatchLengthWithLimit(byte *s1,
                                                              byte *s2,
                                                              size_t limit)
        {
            size_t matched  = 0;
            byte * s2_limit = s2 + limit;
            byte * s2_ptr   = s2;

            /* Find out how long the match is. We loop over the data 32 bits at a
             * time until we find a 32-bit block that doesn't match; then we find
             * the first non-matching bit and use that to calculate the total
             * length of the match. */
            while (s2_ptr <= s2_limit - 4 &&
                   *(uint *)(s2_ptr) ==
                   *(uint *)(s1 + matched))
            {
                s2_ptr  += 4;
                matched += 4;
            }
            while ((s2_ptr < s2_limit) && (s1[matched] == *s2_ptr))
            {
                ++s2_ptr;
                ++matched;
            }
            return(matched);
        }
Ejemplo n.º 5
0
            public static unsafe void InitBlockSplitter(
                ref MemoryManager m, BlockSplitterDistance *self, size_t alphabet_size,
                size_t min_block_size, double split_threshold, size_t num_symbols,
                BlockSplit *split, HistogramDistance **histograms, size_t *histograms_size)
            {
                size_t max_num_blocks = num_symbols / min_block_size + 1;

                /* We have to allocate one more histogram than the maximum number of block
                 * types for the current histogram when the meta-block is too big. */
                size_t max_num_types =
                    Math.Min(max_num_blocks, BROTLI_MAX_NUMBER_OF_BLOCK_TYPES + 1);

                self->alphabet_size_     = alphabet_size;
                self->min_block_size_    = min_block_size;
                self->split_threshold_   = split_threshold;
                self->num_blocks_        = 0;
                self->split_             = split;
                self->histograms_size_   = histograms_size;
                self->target_block_size_ = min_block_size;
                self->block_size_        = 0;
                self->curr_histogram_ix_ = 0;
                self->merge_last_count_  = 0;
                BrotliEnsureCapacity(ref m, sizeof(byte), (void **)&split->types, &split->types_alloc_size, max_num_blocks);
                BrotliEnsureCapacity(ref m, sizeof(uint), (void **)&split->lengths, &split->lengths_alloc_size, max_num_blocks);
                self->split_->num_blocks = max_num_blocks;
                *histograms_size = max_num_types;
                *histograms      = (HistogramDistance *)BrotliAllocate(ref m, *histograms_size * sizeof(HistogramDistance));
                self->histograms_ = *histograms;
                /* Clear only current histogram. */
                HistogramDistance.HistogramClear(&self->histograms_[0]);
                self->last_histogram_ix_0 = self->last_histogram_ix_1 = 0;
            }
Ejemplo n.º 6
0
 /* Here distance_code is an intermediate code, i.e. one of the special codes or
  * the actual distance increased by BROTLI_NUM_DISTANCE_SHORT_CODES - 1. */
 private static unsafe void PrefixEncodeCopyDistance(size_t distance_code,
                                                     size_t num_direct_codes,
                                                     size_t postfix_bits,
                                                     ushort *code,
                                                     uint *extra_bits)
 {
     if (distance_code < BROTLI_NUM_DISTANCE_SHORT_CODES + num_direct_codes)
     {
         *code       = (ushort)distance_code;
         *extra_bits = 0;
         return;
     }
     else
     {
         size_t dist = ((size_t)1 << (int)(postfix_bits + 2u)) +
                       (distance_code - BROTLI_NUM_DISTANCE_SHORT_CODES - num_direct_codes);
         size_t bucket       = Log2FloorNonZero(dist) - 1;
         size_t postfix_mask = (1u << (int)postfix_bits) - 1;
         size_t postfix      = dist & postfix_mask;
         size_t prefix       = (dist >> (int)bucket) & 1;
         size_t offset       = (2 + prefix) << (int)bucket;
         size_t nbits        = bucket - postfix_bits;
         *      code         = (ushort)(
             (BROTLI_NUM_DISTANCE_SHORT_CODES + num_direct_codes +
              ((2 * (nbits - 1) + prefix) << (int)postfix_bits) + postfix));
         *extra_bits = (uint)(
             (nbits << 24) | ((dist - offset) >> (int)postfix_bits));
     }
 }
Ejemplo n.º 7
0
 public abstract void CreateBackwardReferences(
     ushort *dictionary_hash,
     size_t num_bytes, size_t position,
     byte *ringbuffer, size_t ringbuffer_mask,
     BrotliEncoderParams *params_, HasherHandle hasher, int *dist_cache,
     size_t *last_insert_len, Command *commands, size_t *num_commands,
     size_t *num_literals);
Ejemplo n.º 8
0
            public override unsafe void StitchToPreviousBlock(HasherHandle handle, size_t num_bytes, size_t position,
                                                              byte *ringbuffer,
                                                              size_t ringbuffer_mask)
            {
                HashToBinaryTree *self = Self(handle);

                if (num_bytes >= HashTypeLength() - 1 &&
                    position >= MAX_TREE_COMP_LENGTH)
                {
                    /* Store the last `MAX_TREE_COMP_LENGTH - 1` positions in the hasher.
                     * These could not be calculated before, since they require knowledge
                     * of both the previous and the current block. */
                    size_t i_start = position - MAX_TREE_COMP_LENGTH + 1;
                    size_t i_end   = Math.Min(position, i_start + num_bytes);
                    size_t i;
                    for (i = i_start; i < i_end; ++i)
                    {
                        /* Maximum distance is window size - 16, see section 9.1. of the spec.
                         * Furthermore, we have to make sure that we don't look further back
                         * from the start of the next block than the window size, otherwise we
                         * could access already overwritten areas of the ring-buffer. */
                        size_t max_backward =
                            self->window_mask_ - Math.Max(
                                BROTLI_WINDOW_GAP - 1,
                                position - i);

                        /* We know that i + MAX_TREE_COMP_LENGTH <= position + num_bytes, i.e. the
                         * end of the current block and that we have at least
                         * MAX_TREE_COMP_LENGTH tail in the ring-buffer. */
                        StoreAndFindMatches(self, ringbuffer, i, ringbuffer_mask,
                                            MAX_TREE_COMP_LENGTH, max_backward, null, null);
                    }
                }
            }
Ejemplo n.º 9
0
        private static unsafe size_t DecideMultiByteStatsLevel(size_t pos, size_t len, size_t mask,
                                                               byte *data)
        {
            size_t *counts = stackalloc size_t[3];

            memset(counts, 0, 3 * sizeof(size_t));
            size_t max_utf8 = 1;  /* should be 2, but 1 compresses better. */
            size_t last_c   = 0;
            size_t i;

            for (i = 0; i < len; ++i)
            {
                size_t c = data[(pos + i) & mask];
                ++counts[UTF8Position(last_c, c, 2)];
                last_c = c;
            }
            if (counts[2] < 500)
            {
                max_utf8 = 1;
            }
            if (counts[1] + counts[2] < 25)
            {
                max_utf8 = 0;
            }
            return(max_utf8);
        }
Ejemplo n.º 10
0
 private static unsafe void InitDictionaryBackwardMatch(BackwardMatch *self,
                                                        size_t dist, size_t len, size_t len_code)
 {
     self->distance        = (uint)dist;
     self->length_and_code =
         (uint)((len << 5) | (len == len_code ? 0 : len_code));
 }
Ejemplo n.º 11
0
 /* This function writes bits into bytes in increasing addresses, and within
  * a byte least-significant-bit first.
  *
  * The function can write up to 56 bits in one go with WriteBits
  * Example: let's assume that 3 bits (Rs below) have been written already:
  *
  * BYTE-0     BYTE+1       BYTE+2
  *
  * 0000 0RRR    0000 0000    0000 0000
  *
  * Now, we could write 5 or less bits in MSB by just sifting by 3
  * and OR'ing to BYTE-0.
  *
  * For n bits, we take the last 5 bits, OR that with high bits in BYTE-0,
  * and locate the rest in BYTE+1, BYTE+2, etc. */
 private static unsafe void BrotliWriteBits(size_t n_bits,
                                            ulong bits,
                                            size_t *pos,
                                            byte *array)
 {
     if (BROTLI_LITTLE_ENDIAN)
     {
         byte *p = &array[*pos >> 3];
         ulong v = *p;
         v          |= bits << (int)(*pos & 7);
         *(ulong *)p = v; /* Set some bits. */
         *pos += n_bits;
     }
     else
     {
         /* implicit & 0xff is assumed for uint8_t arithmetics */
         byte * array_pos = &array[*pos >> 3];
         size_t bits_reserved_in_first_byte = (*pos & 7);
         size_t bits_left_to_write;
         bits <<= (int)bits_reserved_in_first_byte;
         *array_pos++ |= (byte)bits;
         for (bits_left_to_write = n_bits + bits_reserved_in_first_byte;
              bits_left_to_write >= 9;
              bits_left_to_write -= 8)
         {
             bits >>= 8;
             *array_pos++ = (byte)bits;
         }
         *array_pos = 0;
         *pos      += n_bits;
     }
 }
Ejemplo n.º 12
0
 public override unsafe void CreateBackwardReferences(ushort *dictionary_hash, size_t num_bytes,
                                                      size_t position, byte *ringbuffer, size_t ringbuffer_mask, BrotliEncoderParams *params_,
                                                      HasherHandle hasher, int *dist_cache, size_t *last_insert_len, Command *commands, size_t *num_commands,
                                                      size_t *num_literals)
 {
     throw new InvalidOperationException();
 }
Ejemplo n.º 13
0
 private static ushort GetInsertLengthCode(size_t insertlen)
 {
     if (insertlen < 6)
     {
         return((ushort)insertlen);
     }
     else if (insertlen < 130)
     {
         uint nbits = Log2FloorNonZero(insertlen - 2) - 1u;
         return((ushort)((nbits << 1) + ((insertlen - 2) >> (int)nbits) + 2));
     }
     else if (insertlen < 2114)
     {
         return((ushort)(Log2FloorNonZero(insertlen - 66) + 10));
     }
     else if (insertlen < 6210)
     {
         return(21);
     }
     else if (insertlen < 22594)
     {
         return(22);
     }
     else
     {
         return(23);
     }
 }
Ejemplo n.º 14
0
        private static unsafe void SetCost(uint *histogram, size_t histogram_size,
                                           float *cost)
        {
            size_t sum = 0;
            float  log2sum;
            size_t i;

            for (i = 0; i < histogram_size; i++)
            {
                sum += histogram[i];
            }
            log2sum = (float)FastLog2(sum);
            for (i = 0; i < histogram_size; i++)
            {
                if (histogram[i] == 0)
                {
                    cost[i] = log2sum + 2;
                    continue;
                }

                /* Shannon bits for this symbol. */
                cost[i] = log2sum - (float)FastLog2(histogram[i]);

                /* Cannot be coded with less than 1 bit */
                if (cost[i] < 1)
                {
                    cost[i] = 1;
                }
            }
        }
Ejemplo n.º 15
0
        private static unsafe void BrotliCreateBackwardReferences(
            size_t num_bytes,
            size_t position,
            byte *ringbuffer,
            size_t ringbuffer_mask,
            BrotliEncoderParams *params_,
            HasherHandle hasher,
            int *dist_cache,
            size_t *last_insert_len,
            Command *commands,
            size_t *num_commands,
            size_t *num_literals)
        {
            switch (params_->hasher.type)
            {
            case 2:
            case 3:
            case 4:
            case 5:
            case 6:
            case 40:
            case 41:
            case 42:
            case 54:
                fixed(ushort *ksdh = kStaticDictionaryHash)
                kHashers[params_->hasher.type].CreateBackwardReferences(ksdh, num_bytes,
                                                                        position, ringbuffer, ringbuffer_mask, params_, hasher, dist_cache,
                                                                        last_insert_len, commands, num_commands, num_literals);

                break;
            }
        }
Ejemplo n.º 16
0
        /* Returns the minimum possible copy length that can improve the cost of any */
        /* future position. */
        private static unsafe size_t ComputeMinimumCopyLength(float start_cost,
                                                              ZopfliNode *nodes,
                                                              size_t num_bytes,
                                                              size_t pos)
        {
            /* Compute the minimum possible cost of reaching any future position. */
            float  min_cost        = start_cost;
            size_t len             = 2;
            size_t next_len_bucket = 4;
            size_t next_len_offset = 10;

            while (pos + len <= num_bytes && nodes[pos + len].u.cost <= min_cost)
            {
                /* We already reached (pos + len) with no more cost than the minimum
                 * possible cost of reaching anything from this pos, so there is no point in
                 * looking for lengths <= len. */
                ++len;
                if (len == next_len_offset)
                {
                    /* We reached the next copy length code bucket, so we add one more
                     * extra bit to the minimum cost. */
                    min_cost        += 1.0f;
                    next_len_offset += next_len_bucket;
                    next_len_bucket *= 2;
                }
            }
            return(len);
        }
Ejemplo n.º 17
0
        /* REQUIRES: nodes[pos].cost < kInfinity
         * REQUIRES: nodes[0..pos] satisfies that "ZopfliNode array invariant". */
        private static unsafe uint ComputeDistanceShortcut(size_t block_start,
                                                           size_t pos,
                                                           size_t max_backward,
                                                           ZopfliNode *nodes)
        {
            size_t clen = ZopfliNodeCopyLength(&nodes[pos]);
            size_t ilen = nodes[pos].insert_length;
            size_t dist = ZopfliNodeCopyDistance(&nodes[pos]);

            /* Since |block_start + pos| is the end position of the command, the copy part
             * starts from |block_start + pos - clen|. Distances that are greater than
             * this or greater than |max_backward| are private static unsafe dictionary references, and
             * do not update the last distances. Also distance code 0 (last distance)
             * does not update the last distances. */
            if (pos == 0)
            {
                return(0);
            }
            else if (dist + clen <= block_start + pos &&
                     dist <= max_backward &&
                     ZopfliNodeDistanceCode(&nodes[pos]) > 0)
            {
                return((uint)pos);
            }
            else
            {
                return(nodes[pos - clen - ilen].u.shortcut);
            }
        }
Ejemplo n.º 18
0
        private static unsafe void ZopfliCostModelSetFromLiteralCosts(ZopfliCostModel *self,
                                                                      size_t position,
                                                                      byte *ringbuffer,
                                                                      size_t ringbuffer_mask)
        {
            float *literal_costs = self->literal_costs_;
            float *cost_dist     = self->cost_dist_;
            float *cost_cmd      = self->cost_cmd_;
            size_t num_bytes     = self->num_bytes_;
            size_t i;

            BrotliEstimateBitCostsForLiterals(position, num_bytes, ringbuffer_mask,
                                              ringbuffer, &literal_costs[1]);
            literal_costs[0] = 0.0f;
            for (i = 0; i < num_bytes; ++i)
            {
                literal_costs[i + 1] += literal_costs[i];
            }
            for (i = 0; i < BROTLI_NUM_COMMAND_SYMBOLS; ++i)
            {
                cost_cmd[i] = (float)FastLog2(11 + (uint)i);
            }
            for (i = 0; i < BROTLI_NUM_DISTANCE_SYMBOLS; ++i)
            {
                cost_dist[i] = (float)FastLog2(20 + (uint)i);
            }
            self->min_cost_cmd_ = (float)FastLog2(11);
        }
Ejemplo n.º 19
0
        private static unsafe void BrotliOptimizeHistograms(size_t num_direct_distance_codes,
                                                            size_t distance_postfix_bits,
                                                            MetaBlockSplit *mb)
        {
            byte * good_for_rle = stackalloc byte[BROTLI_NUM_COMMAND_SYMBOLS];
            size_t num_distance_codes;
            size_t i;

            for (i = 0; i < mb->literal_histograms_size; ++i)
            {
                BrotliOptimizeHuffmanCountsForRle(256, mb->literal_histograms[i].data_,
                                                  good_for_rle);
            }
            for (i = 0; i < mb->command_histograms_size; ++i)
            {
                BrotliOptimizeHuffmanCountsForRle(BROTLI_NUM_COMMAND_SYMBOLS,
                                                  mb->command_histograms[i].data_,
                                                  good_for_rle);
            }
            num_distance_codes = BROTLI_NUM_DISTANCE_SHORT_CODES +
                                 num_direct_distance_codes +
                                 ((2 * BROTLI_MAX_DISTANCE_BITS) << (int)distance_postfix_bits);
            for (i = 0; i < mb->distance_histograms_size; ++i)
            {
                BrotliOptimizeHuffmanCountsForRle(num_distance_codes,
                                                  mb->distance_histograms[i].data_,
                                                  good_for_rle);
            }
        }
Ejemplo n.º 20
0
        private static unsafe bool BrotliWarmupBitReader(BrotliBitReader *br)
        {
            size_t aligned_read_mask = (IntPtr.Size >> 1) - 1;

            /* Fixing alignment after unaligned BrotliFillWindow would result accumulator
             * overflow. If unalignment is caused by BrotliSafeReadBits, then there is
             * enough space in accumulator to fix alignment. */
            if (!BROTLI_ALIGNED_READ)
            {
                aligned_read_mask = 0;
            }
            if (BrotliGetAvailableBits(br) == 0)
            {
                if (!BrotliPullByte(br))
                {
                    return(false);
                }
            }

            while ((((size_t)br->next_in) & aligned_read_mask) != 0)
            {
                if (!BrotliPullByte(br))
                {
                    /* If we consumed all the input, we don't care about the alignment. */
                    return(true);
                }
            }
            return(true);
        }
Ejemplo n.º 21
0
        private static unsafe bool SearchInStaticDictionary(
            ushort *dictionary_hash,
            HasherHandle handle, byte *data, size_t max_length,
            size_t max_backward, HasherSearchResult *out_, bool shallow)
        {
            size_t        key;
            size_t        i;
            bool          is_match_found = false;
            HasherCommon *self           = GetHasherCommon(handle);

            if (self->dict_num_matches < (self->dict_num_lookups >> 7))
            {
                return(false);
            }
            key = Hash14(data) << 1;
            for (i = 0; i < (shallow ? 1u : 2u); ++i, ++key)
            {
                size_t item = dictionary_hash[key];
                self->dict_num_lookups++;
                if (item != 0)
                {
                    bool item_matches = TestStaticDictionaryItem(
                        item, data, max_length, max_backward, out_);
                    if (item_matches)
                    {
                        self->dict_num_matches++;
                        is_match_found = true;
                    }
                }
            }
            return(is_match_found);
        }
Ejemplo n.º 22
0
        private static unsafe void BrotliConvertBitDepthsToSymbols(byte *depth,
                                                                   size_t len,
                                                                   ushort *bits)
        {
            /* In Brotli, all bit depths are [1..15]
             * 0 bit depth means that the symbol does not exist. */
            ushort[] bl_count  = new ushort[MAX_HUFFMAN_BITS];
            ushort[] next_code = new ushort[MAX_HUFFMAN_BITS];
            size_t   i;
            int      code = 0;

            for (i = 0; i < len; ++i)
            {
                ++bl_count[depth[i]];
            }
            bl_count[0]  = 0;
            next_code[0] = 0;
            for (i = 1; i < MAX_HUFFMAN_BITS; ++i)
            {
                code         = (code + bl_count[i - 1]) << 1;
                next_code[i] = (ushort)code;
            }
            for (i = 0; i < len; ++i)
            {
                if (depth[i] != 0)
                {
                    bits[i] = BrotliReverseBits(depth[i], next_code[depth[i]]++);
                }
            }
        }
Ejemplo n.º 23
0
 private static unsafe void BrotliBuildMetaBlockGreedy(ref MemoryManager m,
                                                       byte *ringbuffer,
                                                       size_t pos,
                                                       size_t mask,
                                                       byte prev_byte,
                                                       byte prev_byte2,
                                                       ContextType literal_context_mode,
                                                       size_t num_contexts,
                                                       uint *static_context_map,
                                                       Command *commands,
                                                       size_t n_commands,
                                                       MetaBlockSplit *mb)
 {
     if (num_contexts == 1)
     {
         BrotliBuildMetaBlockGreedyInternal(ref m, ringbuffer, pos, mask, prev_byte,
                                            prev_byte2, literal_context_mode, 1, null, commands, n_commands, mb);
     }
     else
     {
         BrotliBuildMetaBlockGreedyInternal(ref m, ringbuffer, pos, mask, prev_byte,
                                            prev_byte2, literal_context_mode, num_contexts, static_context_map,
                                            commands, n_commands, mb);
     }
 }
Ejemplo n.º 24
0
        private static unsafe void DecideOverRleUse(byte *depth, size_t length,
                                                    bool *use_rle_for_non_zero,
                                                    bool *use_rle_for_zero)
        {
            size_t total_reps_zero     = 0;
            size_t total_reps_non_zero = 0;
            size_t count_reps_zero     = 1;
            size_t count_reps_non_zero = 1;
            size_t i;

            for (i = 0; i < length;)
            {
                byte   value = depth[i];
                size_t reps  = 1;
                size_t k;
                for (k = i + 1; k < length && depth[k] == value; ++k)
                {
                    ++reps;
                }
                if (reps >= 3 && value == 0)
                {
                    total_reps_zero += reps;
                    ++count_reps_zero;
                }
                if (reps >= 4 && value != 0)
                {
                    total_reps_non_zero += reps;
                    ++count_reps_non_zero;
                }
                i += reps;
            }
            *use_rle_for_non_zero =
                (total_reps_non_zero > count_reps_non_zero * 2);
            *use_rle_for_zero = (total_reps_zero > count_reps_zero * 2);
        }
Ejemplo n.º 25
0
            /* Find the best 'out_' histogram for each of the 'in' histograms.
             * When called, clusters[0..num_clusters) contains the unique values from
             * symbols[0..in_size), but this property is not preserved in this function.
             * Note: we assume that out_[]->bit_cost_ is already up-to-date. */
            public static void BrotliHistogramRemap(HistogramDistance *in_,
                                                    size_t in_size, uint *clusters, size_t num_clusters,
                                                    HistogramDistance *out_, uint *symbols)
            {
                size_t i;

                for (i = 0; i < in_size; ++i)
                {
                    uint   best_out  = i == 0 ? symbols[0] : symbols[i - 1];
                    double best_bits =
                        BrotliHistogramBitCostDistance(&in_[i], &out_[best_out]);
                    size_t j;
                    for (j = 0; j < num_clusters; ++j)
                    {
                        double cur_bits =
                            BrotliHistogramBitCostDistance(&in_[i], &out_[clusters[j]]);
                        if (cur_bits < best_bits)
                        {
                            best_bits = cur_bits;
                            best_out  = clusters[j];
                        }
                    }
                    symbols[i] = best_out;
                }

                /* Recompute each out_ based on raw and symbols. */
                for (i = 0; i < num_clusters; ++i)
                {
                    HistogramDistance.HistogramClear(&out_[clusters[i]]);
                }
                for (i = 0; i < in_size; ++i)
                {
                    HistogramDistance.HistogramAddHistogram(&out_[symbols[i]], &in_[i]);
                }
            }
Ejemplo n.º 26
0
        private static unsafe double ShannonEntropy(uint *population,
                                                    size_t size, size_t *total)
        {
            size_t sum            = 0;
            double retval         = 0;
            uint * population_end = population + size;
            size_t p;

            if ((size & 1) != 0)
            {
                p       = *population++;
                sum    += p;
                retval -= (double)p * FastLog2(p);
            }
            while (population < population_end)
            {
                p       = *population++;
                sum    += p;
                retval -= (double)p * FastLog2(p);
                p       = *population++;
                sum    += p;
                retval -= (double)p * FastLog2(p);
            }
            if (sum != 0)
            {
                retval += (double)sum * FastLog2(sum);
            }
            *total = sum;
            return(retval);
        }
Ejemplo n.º 27
0
        private void WriteCore(byte[] buffer, int offset, int count, Brotli.BrotliEncoderOperation operation) {
            bool flush = operation == Brotli.BrotliEncoderOperation.BROTLI_OPERATION_FLUSH ||
                         operation == Brotli.BrotliEncoderOperation.BROTLI_OPERATION_FINISH;

            byte[] out_buf = new byte[0x1FFFE];
            size_t available_in = count, available_out = out_buf.Length;
            fixed (byte* out_buf_ptr = out_buf)
            fixed (byte* buf_ptr = buffer) {
                byte* next_in = buf_ptr + offset;
                byte* next_out = out_buf_ptr;

                while ((!flush && available_in > 0) || flush) {
                    if (!Brotli.BrotliEncoderCompressStream(ref _encoderState,
                        operation, &available_in, &next_in,
                        &available_out, &next_out, null)) {
                        throw new InvalidDataException("Compression failed");
                    }

                    bool hasData = available_out != out_buf.Length;
                    if (hasData) {
                        int out_size = (int)(out_buf.Length - available_out);
                        _stream.Write(out_buf, 0, out_size);
                        available_out = out_buf.Length;
                        next_out = out_buf_ptr;
                    }

                    if (Brotli.BrotliEncoderIsFinished(ref _encoderState))
                        break;

                    if (!hasData && flush)
                        break;
                }
            }
        }
Ejemplo n.º 28
0
        /// <summary>
        /// Reads a number of decompressed bytes into the specified byte array.
        /// </summary>
        /// <param name="buffer">The array to store decompressed bytes.</param>
        /// <param name="offset">The byte offset in <paramref name="buffer"/> at which the read bytes will be placed.</param>
        /// <param name="count">The maximum number of decompressed bytes to read.</param>
        /// <returns>The number of bytes that were read into the byte array.</returns>
        public override int Read(byte[] buffer, int offset, int count) {
            if (_mode != CompressionMode.Decompress)
                throw new InvalidOperationException("Read is only supported in Decompress mode");

            EnsureNotDisposed();
            ValidateParameters(buffer, offset, count);

            int totalWritten = 0;
            while (offset < buffer.Length && _lastDecoderState != Brotli.BrotliDecoderResult.BROTLI_DECODER_RESULT_SUCCESS) {
                if (_lastDecoderState == Brotli.BrotliDecoderResult.BROTLI_DECODER_RESULT_NEEDS_MORE_INPUT) {
                    if (_bufferCount > 0 && _bufferOffset != 0) {
                        Array.Copy(_buffer, _bufferOffset, _buffer, 0, _bufferCount);
                    }
                    _bufferOffset = 0;

                    int numRead = 0;
                    while (_bufferCount < _buffer.Length && ((numRead = _stream.Read(_buffer, _bufferCount, _buffer.Length - _bufferCount)) > 0)) {
                        _bufferCount += numRead;
                        if (_bufferCount > _buffer.Length)
                            throw new InvalidDataException("Invalid input stream detected, more bytes supplied than expected.");
                    }

                    if (_bufferCount <= 0)
                        break;
                }

                size_t available_in = _bufferCount;
                size_t available_in_old = available_in;
                size_t available_out = count;
                size_t available_out_old = available_out;

                fixed (byte* out_buf_ptr = buffer)
                fixed (byte* in_buf_ptr = _buffer) {
                    byte* in_buf = in_buf_ptr + _bufferOffset;
                    byte* out_buf = out_buf_ptr + offset;
                    _lastDecoderState = Brotli.BrotliDecoderDecompressStream(ref _decoderState, &available_in, &in_buf,
                        &available_out, &out_buf, null);
                }

                if (_lastDecoderState == Brotli.BrotliDecoderResult.BROTLI_DECODER_RESULT_ERROR)
                    throw new InvalidDataException("Decompression failed with error code: " + _decoderState.error_code);

                size_t bytesConsumed = available_in_old - available_in;
                size_t bytesWritten = available_out_old - available_out;

                if (bytesConsumed > 0) {
                    _bufferOffset += (int) bytesConsumed;
                    _bufferCount -= (int) bytesConsumed;
                }

                if (bytesWritten > 0) {
                    totalWritten += (int)bytesWritten;
                    offset += (int)bytesWritten;
                    count -= (int)bytesWritten;
                }
            }

            return totalWritten;
        }
Ejemplo n.º 29
0
        public static unsafe byte[] DecompressBuffer(byte[] buffer, int offset, int length)
        {
            using (var ms = new MemoryStream()) {
                // Create the decoder state and intialise it.
                var s = BrotliCreateDecoderState();
                BrotliDecoderStateInit(ref s);

                // Create a 4k buffer to temporarily store decompressed contents.
                byte[] writeBuf = new byte[0x10000];

                // Pin the output buffer and the input buffer.
                fixed(byte *outBuffer = writeBuf)
                {
                    fixed(byte *inBuffer = buffer)
                    {
                        // Specify the length of the input buffer.
                        size_t len = length;

                        // Local vars for input/output buffer.
                        var bufPtr = inBuffer + offset;
                        var outPtr = outBuffer;

                        // Specify the amount of bytes available in the output buffer.
                        size_t availOut = writeBuf.Length;

                        // Total number of bytes decoded.
                        size_t total = 0;

                        // Main decompression loop.
                        BrotliDecoderResult result;

                        while (
                            (result =
                                 BrotliDecoderDecompressStream(ref s, &len, &bufPtr, &availOut, &outPtr, &total)) ==
                            BrotliDecoderResult.BROTLI_DECODER_RESULT_NEEDS_MORE_OUTPUT)
                        {
                            ms.Write(writeBuf, 0, (int)(writeBuf.Length - availOut));
                            availOut = writeBuf.Length;
                            outPtr   = outBuffer;
                        }

                        // Check the result and write final block.
                        if (result == BrotliDecoderResult.BROTLI_DECODER_RESULT_SUCCESS)
                        {
                            ms.Write(writeBuf, 0, (int)(writeBuf.Length - availOut));
                        }

                        // Cleanup and throw.
                        BrotliDecoderStateCleanup(ref s);
                        if (result != BrotliDecoderResult.BROTLI_DECODER_RESULT_SUCCESS)
                        {
                            throw new InvalidDataException("Decompress failed with error code: " + s.error_code);
                        }

                        return(ms.ToArray());
                    }
                }
            }
        }
Ejemplo n.º 30
0
            public override unsafe size_t HashMemAllocInBytes(BrotliEncoderParams *params_, bool one_shot,
                                                              size_t input_size)
            {
                size_t bucket_size = (size_t)1 << params_->hasher.bucket_bits;
                size_t block_size  = (size_t)1 << params_->hasher.block_bits;

                return(sizeof(HashLongestMatch) + bucket_size * (2 + 4 * block_size));
            }