Home | History | Annotate | Line # | Download | only in zopfli
deflate.c revision 1.1.1.1.8.2
      1  1.1.1.1.8.2  snj /*
      2  1.1.1.1.8.2  snj Copyright 2011 Google Inc. All Rights Reserved.
      3  1.1.1.1.8.2  snj 
      4  1.1.1.1.8.2  snj Licensed under the Apache License, Version 2.0 (the "License");
      5  1.1.1.1.8.2  snj you may not use this file except in compliance with the License.
      6  1.1.1.1.8.2  snj You may obtain a copy of the License at
      7  1.1.1.1.8.2  snj 
      8  1.1.1.1.8.2  snj     http://www.apache.org/licenses/LICENSE-2.0
      9  1.1.1.1.8.2  snj 
     10  1.1.1.1.8.2  snj Unless required by applicable law or agreed to in writing, software
     11  1.1.1.1.8.2  snj distributed under the License is distributed on an "AS IS" BASIS,
     12  1.1.1.1.8.2  snj WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  1.1.1.1.8.2  snj See the License for the specific language governing permissions and
     14  1.1.1.1.8.2  snj limitations under the License.
     15  1.1.1.1.8.2  snj 
     16  1.1.1.1.8.2  snj Author: lode.vandevenne (at) gmail.com (Lode Vandevenne)
     17  1.1.1.1.8.2  snj Author: jyrki.alakuijala (at) gmail.com (Jyrki Alakuijala)
     18  1.1.1.1.8.2  snj */
     19  1.1.1.1.8.2  snj 
     20  1.1.1.1.8.2  snj /*
     21  1.1.1.1.8.2  snj Modified by madler (at) alumni.caltech.edu (Mark Adler)
     22  1.1.1.1.8.2  snj Moved ZopfliInitOptions() from zopfli_lib.c.
     23  1.1.1.1.8.2  snj */
     24  1.1.1.1.8.2  snj 
     25  1.1.1.1.8.2  snj #include "deflate.h"
     26  1.1.1.1.8.2  snj 
     27  1.1.1.1.8.2  snj #include <assert.h>
     28  1.1.1.1.8.2  snj #include <stdio.h>
     29  1.1.1.1.8.2  snj #include <stdlib.h>
     30  1.1.1.1.8.2  snj 
     31  1.1.1.1.8.2  snj #include "blocksplitter.h"
     32  1.1.1.1.8.2  snj #include "lz77.h"
     33  1.1.1.1.8.2  snj #include "squeeze.h"
     34  1.1.1.1.8.2  snj #include "tree.h"
     35  1.1.1.1.8.2  snj 
     36  1.1.1.1.8.2  snj void ZopfliInitOptions(ZopfliOptions* options) {
     37  1.1.1.1.8.2  snj     options->verbose = 0;
     38  1.1.1.1.8.2  snj     options->numiterations = 15;
     39  1.1.1.1.8.2  snj     options->blocksplitting = 1;
     40  1.1.1.1.8.2  snj     options->blocksplittinglast = 0;
     41  1.1.1.1.8.2  snj     options->blocksplittingmax = 15;
     42  1.1.1.1.8.2  snj }
     43  1.1.1.1.8.2  snj 
     44  1.1.1.1.8.2  snj static void AddBit(int bit,
     45  1.1.1.1.8.2  snj                    unsigned char* bp, unsigned char** out, size_t* outsize) {
     46  1.1.1.1.8.2  snj   if (((*bp) & 7) == 0) ZOPFLI_APPEND_DATA(0, out, outsize);
     47  1.1.1.1.8.2  snj   (*out)[*outsize - 1] |= bit << ((*bp) & 7);
     48  1.1.1.1.8.2  snj   (*bp)++;
     49  1.1.1.1.8.2  snj }
     50  1.1.1.1.8.2  snj 
     51  1.1.1.1.8.2  snj static void AddBits(unsigned symbol, unsigned length,
     52  1.1.1.1.8.2  snj                     unsigned char* bp, unsigned char** out, size_t* outsize) {
     53  1.1.1.1.8.2  snj   /* TODO(lode): make more efficient (add more bits at once). */
     54  1.1.1.1.8.2  snj   unsigned i;
     55  1.1.1.1.8.2  snj   for (i = 0; i < length; i++) {
     56  1.1.1.1.8.2  snj     unsigned bit = (symbol >> i) & 1;
     57  1.1.1.1.8.2  snj     if (((*bp) & 7) == 0) ZOPFLI_APPEND_DATA(0, out, outsize);
     58  1.1.1.1.8.2  snj     (*out)[*outsize - 1] |= bit << ((*bp) & 7);
     59  1.1.1.1.8.2  snj     (*bp)++;
     60  1.1.1.1.8.2  snj   }
     61  1.1.1.1.8.2  snj }
     62  1.1.1.1.8.2  snj 
     63  1.1.1.1.8.2  snj /*
     64  1.1.1.1.8.2  snj Adds bits, like AddBits, but the order is inverted. The deflate specification
     65  1.1.1.1.8.2  snj uses both orders in one standard.
     66  1.1.1.1.8.2  snj */
     67  1.1.1.1.8.2  snj static void AddHuffmanBits(unsigned symbol, unsigned length,
     68  1.1.1.1.8.2  snj                            unsigned char* bp, unsigned char** out,
     69  1.1.1.1.8.2  snj                            size_t* outsize) {
     70  1.1.1.1.8.2  snj   /* TODO(lode): make more efficient (add more bits at once). */
     71  1.1.1.1.8.2  snj   unsigned i;
     72  1.1.1.1.8.2  snj   for (i = 0; i < length; i++) {
     73  1.1.1.1.8.2  snj     unsigned bit = (symbol >> (length - i - 1)) & 1;
     74  1.1.1.1.8.2  snj     if (((*bp) & 7) == 0) ZOPFLI_APPEND_DATA(0, out, outsize);
     75  1.1.1.1.8.2  snj     (*out)[*outsize - 1] |= bit << ((*bp) & 7);
     76  1.1.1.1.8.2  snj     (*bp)++;
     77  1.1.1.1.8.2  snj   }
     78  1.1.1.1.8.2  snj }
     79  1.1.1.1.8.2  snj 
     80  1.1.1.1.8.2  snj /*
     81  1.1.1.1.8.2  snj Ensures there are at least 2 distance codes to support buggy decoders.
     82  1.1.1.1.8.2  snj Zlib 1.2.1 and below have a bug where it fails if there isn't at least 1
     83  1.1.1.1.8.2  snj distance code (with length > 0), even though it's valid according to the
     84  1.1.1.1.8.2  snj deflate spec to have 0 distance codes. On top of that, some mobile phones
     85  1.1.1.1.8.2  snj require at least two distance codes. To support these decoders too (but
     86  1.1.1.1.8.2  snj potentially at the cost of a few bytes), add dummy code lengths of 1.
     87  1.1.1.1.8.2  snj References to this bug can be found in the changelog of
     88  1.1.1.1.8.2  snj Zlib 1.2.2 and here: http://www.jonof.id.au/forum/index.php?topic=515.0.
     89  1.1.1.1.8.2  snj 
     90  1.1.1.1.8.2  snj d_lengths: the 32 lengths of the distance codes.
     91  1.1.1.1.8.2  snj */
     92  1.1.1.1.8.2  snj static void PatchDistanceCodesForBuggyDecoders(unsigned* d_lengths) {
     93  1.1.1.1.8.2  snj   int num_dist_codes = 0; /* Amount of non-zero distance codes */
     94  1.1.1.1.8.2  snj   int i;
     95  1.1.1.1.8.2  snj   for (i = 0; i < 30 /* Ignore the two unused codes from the spec */; i++) {
     96  1.1.1.1.8.2  snj     if (d_lengths[i]) num_dist_codes++;
     97  1.1.1.1.8.2  snj     if (num_dist_codes >= 2) return; /* Two or more codes is fine. */
     98  1.1.1.1.8.2  snj   }
     99  1.1.1.1.8.2  snj 
    100  1.1.1.1.8.2  snj   if (num_dist_codes == 0) {
    101  1.1.1.1.8.2  snj     d_lengths[0] = d_lengths[1] = 1;
    102  1.1.1.1.8.2  snj   } else if (num_dist_codes == 1) {
    103  1.1.1.1.8.2  snj     d_lengths[d_lengths[0] ? 1 : 0] = 1;
    104  1.1.1.1.8.2  snj   }
    105  1.1.1.1.8.2  snj }
    106  1.1.1.1.8.2  snj 
    107  1.1.1.1.8.2  snj static void AddDynamicTree(const unsigned* ll_lengths,
    108  1.1.1.1.8.2  snj                            const unsigned* d_lengths,
    109  1.1.1.1.8.2  snj                            unsigned char* bp,
    110  1.1.1.1.8.2  snj                            unsigned char** out, size_t* outsize) {
    111  1.1.1.1.8.2  snj   unsigned* lld_lengths = 0;  /* All litlen and dist lengthts with ending zeros
    112  1.1.1.1.8.2  snj       trimmed together in one array. */
    113  1.1.1.1.8.2  snj   unsigned lld_total;  /* Size of lld_lengths. */
    114  1.1.1.1.8.2  snj   unsigned* rle = 0;  /* Runlength encoded version of lengths of litlen and dist
    115  1.1.1.1.8.2  snj       trees. */
    116  1.1.1.1.8.2  snj   unsigned* rle_bits = 0;  /* Extra bits for rle values 16, 17 and 18. */
    117  1.1.1.1.8.2  snj   size_t rle_size = 0;  /* Size of rle array. */
    118  1.1.1.1.8.2  snj   size_t rle_bits_size = 0;  /* Should have same value as rle_size. */
    119  1.1.1.1.8.2  snj   unsigned hlit = 29; /* 286 - 257 */
    120  1.1.1.1.8.2  snj   unsigned hdist = 29;  /* 32 - 1, but gzip does not like hdist > 29.*/
    121  1.1.1.1.8.2  snj   unsigned hclen;
    122  1.1.1.1.8.2  snj   size_t i, j;
    123  1.1.1.1.8.2  snj   size_t clcounts[19];
    124  1.1.1.1.8.2  snj   unsigned clcl[19];  /* Code length code lengths. */
    125  1.1.1.1.8.2  snj   unsigned clsymbols[19];
    126  1.1.1.1.8.2  snj   /* The order in which code length code lengths are encoded as per deflate. */
    127  1.1.1.1.8.2  snj   unsigned order[19] = {
    128  1.1.1.1.8.2  snj     16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15
    129  1.1.1.1.8.2  snj   };
    130  1.1.1.1.8.2  snj 
    131  1.1.1.1.8.2  snj   /* Trim zeros. */
    132  1.1.1.1.8.2  snj   while (hlit > 0 && ll_lengths[257 + hlit - 1] == 0) hlit--;
    133  1.1.1.1.8.2  snj   while (hdist > 0 && d_lengths[1 + hdist - 1] == 0) hdist--;
    134  1.1.1.1.8.2  snj 
    135  1.1.1.1.8.2  snj   lld_total = hlit + 257 + hdist + 1;
    136  1.1.1.1.8.2  snj   lld_lengths = (unsigned*)malloc(sizeof(*lld_lengths) * lld_total);
    137  1.1.1.1.8.2  snj   if (!lld_lengths) exit(-1); /* Allocation failed. */
    138  1.1.1.1.8.2  snj 
    139  1.1.1.1.8.2  snj   for (i = 0; i < lld_total; i++) {
    140  1.1.1.1.8.2  snj     lld_lengths[i] = i < 257 + hlit
    141  1.1.1.1.8.2  snj         ? ll_lengths[i] : d_lengths[i - 257 - hlit];
    142  1.1.1.1.8.2  snj     assert(lld_lengths[i] < 16);
    143  1.1.1.1.8.2  snj   }
    144  1.1.1.1.8.2  snj 
    145  1.1.1.1.8.2  snj   for (i = 0; i < lld_total; i++) {
    146  1.1.1.1.8.2  snj     size_t count = 0;
    147  1.1.1.1.8.2  snj     for (j = i; j < lld_total && lld_lengths[i] == lld_lengths[j]; j++) {
    148  1.1.1.1.8.2  snj       count++;
    149  1.1.1.1.8.2  snj     }
    150  1.1.1.1.8.2  snj     if (count >= 4 || (count >= 3 && lld_lengths[i] == 0)) {
    151  1.1.1.1.8.2  snj       if (lld_lengths[i] == 0) {
    152  1.1.1.1.8.2  snj         if (count > 10) {
    153  1.1.1.1.8.2  snj           if (count > 138) count = 138;
    154  1.1.1.1.8.2  snj           ZOPFLI_APPEND_DATA(18, &rle, &rle_size);
    155  1.1.1.1.8.2  snj           ZOPFLI_APPEND_DATA(count - 11, &rle_bits, &rle_bits_size);
    156  1.1.1.1.8.2  snj         } else {
    157  1.1.1.1.8.2  snj           ZOPFLI_APPEND_DATA(17, &rle, &rle_size);
    158  1.1.1.1.8.2  snj           ZOPFLI_APPEND_DATA(count - 3, &rle_bits, &rle_bits_size);
    159  1.1.1.1.8.2  snj         }
    160  1.1.1.1.8.2  snj       } else {
    161  1.1.1.1.8.2  snj         unsigned repeat = count - 1;  /* Since the first one is hardcoded. */
    162  1.1.1.1.8.2  snj         ZOPFLI_APPEND_DATA(lld_lengths[i], &rle, &rle_size);
    163  1.1.1.1.8.2  snj         ZOPFLI_APPEND_DATA(0, &rle_bits, &rle_bits_size);
    164  1.1.1.1.8.2  snj         while (repeat >= 6) {
    165  1.1.1.1.8.2  snj           ZOPFLI_APPEND_DATA(16, &rle, &rle_size);
    166  1.1.1.1.8.2  snj           ZOPFLI_APPEND_DATA(6 - 3, &rle_bits, &rle_bits_size);
    167  1.1.1.1.8.2  snj           repeat -= 6;
    168  1.1.1.1.8.2  snj         }
    169  1.1.1.1.8.2  snj         if (repeat >= 3) {
    170  1.1.1.1.8.2  snj           ZOPFLI_APPEND_DATA(16, &rle, &rle_size);
    171  1.1.1.1.8.2  snj           ZOPFLI_APPEND_DATA(3 - 3, &rle_bits, &rle_bits_size);
    172  1.1.1.1.8.2  snj           repeat -= 3;
    173  1.1.1.1.8.2  snj         }
    174  1.1.1.1.8.2  snj         while (repeat != 0) {
    175  1.1.1.1.8.2  snj           ZOPFLI_APPEND_DATA(lld_lengths[i], &rle, &rle_size);
    176  1.1.1.1.8.2  snj           ZOPFLI_APPEND_DATA(0, &rle_bits, &rle_bits_size);
    177  1.1.1.1.8.2  snj           repeat--;
    178  1.1.1.1.8.2  snj         }
    179  1.1.1.1.8.2  snj       }
    180  1.1.1.1.8.2  snj 
    181  1.1.1.1.8.2  snj       i += count - 1;
    182  1.1.1.1.8.2  snj     } else {
    183  1.1.1.1.8.2  snj       ZOPFLI_APPEND_DATA(lld_lengths[i], &rle, &rle_size);
    184  1.1.1.1.8.2  snj       ZOPFLI_APPEND_DATA(0, &rle_bits, &rle_bits_size);
    185  1.1.1.1.8.2  snj     }
    186  1.1.1.1.8.2  snj     assert(rle[rle_size - 1] <= 18);
    187  1.1.1.1.8.2  snj   }
    188  1.1.1.1.8.2  snj 
    189  1.1.1.1.8.2  snj   for (i = 0; i < 19; i++) {
    190  1.1.1.1.8.2  snj     clcounts[i] = 0;
    191  1.1.1.1.8.2  snj   }
    192  1.1.1.1.8.2  snj   for (i = 0; i < rle_size; i++) {
    193  1.1.1.1.8.2  snj     clcounts[rle[i]]++;
    194  1.1.1.1.8.2  snj   }
    195  1.1.1.1.8.2  snj 
    196  1.1.1.1.8.2  snj   ZopfliCalculateBitLengths(clcounts, 19, 7, clcl);
    197  1.1.1.1.8.2  snj   ZopfliLengthsToSymbols(clcl, 19, 7, clsymbols);
    198  1.1.1.1.8.2  snj 
    199  1.1.1.1.8.2  snj   hclen = 15;
    200  1.1.1.1.8.2  snj   /* Trim zeros. */
    201  1.1.1.1.8.2  snj   while (hclen > 0 && clcounts[order[hclen + 4 - 1]] == 0) hclen--;
    202  1.1.1.1.8.2  snj 
    203  1.1.1.1.8.2  snj   AddBits(hlit, 5, bp, out, outsize);
    204  1.1.1.1.8.2  snj   AddBits(hdist, 5, bp, out, outsize);
    205  1.1.1.1.8.2  snj   AddBits(hclen, 4, bp, out, outsize);
    206  1.1.1.1.8.2  snj 
    207  1.1.1.1.8.2  snj   for (i = 0; i < hclen + 4; i++) {
    208  1.1.1.1.8.2  snj     AddBits(clcl[order[i]], 3, bp, out, outsize);
    209  1.1.1.1.8.2  snj   }
    210  1.1.1.1.8.2  snj 
    211  1.1.1.1.8.2  snj   for (i = 0; i < rle_size; i++) {
    212  1.1.1.1.8.2  snj     unsigned symbol = clsymbols[rle[i]];
    213  1.1.1.1.8.2  snj     AddHuffmanBits(symbol, clcl[rle[i]], bp, out, outsize);
    214  1.1.1.1.8.2  snj     /* Extra bits. */
    215  1.1.1.1.8.2  snj     if (rle[i] == 16) AddBits(rle_bits[i], 2, bp, out, outsize);
    216  1.1.1.1.8.2  snj     else if (rle[i] == 17) AddBits(rle_bits[i], 3, bp, out, outsize);
    217  1.1.1.1.8.2  snj     else if (rle[i] == 18) AddBits(rle_bits[i], 7, bp, out, outsize);
    218  1.1.1.1.8.2  snj   }
    219  1.1.1.1.8.2  snj 
    220  1.1.1.1.8.2  snj   free(lld_lengths);
    221  1.1.1.1.8.2  snj   free(rle);
    222  1.1.1.1.8.2  snj   free(rle_bits);
    223  1.1.1.1.8.2  snj }
    224  1.1.1.1.8.2  snj 
    225  1.1.1.1.8.2  snj /*
    226  1.1.1.1.8.2  snj Gives the exact size of the tree, in bits, as it will be encoded in DEFLATE.
    227  1.1.1.1.8.2  snj */
    228  1.1.1.1.8.2  snj static size_t CalculateTreeSize(const unsigned* ll_lengths,
    229  1.1.1.1.8.2  snj                                 const unsigned* d_lengths,
    230  1.1.1.1.8.2  snj                                 size_t* ll_counts, size_t* d_counts) {
    231  1.1.1.1.8.2  snj   unsigned char* dummy = 0;
    232  1.1.1.1.8.2  snj   size_t dummysize = 0;
    233  1.1.1.1.8.2  snj   unsigned char bp = 0;
    234  1.1.1.1.8.2  snj 
    235  1.1.1.1.8.2  snj   (void)ll_counts;
    236  1.1.1.1.8.2  snj   (void)d_counts;
    237  1.1.1.1.8.2  snj 
    238  1.1.1.1.8.2  snj   AddDynamicTree(ll_lengths, d_lengths, &bp, &dummy, &dummysize);
    239  1.1.1.1.8.2  snj   free(dummy);
    240  1.1.1.1.8.2  snj 
    241  1.1.1.1.8.2  snj   return dummysize * 8 + (bp & 7);
    242  1.1.1.1.8.2  snj }
    243  1.1.1.1.8.2  snj 
    244  1.1.1.1.8.2  snj /*
    245  1.1.1.1.8.2  snj Adds all lit/len and dist codes from the lists as huffman symbols. Does not add
    246  1.1.1.1.8.2  snj end code 256. expected_data_size is the uncompressed block size, used for
    247  1.1.1.1.8.2  snj assert, but you can set it to 0 to not do the assertion.
    248  1.1.1.1.8.2  snj */
    249  1.1.1.1.8.2  snj static void AddLZ77Data(const unsigned short* litlens,
    250  1.1.1.1.8.2  snj                         const unsigned short* dists,
    251  1.1.1.1.8.2  snj                         size_t lstart, size_t lend,
    252  1.1.1.1.8.2  snj                         size_t expected_data_size,
    253  1.1.1.1.8.2  snj                         const unsigned* ll_symbols, const unsigned* ll_lengths,
    254  1.1.1.1.8.2  snj                         const unsigned* d_symbols, const unsigned* d_lengths,
    255  1.1.1.1.8.2  snj                         unsigned char* bp,
    256  1.1.1.1.8.2  snj                         unsigned char** out, size_t* outsize) {
    257  1.1.1.1.8.2  snj   size_t testlength = 0;
    258  1.1.1.1.8.2  snj   size_t i;
    259  1.1.1.1.8.2  snj 
    260  1.1.1.1.8.2  snj   for (i = lstart; i < lend; i++) {
    261  1.1.1.1.8.2  snj     unsigned dist = dists[i];
    262  1.1.1.1.8.2  snj     unsigned litlen = litlens[i];
    263  1.1.1.1.8.2  snj     if (dist == 0) {
    264  1.1.1.1.8.2  snj       assert(litlen < 256);
    265  1.1.1.1.8.2  snj       assert(ll_lengths[litlen] > 0);
    266  1.1.1.1.8.2  snj       AddHuffmanBits(ll_symbols[litlen], ll_lengths[litlen], bp, out, outsize);
    267  1.1.1.1.8.2  snj       testlength++;
    268  1.1.1.1.8.2  snj     } else {
    269  1.1.1.1.8.2  snj       unsigned lls = ZopfliGetLengthSymbol(litlen);
    270  1.1.1.1.8.2  snj       unsigned ds = ZopfliGetDistSymbol(dist);
    271  1.1.1.1.8.2  snj       assert(litlen >= 3 && litlen <= 288);
    272  1.1.1.1.8.2  snj       assert(ll_lengths[lls] > 0);
    273  1.1.1.1.8.2  snj       assert(d_lengths[ds] > 0);
    274  1.1.1.1.8.2  snj       AddHuffmanBits(ll_symbols[lls], ll_lengths[lls], bp, out, outsize);
    275  1.1.1.1.8.2  snj       AddBits(ZopfliGetLengthExtraBitsValue(litlen),
    276  1.1.1.1.8.2  snj               ZopfliGetLengthExtraBits(litlen),
    277  1.1.1.1.8.2  snj               bp, out, outsize);
    278  1.1.1.1.8.2  snj       AddHuffmanBits(d_symbols[ds], d_lengths[ds], bp, out, outsize);
    279  1.1.1.1.8.2  snj       AddBits(ZopfliGetDistExtraBitsValue(dist),
    280  1.1.1.1.8.2  snj               ZopfliGetDistExtraBits(dist),
    281  1.1.1.1.8.2  snj               bp, out, outsize);
    282  1.1.1.1.8.2  snj       testlength += litlen;
    283  1.1.1.1.8.2  snj     }
    284  1.1.1.1.8.2  snj   }
    285  1.1.1.1.8.2  snj   assert(expected_data_size == 0 || testlength == expected_data_size);
    286  1.1.1.1.8.2  snj }
    287  1.1.1.1.8.2  snj 
    288  1.1.1.1.8.2  snj static void GetFixedTree(unsigned* ll_lengths, unsigned* d_lengths) {
    289  1.1.1.1.8.2  snj   size_t i;
    290  1.1.1.1.8.2  snj   for (i = 0; i < 144; i++) ll_lengths[i] = 8;
    291  1.1.1.1.8.2  snj   for (i = 144; i < 256; i++) ll_lengths[i] = 9;
    292  1.1.1.1.8.2  snj   for (i = 256; i < 280; i++) ll_lengths[i] = 7;
    293  1.1.1.1.8.2  snj   for (i = 280; i < 288; i++) ll_lengths[i] = 8;
    294  1.1.1.1.8.2  snj   for (i = 0; i < 32; i++) d_lengths[i] = 5;
    295  1.1.1.1.8.2  snj }
    296  1.1.1.1.8.2  snj 
    297  1.1.1.1.8.2  snj /*
    298  1.1.1.1.8.2  snj Calculates size of the part after the header and tree of an LZ77 block, in bits.
    299  1.1.1.1.8.2  snj */
    300  1.1.1.1.8.2  snj static size_t CalculateBlockSymbolSize(const unsigned* ll_lengths,
    301  1.1.1.1.8.2  snj                                        const unsigned* d_lengths,
    302  1.1.1.1.8.2  snj                                        const unsigned short* litlens,
    303  1.1.1.1.8.2  snj                                        const unsigned short* dists,
    304  1.1.1.1.8.2  snj                                        size_t lstart, size_t lend) {
    305  1.1.1.1.8.2  snj   size_t result = 0;
    306  1.1.1.1.8.2  snj   size_t i;
    307  1.1.1.1.8.2  snj   for (i = lstart; i < lend; i++) {
    308  1.1.1.1.8.2  snj     if (dists[i] == 0) {
    309  1.1.1.1.8.2  snj       result += ll_lengths[litlens[i]];
    310  1.1.1.1.8.2  snj     } else {
    311  1.1.1.1.8.2  snj       result += ll_lengths[ZopfliGetLengthSymbol(litlens[i])];
    312  1.1.1.1.8.2  snj       result += d_lengths[ZopfliGetDistSymbol(dists[i])];
    313  1.1.1.1.8.2  snj       result += ZopfliGetLengthExtraBits(litlens[i]);
    314  1.1.1.1.8.2  snj       result += ZopfliGetDistExtraBits(dists[i]);
    315  1.1.1.1.8.2  snj     }
    316  1.1.1.1.8.2  snj   }
    317  1.1.1.1.8.2  snj   result += ll_lengths[256]; /*end symbol*/
    318  1.1.1.1.8.2  snj   return result;
    319  1.1.1.1.8.2  snj }
    320  1.1.1.1.8.2  snj 
    321  1.1.1.1.8.2  snj double ZopfliCalculateBlockSize(const unsigned short* litlens,
    322  1.1.1.1.8.2  snj                                 const unsigned short* dists,
    323  1.1.1.1.8.2  snj                                 size_t lstart, size_t lend, int btype) {
    324  1.1.1.1.8.2  snj   size_t ll_counts[288];
    325  1.1.1.1.8.2  snj   size_t d_counts[32];
    326  1.1.1.1.8.2  snj 
    327  1.1.1.1.8.2  snj   unsigned ll_lengths[288];
    328  1.1.1.1.8.2  snj   unsigned d_lengths[32];
    329  1.1.1.1.8.2  snj 
    330  1.1.1.1.8.2  snj   double result = 3; /*bfinal and btype bits*/
    331  1.1.1.1.8.2  snj 
    332  1.1.1.1.8.2  snj   assert(btype == 1 || btype == 2); /* This is not for uncompressed blocks. */
    333  1.1.1.1.8.2  snj 
    334  1.1.1.1.8.2  snj   if(btype == 1) {
    335  1.1.1.1.8.2  snj     GetFixedTree(ll_lengths, d_lengths);
    336  1.1.1.1.8.2  snj   } else {
    337  1.1.1.1.8.2  snj     ZopfliLZ77Counts(litlens, dists, lstart, lend, ll_counts, d_counts);
    338  1.1.1.1.8.2  snj     ZopfliCalculateBitLengths(ll_counts, 288, 15, ll_lengths);
    339  1.1.1.1.8.2  snj     ZopfliCalculateBitLengths(d_counts, 32, 15, d_lengths);
    340  1.1.1.1.8.2  snj     PatchDistanceCodesForBuggyDecoders(d_lengths);
    341  1.1.1.1.8.2  snj     result += CalculateTreeSize(ll_lengths, d_lengths, ll_counts, d_counts);
    342  1.1.1.1.8.2  snj   }
    343  1.1.1.1.8.2  snj 
    344  1.1.1.1.8.2  snj   result += CalculateBlockSymbolSize(
    345  1.1.1.1.8.2  snj       ll_lengths, d_lengths, litlens, dists, lstart, lend);
    346  1.1.1.1.8.2  snj 
    347  1.1.1.1.8.2  snj   return result;
    348  1.1.1.1.8.2  snj }
    349  1.1.1.1.8.2  snj 
    350  1.1.1.1.8.2  snj /*
    351  1.1.1.1.8.2  snj Adds a deflate block with the given LZ77 data to the output.
    352  1.1.1.1.8.2  snj options: global program options
    353  1.1.1.1.8.2  snj btype: the block type, must be 1 or 2
    354  1.1.1.1.8.2  snj final: whether to set the "final" bit on this block, must be the last block
    355  1.1.1.1.8.2  snj litlens: literal/length array of the LZ77 data, in the same format as in
    356  1.1.1.1.8.2  snj     ZopfliLZ77Store.
    357  1.1.1.1.8.2  snj dists: distance array of the LZ77 data, in the same format as in
    358  1.1.1.1.8.2  snj     ZopfliLZ77Store.
    359  1.1.1.1.8.2  snj lstart: where to start in the LZ77 data
    360  1.1.1.1.8.2  snj lend: where to end in the LZ77 data (not inclusive)
    361  1.1.1.1.8.2  snj expected_data_size: the uncompressed block size, used for assert, but you can
    362  1.1.1.1.8.2  snj   set it to 0 to not do the assertion.
    363  1.1.1.1.8.2  snj bp: output bit pointer
    364  1.1.1.1.8.2  snj out: dynamic output array to append to
    365  1.1.1.1.8.2  snj outsize: dynamic output array size
    366  1.1.1.1.8.2  snj */
    367  1.1.1.1.8.2  snj static void AddLZ77Block(const ZopfliOptions* options, int btype, int final,
    368  1.1.1.1.8.2  snj                          const unsigned short* litlens,
    369  1.1.1.1.8.2  snj                          const unsigned short* dists,
    370  1.1.1.1.8.2  snj                          size_t lstart, size_t lend,
    371  1.1.1.1.8.2  snj                          size_t expected_data_size,
    372  1.1.1.1.8.2  snj                          unsigned char* bp, unsigned char** out, size_t* outsize) {
    373  1.1.1.1.8.2  snj   size_t ll_counts[288];
    374  1.1.1.1.8.2  snj   size_t d_counts[32];
    375  1.1.1.1.8.2  snj   unsigned ll_lengths[288];
    376  1.1.1.1.8.2  snj   unsigned d_lengths[32];
    377  1.1.1.1.8.2  snj   unsigned ll_symbols[288];
    378  1.1.1.1.8.2  snj   unsigned d_symbols[32];
    379  1.1.1.1.8.2  snj   size_t detect_block_size = *outsize;
    380  1.1.1.1.8.2  snj   size_t compressed_size;
    381  1.1.1.1.8.2  snj   size_t uncompressed_size = 0;
    382  1.1.1.1.8.2  snj   size_t i;
    383  1.1.1.1.8.2  snj 
    384  1.1.1.1.8.2  snj   AddBit(final, bp, out, outsize);
    385  1.1.1.1.8.2  snj   AddBit(btype & 1, bp, out, outsize);
    386  1.1.1.1.8.2  snj   AddBit((btype & 2) >> 1, bp, out, outsize);
    387  1.1.1.1.8.2  snj 
    388  1.1.1.1.8.2  snj   if (btype == 1) {
    389  1.1.1.1.8.2  snj     /* Fixed block. */
    390  1.1.1.1.8.2  snj     GetFixedTree(ll_lengths, d_lengths);
    391  1.1.1.1.8.2  snj   } else {
    392  1.1.1.1.8.2  snj     /* Dynamic block. */
    393  1.1.1.1.8.2  snj     unsigned detect_tree_size;
    394  1.1.1.1.8.2  snj     assert(btype == 2);
    395  1.1.1.1.8.2  snj     ZopfliLZ77Counts(litlens, dists, lstart, lend, ll_counts, d_counts);
    396  1.1.1.1.8.2  snj     ZopfliCalculateBitLengths(ll_counts, 288, 15, ll_lengths);
    397  1.1.1.1.8.2  snj     ZopfliCalculateBitLengths(d_counts, 32, 15, d_lengths);
    398  1.1.1.1.8.2  snj     PatchDistanceCodesForBuggyDecoders(d_lengths);
    399  1.1.1.1.8.2  snj     detect_tree_size = *outsize;
    400  1.1.1.1.8.2  snj     AddDynamicTree(ll_lengths, d_lengths, bp, out, outsize);
    401  1.1.1.1.8.2  snj     if (options->verbose) {
    402  1.1.1.1.8.2  snj       fprintf(stderr, "treesize: %d\n", (int)(*outsize - detect_tree_size));
    403  1.1.1.1.8.2  snj     }
    404  1.1.1.1.8.2  snj 
    405  1.1.1.1.8.2  snj     /* Assert that for every present symbol, the code length is non-zero. */
    406  1.1.1.1.8.2  snj     /* TODO(lode): remove this in release version. */
    407  1.1.1.1.8.2  snj     for (i = 0; i < 288; i++) assert(ll_counts[i] == 0 || ll_lengths[i] > 0);
    408  1.1.1.1.8.2  snj     for (i = 0; i < 32; i++) assert(d_counts[i] == 0 || d_lengths[i] > 0);
    409  1.1.1.1.8.2  snj   }
    410  1.1.1.1.8.2  snj 
    411  1.1.1.1.8.2  snj   ZopfliLengthsToSymbols(ll_lengths, 288, 15, ll_symbols);
    412  1.1.1.1.8.2  snj   ZopfliLengthsToSymbols(d_lengths, 32, 15, d_symbols);
    413  1.1.1.1.8.2  snj 
    414  1.1.1.1.8.2  snj   detect_block_size = *outsize;
    415  1.1.1.1.8.2  snj   AddLZ77Data(litlens, dists, lstart, lend, expected_data_size,
    416  1.1.1.1.8.2  snj               ll_symbols, ll_lengths, d_symbols, d_lengths,
    417  1.1.1.1.8.2  snj               bp, out, outsize);
    418  1.1.1.1.8.2  snj   /* End symbol. */
    419  1.1.1.1.8.2  snj   AddHuffmanBits(ll_symbols[256], ll_lengths[256], bp, out, outsize);
    420  1.1.1.1.8.2  snj 
    421  1.1.1.1.8.2  snj   for (i = lstart; i < lend; i++) {
    422  1.1.1.1.8.2  snj     uncompressed_size += dists[i] == 0 ? 1 : litlens[i];
    423  1.1.1.1.8.2  snj   }
    424  1.1.1.1.8.2  snj   compressed_size = *outsize - detect_block_size;
    425  1.1.1.1.8.2  snj   if (options->verbose) {
    426  1.1.1.1.8.2  snj     fprintf(stderr, "compressed block size: %d (%dk) (unc: %d)\n",
    427  1.1.1.1.8.2  snj            (int)compressed_size, (int)(compressed_size / 1024),
    428  1.1.1.1.8.2  snj            (int)(uncompressed_size));
    429  1.1.1.1.8.2  snj   }
    430  1.1.1.1.8.2  snj }
    431  1.1.1.1.8.2  snj 
    432  1.1.1.1.8.2  snj static void DeflateDynamicBlock(const ZopfliOptions* options, int final,
    433  1.1.1.1.8.2  snj                                 const unsigned char* in,
    434  1.1.1.1.8.2  snj                                 size_t instart, size_t inend,
    435  1.1.1.1.8.2  snj                                 unsigned char* bp,
    436  1.1.1.1.8.2  snj                                 unsigned char** out, size_t* outsize) {
    437  1.1.1.1.8.2  snj   ZopfliBlockState s;
    438  1.1.1.1.8.2  snj   size_t blocksize = inend - instart;
    439  1.1.1.1.8.2  snj   ZopfliLZ77Store store;
    440  1.1.1.1.8.2  snj   int btype = 2;
    441  1.1.1.1.8.2  snj 
    442  1.1.1.1.8.2  snj   ZopfliInitLZ77Store(&store);
    443  1.1.1.1.8.2  snj 
    444  1.1.1.1.8.2  snj   s.options = options;
    445  1.1.1.1.8.2  snj   s.blockstart = instart;
    446  1.1.1.1.8.2  snj   s.blockend = inend;
    447  1.1.1.1.8.2  snj #ifdef ZOPFLI_LONGEST_MATCH_CACHE
    448  1.1.1.1.8.2  snj   s.lmc = (ZopfliLongestMatchCache*)malloc(sizeof(ZopfliLongestMatchCache));
    449  1.1.1.1.8.2  snj   ZopfliInitCache(blocksize, s.lmc);
    450  1.1.1.1.8.2  snj #endif
    451  1.1.1.1.8.2  snj 
    452  1.1.1.1.8.2  snj   ZopfliLZ77Optimal(&s, in, instart, inend, &store);
    453  1.1.1.1.8.2  snj 
    454  1.1.1.1.8.2  snj   /* For small block, encoding with fixed tree can be smaller. For large block,
    455  1.1.1.1.8.2  snj   don't bother doing this expensive test, dynamic tree will be better.*/
    456  1.1.1.1.8.2  snj   if (store.size < 1000) {
    457  1.1.1.1.8.2  snj     double dyncost, fixedcost;
    458  1.1.1.1.8.2  snj     ZopfliLZ77Store fixedstore;
    459  1.1.1.1.8.2  snj     ZopfliInitLZ77Store(&fixedstore);
    460  1.1.1.1.8.2  snj     ZopfliLZ77OptimalFixed(&s, in, instart, inend, &fixedstore);
    461  1.1.1.1.8.2  snj     dyncost = ZopfliCalculateBlockSize(store.litlens, store.dists,
    462  1.1.1.1.8.2  snj         0, store.size, 2);
    463  1.1.1.1.8.2  snj     fixedcost = ZopfliCalculateBlockSize(fixedstore.litlens, fixedstore.dists,
    464  1.1.1.1.8.2  snj         0, fixedstore.size, 1);
    465  1.1.1.1.8.2  snj     if (fixedcost < dyncost) {
    466  1.1.1.1.8.2  snj       btype = 1;
    467  1.1.1.1.8.2  snj       ZopfliCleanLZ77Store(&store);
    468  1.1.1.1.8.2  snj       store = fixedstore;
    469  1.1.1.1.8.2  snj     } else {
    470  1.1.1.1.8.2  snj       ZopfliCleanLZ77Store(&fixedstore);
    471  1.1.1.1.8.2  snj     }
    472  1.1.1.1.8.2  snj   }
    473  1.1.1.1.8.2  snj 
    474  1.1.1.1.8.2  snj   AddLZ77Block(s.options, btype, final,
    475  1.1.1.1.8.2  snj                store.litlens, store.dists, 0, store.size,
    476  1.1.1.1.8.2  snj                blocksize, bp, out, outsize);
    477  1.1.1.1.8.2  snj 
    478  1.1.1.1.8.2  snj #ifdef ZOPFLI_LONGEST_MATCH_CACHE
    479  1.1.1.1.8.2  snj   ZopfliCleanCache(s.lmc);
    480  1.1.1.1.8.2  snj   free(s.lmc);
    481  1.1.1.1.8.2  snj #endif
    482  1.1.1.1.8.2  snj   ZopfliCleanLZ77Store(&store);
    483  1.1.1.1.8.2  snj }
    484  1.1.1.1.8.2  snj 
    485  1.1.1.1.8.2  snj static void DeflateFixedBlock(const ZopfliOptions* options, int final,
    486  1.1.1.1.8.2  snj                               const unsigned char* in,
    487  1.1.1.1.8.2  snj                               size_t instart, size_t inend,
    488  1.1.1.1.8.2  snj                               unsigned char* bp,
    489  1.1.1.1.8.2  snj                               unsigned char** out, size_t* outsize) {
    490  1.1.1.1.8.2  snj   ZopfliBlockState s;
    491  1.1.1.1.8.2  snj   size_t blocksize = inend - instart;
    492  1.1.1.1.8.2  snj   ZopfliLZ77Store store;
    493  1.1.1.1.8.2  snj 
    494  1.1.1.1.8.2  snj   ZopfliInitLZ77Store(&store);
    495  1.1.1.1.8.2  snj 
    496  1.1.1.1.8.2  snj   s.options = options;
    497  1.1.1.1.8.2  snj   s.blockstart = instart;
    498  1.1.1.1.8.2  snj   s.blockend = inend;
    499  1.1.1.1.8.2  snj #ifdef ZOPFLI_LONGEST_MATCH_CACHE
    500  1.1.1.1.8.2  snj   s.lmc = (ZopfliLongestMatchCache*)malloc(sizeof(ZopfliLongestMatchCache));
    501  1.1.1.1.8.2  snj   ZopfliInitCache(blocksize, s.lmc);
    502  1.1.1.1.8.2  snj #endif
    503  1.1.1.1.8.2  snj 
    504  1.1.1.1.8.2  snj   ZopfliLZ77OptimalFixed(&s, in, instart, inend, &store);
    505  1.1.1.1.8.2  snj 
    506  1.1.1.1.8.2  snj   AddLZ77Block(s.options, 1, final, store.litlens, store.dists, 0, store.size,
    507  1.1.1.1.8.2  snj                blocksize, bp, out, outsize);
    508  1.1.1.1.8.2  snj 
    509  1.1.1.1.8.2  snj #ifdef ZOPFLI_LONGEST_MATCH_CACHE
    510  1.1.1.1.8.2  snj   ZopfliCleanCache(s.lmc);
    511  1.1.1.1.8.2  snj   free(s.lmc);
    512  1.1.1.1.8.2  snj #endif
    513  1.1.1.1.8.2  snj   ZopfliCleanLZ77Store(&store);
    514  1.1.1.1.8.2  snj }
    515  1.1.1.1.8.2  snj 
    516  1.1.1.1.8.2  snj static void DeflateNonCompressedBlock(const ZopfliOptions* options, int final,
    517  1.1.1.1.8.2  snj                                       const unsigned char* in, size_t instart,
    518  1.1.1.1.8.2  snj                                       size_t inend,
    519  1.1.1.1.8.2  snj                                       unsigned char* bp,
    520  1.1.1.1.8.2  snj                                       unsigned char** out, size_t* outsize) {
    521  1.1.1.1.8.2  snj   size_t i;
    522  1.1.1.1.8.2  snj   size_t blocksize = inend - instart;
    523  1.1.1.1.8.2  snj   unsigned short nlen = ~blocksize;
    524  1.1.1.1.8.2  snj 
    525  1.1.1.1.8.2  snj   (void)options;
    526  1.1.1.1.8.2  snj   assert(blocksize < 65536);  /* Non compressed blocks are max this size. */
    527  1.1.1.1.8.2  snj 
    528  1.1.1.1.8.2  snj   AddBit(final, bp, out, outsize);
    529  1.1.1.1.8.2  snj   /* BTYPE 00 */
    530  1.1.1.1.8.2  snj   AddBit(0, bp, out, outsize);
    531  1.1.1.1.8.2  snj   AddBit(0, bp, out, outsize);
    532  1.1.1.1.8.2  snj 
    533  1.1.1.1.8.2  snj   /* Any bits of input up to the next byte boundary are ignored. */
    534  1.1.1.1.8.2  snj   *bp = 0;
    535  1.1.1.1.8.2  snj 
    536  1.1.1.1.8.2  snj   ZOPFLI_APPEND_DATA(blocksize % 256, out, outsize);
    537  1.1.1.1.8.2  snj   ZOPFLI_APPEND_DATA((blocksize / 256) % 256, out, outsize);
    538  1.1.1.1.8.2  snj   ZOPFLI_APPEND_DATA(nlen % 256, out, outsize);
    539  1.1.1.1.8.2  snj   ZOPFLI_APPEND_DATA((nlen / 256) % 256, out, outsize);
    540  1.1.1.1.8.2  snj 
    541  1.1.1.1.8.2  snj   for (i = instart; i < inend; i++) {
    542  1.1.1.1.8.2  snj     ZOPFLI_APPEND_DATA(in[i], out, outsize);
    543  1.1.1.1.8.2  snj   }
    544  1.1.1.1.8.2  snj }
    545  1.1.1.1.8.2  snj 
    546  1.1.1.1.8.2  snj static void DeflateBlock(const ZopfliOptions* options,
    547  1.1.1.1.8.2  snj                          int btype, int final,
    548  1.1.1.1.8.2  snj                          const unsigned char* in, size_t instart, size_t inend,
    549  1.1.1.1.8.2  snj                          unsigned char* bp,
    550  1.1.1.1.8.2  snj                          unsigned char** out, size_t* outsize) {
    551  1.1.1.1.8.2  snj   if (btype == 0) {
    552  1.1.1.1.8.2  snj     DeflateNonCompressedBlock(
    553  1.1.1.1.8.2  snj         options, final, in, instart, inend, bp, out, outsize);
    554  1.1.1.1.8.2  snj   } else if (btype == 1) {
    555  1.1.1.1.8.2  snj      DeflateFixedBlock(options, final, in, instart, inend, bp, out, outsize);
    556  1.1.1.1.8.2  snj   } else {
    557  1.1.1.1.8.2  snj     assert (btype == 2);
    558  1.1.1.1.8.2  snj     DeflateDynamicBlock(options, final, in, instart, inend, bp, out, outsize);
    559  1.1.1.1.8.2  snj   }
    560  1.1.1.1.8.2  snj }
    561  1.1.1.1.8.2  snj 
    562  1.1.1.1.8.2  snj /*
    563  1.1.1.1.8.2  snj Does squeeze strategy where first block splitting is done, then each block is
    564  1.1.1.1.8.2  snj squeezed.
    565  1.1.1.1.8.2  snj Parameters: see description of the ZopfliDeflate function.
    566  1.1.1.1.8.2  snj */
    567  1.1.1.1.8.2  snj static void DeflateSplittingFirst(const ZopfliOptions* options,
    568  1.1.1.1.8.2  snj                                   int btype, int final,
    569  1.1.1.1.8.2  snj                                   const unsigned char* in,
    570  1.1.1.1.8.2  snj                                   size_t instart, size_t inend,
    571  1.1.1.1.8.2  snj                                   unsigned char* bp,
    572  1.1.1.1.8.2  snj                                   unsigned char** out, size_t* outsize) {
    573  1.1.1.1.8.2  snj   size_t i;
    574  1.1.1.1.8.2  snj   size_t* splitpoints = 0;
    575  1.1.1.1.8.2  snj   size_t npoints = 0;
    576  1.1.1.1.8.2  snj   if (btype == 0) {
    577  1.1.1.1.8.2  snj     ZopfliBlockSplitSimple(in, instart, inend, 65535, &splitpoints, &npoints);
    578  1.1.1.1.8.2  snj   } else if (btype == 1) {
    579  1.1.1.1.8.2  snj     /* If all blocks are fixed tree, splitting into separate blocks only
    580  1.1.1.1.8.2  snj     increases the total size. Leave npoints at 0, this represents 1 block. */
    581  1.1.1.1.8.2  snj   } else {
    582  1.1.1.1.8.2  snj     ZopfliBlockSplit(options, in, instart, inend,
    583  1.1.1.1.8.2  snj                      options->blocksplittingmax, &splitpoints, &npoints);
    584  1.1.1.1.8.2  snj   }
    585  1.1.1.1.8.2  snj 
    586  1.1.1.1.8.2  snj   for (i = 0; i <= npoints; i++) {
    587  1.1.1.1.8.2  snj     size_t start = i == 0 ? instart : splitpoints[i - 1];
    588  1.1.1.1.8.2  snj     size_t end = i == npoints ? inend : splitpoints[i];
    589  1.1.1.1.8.2  snj     DeflateBlock(options, btype, i == npoints && final, in, start, end,
    590  1.1.1.1.8.2  snj                  bp, out, outsize);
    591  1.1.1.1.8.2  snj   }
    592  1.1.1.1.8.2  snj 
    593  1.1.1.1.8.2  snj   free(splitpoints);
    594  1.1.1.1.8.2  snj }
    595  1.1.1.1.8.2  snj 
    596  1.1.1.1.8.2  snj /*
    597  1.1.1.1.8.2  snj Does squeeze strategy where first the best possible lz77 is done, and then based
    598  1.1.1.1.8.2  snj on that data, block splitting is done.
    599  1.1.1.1.8.2  snj Parameters: see description of the ZopfliDeflate function.
    600  1.1.1.1.8.2  snj */
    601  1.1.1.1.8.2  snj static void DeflateSplittingLast(const ZopfliOptions* options,
    602  1.1.1.1.8.2  snj                                  int btype, int final,
    603  1.1.1.1.8.2  snj                                  const unsigned char* in,
    604  1.1.1.1.8.2  snj                                  size_t instart, size_t inend,
    605  1.1.1.1.8.2  snj                                  unsigned char* bp,
    606  1.1.1.1.8.2  snj                                  unsigned char** out, size_t* outsize) {
    607  1.1.1.1.8.2  snj   size_t i;
    608  1.1.1.1.8.2  snj   ZopfliBlockState s;
    609  1.1.1.1.8.2  snj   ZopfliLZ77Store store;
    610  1.1.1.1.8.2  snj   size_t* splitpoints = 0;
    611  1.1.1.1.8.2  snj   size_t npoints = 0;
    612  1.1.1.1.8.2  snj 
    613  1.1.1.1.8.2  snj   if (btype == 0) {
    614  1.1.1.1.8.2  snj     /* This function only supports LZ77 compression. DeflateSplittingFirst
    615  1.1.1.1.8.2  snj        supports the special case of noncompressed data. Punt it to that one. */
    616  1.1.1.1.8.2  snj     DeflateSplittingFirst(options, btype, final,
    617  1.1.1.1.8.2  snj                           in, instart, inend,
    618  1.1.1.1.8.2  snj                           bp, out, outsize);
    619  1.1.1.1.8.2  snj   }
    620  1.1.1.1.8.2  snj   assert(btype == 1 || btype == 2);
    621  1.1.1.1.8.2  snj 
    622  1.1.1.1.8.2  snj   ZopfliInitLZ77Store(&store);
    623  1.1.1.1.8.2  snj 
    624  1.1.1.1.8.2  snj   s.options = options;
    625  1.1.1.1.8.2  snj   s.blockstart = instart;
    626  1.1.1.1.8.2  snj   s.blockend = inend;
    627  1.1.1.1.8.2  snj #ifdef ZOPFLI_LONGEST_MATCH_CACHE
    628  1.1.1.1.8.2  snj   s.lmc = (ZopfliLongestMatchCache*)malloc(sizeof(ZopfliLongestMatchCache));
    629  1.1.1.1.8.2  snj   ZopfliInitCache(inend - instart, s.lmc);
    630  1.1.1.1.8.2  snj #endif
    631  1.1.1.1.8.2  snj 
    632  1.1.1.1.8.2  snj   if (btype == 2) {
    633  1.1.1.1.8.2  snj     ZopfliLZ77Optimal(&s, in, instart, inend, &store);
    634  1.1.1.1.8.2  snj   } else {
    635  1.1.1.1.8.2  snj     assert (btype == 1);
    636  1.1.1.1.8.2  snj     ZopfliLZ77OptimalFixed(&s, in, instart, inend, &store);
    637  1.1.1.1.8.2  snj   }
    638  1.1.1.1.8.2  snj 
    639  1.1.1.1.8.2  snj   if (btype == 1) {
    640  1.1.1.1.8.2  snj     /* If all blocks are fixed tree, splitting into separate blocks only
    641  1.1.1.1.8.2  snj     increases the total size. Leave npoints at 0, this represents 1 block. */
    642  1.1.1.1.8.2  snj   } else {
    643  1.1.1.1.8.2  snj     ZopfliBlockSplitLZ77(options, store.litlens, store.dists, store.size,
    644  1.1.1.1.8.2  snj                          options->blocksplittingmax, &splitpoints, &npoints);
    645  1.1.1.1.8.2  snj   }
    646  1.1.1.1.8.2  snj 
    647  1.1.1.1.8.2  snj   for (i = 0; i <= npoints; i++) {
    648  1.1.1.1.8.2  snj     size_t start = i == 0 ? 0 : splitpoints[i - 1];
    649  1.1.1.1.8.2  snj     size_t end = i == npoints ? store.size : splitpoints[i];
    650  1.1.1.1.8.2  snj     AddLZ77Block(options, btype, i == npoints && final,
    651  1.1.1.1.8.2  snj                  store.litlens, store.dists, start, end, 0,
    652  1.1.1.1.8.2  snj                  bp, out, outsize);
    653  1.1.1.1.8.2  snj   }
    654  1.1.1.1.8.2  snj 
    655  1.1.1.1.8.2  snj #ifdef ZOPFLI_LONGEST_MATCH_CACHE
    656  1.1.1.1.8.2  snj   ZopfliCleanCache(s.lmc);
    657  1.1.1.1.8.2  snj   free(s.lmc);
    658  1.1.1.1.8.2  snj #endif
    659  1.1.1.1.8.2  snj 
    660  1.1.1.1.8.2  snj   ZopfliCleanLZ77Store(&store);
    661  1.1.1.1.8.2  snj }
    662  1.1.1.1.8.2  snj 
    663  1.1.1.1.8.2  snj /*
    664  1.1.1.1.8.2  snj Deflate a part, to allow ZopfliDeflate() to use multiple master blocks if
    665  1.1.1.1.8.2  snj needed.
    666  1.1.1.1.8.2  snj It is possible to call this function multiple times in a row, shifting
    667  1.1.1.1.8.2  snj instart and inend to next bytes of the data. If instart is larger than 0, then
    668  1.1.1.1.8.2  snj previous bytes are used as the initial dictionary for LZ77.
    669  1.1.1.1.8.2  snj This function will usually output multiple deflate blocks. If final is 1, then
    670  1.1.1.1.8.2  snj the final bit will be set on the last block.
    671  1.1.1.1.8.2  snj */
    672  1.1.1.1.8.2  snj void ZopfliDeflatePart(const ZopfliOptions* options, int btype, int final,
    673  1.1.1.1.8.2  snj                        const unsigned char* in, size_t instart, size_t inend,
    674  1.1.1.1.8.2  snj                        unsigned char* bp, unsigned char** out,
    675  1.1.1.1.8.2  snj                        size_t* outsize) {
    676  1.1.1.1.8.2  snj   if (options->blocksplitting) {
    677  1.1.1.1.8.2  snj     if (options->blocksplittinglast) {
    678  1.1.1.1.8.2  snj       DeflateSplittingLast(options, btype, final, in, instart, inend,
    679  1.1.1.1.8.2  snj                            bp, out, outsize);
    680  1.1.1.1.8.2  snj     } else {
    681  1.1.1.1.8.2  snj       DeflateSplittingFirst(options, btype, final, in, instart, inend,
    682  1.1.1.1.8.2  snj                             bp, out, outsize);
    683  1.1.1.1.8.2  snj     }
    684  1.1.1.1.8.2  snj   } else {
    685  1.1.1.1.8.2  snj     DeflateBlock(options, btype, final, in, instart, inend, bp, out, outsize);
    686  1.1.1.1.8.2  snj   }
    687  1.1.1.1.8.2  snj }
    688  1.1.1.1.8.2  snj 
    689  1.1.1.1.8.2  snj void ZopfliDeflate(const ZopfliOptions* options, int btype, int final,
    690  1.1.1.1.8.2  snj                    const unsigned char* in, size_t insize,
    691  1.1.1.1.8.2  snj                    unsigned char* bp, unsigned char** out, size_t* outsize) {
    692  1.1.1.1.8.2  snj #if ZOPFLI_MASTER_BLOCK_SIZE == 0
    693  1.1.1.1.8.2  snj   ZopfliDeflatePart(options, btype, final, in, 0, insize, bp, out, outsize);
    694  1.1.1.1.8.2  snj #else
    695  1.1.1.1.8.2  snj   size_t i = 0;
    696  1.1.1.1.8.2  snj   while (i < insize) {
    697  1.1.1.1.8.2  snj     int masterfinal = (i + ZOPFLI_MASTER_BLOCK_SIZE >= insize);
    698  1.1.1.1.8.2  snj     int final2 = final && masterfinal;
    699  1.1.1.1.8.2  snj     size_t size = masterfinal ? insize - i : ZOPFLI_MASTER_BLOCK_SIZE;
    700  1.1.1.1.8.2  snj     ZopfliDeflatePart(options, btype, final2,
    701  1.1.1.1.8.2  snj                       in, i, i + size, bp, out, outsize);
    702  1.1.1.1.8.2  snj     i += size;
    703  1.1.1.1.8.2  snj   }
    704  1.1.1.1.8.2  snj #endif
    705  1.1.1.1.8.2  snj }
    706