File indexing completed on 2025-01-18 09:29:36
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037 #ifndef BOOST_BEAST_ZLIB_DETAIL_DEFLATE_STREAM_IPP
0038 #define BOOST_BEAST_ZLIB_DETAIL_DEFLATE_STREAM_IPP
0039
0040 #include <boost/beast/zlib/detail/deflate_stream.hpp>
0041 #include <boost/beast/zlib/detail/ranges.hpp>
0042 #include <boost/assert.hpp>
0043 #include <boost/config.hpp>
0044 #include <boost/make_unique.hpp>
0045 #include <boost/optional.hpp>
0046 #include <boost/throw_exception.hpp>
0047 #include <cstdint>
0048 #include <cstdlib>
0049 #include <cstring>
0050 #include <memory>
0051 #include <stdexcept>
0052 #include <type_traits>
0053
0054 namespace boost {
0055 namespace beast {
0056 namespace zlib {
0057 namespace detail {
0058
0059
0060
0061
0062
0063
0064
0065
0066
0067
0068
0069
0070
0071
0072
0073
0074
0075
0076
0077
0078
0079
0080
0081
0082
0083
0084
0085
0086
0087
0088
0089
0090
0091
0092
0093
0094
0095
0096
0097
0098
0099
0100
0101
0102
0103
0104
0105
0106
0107
0108
0109
0110
0111
0112
0113
0114
0115 void
0116 deflate_stream::
0117 gen_codes(ct_data *tree, int max_code, std::uint16_t *bl_count)
0118 {
0119 std::uint16_t next_code[maxBits+1];
0120 std::uint16_t code = 0;
0121 int bits;
0122 int n;
0123
0124
0125
0126 for(bits = 1; bits <= maxBits; bits++)
0127 {
0128 code = (code + bl_count[bits-1]) << 1;
0129 next_code[bits] = code;
0130 }
0131
0132
0133 BOOST_ASSERT(code + bl_count[maxBits]-1 == (1<<maxBits)-1);
0134 for(n = 0; n <= max_code; n++)
0135 {
0136 int len = tree[n].dl;
0137 if(len == 0)
0138 continue;
0139 tree[n].fc = bi_reverse(next_code[len]++, len);
0140 }
0141 }
0142
0143 auto
0144 deflate_stream::get_lut() ->
0145 lut_type const&
0146 {
0147 struct init
0148 {
0149 lut_type tables;
0150
0151 init()
0152 {
0153
0154
0155
0156
0157 std::uint8_t length = 0;
0158 for(std::uint8_t code = 0; code < lengthCodes-1; ++code)
0159 {
0160 tables.base_length[code] = length;
0161 auto const run = 1U << tables.extra_lbits[code];
0162 for(unsigned n = 0; n < run; ++n)
0163 tables.length_code[length++] = code;
0164 }
0165 BOOST_ASSERT(length == 0);
0166
0167
0168
0169 tables.length_code[255] = lengthCodes-1;
0170
0171
0172 {
0173 std::uint8_t code;
0174 std::uint16_t dist = 0;
0175 for(code = 0; code < 16; code++)
0176 {
0177 tables.base_dist[code] = dist;
0178 auto const run = 1U << tables.extra_dbits[code];
0179 for(unsigned n = 0; n < run; ++n)
0180 tables.dist_code[dist++] = code;
0181 }
0182 BOOST_ASSERT(dist == 256);
0183
0184 dist >>= 7;
0185 for(; code < dCodes; ++code)
0186 {
0187 tables.base_dist[code] = dist << 7;
0188 auto const run = 1U << (tables.extra_dbits[code]-7);
0189 for(std::size_t n = 0; n < run; ++n)
0190 tables.dist_code[256 + dist++] = code;
0191 }
0192 BOOST_ASSERT(dist == 256);
0193 }
0194
0195
0196 std::uint16_t bl_count[maxBits+1];
0197 std::memset(bl_count, 0, sizeof(bl_count));
0198 unsigned n = 0;
0199 while (n <= 143)
0200 tables.ltree[n++].dl = 8;
0201 bl_count[8] += 144;
0202 while (n <= 255)
0203 tables.ltree[n++].dl = 9;
0204 bl_count[9] += 112;
0205 while (n <= 279)
0206 tables.ltree[n++].dl = 7;
0207 bl_count[7] += 24;
0208 while (n <= 287)
0209 tables.ltree[n++].dl = 8;
0210 bl_count[8] += 8;
0211
0212
0213 gen_codes(tables.ltree, lCodes+1, bl_count);
0214
0215 for(n = 0; n < dCodes; ++n)
0216 {
0217 tables.dtree[n].dl = 5;
0218 tables.dtree[n].fc =
0219 static_cast<std::uint16_t>(bi_reverse(n, 5));
0220 }
0221 }
0222 };
0223 static init const data;
0224 return data.tables;
0225 }
0226
0227 void
0228 deflate_stream::
0229 doReset(
0230 int level,
0231 int windowBits,
0232 int memLevel,
0233 Strategy strategy)
0234 {
0235 if(level == default_size)
0236 level = 6;
0237
0238
0239
0240 if(windowBits == 8)
0241 windowBits = 9;
0242
0243 if(level < 0 || level > 9)
0244 BOOST_THROW_EXCEPTION(std::invalid_argument{
0245 "invalid level"});
0246
0247 if(windowBits < 8 || windowBits > 15)
0248 BOOST_THROW_EXCEPTION(std::invalid_argument{
0249 "invalid windowBits"});
0250
0251 if(memLevel < 1 || memLevel > max_mem_level)
0252 BOOST_THROW_EXCEPTION(std::invalid_argument{
0253 "invalid memLevel"});
0254
0255 w_bits_ = windowBits;
0256
0257 hash_bits_ = memLevel + 7;
0258
0259
0260 lit_bufsize_ = 1 << (memLevel + 6);
0261
0262 level_ = level;
0263 strategy_ = strategy;
0264 inited_ = false;
0265 }
0266
0267 void
0268 deflate_stream::
0269 doReset()
0270 {
0271 inited_ = false;
0272 }
0273
0274 void
0275 deflate_stream::
0276 doClear()
0277 {
0278 inited_ = false;
0279 buf_.reset();
0280 }
0281
0282 std::size_t
0283 deflate_stream::
0284 doUpperBound(std::size_t sourceLen) const
0285 {
0286 std::size_t complen;
0287 std::size_t wraplen;
0288
0289
0290 complen = sourceLen +
0291 ((sourceLen + 7) >> 3) + ((sourceLen + 63) >> 6) + 5;
0292
0293
0294 wraplen = 0;
0295
0296
0297 if(w_bits_ != 15 || hash_bits_ != 8 + 7)
0298 return complen + wraplen;
0299
0300
0301 return sourceLen + (sourceLen >> 12) + (sourceLen >> 14) +
0302 (sourceLen >> 25) + 13 - 6 + wraplen;
0303 }
0304
0305 void
0306 deflate_stream::
0307 doTune(
0308 int good_length,
0309 int max_lazy,
0310 int nice_length,
0311 int max_chain)
0312 {
0313 good_match_ = good_length;
0314 nice_match_ = nice_length;
0315 max_lazy_match_ = max_lazy;
0316 max_chain_length_ = max_chain;
0317 }
0318
0319 void
0320 deflate_stream::
0321 doParams(z_params& zs, int level, Strategy strategy, error_code& ec)
0322 {
0323 compress_func func;
0324
0325 if(level == default_size)
0326 level = 6;
0327 if(level < 0 || level > 9)
0328 {
0329 BOOST_BEAST_ASSIGN_EC(ec, error::stream_error);
0330 return;
0331 }
0332 func = get_config(level_).func;
0333
0334 if((strategy != strategy_ || func != get_config(level).func) &&
0335 zs.total_in != 0)
0336 {
0337
0338 doWrite(zs, Flush::block, ec);
0339 if(ec == error::need_buffers && pending_ == 0)
0340 ec = {};
0341 }
0342 if(level_ != level)
0343 {
0344 level_ = level;
0345 max_lazy_match_ = get_config(level).max_lazy;
0346 good_match_ = get_config(level).good_length;
0347 nice_match_ = get_config(level).nice_length;
0348 max_chain_length_ = get_config(level).max_chain;
0349 }
0350 strategy_ = strategy;
0351 }
0352
0353
0354
0355
0356
0357 void
0358 deflate_stream::
0359 doWrite(z_params& zs, boost::optional<Flush> flush, error_code& ec)
0360 {
0361 maybe_init();
0362
0363 if(zs.next_in == nullptr && zs.avail_in != 0)
0364 BOOST_THROW_EXCEPTION(std::invalid_argument{"invalid input"});
0365
0366 if(zs.next_out == nullptr ||
0367 (status_ == FINISH_STATE && flush != Flush::finish))
0368 {
0369 BOOST_BEAST_ASSIGN_EC(ec, error::stream_error);
0370 return;
0371 }
0372 if(zs.avail_out == 0)
0373 {
0374 BOOST_BEAST_ASSIGN_EC(ec, error::need_buffers);
0375 return;
0376 }
0377
0378
0379 auto old_flush = boost::make_optional<Flush>(
0380 last_flush_.is_initialized(),
0381 last_flush_ ? *last_flush_ : Flush::none);
0382
0383 last_flush_ = flush;
0384
0385
0386 if(pending_ != 0)
0387 {
0388 flush_pending(zs);
0389 if(zs.avail_out == 0)
0390 {
0391
0392
0393
0394
0395
0396
0397 last_flush_ = boost::none;
0398 return;
0399 }
0400 }
0401 else if(zs.avail_in == 0 && (
0402 old_flush && flush <= *old_flush
0403 ) && flush != Flush::finish)
0404 {
0405
0406
0407
0408
0409 BOOST_BEAST_ASSIGN_EC(ec, error::need_buffers);
0410 return;
0411 }
0412
0413
0414 if(status_ == FINISH_STATE && zs.avail_in != 0)
0415 {
0416 BOOST_BEAST_ASSIGN_EC(ec, error::need_buffers);
0417 return;
0418 }
0419
0420
0421
0422 if(zs.avail_in != 0 || lookahead_ != 0 ||
0423 (flush != Flush::none && status_ != FINISH_STATE))
0424 {
0425 block_state bstate;
0426
0427 switch(strategy_)
0428 {
0429 case Strategy::huffman:
0430 bstate = deflate_huff(zs, flush.get());
0431 break;
0432 case Strategy::rle:
0433 bstate = deflate_rle(zs, flush.get());
0434 break;
0435 default:
0436 {
0437 bstate = (this->*(get_config(level_).func))(zs, flush.get());
0438 break;
0439 }
0440 }
0441
0442 if(bstate == finish_started || bstate == finish_done)
0443 {
0444 status_ = FINISH_STATE;
0445 }
0446 if(bstate == need_more || bstate == finish_started)
0447 {
0448 if(zs.avail_out == 0)
0449 {
0450 last_flush_ = boost::none;
0451 }
0452 return;
0453
0454
0455
0456
0457
0458
0459
0460 }
0461 if(bstate == block_done)
0462 {
0463 if(flush == Flush::partial)
0464 {
0465 tr_align();
0466 }
0467 else if(flush != Flush::block)
0468 {
0469
0470 tr_stored_block(nullptr, 0L, 0);
0471
0472
0473
0474 if(flush == Flush::full)
0475 {
0476 clear_hash();
0477 if(lookahead_ == 0)
0478 {
0479 strstart_ = 0;
0480 block_start_ = 0L;
0481 insert_ = 0;
0482 }
0483 }
0484 }
0485 flush_pending(zs);
0486 if(zs.avail_out == 0)
0487 {
0488 last_flush_ = boost::none;
0489 return;
0490 }
0491 }
0492 }
0493
0494 if(flush == Flush::finish)
0495 {
0496 BOOST_BEAST_ASSIGN_EC(ec, error::end_of_stream);
0497 return;
0498 }
0499 }
0500
0501
0502 void
0503 deflate_stream::
0504 doDictionary(Byte const* dict, uInt dictLength, error_code& ec)
0505 {
0506 if(lookahead_)
0507 {
0508 BOOST_BEAST_ASSIGN_EC(ec, error::stream_error);
0509 return;
0510 }
0511
0512 maybe_init();
0513
0514
0515 if(dictLength >= w_size_)
0516 {
0517 clear_hash();
0518 strstart_ = 0;
0519 block_start_ = 0L;
0520 insert_ = 0;
0521 dict += dictLength - w_size_;
0522 dictLength = w_size_;
0523 }
0524
0525
0526 z_params zs;
0527 zs.avail_in = dictLength;
0528 zs.next_in = (const Byte *)dict;
0529 zs.avail_out = 0;
0530 zs.next_out = 0;
0531 fill_window(zs);
0532 while(lookahead_ >= minMatch)
0533 {
0534 uInt str = strstart_;
0535 uInt n = lookahead_ - (minMatch-1);
0536 do
0537 {
0538 update_hash(ins_h_, window_[str + minMatch-1]);
0539 prev_[str & w_mask_] = head_[ins_h_];
0540 head_[ins_h_] = (std::uint16_t)str;
0541 str++;
0542 }
0543 while(--n);
0544 strstart_ = str;
0545 lookahead_ = minMatch-1;
0546 fill_window(zs);
0547 }
0548 strstart_ += lookahead_;
0549 block_start_ = (long)strstart_;
0550 insert_ = lookahead_;
0551 lookahead_ = 0;
0552 match_length_ = prev_length_ = minMatch-1;
0553 match_available_ = 0;
0554 }
0555
0556 void
0557 deflate_stream::
0558 doPrime(int bits, int value, error_code& ec)
0559 {
0560 maybe_init();
0561
0562 if((Byte *)(sym_buf_) < pending_out_ + ((Buf_size + 7) >> 3))
0563 {
0564 BOOST_BEAST_ASSIGN_EC(ec, error::need_buffers);
0565 return;
0566 }
0567
0568 do
0569 {
0570 int put = Buf_size - bi_valid_;
0571 if(put > bits)
0572 put = bits;
0573 bi_buf_ |= (std::uint16_t)((value & ((1 << put) - 1)) << bi_valid_);
0574 bi_valid_ += put;
0575 tr_flush_bits();
0576 value >>= put;
0577 bits -= put;
0578 }
0579 while(bits);
0580 }
0581
0582 void
0583 deflate_stream::
0584 doPending(unsigned* value, int* bits)
0585 {
0586 if(value != 0)
0587 *value = pending_;
0588 if(bits != 0)
0589 *bits = bi_valid_;
0590 }
0591
0592
0593
0594
0595 void
0596 deflate_stream::
0597 init()
0598 {
0599
0600
0601
0602
0603
0604
0605
0606 w_size_ = 1 << w_bits_;
0607 w_mask_ = w_size_ - 1;
0608
0609 hash_size_ = 1 << hash_bits_;
0610 hash_mask_ = hash_size_ - 1;
0611 hash_shift_ = ((hash_bits_+minMatch-1)/minMatch);
0612
0613 auto const nwindow = w_size_ * 2*sizeof(Byte);
0614 auto const nprev = w_size_ * sizeof(std::uint16_t);
0615 auto const nhead = hash_size_ * sizeof(std::uint16_t);
0616 auto const noverlay = lit_bufsize_ * (sizeof(std::uint16_t)+2);
0617 auto const needed = nwindow + nprev + nhead + noverlay;
0618
0619 if(! buf_ || buf_size_ != needed)
0620 {
0621 buf_ = boost::make_unique_noinit<
0622 std::uint8_t[]>(needed);
0623 buf_size_ = needed;
0624 }
0625
0626 window_ = reinterpret_cast<Byte*>(buf_.get());
0627 prev_ = reinterpret_cast<std::uint16_t*>(buf_.get() + nwindow);
0628 std::memset(prev_, 0, nprev);
0629 head_ = reinterpret_cast<std::uint16_t*>(buf_.get() + nwindow + nprev);
0630
0631
0632 high_water_ = 0;
0633
0634
0635
0636
0637
0638
0639
0640
0641
0642
0643
0644
0645
0646
0647
0648
0649
0650
0651
0652
0653
0654
0655
0656
0657
0658
0659
0660
0661
0662
0663
0664
0665
0666
0667
0668
0669
0670
0671
0672
0673 pending_buf_ =
0674 buf_.get() + nwindow + nprev + nhead;
0675 pending_buf_size_ =
0676 static_cast<std::uint32_t>(lit_bufsize_) * 4;
0677
0678 sym_buf_ = pending_buf_ + lit_bufsize_;
0679 sym_end_ = (lit_bufsize_ - 1) * 3;
0680
0681 pending_ = 0;
0682 pending_out_ = pending_buf_;
0683
0684 status_ = BUSY_STATE;
0685 last_flush_ = Flush::none;
0686
0687 tr_init();
0688 lm_init();
0689
0690 inited_ = true;
0691 }
0692
0693
0694
0695 void
0696 deflate_stream::
0697 lm_init()
0698 {
0699 window_size_ = (std::uint32_t)2L*w_size_;
0700
0701 clear_hash();
0702
0703
0704
0705
0706 max_lazy_match_ = get_config(level_).max_lazy;
0707 good_match_ = get_config(level_).good_length;
0708 nice_match_ = get_config(level_).nice_length;
0709 max_chain_length_ = get_config(level_).max_chain;
0710
0711 strstart_ = 0;
0712 block_start_ = 0L;
0713 lookahead_ = 0;
0714 insert_ = 0;
0715 match_length_ = prev_length_ = minMatch-1;
0716 match_available_ = 0;
0717 ins_h_ = 0;
0718 }
0719
0720
0721
0722 void
0723 deflate_stream::
0724 init_block()
0725 {
0726 for(int n = 0; n < lCodes; n++)
0727 dyn_ltree_[n].fc = 0;
0728 for(int n = 0; n < dCodes; n++)
0729 dyn_dtree_[n].fc = 0;
0730 for(int n = 0; n < blCodes; n++)
0731 bl_tree_[n].fc = 0;
0732 dyn_ltree_[END_BLOCK].fc = 1;
0733 opt_len_ = 0L;
0734 static_len_ = 0L;
0735 sym_next_ = 0;
0736 matches_ = 0;
0737 }
0738
0739
0740
0741
0742
0743
0744 void
0745 deflate_stream::
0746 pqdownheap(
0747 ct_data const* tree,
0748 int k)
0749 {
0750 int v = heap_[k];
0751 int j = k << 1;
0752 while(j <= heap_len_)
0753 {
0754
0755 if(j < heap_len_ &&
0756 smaller(tree, heap_[j+1], heap_[j]))
0757 j++;
0758
0759 if(smaller(tree, v, heap_[j]))
0760 break;
0761
0762
0763 heap_[k] = heap_[j];
0764 k = j;
0765
0766
0767
0768 j <<= 1;
0769 }
0770 heap_[k] = v;
0771 }
0772
0773
0774
0775
0776 void
0777 deflate_stream::
0778 pqremove(ct_data const* tree, int& top)
0779 {
0780 top = heap_[kSmallest];
0781 heap_[kSmallest] = heap_[heap_len_--];
0782 pqdownheap(tree, kSmallest);
0783 }
0784
0785
0786
0787
0788
0789
0790
0791
0792
0793
0794 void
0795 deflate_stream::
0796 gen_bitlen(tree_desc *desc)
0797 {
0798 ct_data *tree = desc->dyn_tree;
0799 int max_code = desc->max_code;
0800 ct_data const* stree = desc->stat_desc->static_tree;
0801 std::uint8_t const *extra = desc->stat_desc->extra_bits;
0802 int base = desc->stat_desc->extra_base;
0803 int max_length = desc->stat_desc->max_length;
0804 int h;
0805 int n, m;
0806 int bits;
0807 int xbits;
0808 std::uint16_t f;
0809 int overflow = 0;
0810
0811 std::fill(&bl_count_[0], &bl_count_[maxBits+1], std::uint16_t{0});
0812
0813
0814
0815
0816 tree[heap_[heap_max_]].dl = 0;
0817
0818 for(h = heap_max_+1; h < HEAP_SIZE; h++) {
0819 n = heap_[h];
0820 bits = tree[tree[n].dl].dl + 1;
0821 if(bits > max_length) bits = max_length, overflow++;
0822
0823 tree[n].dl = (std::uint16_t)bits;
0824
0825 if(n > max_code)
0826 continue;
0827
0828 bl_count_[bits]++;
0829 xbits = 0;
0830 if(n >= base)
0831 xbits = extra[n-base];
0832 f = tree[n].fc;
0833 opt_len_ += (std::uint32_t)f * (bits + xbits);
0834 if(stree)
0835 static_len_ += (std::uint32_t)f * (stree[n].dl + xbits);
0836 }
0837 if(overflow == 0)
0838 return;
0839
0840
0841 do
0842 {
0843 bits = max_length-1;
0844 while(bl_count_[bits] == 0)
0845 bits--;
0846 bl_count_[bits]--;
0847 bl_count_[bits+1] += 2;
0848 bl_count_[max_length]--;
0849
0850
0851
0852 overflow -= 2;
0853 }
0854 while(overflow > 0);
0855
0856
0857
0858
0859
0860
0861 for(bits = max_length; bits != 0; bits--)
0862 {
0863 n = bl_count_[bits];
0864 while(n != 0)
0865 {
0866 m = heap_[--h];
0867 if(m > max_code)
0868 continue;
0869 if((unsigned) tree[m].dl != (unsigned) bits)
0870 {
0871 opt_len_ += ((long)bits - (long)tree[m].dl) *(long)tree[m].fc;
0872 tree[m].dl = (std::uint16_t)bits;
0873 }
0874 n--;
0875 }
0876 }
0877 }
0878
0879
0880
0881
0882
0883
0884
0885
0886 void
0887 deflate_stream::
0888 build_tree(tree_desc *desc)
0889 {
0890 ct_data *tree = desc->dyn_tree;
0891 ct_data const* stree = desc->stat_desc->static_tree;
0892 int elems = desc->stat_desc->elems;
0893 int n, m;
0894 int max_code = -1;
0895 int node;
0896
0897
0898
0899
0900
0901 heap_len_ = 0;
0902 heap_max_ = HEAP_SIZE;
0903
0904 for(n = 0; n < elems; n++)
0905 {
0906 if(tree[n].fc != 0)
0907 {
0908 heap_[++(heap_len_)] = max_code = n;
0909 depth_[n] = 0;
0910 }
0911 else
0912 {
0913 tree[n].dl = 0;
0914 }
0915 }
0916
0917
0918
0919
0920
0921
0922 while(heap_len_ < 2)
0923 {
0924 node = heap_[++(heap_len_)] = (max_code < 2 ? ++max_code : 0);
0925 tree[node].fc = 1;
0926 depth_[node] = 0;
0927 opt_len_--;
0928 if(stree)
0929 static_len_ -= stree[node].dl;
0930
0931 }
0932 desc->max_code = max_code;
0933
0934
0935
0936
0937 for(n = heap_len_/2; n >= 1; n--)
0938 pqdownheap(tree, n);
0939
0940
0941
0942
0943 node = elems;
0944 do
0945 {
0946 pqremove(tree, n);
0947 m = heap_[kSmallest];
0948
0949 heap_[--(heap_max_)] = n;
0950 heap_[--(heap_max_)] = m;
0951
0952
0953 tree[node].fc = tree[n].fc + tree[m].fc;
0954 depth_[node] = (std::uint8_t)((depth_[n] >= depth_[m] ?
0955 depth_[n] : depth_[m]) + 1);
0956 tree[n].dl = tree[m].dl = (std::uint16_t)node;
0957
0958 heap_[kSmallest] = node++;
0959 pqdownheap(tree, kSmallest);
0960
0961 }
0962 while(heap_len_ >= 2);
0963
0964 heap_[--(heap_max_)] = heap_[kSmallest];
0965
0966
0967
0968
0969 gen_bitlen((tree_desc *)desc);
0970
0971
0972 gen_codes(tree, max_code, bl_count_);
0973 }
0974
0975
0976
0977
0978 void
0979 deflate_stream::
0980 scan_tree(
0981 ct_data *tree,
0982 int max_code)
0983 {
0984 int n;
0985 int prevlen = -1;
0986 int curlen;
0987 int nextlen = tree[0].dl;
0988 std::uint16_t count = 0;
0989 int max_count = 7;
0990 int min_count = 4;
0991
0992 if(nextlen == 0)
0993 {
0994 max_count = 138;
0995 min_count = 3;
0996 }
0997 tree[max_code+1].dl = (std::uint16_t)0xffff;
0998
0999 for(n = 0; n <= max_code; n++)
1000 {
1001 curlen = nextlen; nextlen = tree[n+1].dl;
1002 if(++count < max_count && curlen == nextlen)
1003 {
1004 continue;
1005 }
1006 else if(count < min_count)
1007 {
1008 bl_tree_[curlen].fc += count;
1009 }
1010 else if(curlen != 0)
1011 {
1012 if(curlen != prevlen) bl_tree_[curlen].fc++;
1013 bl_tree_[REP_3_6].fc++;
1014 }
1015 else if(count <= 10)
1016 {
1017 bl_tree_[REPZ_3_10].fc++;
1018 }
1019 else
1020 {
1021 bl_tree_[REPZ_11_138].fc++;
1022 }
1023 count = 0;
1024 prevlen = curlen;
1025 if(nextlen == 0)
1026 {
1027 max_count = 138;
1028 min_count = 3;
1029 }
1030 else if(curlen == nextlen)
1031 {
1032 max_count = 6;
1033 min_count = 3;
1034 }
1035 else
1036 {
1037 max_count = 7;
1038 min_count = 4;
1039 }
1040 }
1041 }
1042
1043
1044
1045
1046 void
1047 deflate_stream::
1048 send_tree(
1049 ct_data *tree,
1050 int max_code)
1051 {
1052 int n;
1053 int prevlen = -1;
1054 int curlen;
1055 int nextlen = tree[0].dl;
1056 int count = 0;
1057 int max_count = 7;
1058 int min_count = 4;
1059
1060
1061 if(nextlen == 0)
1062 {
1063 max_count = 138;
1064 min_count = 3;
1065 }
1066
1067 for(n = 0; n <= max_code; n++)
1068 {
1069 curlen = nextlen;
1070 nextlen = tree[n+1].dl;
1071 if(++count < max_count && curlen == nextlen)
1072 {
1073 continue;
1074 }
1075 else if(count < min_count)
1076 {
1077 do
1078 {
1079 send_code(curlen, bl_tree_);
1080 }
1081 while (--count != 0);
1082 }
1083 else if(curlen != 0)
1084 {
1085 if(curlen != prevlen)
1086 {
1087 send_code(curlen, bl_tree_);
1088 count--;
1089 }
1090 BOOST_ASSERT(count >= 3 && count <= 6);
1091 send_code(REP_3_6, bl_tree_);
1092 send_bits(count-3, 2);
1093 }
1094 else if(count <= 10)
1095 {
1096 send_code(REPZ_3_10, bl_tree_);
1097 send_bits(count-3, 3);
1098 }
1099 else
1100 {
1101 send_code(REPZ_11_138, bl_tree_);
1102 send_bits(count-11, 7);
1103 }
1104 count = 0;
1105 prevlen = curlen;
1106 if(nextlen == 0)
1107 {
1108 max_count = 138;
1109 min_count = 3;
1110 }
1111 else if(curlen == nextlen)
1112 {
1113 max_count = 6;
1114 min_count = 3;
1115 }
1116 else
1117 {
1118 max_count = 7;
1119 min_count = 4;
1120 }
1121 }
1122 }
1123
1124
1125
1126
1127 int
1128 deflate_stream::
1129 build_bl_tree()
1130 {
1131 int max_blindex;
1132
1133
1134 scan_tree((ct_data *)dyn_ltree_, l_desc_.max_code);
1135 scan_tree((ct_data *)dyn_dtree_, d_desc_.max_code);
1136
1137
1138 build_tree((tree_desc *)(&(bl_desc_)));
1139
1140
1141
1142
1143
1144
1145
1146
1147 for(max_blindex = blCodes-1; max_blindex >= 3; max_blindex--)
1148 {
1149 if(bl_tree_[lut_.bl_order[max_blindex]].dl != 0)
1150 break;
1151 }
1152
1153 opt_len_ += 3*(max_blindex+1) + 5+5+4;
1154 return max_blindex;
1155 }
1156
1157
1158
1159
1160
1161
1162 void
1163 deflate_stream::
1164 send_all_trees(
1165 int lcodes,
1166 int dcodes,
1167 int blcodes)
1168 {
1169 int rank;
1170
1171 BOOST_ASSERT(lcodes >= 257 && dcodes >= 1 && blcodes >= 4);
1172 BOOST_ASSERT(lcodes <= lCodes && dcodes <= dCodes && blcodes <= blCodes);
1173 send_bits(lcodes-257, 5);
1174 send_bits(dcodes-1, 5);
1175 send_bits(blcodes-4, 4);
1176 for(rank = 0; rank < blcodes; rank++)
1177 send_bits(bl_tree_[lut_.bl_order[rank]].dl, 3);
1178 send_tree((ct_data *)dyn_ltree_, lcodes-1);
1179 send_tree((ct_data *)dyn_dtree_, dcodes-1);
1180 }
1181
1182
1183
1184 void
1185 deflate_stream::
1186 compress_block(
1187 ct_data const* ltree,
1188 ct_data const* dtree)
1189 {
1190 unsigned dist;
1191 int lc;
1192 unsigned sx = 0;
1193 unsigned code;
1194 int extra;
1195
1196 if(sym_next_ != 0)
1197 {
1198 do
1199 {
1200 dist = sym_buf_[sx++] & 0xff;
1201 dist += (unsigned)(sym_buf_[sx++] & 0xff) << 8;
1202 lc = sym_buf_[sx++];
1203 if(dist == 0)
1204 {
1205 send_code(lc, ltree);
1206 }
1207 else
1208 {
1209
1210 code = lut_.length_code[lc];
1211 send_code(code+literals+1, ltree);
1212 extra = lut_.extra_lbits[code];
1213 if(extra != 0)
1214 {
1215 lc -= lut_.base_length[code];
1216 send_bits(lc, extra);
1217 }
1218 dist--;
1219 code = d_code(dist);
1220 BOOST_ASSERT(code < dCodes);
1221
1222 send_code(code, dtree);
1223 extra = lut_.extra_dbits[code];
1224 if(extra != 0)
1225 {
1226 dist -= lut_.base_dist[code];
1227 send_bits(dist, extra);
1228 }
1229 }
1230
1231
1232 BOOST_ASSERT((uInt)(pending_) < lit_bufsize_ + sx);
1233 }
1234 while(sx < sym_next_);
1235 }
1236
1237 send_code(END_BLOCK, ltree);
1238 }
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252 int
1253 deflate_stream::
1254 detect_data_type()
1255 {
1256
1257
1258
1259
1260 unsigned long block_mask = 0xf3ffc07fUL;
1261 int n;
1262
1263
1264 for(n = 0; n <= 31; n++, block_mask >>= 1)
1265 if((block_mask & 1) && (dyn_ltree_[n].fc != 0))
1266 return binary;
1267
1268
1269 if(dyn_ltree_[9].fc != 0 || dyn_ltree_[10].fc != 0
1270 || dyn_ltree_[13].fc != 0)
1271 return text;
1272 for(n = 32; n < literals; n++)
1273 if(dyn_ltree_[n].fc != 0)
1274 return text;
1275
1276
1277
1278
1279 return binary;
1280 }
1281
1282
1283
1284 void
1285 deflate_stream::
1286 bi_windup()
1287 {
1288 if(bi_valid_ > 8)
1289 put_short(bi_buf_);
1290 else if(bi_valid_ > 0)
1291 put_byte((Byte)bi_buf_);
1292 bi_buf_ = 0;
1293 bi_valid_ = 0;
1294 }
1295
1296
1297
1298 void
1299 deflate_stream::
1300 bi_flush()
1301 {
1302 if(bi_valid_ == 16)
1303 {
1304 put_short(bi_buf_);
1305 bi_buf_ = 0;
1306 bi_valid_ = 0;
1307 }
1308 else if(bi_valid_ >= 8)
1309 {
1310 put_byte((Byte)bi_buf_);
1311 bi_buf_ >>= 8;
1312 bi_valid_ -= 8;
1313 }
1314 }
1315
1316
1317
1318
1319 void
1320 deflate_stream::
1321 copy_block(
1322 char *buf,
1323 unsigned len,
1324 int header)
1325 {
1326 bi_windup();
1327
1328 if(header)
1329 {
1330 put_short((std::uint16_t)len);
1331 put_short((std::uint16_t)~len);
1332 }
1333 if(buf)
1334 std::memcpy(&pending_buf_[pending_], buf, len);
1335 pending_ += len;
1336 }
1337
1338
1339
1340
1341
1342 void
1343 deflate_stream::
1344 tr_init()
1345 {
1346 l_desc_.dyn_tree = dyn_ltree_;
1347 l_desc_.stat_desc = &lut_.l_desc;
1348
1349 d_desc_.dyn_tree = dyn_dtree_;
1350 d_desc_.stat_desc = &lut_.d_desc;
1351
1352 bl_desc_.dyn_tree = bl_tree_;
1353 bl_desc_.stat_desc = &lut_.bl_desc;
1354
1355 bi_buf_ = 0;
1356 bi_valid_ = 0;
1357
1358
1359 init_block();
1360 }
1361
1362
1363
1364
1365 void
1366 deflate_stream::
1367 tr_align()
1368 {
1369 send_bits(STATIC_TREES<<1, 3);
1370 send_code(END_BLOCK, lut_.ltree);
1371 bi_flush();
1372 }
1373
1374
1375
1376 void
1377 deflate_stream::
1378 tr_flush_bits()
1379 {
1380 bi_flush();
1381 }
1382
1383
1384
1385 void
1386 deflate_stream::
1387 tr_stored_block(
1388 char *buf,
1389 std::uint32_t stored_len,
1390 int last)
1391 {
1392 send_bits((STORED_BLOCK<<1)+last, 3);
1393 copy_block(buf, (unsigned)stored_len, 1);
1394 }
1395
1396 void
1397 deflate_stream::
1398 tr_tally_dist(std::uint16_t dist, std::uint8_t len, bool& flush)
1399 {
1400 sym_buf_[sym_next_++] = dist & 0xFF;
1401 sym_buf_[sym_next_++] = dist >> 8;
1402 sym_buf_[sym_next_++] = len;
1403 dist--;
1404 dyn_ltree_[lut_.length_code[len]+literals+1].fc++;
1405 dyn_dtree_[d_code(dist)].fc++;
1406 flush = (sym_next_ == sym_end_);
1407 }
1408
1409 void
1410 deflate_stream::
1411 tr_tally_lit(std::uint8_t c, bool& flush)
1412 {
1413 sym_buf_[sym_next_++] = 0;
1414 sym_buf_[sym_next_++] = 0;
1415 sym_buf_[sym_next_++] = c;
1416 dyn_ltree_[c].fc++;
1417 flush = (sym_next_ == sym_end_);
1418 }
1419
1420
1421
1422
1423
1424
1425 void
1426 deflate_stream::
1427 tr_flush_block(
1428 z_params& zs,
1429 char *buf,
1430 std::uint32_t stored_len,
1431 int last)
1432 {
1433 std::uint32_t opt_lenb;
1434 std::uint32_t static_lenb;
1435 int max_blindex = 0;
1436
1437
1438 if(level_ > 0)
1439 {
1440
1441 if(zs.data_type == unknown)
1442 zs.data_type = detect_data_type();
1443
1444
1445 build_tree((tree_desc *)(&(l_desc_)));
1446
1447 build_tree((tree_desc *)(&(d_desc_)));
1448
1449
1450
1451
1452
1453
1454
1455 max_blindex = build_bl_tree();
1456
1457
1458 opt_lenb = (opt_len_+3+7)>>3;
1459 static_lenb = (static_len_+3+7)>>3;
1460
1461 if(static_lenb <= opt_lenb)
1462 opt_lenb = static_lenb;
1463 }
1464 else
1465 {
1466
1467
1468
1469
1470 #if 0
1471 BOOST_ASSERT(buf);
1472 #endif
1473 opt_lenb = static_lenb = stored_len + 5;
1474 }
1475
1476 #ifdef FORCE_STORED
1477 if(buf != (char*)0) {
1478 #else
1479 if(stored_len+4 <= opt_lenb && buf != (char*)0) {
1480
1481 #endif
1482
1483
1484
1485
1486
1487
1488 tr_stored_block(buf, stored_len, last);
1489
1490 #ifdef FORCE_STATIC
1491 }
1492 else if(static_lenb >= 0)
1493 {
1494
1495 #else
1496 }
1497 else if(strategy_ == Strategy::fixed || static_lenb == opt_lenb)
1498 {
1499 #endif
1500 send_bits((STATIC_TREES<<1)+last, 3);
1501 compress_block(lut_.ltree, lut_.dtree);
1502 }
1503 else
1504 {
1505 send_bits((DYN_TREES<<1)+last, 3);
1506 send_all_trees(l_desc_.max_code+1, d_desc_.max_code+1,
1507 max_blindex+1);
1508 compress_block((const ct_data *)dyn_ltree_,
1509 (const ct_data *)dyn_dtree_);
1510 }
1511
1512
1513
1514 init_block();
1515
1516 if(last)
1517 bi_windup();
1518 }
1519
1520 void
1521 deflate_stream::
1522 fill_window(z_params& zs)
1523 {
1524 unsigned n, m;
1525 unsigned more;
1526 std::uint16_t *p;
1527 uInt wsize = w_size_;
1528
1529 do
1530 {
1531 more = (unsigned)(window_size_ -
1532 (std::uint32_t)lookahead_ -(std::uint32_t)strstart_);
1533
1534
1535 #if 0
1536
1537 if(sizeof(int) <= 2)
1538 {
1539 if(more == 0 && strstart_ == 0 && lookahead_ == 0)
1540 {
1541 more = wsize;
1542 }
1543 else if(more == (unsigned)(-1))
1544 {
1545
1546
1547
1548 more--;
1549 }
1550 }
1551 #endif
1552
1553
1554
1555
1556 if(strstart_ >= wsize+max_dist())
1557 {
1558 std::memcpy(window_, window_+wsize, (unsigned)wsize);
1559 match_start_ -= wsize;
1560 strstart_ -= wsize;
1561 block_start_ -= (long) wsize;
1562 if (insert_ > strstart_)
1563 insert_ = strstart_;
1564
1565
1566
1567
1568
1569
1570
1571 n = hash_size_;
1572 p = &head_[n];
1573 do
1574 {
1575 m = *--p;
1576 *p = (std::uint16_t)(m >= wsize ? m-wsize : 0);
1577 }
1578 while(--n);
1579
1580 n = wsize;
1581 p = &prev_[n];
1582 do
1583 {
1584 m = *--p;
1585 *p = (std::uint16_t)(m >= wsize ? m-wsize : 0);
1586
1587
1588
1589 }
1590 while(--n);
1591 more += wsize;
1592 }
1593 if(zs.avail_in == 0)
1594 break;
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607 n = read_buf(zs, window_ + strstart_ + lookahead_, more);
1608 lookahead_ += n;
1609
1610
1611 if(lookahead_ + insert_ >= minMatch)
1612 {
1613 uInt str = strstart_ - insert_;
1614 ins_h_ = window_[str];
1615 update_hash(ins_h_, window_[str + 1]);
1616 while(insert_)
1617 {
1618 update_hash(ins_h_, window_[str + minMatch-1]);
1619 prev_[str & w_mask_] = head_[ins_h_];
1620 head_[ins_h_] = (std::uint16_t)str;
1621 str++;
1622 insert_--;
1623 if(lookahead_ + insert_ < minMatch)
1624 break;
1625 }
1626 }
1627
1628
1629
1630 }
1631 while(lookahead_ < kMinLookahead && zs.avail_in != 0);
1632
1633
1634
1635
1636
1637
1638
1639
1640 if(high_water_ < window_size_)
1641 {
1642 std::uint32_t curr = strstart_ + (std::uint32_t)(lookahead_);
1643 std::uint32_t winit;
1644
1645 if(high_water_ < curr)
1646 {
1647
1648
1649
1650 winit = window_size_ - curr;
1651 if(winit > kWinInit)
1652 winit = kWinInit;
1653 std::memset(window_ + curr, 0, (unsigned)winit);
1654 high_water_ = curr + winit;
1655 }
1656 else if(high_water_ < (std::uint32_t)curr + kWinInit)
1657 {
1658
1659
1660
1661
1662 winit = (std::uint32_t)curr + kWinInit - high_water_;
1663 if(winit > window_size_ - high_water_)
1664 winit = window_size_ - high_water_;
1665 std::memset(window_ + high_water_, 0, (unsigned)winit);
1666 high_water_ += winit;
1667 }
1668 }
1669 }
1670
1671
1672
1673
1674
1675
1676 void
1677 deflate_stream::
1678 flush_pending(z_params& zs)
1679 {
1680 tr_flush_bits();
1681 auto len = clamp(pending_, zs.avail_out);
1682 if(len == 0)
1683 return;
1684
1685 std::memcpy(zs.next_out, pending_out_, len);
1686 zs.next_out =
1687 static_cast<std::uint8_t*>(zs.next_out) + len;
1688 pending_out_ += len;
1689 zs.total_out += len;
1690 zs.avail_out -= len;
1691 pending_ -= len;
1692 if(pending_ == 0)
1693 pending_out_ = pending_buf_;
1694 }
1695
1696
1697
1698
1699 void
1700 deflate_stream::
1701 flush_block(z_params& zs, bool last)
1702 {
1703 tr_flush_block(zs,
1704 (block_start_ >= 0L ?
1705 (char *)&window_[(unsigned)block_start_] :
1706 (char *)0),
1707 (std::uint32_t)((long)strstart_ - block_start_),
1708 last);
1709 block_start_ = strstart_;
1710 flush_pending(zs);
1711 }
1712
1713
1714
1715
1716
1717
1718
1719 int
1720 deflate_stream::
1721 read_buf(z_params& zs, Byte *buf, unsigned size)
1722 {
1723 auto len = clamp(zs.avail_in, size);
1724 if(len == 0)
1725 return 0;
1726
1727 zs.avail_in -= len;
1728
1729 std::memcpy(buf, zs.next_in, len);
1730 zs.next_in = static_cast<
1731 std::uint8_t const*>(zs.next_in) + len;
1732 zs.total_in += len;
1733 return (int)len;
1734 }
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747 uInt
1748 deflate_stream::
1749 longest_match(IPos cur_match)
1750 {
1751 unsigned chain_length = max_chain_length_;
1752 Byte *scan = window_ + strstart_;
1753 Byte *match;
1754 int len;
1755 int best_len = prev_length_;
1756 int nice_match = nice_match_;
1757 IPos limit = strstart_ > (IPos)max_dist() ?
1758 strstart_ - (IPos)max_dist() : 0;
1759
1760
1761
1762 std::uint16_t *prev = prev_;
1763 uInt wmask = w_mask_;
1764
1765 Byte *strend = window_ + strstart_ + maxMatch;
1766 Byte scan_end1 = scan[best_len-1];
1767 Byte scan_end = scan[best_len];
1768
1769
1770
1771
1772 BOOST_ASSERT(hash_bits_ >= 8 && maxMatch == 258);
1773
1774
1775 if(prev_length_ >= good_match_) {
1776 chain_length >>= 2;
1777 }
1778
1779
1780
1781 if((uInt)nice_match > lookahead_)
1782 nice_match = lookahead_;
1783
1784 BOOST_ASSERT((std::uint32_t)strstart_ <= window_size_-kMinLookahead);
1785
1786 do {
1787 BOOST_ASSERT(cur_match < strstart_);
1788 match = window_ + cur_match;
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798 if( match[best_len] != scan_end ||
1799 match[best_len-1] != scan_end1 ||
1800 *match != *scan ||
1801 *++match != scan[1])
1802 continue;
1803
1804
1805
1806
1807
1808
1809
1810 scan += 2, match++;
1811 BOOST_ASSERT(*scan == *match);
1812
1813
1814
1815
1816 do
1817 {
1818 }
1819 while( *++scan == *++match && *++scan == *++match &&
1820 *++scan == *++match && *++scan == *++match &&
1821 *++scan == *++match && *++scan == *++match &&
1822 *++scan == *++match && *++scan == *++match &&
1823 scan < strend);
1824
1825 BOOST_ASSERT(scan <= window_+(unsigned)(window_size_-1));
1826
1827 len = maxMatch - (int)(strend - scan);
1828 scan = strend - maxMatch;
1829
1830 if(len > best_len) {
1831 match_start_ = cur_match;
1832 best_len = len;
1833 if(len >= nice_match) break;
1834 scan_end1 = scan[best_len-1];
1835 scan_end = scan[best_len];
1836 }
1837 }
1838 while((cur_match = prev[cur_match & wmask]) > limit
1839 && --chain_length != 0);
1840
1841 if((uInt)best_len <= lookahead_)
1842 return (uInt)best_len;
1843 return lookahead_;
1844 }
1845
1846
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856 auto
1857 deflate_stream::
1858 f_stored(z_params& zs, Flush flush) ->
1859 block_state
1860 {
1861
1862
1863
1864 std::uint32_t max_block_size = 0xffff;
1865 std::uint32_t max_start;
1866
1867 if(max_block_size > pending_buf_size_ - 5) {
1868 max_block_size = pending_buf_size_ - 5;
1869 }
1870
1871
1872 for(;;) {
1873
1874 if(lookahead_ <= 1) {
1875
1876 BOOST_ASSERT(strstart_ < w_size_+max_dist() ||
1877 block_start_ >= (long)w_size_);
1878
1879 fill_window(zs);
1880 if(lookahead_ == 0 && flush == Flush::none)
1881 return need_more;
1882
1883 if(lookahead_ == 0) break;
1884 }
1885 BOOST_ASSERT(block_start_ >= 0L);
1886
1887 strstart_ += lookahead_;
1888 lookahead_ = 0;
1889
1890
1891 max_start = block_start_ + max_block_size;
1892 if(strstart_ == 0 || (std::uint32_t)strstart_ >= max_start) {
1893
1894 lookahead_ = (uInt)(strstart_ - max_start);
1895 strstart_ = (uInt)max_start;
1896 flush_block(zs, false);
1897 if(zs.avail_out == 0)
1898 return need_more;
1899 }
1900
1901
1902
1903 if(strstart_ - (uInt)block_start_ >= max_dist()) {
1904 flush_block(zs, false);
1905 if(zs.avail_out == 0)
1906 return need_more;
1907 }
1908 }
1909 insert_ = 0;
1910 if(flush == Flush::finish)
1911 {
1912 flush_block(zs, true);
1913 if(zs.avail_out == 0)
1914 return finish_started;
1915 return finish_done;
1916 }
1917 if((long)strstart_ > block_start_)
1918 {
1919 flush_block(zs, false);
1920 if(zs.avail_out == 0)
1921 return need_more;
1922 }
1923 return block_done;
1924 }
1925
1926
1927
1928
1929
1930
1931
1932 auto
1933 deflate_stream::
1934 f_fast(z_params& zs, Flush flush) ->
1935 block_state
1936 {
1937 IPos hash_head;
1938 bool bflush;
1939
1940 for(;;)
1941 {
1942
1943
1944
1945
1946
1947 if(lookahead_ < kMinLookahead)
1948 {
1949 fill_window(zs);
1950 if(lookahead_ < kMinLookahead && flush == Flush::none)
1951 return need_more;
1952 if(lookahead_ == 0)
1953 break;
1954 }
1955
1956
1957
1958
1959 hash_head = 0;
1960 if(lookahead_ >= minMatch) {
1961 insert_string(hash_head);
1962 }
1963
1964
1965
1966
1967 if(hash_head != 0 && strstart_ - hash_head <= max_dist()) {
1968
1969
1970
1971
1972 match_length_ = longest_match (hash_head);
1973
1974 }
1975 if(match_length_ >= minMatch)
1976 {
1977 tr_tally_dist(static_cast<std::uint16_t>(strstart_ - match_start_),
1978 static_cast<std::uint8_t>(match_length_ - minMatch), bflush);
1979
1980 lookahead_ -= match_length_;
1981
1982
1983
1984
1985 if(match_length_ <= max_lazy_match_ &&
1986 lookahead_ >= minMatch) {
1987 match_length_--;
1988 do
1989 {
1990 strstart_++;
1991 insert_string(hash_head);
1992
1993
1994
1995 }
1996 while(--match_length_ != 0);
1997 strstart_++;
1998 }
1999 else
2000 {
2001 strstart_ += match_length_;
2002 match_length_ = 0;
2003 ins_h_ = window_[strstart_];
2004 update_hash(ins_h_, window_[strstart_+1]);
2005
2006
2007
2008 }
2009 }
2010 else
2011 {
2012
2013 tr_tally_lit(window_[strstart_], bflush);
2014 lookahead_--;
2015 strstart_++;
2016 }
2017 if(bflush)
2018 {
2019 flush_block(zs, false);
2020 if(zs.avail_out == 0)
2021 return need_more;
2022 }
2023 }
2024 insert_ = strstart_ < minMatch-1 ? strstart_ : minMatch-1;
2025 if(flush == Flush::finish)
2026 {
2027 flush_block(zs, true);
2028 if(zs.avail_out == 0)
2029 return finish_started;
2030 return finish_done;
2031 }
2032 if(sym_next_)
2033 {
2034 flush_block(zs, false);
2035 if(zs.avail_out == 0)
2036 return need_more;
2037 }
2038 return block_done;
2039 }
2040
2041
2042
2043
2044
2045 auto
2046 deflate_stream::
2047 f_slow(z_params& zs, Flush flush) ->
2048 block_state
2049 {
2050 IPos hash_head;
2051 bool bflush;
2052
2053
2054 for(;;)
2055 {
2056
2057
2058
2059
2060
2061 if(lookahead_ < kMinLookahead)
2062 {
2063 fill_window(zs);
2064 if(lookahead_ < kMinLookahead && flush == Flush::none)
2065 return need_more;
2066 if(lookahead_ == 0)
2067 break;
2068 }
2069
2070
2071
2072
2073 hash_head = 0;
2074 if(lookahead_ >= minMatch)
2075 insert_string(hash_head);
2076
2077
2078
2079 prev_length_ = match_length_, prev_match_ = match_start_;
2080 match_length_ = minMatch-1;
2081
2082 if(hash_head != 0 && prev_length_ < max_lazy_match_ &&
2083 strstart_ - hash_head <= max_dist())
2084 {
2085
2086
2087
2088
2089 match_length_ = longest_match(hash_head);
2090
2091
2092 if(match_length_ <= 5 && (strategy_ == Strategy::filtered
2093 || (match_length_ == minMatch &&
2094 strstart_ - match_start_ > kTooFar)
2095 ))
2096 {
2097
2098
2099
2100 match_length_ = minMatch-1;
2101 }
2102 }
2103
2104
2105
2106 if(prev_length_ >= minMatch && match_length_ <= prev_length_)
2107 {
2108
2109 uInt max_insert = strstart_ + lookahead_ - minMatch;
2110
2111 tr_tally_dist(
2112 static_cast<std::uint16_t>(strstart_ -1 - prev_match_),
2113 static_cast<std::uint8_t>(prev_length_ - minMatch), bflush);
2114
2115
2116
2117
2118
2119
2120 lookahead_ -= prev_length_-1;
2121 prev_length_ -= 2;
2122 do {
2123 if(++strstart_ <= max_insert)
2124 insert_string(hash_head);
2125 }
2126 while(--prev_length_ != 0);
2127 match_available_ = 0;
2128 match_length_ = minMatch-1;
2129 strstart_++;
2130
2131 if(bflush)
2132 {
2133 flush_block(zs, false);
2134 if(zs.avail_out == 0)
2135 return need_more;
2136 }
2137
2138 }
2139 else if(match_available_)
2140 {
2141
2142
2143
2144
2145 tr_tally_lit(window_[strstart_-1], bflush);
2146 if(bflush)
2147 flush_block(zs, false);
2148 strstart_++;
2149 lookahead_--;
2150 if(zs.avail_out == 0)
2151 return need_more;
2152 }
2153 else
2154 {
2155
2156
2157
2158 match_available_ = 1;
2159 strstart_++;
2160 lookahead_--;
2161 }
2162 }
2163 BOOST_ASSERT(flush != Flush::none);
2164 if(match_available_)
2165 {
2166 tr_tally_lit(window_[strstart_-1], bflush);
2167 match_available_ = 0;
2168 }
2169 insert_ = strstart_ < minMatch-1 ? strstart_ : minMatch-1;
2170 if(flush == Flush::finish)
2171 {
2172 flush_block(zs, true);
2173 if(zs.avail_out == 0)
2174 return finish_started;
2175 return finish_done;
2176 }
2177 if(sym_next_)
2178 {
2179 flush_block(zs, false);
2180 if(zs.avail_out == 0)
2181 return need_more;
2182 }
2183 return block_done;
2184 }
2185
2186
2187
2188
2189
2190 auto
2191 deflate_stream::
2192 f_rle(z_params& zs, Flush flush) ->
2193 block_state
2194 {
2195 bool bflush;
2196 uInt prev;
2197 Byte *scan, *strend;
2198
2199 for(;;)
2200 {
2201
2202
2203
2204
2205 if(lookahead_ <= maxMatch) {
2206 fill_window(zs);
2207 if(lookahead_ <= maxMatch && flush == Flush::none) {
2208 return need_more;
2209 }
2210 if(lookahead_ == 0) break;
2211 }
2212
2213
2214 match_length_ = 0;
2215 if(lookahead_ >= minMatch && strstart_ > 0) {
2216 scan = window_ + strstart_ - 1;
2217 prev = *scan;
2218 if(prev == *++scan && prev == *++scan && prev == *++scan) {
2219 strend = window_ + strstart_ + maxMatch;
2220 do {
2221 } while(prev == *++scan && prev == *++scan &&
2222 prev == *++scan && prev == *++scan &&
2223 prev == *++scan && prev == *++scan &&
2224 prev == *++scan && prev == *++scan &&
2225 scan < strend);
2226 match_length_ = maxMatch - (int)(strend - scan);
2227 if(match_length_ > lookahead_)
2228 match_length_ = lookahead_;
2229 }
2230 BOOST_ASSERT(scan <= window_+(uInt)(window_size_-1));
2231 }
2232
2233
2234 if(match_length_ >= minMatch) {
2235 tr_tally_dist(std::uint16_t{1},
2236 static_cast<std::uint8_t>(match_length_ - minMatch),
2237 bflush);
2238
2239 lookahead_ -= match_length_;
2240 strstart_ += match_length_;
2241 match_length_ = 0;
2242 } else {
2243
2244 tr_tally_lit(window_[strstart_], bflush);
2245 lookahead_--;
2246 strstart_++;
2247 }
2248 if(bflush)
2249 {
2250 flush_block(zs, false);
2251 if(zs.avail_out == 0)
2252 return need_more;
2253 }
2254 }
2255 insert_ = 0;
2256 if(flush == Flush::finish)
2257 {
2258 flush_block(zs, true);
2259 if(zs.avail_out == 0)
2260 return finish_started;
2261 return finish_done;
2262 }
2263 if(sym_next_)
2264 {
2265 flush_block(zs, false);
2266 if(zs.avail_out == 0)
2267 return need_more;
2268 }
2269 return block_done;
2270 }
2271
2272
2273
2274
2275
2276 auto
2277 deflate_stream::
2278 f_huff(z_params& zs, Flush flush) ->
2279 block_state
2280 {
2281 bool bflush;
2282
2283 for(;;)
2284 {
2285
2286 if(lookahead_ == 0)
2287 {
2288 fill_window(zs);
2289 if(lookahead_ == 0)
2290 {
2291 if(flush == Flush::none)
2292 return need_more;
2293 break;
2294 }
2295 }
2296
2297
2298 match_length_ = 0;
2299 tr_tally_lit(window_[strstart_], bflush);
2300 lookahead_--;
2301 strstart_++;
2302 if(bflush)
2303 {
2304 flush_block(zs, false);
2305 if(zs.avail_out == 0)
2306 return need_more;
2307 }
2308 }
2309 insert_ = 0;
2310 if(flush == Flush::finish)
2311 {
2312 flush_block(zs, true);
2313 if(zs.avail_out == 0)
2314 return finish_started;
2315 return finish_done;
2316 }
2317 if(sym_next_)
2318 {
2319 flush_block(zs, false);
2320 if(zs.avail_out == 0)
2321 return need_more;
2322 }
2323 return block_done;
2324 }
2325
2326 }
2327 }
2328 }
2329 }
2330
2331 #endif